{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "provenance": []
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "source": [
        "# Ноутбук для решения задач для урока М4 Basic-Advansic prompting"
      ],
      "metadata": {
        "id": "-mnYN5T7EkAf"
      }
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "YfVGMp8AkODF"
      },
      "outputs": [],
      "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"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "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": "a339b6d6-b52a-4874-9017-438ac83970a0"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "--2024-04-16 10:16:55--  https://raw.githubusercontent.com/a-milenkin/LLM_practical_course/main/notebooks/utils.py\n",
            "Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...\n",
            "Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.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-16 10:16:55 (84.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": "cdfe581c-e2c4-4f03-eed7-9845742d2923"
      },
      "execution_count": null,
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Введите ваш API ключ, полученный в боте курса··········\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Задание 4.3.6 Судоку 🔢\n",
        "\n"
      ],
      "metadata": {
        "id": "QpOaZMEOjr6u"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# если давать условие на английском, модель работает лучше\n",
        "sudoku_puzzle = \"3,*,*,2|1,*,3,*|*,1,*,3|4,*,*,1\"\n",
        "sudoku_solution = \"3,4,1,2|1,2,3,4|2,1,4,3|4,3,2,1\"\n",
        "problem_description = f\"\"\"\n",
        "{sudoku_puzzle}\n",
        "\n",
        "- This is a 4x4 Sudoku puzzle.\n",
        "- The * represents a cell to be filled.\n",
        "- The | character separates rows.\n",
        "- At each step, replace one or more * with digits 1-4.\n",
        "- There must be no duplicate digits in any row, column or 2x2 subgrid.\n",
        "- Keep the known digits from previous valid thoughts in place.\n",
        "- Each thought can be a partial or the final solution.\n",
        "\"\"\".strip()\n",
        "print(problem_description)"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "Zh03MuT9ajxm",
        "outputId": "6a7439f3-c624-452e-defb-7b16b5d2fa80"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "3,*,*,2|1,*,3,*|*,1,*,3|4,*,*,1\n",
            "\n",
            "- This is a 4x4 Sudoku puzzle.\n",
            "- The * represents a cell to be filled.\n",
            "- The | character separates rows.\n",
            "- At each step, replace one or more * with digits 1-4.\n",
            "- There must be no duplicate digits in any row, column or 2x2 subgrid.\n",
            "- Keep the known digits from previous valid thoughts in place.\n",
            "- Each thought can be a partial or the final solution.\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "sudoku_puzzle = \"3,*,*,2|1,*,3,*|*,1,*,3|4,*,*,1\"\n",
        "sudoku_solution = \"3,4,1,2|1,2,3,4|2,1,4,3|4,3,2,1\"\n",
        "problem_description = f\"\"\"\n",
        "{sudoku_puzzle}\n",
        "- Это головоломка Судоку размером 4x4.\n",
        "- Символ * обозначает ячейку, которую тебе нужно заполнить.\n",
        "- Символ | разделяет строки.\n",
        "- На каждом шаге замени одну или несколько * цифрами от 1 до 4.\n",
        "- Напиши текущее состояние пазла с добавленными цифрами\n",
        "- Ни в одной строке, столбце или 2x2 подсетке не должно быть одинаковых цифр.\n",
        "- Сохраняй полученные цифры из предыдущих успешных мыслей на своих местах.\n",
        "- Каждая мысль может быть промежуточным или окончательным решением.\n",
        "\"\"\".strip()\n",
        "print(problem_description)"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "l8NPOobddwbj",
        "outputId": "0f130fb0-b308-4bd9-e693-4848b295b25b"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "3,*,*,2|1,*,3,*|*,1,*,3|4,*,*,1\n",
            "- Это головоломка Судоку размером 4x4.\n",
            "- Символ * обозначает ячейку, которую тебе нужно заполнить.\n",
            "- Символ | разделяет строки.\n",
            "- На каждом шаге замени одну или несколько * цифрами от 1 до 4.\n",
            "- Напиши текущее состояние пазла с добавленными цифрами\n",
            "- Ни в одной строке, столбце или 2x2 подсетке не должно быть одинаковых цифр.\n",
            "- Сохраняй полученные цифры из предыдущих успешных мыслей на своих местах.\n",
            "- Каждая мысль может быть промежуточным или окончательным решением.\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# напишите чекер для нашей задачи, и проверьте его работоспособность на тестах в следующей ячейке\n",
        "import re\n",
        "from typing import Tuple\n",
        "\n",
        "from langchain_experimental.tot.checker import ToTChecker\n",
        "from langchain_experimental.tot.thought import ThoughtValidity\n",
        "\n",
        "\n",
        "class MyChecker(ToTChecker):\n",
        "    # реализация класса"
      ],
      "metadata": {
        "id": "J_w3deFpajuy"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "Проверьте, правильно ли работает ваш чекер на тестах. Можете также написать свои тесты."
      ],
      "metadata": {
        "id": "3NWKXKyhi1ks"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "checker = MyChecker()\n",
        "assert (\n",
        "    checker.evaluate(\"\", (\"3,*,*,2|1,*,3,*|*,1,*,3|4,*,*,1\",))\n",
        "    == ThoughtValidity.VALID_INTERMEDIATE\n",
        ")\n",
        "assert (\n",
        "    checker.evaluate(\"\", (\"3,4,1,2|1,2,3,4|2,1,4,3|4,3,2,1\",))\n",
        "    == ThoughtValidity.VALID_FINAL\n",
        ")\n",
        "assert (\n",
        "    checker.evaluate(\"\", (\"3,4,1,2|1,2,3,4|2,1,4,3|4,3,*,1\",))\n",
        "    == ThoughtValidity.VALID_INTERMEDIATE\n",
        ")\n",
        "assert (\n",
        "    checker.evaluate(\"\", (\"3,4,1,2|1,2,3,4|2,1,4,3|4,*,3,1\",))\n",
        "    == ThoughtValidity.INVALID\n",
        ")"
      ],
      "metadata": {
        "id": "WwFq8ZKcdcp6"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "# запустим tot, если хотите (будут тратиться токены)\n",
        "from langchain_experimental.tot.base import ToTChain\n",
        "\n",
        "tot_chain = ToTChain(\n",
        "    llm=llm, checker=MyChecker(), k=30, c=2, verbose=True, verbose_llm=False\n",
        ")\n",
        "tot_chain.invoke({'problem_description': problem_description})"
      ],
      "metadata": {
        "id": "dBx62BxCbjAL"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Задание 4.3.7 🥊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 ###\n",
        "\n",
        "pal_chain = ###"
      ],
      "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",
        "    answer = # ваш код\n",
        "\n",
        "    answers.append(answer)\n",
        "\n",
        "\n",
        "    #break # Для отладки. Уберите, когда убедитесь, что на одном примере работает"
      ],
      "metadata": {
        "id": "aJCWxZshoZZO"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "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": []
    }
  ]
}