You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

616 lines
57 KiB
Plaintext

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

{
"cells": [
{
"cell_type": "markdown",
"id": "a85683d0",
"metadata": {},
"source": [
"# Отладка #"
]
},
{
"cell_type": "markdown",
"id": "696f9c7a",
"metadata": {},
"source": [
"Привет. На этой лекции мы с вами поговорим про отладку в Python. Скорее всего отладкой вы уже занимались, когда пытались выяснить, почему ваша программа не работает или работает некорректно. Если вы программируете в IDE, скорее всего, там уже есть инструментарий для отладки вашего кода, и вы можете запускать вашу программу под отладчиком, ставить какие-то брейкпоинты, следить за переменными, и так далее. Мы с вами разберём классический механизм отладки с помощью Python Debugger'а и делать мы это будем на примере."
]
},
{
"cell_type": "markdown",
"id": "7a9e869b",
"metadata": {},
"source": [
"Мы напишем программу, которая принимает на вход сайт, URL сайта и какую-то строчку, и ищет в коде сайта эту строчку и считает, сколько раз там встретилась эта строка. Давайте напишем нашу программу и попробуем её отладить."
]
},
{
"cell_type": "markdown",
"id": "ec880120",
"metadata": {},
"source": [
"Определим функцию `main`, которая принимает `site_url` и `substring`, и давайте получим вначале `site_code` с помощью функции `get_site_code`, которой передадим `site_url`."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "0f852142",
"metadata": {},
"outputs": [],
"source": [
"def main(site_url, substring):\n",
" site_code = get_site_code(site_url)"
]
},
{
"cell_type": "markdown",
"id": "463acf3b",
"metadata": {},
"source": [
"Давайте определим ниже функцию `get_site_code`, которая принимает `site_url`, и чтобы получить `site_code` мы можем воспользоваться уже знакомой вам библиотекой `requests` и передать туда `site_url` и вернуть текст.\n",
"\n",
"Давайте ещё проверим, что нам, допустим, передан корректный `site_url`. Здесь у нас с этого начинается, со схемы, мы эту схему добавим. Простая проверка, почему бы и нет?"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "edb2cff5",
"metadata": {},
"outputs": [],
"source": [
"def get_site_code(site_url):\n",
" if not site_url.startswith(\"http\"):\n",
" site_url = \"http://\" + site_url\n",
" \n",
" return requests.get(site_url).text"
]
},
{
"cell_type": "markdown",
"id": "27c8dac9",
"metadata": {},
"source": [
"Итак, у нас есть наш `site_code`, осталось импортировать `requests`, чтоб всё работало, теперь нам нужно получить все подстроки, которые мы нашли."
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "a488e462",
"metadata": {},
"outputs": [],
"source": [
"import requests"
]
},
{
"cell_type": "markdown",
"id": "8b3e4b8c",
"metadata": {},
"source": [
"Давайте назовем переменнную `matching_substrings` и вызовем функцию `get_matching_substrings`, которой передадим `site_code` и `substring`. Отлично."
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "257bb19e",
"metadata": {},
"outputs": [],
"source": [
"def main(site_url, substring):\n",
" site_code = get_site_code(site_url)\n",
" matching_substrings = get_matching_substrings(site_code, substring)"
]
},
{
"cell_type": "markdown",
"id": "34e4025a",
"metadata": {},
"source": [
"Определим чуть ниже эту самую функцию `get_matching_substrings`. Давайте, пусть у нас переменные будут называться `source` и `substring`, потому что мы можем использовать эту функцию в разных местах, не только здесь. Для того чтобы найти вхождения подстроки в строку мы воспользуемся регулярными выражениями стандартной библиотеки, модулем `re`, используем функцию `findall` и передадим в неё `source` и `substring`. Таким образом, мы будeм искать не только подстроки, но можем искать, например, по какому-то регулярному выражению."
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "89950f89",
"metadata": {},
"outputs": [],
"source": [
"def get_matching_substrings(source, substring):\n",
" return re.findall(source, substring)"
]
},
{
"cell_type": "markdown",
"id": "9d62a32a",
"metadata": {},
"source": [
"Давайте импортируем `re` для того, чтобы всё работало. Отлично."
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "7bc159b2",
"metadata": {},
"outputs": [],
"source": [
"import re"
]
},
{
"cell_type": "markdown",
"id": "302a5e85",
"metadata": {},
"source": [
"Мы получили подстроки и нам нужно их посчитать. Давайте выведем сразу наш результат и мы скажем, что мы нашли подстроку сколько-то раз в таком-то сайте. Давайте отформатируем. Форматируем. Напишем `substring`, найдена она ровно `len(matching_substring)` раз `site_url`. Отлично!"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "c01187fc",
"metadata": {},
"outputs": [],
"source": [
"def main(site_url, substring):\n",
" site_code = get_site_code(site_url)\n",
" matching_substrings = get_matching_substrings(site_code, substring)\n",
" print(f\"'{substring}' found {len(matching_substrings)} times in {site_url}\")"
]
},
{
"cell_type": "markdown",
"id": "dc340754",
"metadata": {},
"source": [
"Это и будет результатом. И давайте вызовем нашу функцию. В этот момент уже начнётся процесс отладки, потому что скорее всего сразу она не заработает. И, например, не заработает она потому, что мы не передали в функцию main параметра."
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "277aa27d",
"metadata": {},
"outputs": [
{
"ename": "TypeError",
"evalue": "main() missing 2 required positional arguments: 'site_url' and 'substring'",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-8-263240bbee7e>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mmain\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;31mTypeError\u001b[0m: main() missing 2 required positional arguments: 'site_url' and 'substring'"
]
}
],
"source": [
"main()"
]
},
{
"cell_type": "markdown",
"id": "ce93873e",
"metadata": {},
"source": [
"Итак, процесс отладки уже начат, мы смотрим на исключения, читаем, что нам исключение это говорит. Давайте исправим это, передадим туда сайт vniitf.ru и python, допустим, поскольку python будем искать в сайте vniitf.ru. Давайте запустим и посмотрим, что у нас не работает дальше. Итак, у нас какая-то проблема в `get_matching_substrings` очевидно."
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "3a63069d",
"metadata": {},
"outputs": [
{
"ename": "error",
"evalue": "bad character range 0-% at position 20016 (line 412, column 353)",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31merror\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-9-558214cc4502>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mmain\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"sinfo\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"python\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;32m<ipython-input-7-7cd9a99164ff>\u001b[0m in \u001b[0;36mmain\u001b[0;34m(site_url, substring)\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mmain\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msite_url\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msubstring\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0msite_code\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_site_code\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msite_url\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mmatching_substrings\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_matching_substrings\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msite_code\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msubstring\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mf\"'{substring}' found {len(matching_substrings)} times in {site_url}\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m<ipython-input-5-cc21a11c7363>\u001b[0m in \u001b[0;36mget_matching_substrings\u001b[0;34m(source, substring)\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mget_matching_substrings\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msource\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msubstring\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mre\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfindall\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msource\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msubstring\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;32m/usr/lib64/python3.6/re.py\u001b[0m in \u001b[0;36mfindall\u001b[0;34m(pattern, string, flags)\u001b[0m\n\u001b[1;32m 220\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 221\u001b[0m Empty matches are included in the result.\"\"\"\n\u001b[0;32m--> 222\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0m_compile\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpattern\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mflags\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfindall\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstring\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 223\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 224\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mfinditer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpattern\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstring\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mflags\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/usr/lib64/python3.6/re.py\u001b[0m in \u001b[0;36m_compile\u001b[0;34m(pattern, flags)\u001b[0m\n\u001b[1;32m 299\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0msre_compile\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0misstring\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpattern\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 300\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mTypeError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"first argument must be string or compiled pattern\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 301\u001b[0;31m \u001b[0mp\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0msre_compile\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcompile\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpattern\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mflags\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 302\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mflags\u001b[0m \u001b[0;34m&\u001b[0m \u001b[0mDEBUG\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 303\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0m_cache\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m>=\u001b[0m \u001b[0m_MAXCACHE\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/usr/lib64/python3.6/sre_compile.py\u001b[0m in \u001b[0;36mcompile\u001b[0;34m(p, flags)\u001b[0m\n\u001b[1;32m 560\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0misstring\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mp\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 561\u001b[0m \u001b[0mpattern\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mp\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 562\u001b[0;31m \u001b[0mp\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0msre_parse\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mparse\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mp\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mflags\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 563\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 564\u001b[0m \u001b[0mpattern\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/usr/lib64/python3.6/sre_parse.py\u001b[0m in \u001b[0;36mparse\u001b[0;34m(str, flags, pattern)\u001b[0m\n\u001b[1;32m 853\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 854\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 855\u001b[0;31m \u001b[0mp\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0m_parse_sub\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msource\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mpattern\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mflags\u001b[0m \u001b[0;34m&\u001b[0m \u001b[0mSRE_FLAG_VERBOSE\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 856\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mVerbose\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 857\u001b[0m \u001b[0;31m# the VERBOSE flag was switched on inside the pattern. to be\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/usr/lib64/python3.6/sre_parse.py\u001b[0m in \u001b[0;36m_parse_sub\u001b[0;34m(source, state, verbose, nested)\u001b[0m\n\u001b[1;32m 414\u001b[0m \u001b[0;32mwhile\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 415\u001b[0m itemsappend(_parse(source, state, verbose, nested + 1,\n\u001b[0;32m--> 416\u001b[0;31m not nested and not items))\n\u001b[0m\u001b[1;32m 417\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0msourcematch\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"|\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 418\u001b[0m \u001b[0;32mbreak\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/usr/lib64/python3.6/sre_parse.py\u001b[0m in \u001b[0;36m_parse\u001b[0;34m(source, state, verbose, nested, first)\u001b[0m\n\u001b[1;32m 551\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mhi\u001b[0m \u001b[0;34m<\u001b[0m \u001b[0mlo\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 552\u001b[0m \u001b[0mmsg\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m\"bad character range %s-%s\"\u001b[0m \u001b[0;34m%\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mthis\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mthat\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 553\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0msource\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0merror\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmsg\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mthis\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m1\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mthat\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 554\u001b[0m \u001b[0msetappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mRANGE\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mlo\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mhi\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 555\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31merror\u001b[0m: bad character range 0-% at position 20016 (line 412, column 353)"
]
}
],
"source": [
"main(\"vniitf.ru\", \"python\")"
]
},
{
"cell_type": "markdown",
"id": "2457b754",
"metadata": {},
"source": [
"Совершенно непонятно, что же случилось. По этой ошибке нельзя однозначно сказать, почему наша программа не работает. В данном случае на помощь нам может прийти отладчик. Опять же простейшая отладка заключается в том, что мы смотрим на исключения или на ошибку и, допустим, выводим какие-то переменные, смотрим, что они корректные или некорректные. Можно использовать отладчик. Для того чтобы запустить отладчик в нашей программе, мы можем импортировать `pdb` и сказать, что, пожалуйста, запусти отладку в этом месте. `pdb.set_trace` — это стандартный способ, импорт прямо здесь, `set_trace` прямо здесь, и давайте запустим нашу программу под отладчиком."
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "21d4d55d",
"metadata": {},
"outputs": [],
"source": [
"def main(site_url, substring):\n",
" import pdb\n",
" pdb.set_trace()\n",
" \n",
" site_code = get_site_code(site_url)\n",
" matching_substrings = get_matching_substrings(site_code, substring)\n",
" print(f\"'{substring}' found {len(matching_substrings)} times in {site_url}\")"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "894621f2",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"> \u001b[0;32m<ipython-input-10-dd0d3292f80f>\u001b[0m(5)\u001b[0;36mmain\u001b[0;34m()\u001b[0m\n",
"\u001b[0;32m 3 \u001b[0;31m \u001b[0mpdb\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mset_trace\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0m\u001b[0;32m 4 \u001b[0;31m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0m\u001b[0;32m----> 5 \u001b[0;31m \u001b[0msite_code\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_site_code\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msite_url\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0m\u001b[0;32m 6 \u001b[0;31m \u001b[0mmatching_substrings\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_matching_substrings\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msite_code\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msubstring\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0m\u001b[0;32m 7 \u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mf\"'{substring}' found {len(matching_substrings)} times in {site_url}\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0m\n",
"ipdb> ll\n",
"\u001b[1;32m 1 \u001b[0m\u001b[0;32mdef\u001b[0m \u001b[0mmain\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msite_url\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msubstring\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[1;32m 2 \u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mpdb\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[1;32m 3 \u001b[0m \u001b[0mpdb\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mset_trace\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[1;32m 4 \u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m----> 5 \u001b[0;31m \u001b[0msite_code\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_site_code\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msite_url\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0m\u001b[1;32m 6 \u001b[0m \u001b[0mmatching_substrings\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_matching_substrings\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msite_code\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msubstring\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[1;32m 7 \u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mf\"'{substring}' found {len(matching_substrings)} times in {site_url}\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\n",
"ipdb> help\n",
"\n",
"Documented commands (type help <topic>):\n",
"========================================\n",
"EOF cl disable interact next psource rv undisplay\n",
"a clear display j p q s unt \n",
"alias commands down jump pdef quit skip_hidden until \n",
"args condition enable l pdoc r source up \n",
"b cont exit list pfile restart step w \n",
"break continue h ll pinfo return tbreak whatis \n",
"bt d help longlist pinfo2 retval u where \n",
"c debug ignore n pp run unalias \n",
"\n",
"Miscellaneous help topics:\n",
"==========================\n",
"exec pdb\n",
"\n",
"ipdb> ? p\n",
"p expression\n",
" Print the value of the expression.\n",
"ipdb> args\n",
"site_url = 'sinfo'\n",
"substring = 'python'\n",
"ipdb> ll\n",
"\u001b[1;32m 1 \u001b[0m\u001b[0;32mdef\u001b[0m \u001b[0mmain\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msite_url\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msubstring\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[1;32m 2 \u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mpdb\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[1;32m 3 \u001b[0m \u001b[0mpdb\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mset_trace\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[1;32m 4 \u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m----> 5 \u001b[0;31m \u001b[0msite_code\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_site_code\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msite_url\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0m\u001b[1;32m 6 \u001b[0m \u001b[0mmatching_substrings\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_matching_substrings\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msite_code\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msubstring\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[1;32m 7 \u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mf\"'{substring}' found {len(matching_substrings)} times in {site_url}\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\n",
"ipdb> next\n",
"> \u001b[0;32m<ipython-input-10-dd0d3292f80f>\u001b[0m(6)\u001b[0;36mmain\u001b[0;34m()\u001b[0m\n",
"\u001b[0;32m 3 \u001b[0;31m \u001b[0mpdb\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mset_trace\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0m\u001b[0;32m 4 \u001b[0;31m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0m\u001b[0;32m 5 \u001b[0;31m \u001b[0msite_code\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_site_code\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msite_url\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0m\u001b[0;32m----> 6 \u001b[0;31m \u001b[0mmatching_substrings\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_matching_substrings\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msite_code\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msubstring\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0m\u001b[0;32m 7 \u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mf\"'{substring}' found {len(matching_substrings)} times in {site_url}\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0m\n",
"ipdb> step\n",
"--Call--\n",
"> \u001b[0;32m<ipython-input-5-cc21a11c7363>\u001b[0m(1)\u001b[0;36mget_matching_substrings\u001b[0;34m()\u001b[0m\n",
"\u001b[0;32m----> 1 \u001b[0;31m\u001b[0;32mdef\u001b[0m \u001b[0mget_matching_substrings\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msource\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msubstring\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0m\u001b[0;32m 2 \u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mre\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfindall\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msource\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msubstring\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0m\n",
"ipdb> n\n",
"> \u001b[0;32m<ipython-input-5-cc21a11c7363>\u001b[0m(2)\u001b[0;36mget_matching_substrings\u001b[0;34m()\u001b[0m\n",
"\u001b[0;32m 1 \u001b[0;31m\u001b[0;32mdef\u001b[0m \u001b[0mget_matching_substrings\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msource\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msubstring\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0m\u001b[0;32m----> 2 \u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mre\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfindall\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msource\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msubstring\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0m\n",
"ipdb> s\n",
"--Call--\n",
"> \u001b[0;32m/usr/lib64/python3.6/re.py\u001b[0m(214)\u001b[0;36mfindall\u001b[0;34m()\u001b[0m\n",
"\u001b[0;32m 212 \u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0m_compile\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpattern\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mflags\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msplit\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstring\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmaxsplit\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0m\u001b[0;32m 213 \u001b[0;31m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0m\u001b[0;32m--> 214 \u001b[0;31m\u001b[0;32mdef\u001b[0m \u001b[0mfindall\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpattern\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstring\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mflags\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0m\u001b[0;32m 215 \u001b[0;31m \"\"\"Return a list of all non-overlapping matches in the string.\n",
"\u001b[0m\u001b[0;32m 216 \u001b[0;31m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0m\n",
"ipdb> q\n"
]
},
{
"ename": "BdbQuit",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mBdbQuit\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-11-558214cc4502>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mmain\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"sinfo\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"python\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;32m<ipython-input-10-dd0d3292f80f>\u001b[0m in \u001b[0;36mmain\u001b[0;34m(site_url, substring)\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0msite_code\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_site_code\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msite_url\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m \u001b[0mmatching_substrings\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_matching_substrings\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msite_code\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msubstring\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 7\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mf\"'{substring}' found {len(matching_substrings)} times in {site_url}\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m<ipython-input-5-cc21a11c7363>\u001b[0m in \u001b[0;36mget_matching_substrings\u001b[0;34m(source, substring)\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mget_matching_substrings\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msource\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msubstring\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mre\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfindall\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msource\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msubstring\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;32m/usr/lib64/python3.6/re.py\u001b[0m in \u001b[0;36mfindall\u001b[0;34m(pattern, string, flags)\u001b[0m\n\u001b[1;32m 212\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0m_compile\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpattern\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mflags\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msplit\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstring\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmaxsplit\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 213\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 214\u001b[0;31m \u001b[0;32mdef\u001b[0m \u001b[0mfindall\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpattern\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstring\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mflags\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 215\u001b[0m \"\"\"Return a list of all non-overlapping matches in the string.\n\u001b[1;32m 216\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/usr/lib64/python3.6/bdb.py\u001b[0m in \u001b[0;36mtrace_dispatch\u001b[0;34m(self, frame, event, arg)\u001b[0m\n\u001b[1;32m 51\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdispatch_line\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mframe\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 52\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mevent\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m'call'\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 53\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdispatch_call\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mframe\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0marg\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 54\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mevent\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m'return'\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 55\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdispatch_return\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mframe\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0marg\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/usr/lib64/python3.6/bdb.py\u001b[0m in \u001b[0;36mdispatch_call\u001b[0;34m(self, frame, arg)\u001b[0m\n\u001b[1;32m 84\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtrace_dispatch\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 85\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0muser_call\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mframe\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0marg\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 86\u001b[0;31m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mquitting\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mBdbQuit\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 87\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtrace_dispatch\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 88\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mBdbQuit\u001b[0m: "
]
}
],
"source": [
"main(\"vniitf.ru\", \"python\")"
]
},
{
"cell_type": "markdown",
"id": "997970f2",
"metadata": {},
"source": [
"Итак, мы запустили программу, однако, она не дошла до ошибки, она остановилась именно в том месте, где мы наш отладчик определили. Мы можем посмотреть, где это находится, с помощью команды `long list`. Итак, мы находимся ровно за тем местом, где наш отладчик определён и смотрим на функцию `get_site_code`.\n",
"\n",
"У отладчика довольно много команд, их можно посмотреть с помощью функции `help`. Функция `help` выводит все команды, мы можем также написать знак вопроса вместо функции `help` и, например, мы можем посмотреть про какую-то конкретную команду, что она делает.\n",
"\n",
"Например, давайте посмотрим, что делает команда `p`. Команда `p` — это сокращение от `print`'а и она выводит просто выражение. Мы можем вывести какую-то переменную, которая находится в области нашей видимости. Есть полезная команда `args`, которая говорит о том, какие аргументы переданы функции, в которой мы находимся. Сейчас мы находимся в функции `main` и аргументы переданы правильно и всё корректно. Итак, дальше у нас есть несколько опций. Мы остановились в отладчике и мы можем продолжать как-то наше исполнение кода под отладчиком. Мы можем написать `continue` или `c` и продолжить исполнение дальше до конца, пока у нас не закончится программа или не упадёт исключение или не появится какой-то брейкпоинт.\n",
"\n",
"Однако, нам интересно отлаживать, поэтому это не вариант. Дальше, у нас есть несколько опций. Мы можем написать `step` и провалиться внутрь функции, однако у нас ошибка не внутри функции, а дальше, поэтому мы напишем `next` и перейдём на следующую строку. Следующая строка — это вызов функции `get_matching_substrings`, куда нам и нужно. Чтобы пройти внутрь функции, не пропуская её, мы можем написать `step` и `less` и оказаться внутри функции внутри функции `get_matching_substrings`. Итак, давайте пойдём дальше, и дальше у нас вызов функции `findall`. Именно там и была ошибка. Давайте посмотрим, что же у нас происходит. Итак, мы в `findall` передаём `source` и `substring` и пытаемся найти `substring` в `source`. Давайте зайдём в `findall`, которая определена в стандартной библиотеке и посмотрим, что же там происходит. Итак, на самом деле, внимательный читатель уже заметит, в чём была ошибка, если мы посмотрим на определение `findall`. `findall` принимает вначале паттерн, а потом строку, и ищет этот паттерн в строке, а мы передаём ровно наоборот. Именно это и является ошибкой. Давайте выйдем или продолжим исполнение. Давайте выйдем. Чтобы выйти, нужно написать в `query quit`, и мы просто выйдем из `debugger`'а по исключению.\n",
"\n",
"Итак, давайте поменяем местами и посмотрим, неужели это и была ошибка наша."
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "b6bbf6c6",
"metadata": {},
"outputs": [],
"source": [
"def get_matching_substrings(source, substring):\n",
" return re.findall(substring, source)"
]
},
{
"cell_type": "markdown",
"id": "c3d3f48a",
"metadata": {},
"source": [
"Давайте запустим ещё с отладчиком, и я покажу вам ещё один момент, который бывает полезным. Часто вам необходимо отлаживать не в одном месте, а вы хотите, например, продолжить исполнение до какого-то определённого момента. На помощь нам могут прийти брейкпоинты, которые, например, в IDE ставятся очень удобно."
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "a5280d4a",
"metadata": {
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"> \u001b[0;32m<ipython-input-10-dd0d3292f80f>\u001b[0m(5)\u001b[0;36mmain\u001b[0;34m()\u001b[0m\n",
"\u001b[0;32m 3 \u001b[0;31m \u001b[0mpdb\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mset_trace\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0m\u001b[0;32m 4 \u001b[0;31m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0m\u001b[0;32m----> 5 \u001b[0;31m \u001b[0msite_code\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_site_code\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msite_url\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0m\u001b[0;32m 6 \u001b[0;31m \u001b[0mmatching_substrings\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_matching_substrings\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msite_code\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msubstring\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0m\u001b[0;32m 7 \u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mf\"'{substring}' found {len(matching_substrings)} times in {site_url}\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0m\n",
"ipdb> ll\n",
"\u001b[1;32m 1 \u001b[0m\u001b[0;32mdef\u001b[0m \u001b[0mmain\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msite_url\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msubstring\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[1;32m 2 \u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mpdb\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[1;32m 3 \u001b[0m \u001b[0mpdb\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mset_trace\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[1;32m 4 \u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m----> 5 \u001b[0;31m \u001b[0msite_code\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_site_code\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msite_url\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0m\u001b[1;32m 6 \u001b[0m \u001b[0mmatching_substrings\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_matching_substrings\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msite_code\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msubstring\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[1;32m 7 \u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mf\"'{substring}' found {len(matching_substrings)} times in {site_url}\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\n",
"ipdb> b\n",
"ipdb> b 7\n",
"Breakpoint 1 at <ipython-input-10-dd0d3292f80f>:7\n",
"ipdb> cont\n",
"> \u001b[0;32m<ipython-input-10-dd0d3292f80f>\u001b[0m(7)\u001b[0;36mmain\u001b[0;34m()\u001b[0m\n",
"\u001b[0;32m 3 \u001b[0;31m \u001b[0mpdb\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mset_trace\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0m\u001b[0;32m 4 \u001b[0;31m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0m\u001b[0;32m 5 \u001b[0;31m \u001b[0msite_code\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_site_code\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msite_url\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0m\u001b[0;32m 6 \u001b[0;31m \u001b[0mmatching_substrings\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_matching_substrings\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msite_code\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msubstring\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0m\u001b[1;31m1\u001b[0;32m---> 7 \u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mf\"'{substring}' found {len(matching_substrings)} times in {site_url}\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0m\n",
"ipdb> q\n"
]
},
{
"ename": "BdbQuit",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mBdbQuit\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-14-558214cc4502>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mmain\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"sinfo\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"python\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;32m<ipython-input-10-dd0d3292f80f>\u001b[0m in \u001b[0;36mmain\u001b[0;34m(site_url, substring)\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0msite_code\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_site_code\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msite_url\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0mmatching_substrings\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_matching_substrings\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msite_code\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msubstring\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 7\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mf\"'{substring}' found {len(matching_substrings)} times in {site_url}\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;32m<ipython-input-10-dd0d3292f80f>\u001b[0m in \u001b[0;36mmain\u001b[0;34m(site_url, substring)\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0msite_code\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_site_code\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msite_url\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0mmatching_substrings\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_matching_substrings\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msite_code\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msubstring\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 7\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mf\"'{substring}' found {len(matching_substrings)} times in {site_url}\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;32m/usr/lib64/python3.6/bdb.py\u001b[0m in \u001b[0;36mtrace_dispatch\u001b[0;34m(self, frame, event, arg)\u001b[0m\n\u001b[1;32m 49\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;31m# None\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 50\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mevent\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m'line'\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 51\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdispatch_line\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mframe\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 52\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mevent\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m'call'\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 53\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdispatch_call\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mframe\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0marg\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/usr/lib64/python3.6/bdb.py\u001b[0m in \u001b[0;36mdispatch_line\u001b[0;34m(self, frame)\u001b[0m\n\u001b[1;32m 68\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstop_here\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mframe\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbreak_here\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mframe\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 69\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0muser_line\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mframe\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 70\u001b[0;31m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mquitting\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mBdbQuit\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 71\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtrace_dispatch\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 72\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mBdbQuit\u001b[0m: "
]
}
],
"source": [
"main(\"vniitf.ru\", \"python\")"
]
},
{
"cell_type": "markdown",
"id": "9707481e",
"metadata": {},
"source": [
"Здесь можно воспользоваться командой `b`, которая, если просто напишем `b`, она выводит все брейкопоинты, которые мы уже определили. Если мы напишем `b` с номером строки, например, `b 7`, мы поставим брейкопоинт на десятую строку. И когда исполнение интерпретатором программы дойдёт до этой строки, он остановится. Мы можем написать `continue` и остановиться ровно на нашем брейкпоинте. Давайте выйдем, уберём `debugger` и проверим, корректно ли работает наша программа."
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "320d9e39",
"metadata": {},
"outputs": [],
"source": [
"def main(site_url, substring): \n",
" site_code = get_site_code(site_url)\n",
" matching_substrings = get_matching_substrings(site_code, substring)\n",
" print(f\"'{substring}' found {len(matching_substrings)} times in {site_url}\")"
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "f79af11d",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"'python' found 19 times in sinfo\n"
]
}
],
"source": [
"main(\"vniitf.ru\", \"python\")"
]
},
{
"cell_type": "markdown",
"id": "0dacbb93",
"metadata": {},
"source": [
"Мы нашли 19 раза в `site_code` vniitf.ru слово python."
]
},
{
"cell_type": "markdown",
"id": "3a274579",
"metadata": {},
"source": [
"Отлично, мы отладили нашу программу и посмотрели, почему она не работает с помощью `debugger`'а. Точно так же из `debugger`'а можно работать не в Jupyter ноутбуке, а в консоли, и можно запускать программу под отладкой с помощью такого механизма."
]
},
{
"cell_type": "markdown",
"id": "2051dc05",
"metadata": {},
"source": [
"Код нашей программы в данном случае называется `wc_web`, и мы можем запустить его под отладчиком. Здесь происходит всё то же самое, мы можем выполнять все те же самые команды и ставить брейкпоинты на какие-то места. Например, мы можем поставить брейкпоинт на шестую строку, продолжить исполнение, дойти до шестой строки, посмотреть аргументы, и так далее."
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "5550ac58",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"> /home/mikhaylovaf/projects/python/4. Углубленный Python/3. Отладка и тестирование/wc_web.py(1)<module>()\n",
"-> import re\n",
"(Pdb) \n",
"--KeyboardInterrupt--\n",
"(Pdb) "
]
}
],
"source": [
"! python -m pdb wc_web.py"
]
},
{
"cell_type": "markdown",
"id": "a2d4ee94",
"metadata": {},
"source": [
"Итак, мы с вами разобрали отладку в Python'е и теперь можем отлаживать наши программы и выяснять, почему они не работают. Удачи."
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "7ee7851b",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"'python' found 19 times in sinfo\n"
]
}
],
"source": [
"import re\n",
"import requests\n",
"\n",
"def main(site_url, substring):\n",
" site_code = get_site_code(site_url)\n",
" matching_substrings = get_matching_substrings(site_code, substring)\n",
" print(f\"'{substring}' found {len(matching_substrings)} times in {site_url}\")\n",
" \n",
"def get_site_code(site_url):\n",
" if not site_url.startswith(\"http\"):\n",
" site_url = \"http://\" + site_url\n",
" \n",
" return requests.get(site_url).text\n",
"\n",
"def get_matching_substrings(source, substring):\n",
" return re.findall(substring, source)\n",
"\n",
"main(\"vniitf.ru\", \"python\")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.8"
}
},
"nbformat": 4,
"nbformat_minor": 5
}