├── .gitignore ├── Homework.md ├── README.md ├── data ├── Twitter- Oscars(2).csv ├── addresses.txt ├── airbnb.csv ├── barcelona.zip ├── christmas_recipes.csv ├── cinnamon_roll.txt ├── city_smells.txt ├── corgi.txt ├── d_speech.txt ├── dreams.csv ├── elonmusk.csv ├── postcards.csv ├── test_basni.txt ├── tips.zip ├── transports.csv ├── world-happiness-report-2021.csv ├── world-happiness-report.csv ├── вертолет.txt ├── морж-корж.txt └── синт_неоднозначность.txt ├── homework ├── HW3.md ├── ДЗ-1.ipynb └── ДЗ-2.ipynb ├── notebooks ├── Markov_Chains_TexGen.ipynb ├── NER(SpaCy).ipynb ├── OOP-2_libraries.ipynb ├── Python functions.ipynb ├── classes.py ├── collocation_extraction.ipynb ├── files_OS.ipynb ├── freq_analysis_tf_idf.ipynb ├── generators.ipynb ├── get_your_dataset.ipynb ├── input,output.ipynb ├── intro_to_OOP.ipynb ├── lists,cycles.ipynb ├── morphology.ipynb ├── networkx.ipynb ├── ngrams.ipynb ├── pandas.ipynb ├── python_intro.ipynb ├── python_viz_mpl_seaborn.ipynb ├── regexes_class.ipynb ├── syntactic_parsers.ipynb ├── syntax_analysis_DeepPavlov.ipynb └── tuples, sets, dicts.ipynb ├── practice ├── func-practice.ipynb ├── pandas_practice.ipynb └── Отзывы_к_фильмам.ipynb └── slides ├── Pandas_Cheat_Sheet.pdf ├── Python & Git - лекция1 (2021).pdf └── git_instruction.pdf /.gitignore: -------------------------------------------------------------------------------- 1 | .ipynb_checkpoints 2 | */.ipynb_checkpoints/* 3 | -------------------------------------------------------------------------------- /Homework.md: -------------------------------------------------------------------------------- 1 | **формула оценки за курс**
2 | 30%(ДЗ) + 70%(финальный проект)
3 | оценка по 10-балльной шкале 4 | 5 | Время выполнения дз - 2 недели
6 | После дедлайна работу можно сдать, но максимальный балл за работу будет 7 7 | 8 | Как сдавать дз:
9 | сделайте его в удобном формате (.ipynb или .py), выложите код в свой репозиторий на гитхаб и пришлите ссылку Лиле.
10 | Если ваш репозиторий приватный, добавьте меня и Лилю коллабораторами ([инструкция](https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-github-user-account/managing-access-to-your-personal-repositories/inviting-collaborators-to-a-personal-repository)) 11 | 12 | |№ ДЗ|дата|тема|дедлайн| 13 | |-|-|-|-| 14 | |1|30 октября 2021|[списки,множества,словари + циклы](https://github.com/nstsj/python_for_CL/blob/master/homework/%D0%94%D0%97-1.ipynb)|13 ноября 2021| 15 | |2|||| 16 | |3|||| 17 | |4|||| 18 | |5|||| 19 | 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # python_for_CL 2 | материалы курса по Python для дпо-программы "[компьютерная лингвистика](https://addenda.hse.ru/computational-linguistics)" (2021-2022) 3 | 4 | **формула оценки за курс**
5 | 30%(ДЗ) + 70%(финальный проект)
6 | оценка по 10-балльной шкале 7 | 8 | ## Расписание: 9 | 10 | |№ занятия|дата|тема| 11 | |-|-|-| 12 | |1|13 октября 2021|[установка EDA + git](https://github.com/nstsj/python_for_CL/blob/master/slides/Python%20%26%20Git%20-%20%D0%BB%D0%B5%D0%BA%D1%86%D0%B8%D1%8F1%20(2021).pdf) и [введение в Python](https://github.com/nstsj/python_for_CL/blob/master/notebooks/python_intro.ipynb)| 13 | |2|20 октября 2021|[операторы ввода/вывода](https://github.com/nstsj/python_for_CL/blob/master/notebooks/input%2Coutput.ipynb)| 14 | |3|25 октября 2021|[списки, циклы](https://github.com/nstsj/python_for_CL/blob/master/notebooks/lists%2Ccycles.ipynb)| 15 | |4|27 октября 2021|[множества, кортежи, словари](https://github.com/nstsj/python_for_CL/blob/master/notebooks/tuples%2C%20sets%2C%20dicts.ipynb)| 16 | |5|10 ноября 2021|[работа с функциями](https://github.com/nstsj/python_for_CL/blob/master/notebooks/Python%20functions.ipynb)| 17 | |6|24 ноября 2021|[регулярные выражения в Python](https://github.com/nstsj/python_for_CL/blob/master/notebooks/regexes_class.ipynb)| 18 | |7|1 декабря 2021|[работа с файлами, модуль os](https://github.com/nstsj/python_for_CL/blob/master/notebooks/files_OS.ipynb)| 19 | |8|8 декабря 2021|[разбор практических задач + частотный анализ текстов и TF-IDF](https://github.com/nstsj/python_for_CL/blob/master/notebooks/freq_analysis_tf_idf.ipynb)| 20 | |9|15 декабря 2021|[анонс проектов + pandas, работа с датасетами](https://github.com/nstsj/python_for_CL/blob/master/notebooks/pandas.ipynb)| 21 | |10|20 декабря 2021|[собираем корпус: парсеры,краулеры,скрепперы](https://github.com/nstsj/python_for_CL/blob/master/notebooks/get_your_dataset.ipynb)| 22 | |11|22 декабря 2021|обсуждение проектов| 23 | |12|19 января 2022|[синтаксический анализ](https://github.com/nstsj/python_for_CL/blob/master/notebooks/syntactic_parsers.ipynb)| 24 | |13|22 января 2022|[визуализация данных](https://github.com/nstsj/python_for_CL/blob/master/notebooks/python_viz_mpl_seaborn.ipynb)| 25 | |14|29 января 2022|networkx| 26 | |15|2 февраля 2022|OOП| 27 | 28 | 29 | ## Полезные ссылки: 30 | 31 | * [ссылка на форму для вопросов/фидбеков](https://forms.gle/3aycLhcVfpPmZCA77)
32 | 33 | **IDE** 34 | * [как работать в PyCharm](https://py-charm.blogspot.com/2017/09/blog-post.html) 35 | * [как работать в jupyter notebook](https://devpractice.ru/python-lesson-6-work-in-jupyter-notebook/) 36 | * [как работать в Google Colab](https://towardsdatascience.com/getting-started-with-google-colab-f2fff97f594c)
37 | 38 | **git** 39 | * [где скачать гит](https://git-scm.com/downloads) 40 | * [гайд по установке git на компьютер](https://githowto.com/ru) 41 | * [руководства по git на все случаи жизни](https://guides.github.com/)
42 | 43 | **Python** 44 | * [установка Python](https://www.python.org/downloads/) 45 | * [введение для людей без опыта программирования](https://wiki.python.org/moin/BeginnersGuide/NonProgrammers) 46 | * [интерактивный учебник по Python](https://snakify.org/ru) 47 | * [тренажер с упражнениями на все темы](https://www.w3resource.com/python-exercises/python-basic-exercises.php) 48 | * [тренажер по Python и математике от Stepik](https://stepik.org/course/3356/promo#toc)
49 | 50 | **текстовые редакторы** 51 | * [Visual Studio Code](https://code.visualstudio.com/) 52 | * [Notepad++](https://notepad-plus-plus.org/downloads/v7.7.1/) 53 | * [SublimeText](https://www.sublimetext.com/3)
54 | 55 | 56 | **список библиотек для NLP** 57 | * [awesome list](https://github.com/keon/awesome-nlp#user-content-python) 58 | -------------------------------------------------------------------------------- /data/Twitter- Oscars(2).csv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anklowait/python_for_CL/685d52838288001606f2635637b603b008cef537/data/Twitter- Oscars(2).csv -------------------------------------------------------------------------------- /data/addresses.txt: -------------------------------------------------------------------------------- 1 | Nordstrom Rack and HauteLook 2 | Nordstrom Rack is the off-price retail division of Nordstrom Inc., which was founded in 1901 in Seattle, Washington, by John W. Nordstrom. 3 | 4 | Nordstrom encourages contact from its customers and has supplied contact details to us. 5 | 6 | 700 S. Flower Street 7 | Suite 1700 8 | Los Angeles, CA 90017 9 | https://www.nordstromrack.com/ 10 | 11 | Phone Contacts 12 | Main: (206) 628-2111 13 | Customer Service: (888)966-6283 14 | International: (319) 846-4140 15 | 16 | Nordstrom Customer Service: (888)282-6060 17 | 18 | 19 | 20 | Email Contacts 21 | Contact@nordstrom.com 22 | 23 | Social Media Contacts 24 | Facebook 25 | Twitter 26 | 27 | Executive Contacts 28 | Primary Contact 29 | Andrew Breen 30 | Director Customer Care 31 | 32 | 700 S. Flower Street 33 | Suite 1700 34 | Los Angeles, CA 90017 35 | Andrew.Breen@HauteLook.com 36 | 37 | Secondary Contact 38 | James F. Nordstrom 39 | Executive Vice President and President of Nordstrom Stores 40 | 1600 Seventh Avenue 41 | Suite 2600 42 | Seattle, WA 98101 43 | Jamie.nordstrom@nordstrom.com 44 | 45 | Geevy Thomas 46 | President of Nordstrom Rack 47 | 48 | 1600 Seventh Avenue 49 | Suite 2600 50 | Seattle, WA 98101 51 | Geevy.Thomas@nordstrom.com 52 | 53 | Chief Executive 54 | See Notes Below 55 | 56 | 700 S. Flower Street 57 | Suite 1700 58 | Los Angeles, CA 90017 59 | 60 | Erik B. Nordstrom 61 | Co-President 62 | erik.nordstrom@nordstrom.com 63 | 64 | Peter E. Nordstrom 65 | Co-President 66 | Pete.Nordstrom@nordstrom.com 67 | 68 | -------------------------------------------------------------------------------- /data/barcelona.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anklowait/python_for_CL/685d52838288001606f2635637b603b008cef537/data/barcelona.zip -------------------------------------------------------------------------------- /data/cinnamon_roll.txt: -------------------------------------------------------------------------------- 1 | Cinnamon roll 2 | From Wikipedia, the free encyclopedia 3 | Jump to navigationJump to search 4 | For the personality type, see Wiktionary:cinnamon roll. 5 | Cinnamon roll (or bun) 6 | Cinnamon-Roll-US-Bakery.jpg 7 | A cinnamon roll with white icing 8 | Alternative names Cinnamon bun, cinnamon swirl, cinnamon Danish, cinnamon snail 9 | Type Sweet roll 10 | Place of origin Sweden and Denmark[citation needed] 11 | Main ingredients flour, cinnamon, sugar, and butter 12 | Cookbook: Cinnamon roll (or bun) 13 | Media: Cinnamon roll (or bun) 14 | A cinnamon roll (also cinnamon bun, cinnamon swirl, cinnamon Danish and cinnamon snail) is a sweet roll served commonly in Northern Europe (mainly in Scandinavia) and North America. In Sweden it is called kanelbulle, in Denmark it is known as kanelsnegl, in Norway it is known as Kanelbolle, Skillingsboller and Kanelsnurr, and in Finland it is known as korvapuusti. 15 | 16 | A cinnamon roll consists of a rolled sheet of yeast-leavened dough onto which a cinnamon and sugar mixture (and raisins or other ingredients in some cases) is sprinkled over a thin coat of butter. The dough is then rolled, cut into individual portions, and baked or deep fried. Its main ingredients are flour, cinnamon, sugar, and butter, which provide a robust and sweet flavor 17 | 18 | 19 | Loaf of raw cinnamon roll dough being cut into individual rolls prior to being baked 20 | 21 | Uncooked cinnamon roll buns 22 | Origins 23 | Roman spice traders introduced the Sri Lankan cinnamon spice to Europe. 24 | 25 | Much later, Sweden began using it in its pastries, developing the kanelbulle (lit. ''cinnamon bun'').[dead link] Since 1999, October 4th has been promoted as Cinnamon Roll Day (Kanelbullens dag). Swedish kanelbulle dough typically also contains cardamom (powder or buds), giving it a distinctive flavour. 26 | 27 | The size of a cinnamon roll varies from place to place, but many vendors supply a smaller size about 5 centimeters (2.0 in) in diameter and a larger size about 10 cm (3.9 in) to a side. The larger variety can be found in Finland, called korvapuusti (lit. 'a 'cuff on the ear'', fig. "pulling someone's ear for disciplining"), where it can be up to 20 cm (7.9 in) in diameter and weigh up to 200 g (7.1 oz). 28 | 29 | Haga, a district in Gothenburg, Sweden, is well known for its very large cinnamon rolls. These cinnamon rolls are called hagabullar or 'Queen of the kitchen'. Hagabullar are usually 30 centimeters (12 in) or more in diameter and are, despite their size, not considered a communal roll. Each person usually orders one each. Swedes use pearl sugar to top their cinnamon pastries, not icing as is common in North America. 30 | 31 | National variations 32 | The Swedish Butterkaka and Finnish bostonkakku ('Boston cake') is a cake made by baking cinnamon rolls in a round cake pan instead of baking them separately, so that they stick together to form a large, round cake. 33 | 34 | A German variety, which closely follows the form of the Scandinavian pastry, originating in Hamburg and its surroundings is the Franzbrötchen, a cinnamon pastry inspired by the non-cinnamon French croissant. 35 | 36 | The British version is called Chelsea bun, which they invented in the 18th century. It is now available in cafes, supermarkets, and bakeries across the UK. 37 | 38 | American cinnamon rolls are frequently topped with icing (usually confectioners' sugar-based) and are sometimes fried, finished with glaze, and served as a variation of a raised donut. There are also regional combinations: in the American Midwest, especially Kansas, cinnamon rolls are commonly eaten with chili. 39 | 40 | In Canada, they are known as cinnamon buns. They are usually self-glazed and not iced, nor do they usually have raisins. They can have so much cinnamon that they are spicy and hot to the taste. 41 | 42 | Cinnamon roll traditions 43 | In Sweden and Finland, cinnamon rolls are traditionally enjoyed during a coffee break, or fika, which is a get-together with friends. National Cinnamon Bun Day (Kanelbullens dag) is observed on October 4 in Sweden. 44 | 45 | In North America, it is commonly eaten for breakfast or dessert. When eaten for a breakfast in the U.S., it may be served with cream cheese frosting. -------------------------------------------------------------------------------- /data/city_smells.txt: -------------------------------------------------------------------------------- 1 | Помните запах свежевыпеченного хлеба на дождливой улочке из той булочной, в которую вы заходили в прошлом месяце? 2 | А как он смешался с запахом смолотого кофе? 3 | А запах свежескошенной травы в парке освежающим вечером после жаркого дня? 4 | Запахи ежеминутно сопровождают нас в городе, но они мимолетны и невидимы, поэтому часто ускользают от внимания урбанистов и исследователей городской среды. 5 | Группа ученых из разных университетов мира в рамках проекта Smelly Maps решила исправить эту несправедливость и занялась исследованием городских запахов. 6 | Самый первый и важный вопрос, с которым они столкнулись — откуда брать данные для работы? Один из очевидных ответов — собирать данные на месте при помощи так называемых «smell walks». 7 | Принцип прост: группа добровольцев идет по маршруту и записывает все запахи, которые чувствует по пути, отмечая конкретные места на карте. 8 | На основе таких прогулок и нескольких исследований был составлен «словарь запахов», который состоял из всех слов, которыми добровольцы описывали запахи во время прогулки. 9 | Просто, эффективно и дешево. 10 | Но у такого метода есть недостатки: на обход даже небольшого города несколько десятков добровольцев потратит очень много времени, а если мы хотим еще и рассмотреть динамику, этот способ не подходит совсем. 11 | Остается обратиться к добровольно собираемым и публикуемым в сети большим данным, а именно к данным социальных сетей. 12 | Взять 17 миллионов фотографий из Flickr, 5.1 миллиона снимков из публичных аккаунтов Instagram и 5.3 миллиона твитов из Твиттера, каждый из которых обладает геотегом — и с этим уже можно работать. 13 | Набор данных из Твиттера был очищен от ретвитов и ответов, после чего в сумме для анализа было готово 1.7 миллиона твитов. 14 | Тексты твитов и подписей к фотографиям был распарсен, и из всего массива слов были отобраны только те, которые имеют отношение к запахам. 15 | На основе этих данных был построен взвешенный граф связей между словами, в вершинах которого закреплены сами слова, а вес ребра соответствует количеству раз, когда эти два слова встречаются в одном тексте. Такой анализ выявил несколько четко определенных категорий запахов, например, «природные», «индустриальные», «еда», «выбросы/выхлопы», «мусор». 16 | Внутри категорий иногда можно было выделить подкатегории и определить самые часто встречающиеся слова-метки этой категории. 17 | Схему этих категорий можно увидеть ниже. 18 | Цвета выбраны не просто так. 19 | Исследователи нашли связи между запахами и цветами, преобладающими на анализируемых фотографиях. 20 | Запахи также связаны с негативными или позитивными эмоциями, например, категория «мусор» будет положительно коррелировать с негативными эмоциями, отвращением и печалью, но отрицательно — с радостью. 21 | 22 | В современных городах существуют программы мониторинга качества воздуха, позволяющие городским службам оперативно реагировать на аномалии, а обычным горожанам следить за составом воздуха, которым они дышат. Массив данных о городских запахах сравнили и с такими данными и сделали вывод о том, что данные о более низком качестве воздуха с примесями положительно коррелируют с такими категориями, как «выбросы/выхлопы», и отрицательно — с категорией «природа». 23 | Такой вывод кажется логичным, но теперь он доказан научно. 24 | 25 | По геотегам исследователи сделали интерактивные карты, где можно узнать, чем пахнут улицы таких городов мира, как Лондон и Барселона (два первых города, для которых были собраны и проанализированы данные). 26 | Есть также карты Мадрида, Рима, Милана, Нью-Йорка и еще шести крупных американских городов. 27 | Авторы утверждают, что список будет пополняться и дальше. 28 | 29 | Для картографирования использовались открытые данные Open Street Map, внутри которых были выделены сегменты улиц от перекрестка до перекрестка, к которым были привязаны геотеги оригинальных данных. 30 | На странице проекта, путешествуя по интерактивным картам, можно посмотреть соотношение запахов по каждому сегменту, например, в Барселоне на улице Бальмес запах еды преобладает: 31 | 32 | Вместе запахи складываются в комплексный и сложный ландшафт, уникальный для каждого города, и он нуждается в исследовании так же, как и ландшафт визуальный или звуковой. 33 | Кстати, по запросу от авторов можно получить также данные, на которых основывался проект, если есть желание исследовать их самостоятельно. 34 | 35 | Источники: 36 | Страница проекта Smelly Maps 37 | Интерактивные карты проекта 38 | Нелли Бурцева 39 | -------------------------------------------------------------------------------- /data/corgi.txt: -------------------------------------------------------------------------------- 1 | Вельш-ко́рги — породы пастушьих собак, происходящие из Уэльса. К уэльским корги относятся: 2 | 3 | Вельш-корги-кардиган (англ. Welsh Corgi Cardigan) — порода, появившаяся на изолированной территории Кардиганшира. Согласно наиболее популярной версии, предки вельш-корги-кардиганов были завезены кельтами при освоении территории Британских островов в конце бронзового века. Первое упоминание породы в письменных источниках датируется X веком. 4 | Вельш-корги-пемброк (англ. Welsh Corgi Pembroke) — порода, выведенная в Пембрукшире, предположительно, из собак фламандского происхождения и ведущая свою историю с XIII века. 5 | 6 | Происхождение слова «корги» достоверно неизвестно. Существуют две теории на этот счёт. По основной версии, слово «corgi» образовано от валлийского cor gi ([kɔrɡi]) cor, «карлик» и ci ([kiː]), «собака». Другие источники, однако, объясняют происхождение «corgi» изменённым словом cur («смотреть, сторожить») и ci («собака»). 7 | 8 | Происхождение 9 | Зародилась порода в Уэльсе, где она стала одной из первых пастушьих собак. Вельш-корги получили распространение в XХ веке. Основой для выведения породы, вероятно, послужили шведский вальхунд (вестготашпиц) или исландская собака. 10 | 11 | По одной из легенд, объясняющих появление этих собак, щенков людям подарили феи, у которых порода использовалась в качестве ездовых. Этим сторонники версии объясняют отметину в виде седла на спине у вельш-корги пемброк. 12 | 13 | Согласно другой валлийской легенде, двух щенков, сидящих на поваленном дереве в лесу, нашли крестьянские дети и принесли домой. 14 | 15 | Вельш-корги относятся к семейству овчарок, хотя и довольно миниатюрных. Невысокий рост позволяет им ловко уворачиваться от копыт и рогов при пастушьей работе. 16 | 17 | Хотя собаки оказались довольно привлекательными с точки зрения заводчиков, они долго оставались неизвестными широкому кругу. Лишь в 1892 году корги впервые стали участниками выставки, где их заметили. Потом порода стремительно развивалась и быстро получила распространение по всему миру. 18 | 19 | Наибольшую известность собаки получили потому, что в 1933 году герцог Йоркский (будущий король Великобритании Георг VI) подарил щенков вельш-корги своим дочерям Элизабет (сейчас — Елизавета II) и Маргарет Роз. 20 | 21 | Внешний вид собаки 22 | Вельш-корги — это небольшая собака ростом около тридцати сантиметров и массой тела до четырнадцати килограммов. Существуют два основных вида вельш-корги — пемброк и кардиган, которые довольно серьёзно различаются между собой. Так, например, пемброк немного меньше, также у этих видов разная форма головы и строение грудных конечностей. 23 | 24 | 25 | Вельш-корги-кардиган тигрового окраса 26 | У кардигана лапы чуть длиннее, их отличает специфический постав передних конечностей, повторяющий форму грудной клетки, что делает их более маневренными в работе со скотом. Широкогрудые, с головой благородных очертаний и прямой, прочной спиной. Они олицетворяют силу и благородство, мощь и работоспособность. 27 | 28 | 29 | Вельш-корги-пемброк на выставке «Corgi Symphony 2019» 30 | У пемброков рыже-белого окраса яркая, золотого окраса шерсть, белые отметины на морде, груди и лапах. Также пемброки бывают окраса чёрный триколор. Морда больше похожа на лисью. Из-за контрастной обводки пасти многим кажется, что пемброки «улыбаются». Глаза карие. Красивый крепкий корпус, крепкие короткие лапы с хорошо выраженными углами. 31 | 32 | Считается, что пемброки отличаются от кардиганов отсутствием хвоста, однако это ошибка. Пемброки не всегда рождаются куцехвостыми, иногда хвосты купируют. С конца 1980-х годов, когда некоторые страны ввели запреты на купирование, всё больше появляется хвостатых пемброков, что делает их более похожими на лис. (Естественно, что перестав купировать хвосты, многие заводчики обнаружили большое разнообразие пемброков по качеству хвостов, потому что раньше это никак не отслеживалось). 33 | 34 | Подшёрсток у них короткий, стойкий к намоканию, шерсть примерно такой же длины, как у овчарки, на ощупь шелковистая и имеет великолепный блеск. Окрас таких собак может быть рыже-белым, трёхцветным (чёрный, белый плюс рыжевато-коричневый), чёрным (редко), оленьим; у кардиганов распространён тигровый окрас. На цвет их шерсти есть строго установленные правила, не бывает лишь белых вельш-корги. 35 | 36 | В последние годы, из-за роста популярности породы, увеличилось количество коммерческих вязок и недобросовестных заводчиков, что привело к снижению качества поголовья. Также наблюдается тенденция к увеличению размера и веса, особенно среди кобелей. У таких собак из-за увеличения массивности грудной клетки и головы при неизменно коротких лапах, снижается подвижность, ухудшается продуктивность движений, снижаются рабочие качества, а также могут возникать проблемы со здоровьем. 37 | 38 | Характер и поведение 39 | Корги — преданные, трепетно любят семью своего хозяина. Они лояльно относятся ко всем людям и другим животным, легко уживаются с кошками. Очень тепло относятся к детям, особенно маленьким, следят за ними и оберегают. Спокойно переносят жизнь в городе. К климату приспосабливаются без особого труда, но из-за очень густого подшёрстка лучше чувствуют себя в холодную погоду, чем в жару. 40 | 41 | Это очень весёлая и подвижная собака. Корги очень любят играть и требуют продолжения, если хозяин решил закончить игру. Со всеми домочадцами они поддерживают прекрасные отношения, не показывая явно своего предпочтения. При этом с теми, кто не желает их принять, «держат дистанцию». Они точно знают, когда можно подойти и приласкаться, когда лучше не попадаться на глаза, когда можно покапризничать, а когда от них требуется полная отдача. 42 | 43 | Вельш-корги пемброк и кардиган похожи по характеру, но есть и различия. Например, и кардиган, и пемброк дружелюбные добродушные собаки, привязанные к своему хозяину, уравновешенные, очень обаятельные, превосходные компаньоны, также обладающие чувством такта и даже чувством юмора (что отмечено в стандарте породы). Но, в отличие от пемброка, кардиган спокойнее, рассудительнее и осторожнее, а пемброк более возбудимый, живой и чуткий. 44 | 45 | По обучаемости эта порода может уступить разве что бордер-колли. Запоминание команды со второго-третьего раза — не редкость, а норма. Легко и с интересом пемброки обучаются цирковым номерам, участвуют в аджилити, флайболе и других соревнованиях. Впрочем, изучение привычек хозяев и использование полученных знаний в своих собачьих интересах тоже не редкость. При этом шкодливость и злопамятность, как правило, отсутствуют у этой породы в принципе. 46 | 47 | Вельш-корги склонны к перееданию, поэтому для слабовольного хозяина эта порода противопоказана. Нужно иметь в себе силы противостоять обаянию и хитроумию очаровательнейших попрошаек. Иначе собака запросто может превратиться в малоподвижное перекормленное существо. 48 | 49 | Большинство вельш-корги не склонны лаять по любому поводу: чаще всего они подают голос, увидев кого-то знакомого, а также встречая вернувшегося хозяина или гостей. Кроме того, некоторые представители породы исполняют «коржиные песни» — это забавный вой с переливами, который исполняется однократно исключительно в приветственном порыве. Но, учитывая лёгкую обучаемость собаки, при желании можно отдрессировать и эти манеры. Любая излишняя шумность вельш-корги — это аномалия, свидетельствующая, как правило, о каких-либо отклонениях в воспитании в раннем детстве. 50 | 51 | Вельш-корги не относятся к породам собак повышенной опасности (в отличие от большинства овчарок). Кроме этого, корги могут быть служебными собаками. Так, в Нижнем Новгороде около 10 лет служил вельш-корги-пемброк по кличке Рыжий. 52 | 53 | Корги Елизаветы II 54 | 55 | Щенок вельш-корги пемброка рыже-белого окраса 56 | Основная статья: Королевские корги 57 | Первого корги, появившегося в британской королевской семье в 1933 году, звали «Розавел Золотой Орел» (Rozavel Golden Eagle), коротко «Дуки» (The Dookie). Будущий король Георг VI купил собаку для своих дочерей — Элизабет и Маргарет. Герцог Йоркский выбрал именно корги из-за длины его хвоста, а точнее по той причине, что крайне важно видеть, доволен ли пёс, а это возможно только в том случае, если хвост у собаки определённой длины. Принцессе Елизавете на тот момент было 7 лет. 58 | 59 | С того дня при королевском дворе жили 14 поколений корги. Также члены британской королевской семьи патронируют Crufts, кинологическое мероприятие проводимое ежегодно. Род начался от собаки породы вельш корги пемброк по кличке Сьюзан, которую родители подарили Елизавете на совершеннолетие. Сьюзан, в свою очередь, была потомком Дуки. Всего у Елизаветы II было больше 30 собак породы корги. 60 | 61 | В 2012 году три собаки Её Величества (Монти, Уиллоу и Холли) снялись вместе с хозяйкой и актёром Дэниэлом Крейгом в коротком ролике о приключениях Джеймса Бонда. Ролик был приурочен к Олимпийским играм в Лондоне. 62 | -------------------------------------------------------------------------------- /data/d_speech.txt: -------------------------------------------------------------------------------- 1 | А.П.Чехов "Глупый француз" 2 | 3 | Клоун из цирка братьев Гинц, Генри Пуркуа, зашёл в московский трактир Тестова позавтракать. 4 | 5 | — Дайте мне консоме! — приказал он половому. 6 | 7 | — Прикажете с пашотом или без пашота? 8 | 9 | — Нет, с пашотом слишком сытно... Две-три гренки, пожалуй, дайте... 10 | 11 | В ожидании, пока подадут консоме, Пуркуа занялся наблюдением. Первое, что бросилось ему в глава, был какой-то полный благообразный господин, сидевший за соседним столом и приготовлявшийся есть блины. 12 | 13 | «Как, однако, много подают в русских ресторанах! — подумал француз, глядя, как сосед поливает свои блины горячим маслом.— Пять блинов! Разве один человек может съесть так много теста?» 14 | 15 | Сосед между тем помазал блины икрой, разрезал все их на половинки и проглотил скорее, чем в пять минут... 16 | 17 | — Челаэк! — обернулся он к половому.— Подай ещё порцию! Да что у вас за порции такие? Подай сразу штук десять или пятнадцать! Дай балыка... семги, что ли? 18 | 19 | «Странно...— подумал Пуркуа, рассматривая соседа.— Съел пять кусков теста и ещё просит! Впрочем, такие феномены не составляют редкости... У меня у самого в Бретани был дядя Франсуа, который на пари съедал две тарелки супу и пять бараньих котлет... Говорят, что есть также болезни, когда много едят...» 20 | 21 | Половой поставил перед соседом гору блинов и две тарелки с балыком и семгой. Благообразный господин выпил рюмку водки, закусил семгой и принялся за блины. К великому удивлению Пуркуа, ел он их спеша, едва разжёвывая, как голодный... 22 | 23 | «Очевидно, болен...— подумал француз.— И неужели он, чудак, воображает, что съест всю эту гору? Не съест и трёх кусков, как желудок его будет уже полон, а ведь придётся платить за всю гору!» 24 | 25 | — Дай ещё икры! — крикнул сосед, утирая салфеткой масляные губы.— Не забудь зелёного луку! 26 | 27 | «Но... однако, уж половины горы нет! — ужаснулся клоун.— Боже мой, он и всю семгу съел? Это даже неестественно... Неужели человеческий желудок так растяжим? Не может быть! Как бы ни был растяжим желудок, но он не может растянуться за пределы живота... Будь этот господин у нас во Франции, его показывали бы за деньги... Боже, уже нет горы!» 28 | 29 | — Подашь бутылку Нюи...— сказал сосед, принимая от полового икру и лук.— Только погрей сначала... Что ещё? Пожалуй, дай ещё порцию блинов... Поскорей только... 30 | 31 | — Слушаю... А на после блинов что прикажете? 32 | 33 | — Что-нибудь полегче... Закажи порцию селянки из осетрины по-русски и... и... Я подумаю, ступай! 34 | 35 | «Может быть, это мне снится? — изумился клоун, откидываясь на спинку стула.— Этот человек хочет умереть! Нельзя безнаказанно съесть такую массу! Да, да, он хочет умереть. Это видно по его грустному лицу. И неужели прислуге не кажется подозрительным, что он так много ест? Не может быть!» 36 | 37 | Пуркуа подозвал к себе полового, который служил у соседнего стола, и спросил шёпотом: 38 | 39 | — Послушайте, зачем вы так много ему подаёте? 40 | 41 | — То есть, э... э... они требуют-с! Как же не подавать-с? — удивился половой. 42 | 43 | — Странно, но ведь он таким образом может до вечера сидеть здесь и требовать! Если у вас у самих не хватает смелости отказывать ему, то доложите метрдотелю, пригласите полицию! 44 | 45 | Половой ухмыльнулся, пожал плечами и отошёл. 46 | 47 | «Дикари! — возмутился про себя француз.— Они ещё рады, что за столом сидит сумасшедший, самоубийца, который может съесть на лишний рубль! Ничего, что умрёт человек, была бы только выручка!» 48 | 49 | — Порядки, нечего сказать! — проворчал сосед, обращаясь к французу.— Меня ужасно раздражают эти длинные антракты! От порции до порции изволь ждать полчаса! Этак и аппетит пропадёт к чёрту, и опоздаешь... Сейчас три часа, а мне к пяти надо быть на юбилейном обеде. 50 | 51 | — Pardon, monsieur, — побледнел Пуркуа,— ведь вы уж обедаете! 52 | 53 | — Не-ет... Какой же это обед? Это завтрак... блины... 54 | 55 | Тут соседу принесли селянку. Он налил себе полную тарелку, поперчил кайенским перцем и стал хлебать... 56 | 57 | «Бедняга...— продолжал ужасаться француз.— Или он болен и не замечает своего опасного состояния, или же он делает всё это нарочно... с целью самоубийства... Боже мой, знай я, что наткнусь здесь на такую картину, то ни за что бы не пришёл сюда! Мои нервы не выносят таких сцен!» 58 | 59 | И француз с сожалением стал рассматривать лицо соседа, каждую минуту ожидая, что вот-вот начнутся с ним судороги, какие всегда бывали у дяди Франсуа после опасного пари... 60 | 61 | «По-видимому, человек интеллигентный, молодой... полный сил...— думал он, глядя на соседа.— Быть может, приносит пользу своему отечеству... и весьма возможно, что имеет молодую жену, детей... Судя по одежде, он должен быть богат, доволен... но что же заставляет его решаться на такой шаг?.. И неужели он не мог избрать другого способа, чтобы умереть? Чёрт знает как дёшево ценится жизнь! И как низок, бесчеловечен я, сидя здесь и не идя к нему на помощь! Быть может, его ещё можно спасти!» 62 | 63 | Пуркуа решительно встал из-за стола и подошёл к соседу. 64 | 65 | — Послушайте, monsieur,— обратился он к нему тихим, вкрадчивым голосом.— Я не имею чести быть знаком с вами, но, тем не менее, верьте, я друг ваш... Не могу ли я вам помочь чем-нибудь? Вспомните, вы ещё молоды... у вас жена, дети... 66 | 67 | — Я вас не понимаю! — замотал головой сосед, тараща на француза глаза. 68 | 69 | — Ах, зачем скрытничать, monsieur? Ведь я отлично вижу! Вы так много едите, что... трудно не подозревать... 70 | 71 | — Я много ем?! — удивился сосед.— Я?! Полноте... Как же мне не есть, если я с самого утра ничего не ел? 72 | 73 | — Но вы ужасно много едите! 74 | 75 | — Да ведь не вам платить! Что вы беспокоитесь? И вовсе я не много ем! Поглядите, ем, как все! 76 | 77 | Пуркуа поглядел вокруг себя и ужаснулся. Половые, толкаясь и налетая друг на друга, носили целые горы блинов... За столами сидели люди и поедали горы блинов, семгу, икру... с таким же аппетитом и бесстрашием, как и благообразный господин. 78 | 79 | «О, страна чудес! — думал Пуркуа, выходя из ресторана.— Не только климат, но даже желудки делают у них чудеса! О страна, чудная страна!» -------------------------------------------------------------------------------- /data/postcards.csv: -------------------------------------------------------------------------------- 1 | ,city,age,job 2 | Maria,London,37,Artist 3 | Lorenzo,Milan,28,Teacher 4 | Oleg,Canberra,31,Chef 5 | Hans,Calgary,80,Artist 6 | Mark,Milan,55,Manager 7 | Alex,Krakow,35,Chef 8 | Julia,Murmansk,43,Engineer 9 | Alice,NY,36,Engineer 10 | -------------------------------------------------------------------------------- /data/test_basni.txt: -------------------------------------------------------------------------------- 1 | «Как, милый Петушок, поешь, ты громко, важно!»- 2 | «А ты, Кукушечка, мой свет, 3 | Как тянешь плавно и протяжно: 4 | Во всем лесу у нас такой певицы нет!» — 5 | «Тебя, мой куманек, век слушать я готова».— 6 | «А ты, красавица, божусь, 7 | Лишь только замолчишь, то жду я, не дождусь, 8 | Чтоб начала ты снова… 9 | Отколь такой берется голосок? 10 | И чист, и нежен, и высок!.. 11 | Да вы уж родом так: собою невелички, 12 | А песни, что твой соловей!» — 13 | «Спасибо, кум; зато, по совести моей, 14 | Поешь ты лучше райской птички, 15 | На всех ссылаюсь в этом я». 16 | Тут Воробей, случась, примолвил им: «Друзья! 17 | Хоть вы охрипните, хваля друг дружку,— 18 | Все ваша музыка плоха!..» 19 | Басня Квартет читать 20 | Проказница-Мартышка, Осел, Козел да косолапый Мишка 21 | Затеяли сыграть Квартет. 22 | Достали нот, баса, альта, две скрипки 23 | И сели на лужок под липки - 24 | Пленять своим искусством свет. 25 | Ударили в смычки, дерут, а толку нет. 26 | "Стой, братцы, стой! - кричит Мартышка. - Погодите! 27 | Как музыке идти? Ведь вы не так сидите. 28 | Ты с басом, Мишенька, садись против альта, 29 | Я, прима, сяду против вторы; 30 | Тогда пойдет уж музыка не та: 31 | У нас запляшут лес и горы!" 32 | Расселись, начали Квартет; 33 | Он все-таки на лад нейдет. 34 | "Постойте ж, я сыскал секрет, - 35 | Кричит Осел, - мы, верно, уж поладим, 36 | Коль рядом сядем". 37 | Послушались Осла: уселись чинно в ряд, 38 | А все-таки Квартет нейдет на лад. 39 | Вот пуще прежнего пошли у них разборы 40 | И споры, кому и как сидеть. 41 | Случилось Соловью на шум их прилететь. 42 | Тут с просьбой все к нему, чтоб их решать сомненье: 43 | "Пожалуй, - говорят, - возьми на час терпенье, 44 | Чтобы Квартет в порядок наш привесть: 45 | И ноты есть у нас, и инструменты есть; 46 | Скажи лишь, как нам сесть!" - 47 | "Чтоб музыкантом быть, так надобно уменье 48 | И уши ваших понежней, - 49 | Им отвечает Соловей. - 50 | А вы, друзья, как ни садитесь, 51 | Все в музыканты не годитесь". 52 | Проказница-Мартышка, Осел, Козел да косолапый Мишка 53 | Затеяли сыграть Квартет. 54 | Достали нот, баса, альта, две скрипки 55 | И сели на лужок под липки - 56 | Пленять своим искусством свет. 57 | Ударили в смычки, дерут, а толку нет. 58 | "Стой, братцы, стой! - кричит Мартышка. - Погодите! 59 | Как музыке идти? Ведь вы не так сидите. 60 | Ты с басом, Мишенька, садись против альта, 61 | Я, прима, сяду против вторы; 62 | Тогда пойдет уж музыка не та: 63 | У нас запляшут лес и горы!" 64 | Расселись, начали Квартет; 65 | Он все-таки на лад нейдет. 66 | "Постойте ж, я сыскал секрет, - 67 | Кричит Осел, - мы, верно, уж поладим, 68 | Коль рядом сядем". 69 | Послушались Осла: уселись чинно в ряд, 70 | А все-таки Квартет нейдет на лад. 71 | Вот пуще прежнего пошли у них разборы 72 | И споры, кому и как сидеть. 73 | Случилось Соловью на шум их прилететь. 74 | Тут с просьбой все к нему, чтоб их решать сомненье: 75 | "Пожалуй, - говорят, - возьми на час терпенье, 76 | Чтобы Квартет в порядок наш привесть: 77 | И ноты есть у нас, и инструменты есть; 78 | Скажи лишь, как нам сесть!" - 79 | "Чтоб музыкантом быть, так надобно уменье 80 | И уши ваших понежней, - 81 | Им отвечает Соловей. - 82 | А вы, друзья, как ни садитесь, 83 | Все в музыканты не годитесь". 84 | Проказница-Мартышка, Осел, Козел да косолапый Мишка 85 | Затеяли сыграть Квартет. 86 | Достали нот, баса, альта, две скрипки 87 | И сели на лужок под липки - 88 | Пленять своим искусством свет. 89 | Ударили в смычки, дерут, а толку нет. 90 | "Стой, братцы, стой! - кричит Мартышка. - Погодите! 91 | Как музыке идти? Ведь вы не так сидите. 92 | Ты с басом, Мишенька, садись против альта, 93 | Я, прима, сяду против вторы; 94 | Тогда пойдет уж музыка не та: 95 | У нас запляшут лес и горы!" 96 | Расселись, начали Квартет; 97 | Он все-таки на лад нейдет. 98 | "Постойте ж, я сыскал секрет, - 99 | Кричит Осел, - мы, верно, уж поладим, 100 | Коль рядом сядем". 101 | Послушались Осла: уселись чинно в ряд, 102 | А все-таки Квартет нейдет на лад. 103 | Вот пуще прежнего пошли у них разборы 104 | И споры, кому и как сидеть. 105 | Случилось Соловью на шум их прилететь. 106 | Тут с просьбой все к нему, чтоб их решать сомненье: 107 | "Пожалуй, - говорят, - возьми на час терпенье, 108 | Чтобы Квартет в порядок наш привесть: 109 | И ноты есть у нас, и инструменты есть; 110 | Скажи лишь, как нам сесть!" - 111 | "Чтоб музыкантом быть, так надобно уменье 112 | И уши ваших понежней, - 113 | Им отвечает Соловей. - 114 | А вы, друзья, как ни садитесь, 115 | Все в музыканты не годитесь". 116 | Проказница-Мартышка, Осел, Козел да косолапый Мишка 117 | Затеяли сыграть Квартет. 118 | Достали нот, баса, альта, две скрипки 119 | И сели на лужок под липки - 120 | Пленять своим искусством свет. 121 | Ударили в смычки, дерут, а толку нет. 122 | "Стой, братцы, стой! - кричит Мартышка. - Погодите! 123 | Как музыке идти? Ведь вы не так сидите. 124 | Ты с басом, Мишенька, садись против альта, 125 | Я, прима, сяду против вторы; 126 | Тогда пойдет уж музыка не та: 127 | У нас запляшут лес и горы!" 128 | Расселись, начали Квартет; 129 | Он все-таки на лад нейдет. 130 | "Постойте ж, я сыскал секрет, - 131 | Кричит Осел, - мы, верно, уж поладим, 132 | Коль рядом сядем". 133 | Послушались Осла: уселись чинно в ряд, 134 | А все-таки Квартет нейдет на лад. 135 | Вот пуще прежнего пошли у них разборы 136 | И споры, кому и как сидеть. 137 | Случилось Соловью на шум их прилететь. 138 | Тут с просьбой все к нему, чтоб их решать сомненье: 139 | "Пожалуй, - говорят, - возьми на час терпенье, 140 | Чтобы Квартет в порядок наш привесть: 141 | И ноты есть у нас, и инструменты есть; 142 | Скажи лишь, как нам сесть!" - 143 | "Чтоб музыкантом быть, так надобно уменье 144 | И уши ваших понежней, - 145 | Им отвечает Соловей. - 146 | А вы, друзья, как ни садитесь, 147 | Все в музыканты не годитесь". 148 | Проказница-Мартышка, Осел, Козел да косолапый Мишка 149 | Затеяли сыграть Квартет. 150 | Достали нот, баса, альта, две скрипки 151 | И сели на лужок под липки - 152 | Пленять своим искусством свет. 153 | Ударили в смычки, дерут, а толку нет. 154 | "Стой, братцы, стой! - кричит Мартышка. - Погодите! 155 | Как музыке идти? Ведь вы не так сидите. 156 | Ты с басом, Мишенька, садись против альта, 157 | Я, прима, сяду против вторы; 158 | Тогда пойдет уж музыка не та: 159 | У нас запляшут лес и горы!" 160 | Проказница-Мартышка, Осел, Козел да косолапый Мишка 161 | Затеяли сыграть Квартет. 162 | Достали нот, баса, альта, две скрипки 163 | И сели на лужок под липки - 164 | Пленять своим искусством свет. 165 | Ударили в смычки, дерут, а толку нет. 166 | "Стой, братцы, стой! - кричит Мартышка. - Погодите! 167 | Как музыке идти? Ведь вы не так сидите. 168 | Ты с басом, Мишенька, садись против альта, 169 | Я, прима, сяду против вторы; 170 | Тогда пойдет уж музыка не та: 171 | У нас запляшут лес и горы!" 172 | Расселись, начали Квартет; 173 | Он все-таки на лад нейдет. 174 | "Постойте ж, я сыскал секрет, - 175 | Кричит Осел, - мы, верно, уж поладим, 176 | Коль рядом сядем". 177 | Послушались Осла: уселись чинно в ряд, 178 | А все-таки Квартет нейдет на лад. 179 | Вот пуще прежнего пошли у них разборы 180 | И споры, кому и как сидеть. 181 | Случилось Соловью на шум их прилететь. 182 | Тут с просьбой все к нему, чтоб их решать сомненье: 183 | "Пожалуй, - говорят, - возьми на час терпенье, 184 | Чтобы Квартет в порядок наш привесть: 185 | И ноты есть у нас, и инструменты есть; 186 | Скажи лишь, как нам сесть!" - 187 | «Как, милый Петушок, поешь, ты громко, важно!»- 188 | «А ты, Кукушечка, мой свет, 189 | Как тянешь плавно и протяжно: 190 | Поешь ты лучше райской птички, 191 | На всех ссылаюсь в этом я». 192 | Тут Воробей, случась, примолвил им: «Друзья! 193 | Хоть вы охрипните, хваля друг дружку,— 194 | Все ваша музыка плоха!..» 195 | "Чтоб музыкантом быть, так надобно уменье 196 | И уши ваших понежней, - 197 | Им отвечает Соловей. - 198 | А вы, друзья, как ни садитесь, 199 | Все в музыканты не годитесь". 200 | «Отколе, умная, бредешь ты, голова?» 201 | Лисица, встретяся с Ослом, его спросила.— 202 | «Сейчас лишь ото Льва! 203 | Ну, кумушка, куда его девалась сила: 204 | Бывало, зарычит, так стонет лес кругом, 205 | И я, без памяти, бегом, 206 | Куда глаза глядят, от этого урода; 207 | А ныне в старости и дряхл и хил, 208 | Совсем без сил, 209 | Валяется в пещере, как колода. 210 | Поверишь ли, в зверях 211 | Пропал к нему весь прежний страх, 212 | И поплатился он старинными долгами! 213 | Кто мимо Льва ни шел, всяк вымещал ему 214 | По-своему: 215 | Кто зубом, кто рогами…» 216 | «Но ты коснуться Льву, конечно, не дерзнул?» 217 | Лиса Осла перерывает. 218 | «Вот-на!» Осел ей отвечает: 219 | «А мне чего робеть? и я его лягнул: 220 | Пускай ослиные копыта знает!» 221 | Так души низкие, будь знатен, силен ты, 222 | Не смеют на тебя поднять они и взгляды; 223 | Но упади лишь с высоты: 224 | От первых жди от них обиды и досады. 225 | Осел увидел Соловья 226 | И говорит ему: «Послушай-ка, дружище! 227 | Ты, сказывают, петь великий мастерище. 228 | Хотел бы очень я 229 | Сам посудить, твое услышав пенье, 230 | Велико ль подлинно твое уменье?» 231 | Тут Соловей являть свое искусство стал: 232 | Защелкал, засвистал 233 | На тысячу ладов, тянул, переливался; 234 | То нежно он ослабевал 235 | И томной вдалеке свирелью отдавался, 236 | То мелкой дробью вдруг по роще рассыпался. 237 | Внимало все тогда 238 | Любимцу и певцу Авроры: 239 | Затихли ветерки, замолкли птичек хоры, 240 | И прилегли стада. 241 | Чуть-чуть дыша, пастух им любовался 242 | И только иногда, 243 | Внимая Соловью, пастушке улыбался 244 | Скончал певец. Осел, уставясь в землю лбом; 245 | «Изрядно, — говорит, — сказать неложно, 246 | Тебя без скуки слушать можно; 247 | А жаль, что незнаком 248 | Ты с нашим петухом; 249 | Еще б ты боле навострился, 250 | Когда бы у него немножко поучился». 251 | Услыша суд такой, мой бедный Соловей 252 | Вспорхнул и — полетел за тридевять полей. 253 | Избави, Бог, и нас от этаких судей. 254 | Уж сколько раз твердили миру, 255 | Что лесть гнусна, вредна; но только все не впрок, 256 | И в сердце льстец всегда отыщет уголок. 257 | Вороне где-то бог послал кусочек сыру; 258 | На ель Ворона взгромоздясь, 259 | Позавтракать было совсем уж собралась, 260 | Да призадумалась, а сыр во рту держала. 261 | На ту беду Лиса близехонько бежала; 262 | Вдруг сырный дух Лису остановил: 263 | Лисица видит сыр, Лисицу сыр пленил. 264 | Плутовка к дереву на цыпочках подходит; 265 | Вертит хвостом, с Вороны глаз не сводит 266 | И говорит так сладко, чуть дыша: 267 | «Голубушка, как хороша! 268 | Ну что за шейка, что за глазки! 269 | Рассказывать, так, право, сказки! 270 | Какие перушки! какой носок! 271 | И, верно, ангельский быть должен голосок! 272 | Спой, светик, не стыдись! Что, ежели, сестрица, 273 | При красоте такой и петь ты мастерица,- 274 | Ведь ты б у нас была царь-птица!» 275 | Вещуньина с похвал вскружилась голова, 276 | От радости в зобу дыханье сперло,- 277 | И на приветливы Лисицыны слова 278 | Ворона каркнула во все воронье горло: 279 | Сыр выпал — с ним была плутовка такова. 280 | -------------------------------------------------------------------------------- /data/tips.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anklowait/python_for_CL/685d52838288001606f2635637b603b008cef537/data/tips.zip -------------------------------------------------------------------------------- /data/вертолет.txt: -------------------------------------------------------------------------------- 1 | Этимология 2 | Устаревшее название «геликоптер» было заимствовано из французского языка (фр. hélicoptère) уже в конце XIX века. Во французском языке, в свою очередь, слово создано из корней греческого языка (др.-греч. ἕλιξ, родительный падеж ἕλικος «спираль, винт» и πτερόν «крыло»). 3 | 4 | Авторство слова «вертолёт» (от «вертится» и «летает») принадлежит Н. И. Камову. Самым ранним документом, в котором употребляется «вертолёт», является Протокол заседания Технической Комиссии Центрального Совета ОСОАВИАХИМа под председательством Б. Н. Юрьева, датированный 8 февраля 1929 года. Заседание Комиссии было посвящено рассмотрению проекта автожира КАСКР-1 инженеров Н. И. Камова и Н. К. Скржинского. Новое слово прижилось как синоним слова «геликоптер», в конце 1940-х годов полностью заменив его. Слово «автожир» осталось в русском языке в своём первоначальном значении. 5 | 6 | Не представляется верным утверждение Л. А. Введенской и Н. П. Колесникова, что, «когда изобрели летательный аппарат, которому не нужен разбег перед взлётом, поскольку он способен вертикально подняться и полететь с любой площадки, то для его наименования создали слово „вертолёт“ (вертикально + лететь)», тем более, что КАСКР-1, являющийся автожиром, не мог подниматься вертикально. 7 | 8 | Также существует версия, что слово «вертолёт» придумал и ввёл в русский язык советский писатель-фантаст А. П. Казанцев. 9 | 10 | Существует версия происхождения слова «вертолёт» от названия предприятия-производителя вертолётов «Vertol» (название, в свою очередь, произошло от сокращения термина «Vertical Take-off and Landing aircraft» — «воздушное судно вертикального взлёта и посадки»). В 1959 году советская делегация, в состав которой входил и разработчик первых советских серийных вертолётов М. Л. Миль, приобрела в США образцы американских вертолётов Sikorsky S-58 и Vertol V-44. Именно с этого времени слово «вертолёт» в русском языке окончательно вытеснило слово «геликоптер» для обозначения этих машин. 11 | 12 | Основные принципы 13 | 14 | Подобно крылу самолёта, лопасти несущего винта вертолёта находятся под углом к плоскости вращения винта, который называется углом установки лопастей. Однако, в отличие от неподвижного самолётного крыла, угол установки лопастей вертолёта может меняться в широких пределах (до 30°). 15 | 16 | Почти всегда несущий винт вертолёта оснащён автоматом перекоса, который для управления полётом обеспечивает смещение центра давления винта в случае шарнирного соединения лопастей или же наклоняет плоскость вращения винта в случае полужёсткого соединения. Автомат перекоса, как правило, жёстко соединяется с осевым шарниром для изменения угла атаки лопастей. В схемах с тремя и более несущими винтами автомат перекоса может отсутствовать. 17 | 18 | Лопасти вертолёта, как правило, во всех режимах полёта вращаются с постоянной частотой, увеличение или уменьшение мощности несущего винта зависит от шага винта. 19 | 20 | Вращение винту обычно передаётся от одного или двух двигателей через трансмиссию и промежуточный редуктор колонки несущего винта. При этом возникает реактивный момент, который стремится закрутить вертолёт в сторону, противоположную от вращения несущего винта. Для противодействия реактивному моменту, а также для путевого управления, используется либо рулевой винт, либо соосная схема несущих винтов, вращающихся в разных направлениях. 21 | 22 | В качестве рулевого устройства обычно используется вертикальный рулевой винт на конце хвостовой балки, реже применяют рулевой винт в кольцевом канале — фенестрон, ещё реже систему NOTAR, основанную на эффекте Коанды. 23 | 24 | Система NOTAR состоит из полой хвостовой балки, у основания которой находится винт для создания необходимого давления, управляемых щелей вдоль поверхности балки и поворотного сопла для путевого управления на конце балки. Воздух, выходящий из управляемых щелей, создаёт разные скорости на поверхности хвостовой балки. По закону Бернулли, на той части поверхности, где скорость протекания пограничного воздушного слоя больше, меньше давление воздуха. Из-за разницы давлений воздуха на стороны хвостовой балки возникает необходимая сила, направленная от участка с большим давлением к участку с меньшим давлением. (Пример такого вертолёта — MD 500.) 25 | 26 | Также существуют варианты с расположением рулевого винта на крыле вертолёта, при этом винт не только противодействует реактивному моменту и участвует в путевом управлении, но и создаёт дополнительную тягу, направленную вперёд, разгружая тем самым несущий винт во время полёта. 27 | 28 | При использовании соосной схемы противоположно вращающихся винтов, реактивные моменты взаимно компенсируются, при этом дополнительная мощность от двигателей не требуется. Однако такая схема заметно усложняет конструкцию вертолёта. 29 | 30 | В случае, если винт приводится во вращение реактивными двигателями, закреплёнными на самих лопастях, реактивный момент почти не заметен. 31 | 32 | Для разгрузки несущего винта на большой скорости вертолёт может оснащаться достаточно развитым крылом, для увеличения путевой устойчивости может также применяться оперение. 33 | 34 | Когда вертолёт летит вперёд, лопасти, движущиеся вперёд, имеют бо́льшую скорость относительно воздуха, чем движущиеся назад. Вследствие этого одна из половин винта создаёт бо́льшую подъёмную силу, чем другая, и возникает дополнительный кренящий момент. При этом половина винта с наступающими лопастями по отношению к набегающему воздушному потоку под действием этого потока стремится совершить взмах вверх в горизонтальном шарнире. При наличии жёсткой связи с автоматом перекоса это ведёт к уменьшению угла атаки и, следовательно, к уменьшению подъёмной силы. На другой же половине винта лопасти испытывают гораздо меньшее давление воздуха, угол установки лопастей увеличивается, увеличивается и подъёмная сила. Этот простой способ уменьшает влияние кренящего момента. Стоит отметить, что на отступающих лопастях, при определённых обстоятельствах, может наблюдаться срыв потока, а концевые участки наступающих лопастей могут преодолевать волновой кризис при прохождении звукового барьера. 35 | 36 | Кроме того, для улучшения устойчивости во время полёта, повышения наибольших скорости и грузоподъёмности применяют дополнительные крылья (например, на Ми-6 и частично на Ми-24 — у этого вертолёта роль дополнительных крыльев выполняют пилоны подвесного оружия). За счёт дополнительной подъёмной силы на крыльях удаётся разгрузить несущий винт, снизить общий шаг винта и несколько снизить силу эффекта кренения, однако в режиме висения крылья создают дополнительное сопротивление нисходящему воздушному потоку от несущего винта, тем самым снижая устойчивость. 37 | 38 | Несущий винт создаёт вибрацию, угрожающую разрушением конструкции. Поэтому в большинстве случаев применяется активная система гашения возникающих колебаний. 39 | 40 | При отказе двигателей вертолёт должен иметь возможность безопасно приземлиться в режиме авторотации, то есть в режиме самовращения несущего винта под действием набегающего потока воздуха. 41 | 42 | Для этого почти все вертолёты, за исключением реактивных, снабжены муфтой свободного хода, которая в случае необходимости разъединяет трансмиссию с несущим винтом. Посадка в режиме авторотации получается управляемой, но считается аварийным режимом: установившаяся скорость снижения у лёгких вертолётов от 5 м/с, а у тяжёлых до 30 м/с и более, — без резкого «затяжеления» винта перед столкновением с землёй такая посадка мало отличается от падения. 43 | 44 | Характеристики вертолёта зависят от давления окружающего воздуха, в частности от высоты полёта, температуры воздуха, влажности. 45 | 46 | Основные части вертолёта 47 | Несущий винт предназначен для создания подъёмной и пропульсивной (движущей) сил, а также для управления полётом. Он состоит из лопастей и втулки, которая передаёт крутящий момент с вала главного редуктора к лопастям. 48 | 49 | Рулевой винт служит для компенсации реактивного крутящего момента несущего винта и путевого управления одновинтового вертолёта. Он состоит из лопастей и втулки, закреплённой на вале хвостового редуктора. См. также: Фенестрон 50 | 51 | Автомат перекоса обеспечивает управление общим и циклическим шагом несущего винта, передавая управляющий сигнал от цепи управления к осевому шарниру втулки несущего винта. 52 | 53 | Система управления предназначена для создания сил и моментов, необходимых для движения вертолёта по заданной траектории. 54 | 55 | Трансмиссия предназначена для передачи мощности от двигателей к несущему и рулевому винтам и вспомогательным узлам. Схема трансмиссии определяется схемой вертолёта, числом и расположением двигателей. Трансмиссия состоит из главного, промежуточного и хвостового редукторов, валов и их опор, соединительных муфт, тормоза несущего винта. 56 | 57 | Фюзеляж служит для размещения экипажа, пассажиров, грузов, оборудования, топлива и т. д. К фюзеляжу крепятся шасси, подредукторные рамы, узлы крепления двигателя, оперение и т. д. 58 | 59 | Крыло создаёт дополнительную подъёмную силу, разгружая несущий винт, что позволяет увеличить скорость полёта. В крыле могут размещаться топливные баки, оборудование, ниши для уборки шасси. У вертолётов поперечной схемы крыло поддерживает несущие винты. 60 | 61 | Оперение предназначено для обеспечения устойчивости и управляемости вертолёта. Оно разделяется на горизонтальное (стабилизатор) и вертикальное (киль). 62 | 63 | Взлётно-посадочные устройства служат для стоянки вертолёта, передвижения его по земле и гашения энергии удара при посадке. Они могут быть выполнены в виде колёсного шасси, полозкового шасси или поплавков (жёстких или надувных). Колёсное шасси может быть убираемым в полёте. 64 | 65 | Силовая установка предназначена для создания мощности, потребляемой на привод несущего и рулевого винтов и вспомогательных агрегатов. Представляет собой комплекс двигателей (поршневых, газотурбинных или электрических числом от 1 до 3 и (редко) более) с системами, обеспечивающими их нормальную устойчивую работу на всех режимах полёта. 66 | 67 | Управление 68 | 69 | Органы управления вертолёта: ручка циклического шага, ручка общего шага, педали 70 | Управление по крену и тангажу на большинстве существующих вертолётов осуществляется с помощью циклического изменения угла атаки лопастей (шага) несущего винта, называемого циклическим шагом, с помощью автомата перекоса. При изменении циклического шага создаётся момент, наклоняющий вертолёт, вследствие чего вектор тяги несущего винта отклоняется в заданном направлении. На конвертопланах управление осуществляется по-самолётному. Также возможны иные способы управления по крену и тангажу, но они не применяются на существующих вертолётах. 71 | 72 | Управление по рысканью разнится в зависимости от аэродинамической схемы вертолёта и может быть осуществлено с помощью рулевого винта (у вертолётов классической схемы), разницы общего шага винтов (у двухвинтовых вертолётов), с помощью реактивного сопла (у вертолётов со струйной системой), а также при горизонтальном движении с помощью вертикального оперения. 73 | 74 | Для управления циклическим шагом в кабине вертолёта установлена вертикальная ручка. Её отклонение вперёд/назад обеспечивает управление по тангажу, влево/вправо — по крену. Для изменения общего шага несущего винта (соответственно, подъёмной силы вертолёта) используется отклоняемая вверх ручка «шаг-газ» под левой рукой лётчика. Управление по рысканью осуществляется педалями. 75 | 76 | Существенно, что в вертолёте, в отличие от самолётов, применяется не прямое управление мощностью двигателя, а опосредованное. В ходе полёта скорость вращения несущего винта изменяется в относительно узких пределах. Логику работы управления мощностью можно описать следующим образом. Например, для выполнения взлёта лётчик увеличивает общий шаг несущего винта, возросшее сопротивление воздуха уменьшает обороты винта, автоматика управления двигателем обнаруживает такое падение оборотов и увеличивает подачу топлива, таким образом увеличивая мощность. Такая система устанавливается на всех без исключения вертолётах с газотурбинными двигателями, а также на подавляющем большинстве поршневых вертолётов, за исключением редких образцов 1950-х годов. 77 | 78 | Несмотря на наличие такой автоматической системы управления, в ряде случаев всё же требуется вмешательство лётчика (прямое регулирование мощности двигателя). Для этого на ручке общего шага расположен регулятор мощности (т. н. «коррекция»). Регулятор выполнен в виде поворотного кольца, подобного мотоциклетной ручке газа. Диапазон коррекции относительно невелик; коррекция применяется для точной регулировки мощности. По этой причине ручка общего шага зачастую называется «шаг-газ». 79 | 80 | На двухдвигательных вертолётах может также устанавливаться система прямого раздельного управления двигателями. Она используется как резервная — на случай различных отказов или аварийных ситуаций. 81 | 82 | Преимущества и недостатки 83 | Главным достоинством является способность совершать взлёт и посадку по вертикали — вертолёт может приземлиться (и взлететь) в любом месте, где есть ровная площадка размером в полтора диаметра винта. Также их манёвренность: вертолёты способны к зависанию в воздухе и даже к полёту «задом наперёд». Кроме того, вертолёты могут перевозить груз на внешней подвеске, что позволяет перевозить очень громоздкие грузы, а также выполнять монтажные работы. 84 | 85 | Основные недостатки, присущие всей винтокрылой технике, по сравнению с самолётами, — меньшая максимальная скорость полёта и повышенный расход горючего (удельный расход топлива). Как следствие, более высокая стоимость полёта в расчёте на пассажиро-километр или единицу массы перевозимого груза. Также к недостаткам вертолётов можно отнести и сложность в управлении. 86 | 87 | У вертолётов с реактивным приводом несущего винта резко усложняется посадка на авторотации (при отключении двигателей большое лобовое сопротивление гондол двигателей быстро замедляет вращение несущего винта), также высокий шум и большая заметность от факелов двигателей. 88 | 89 | Как и у самолётов, у вертолётов существуют свои особенные, характерные только для них опасные режимы полёта, аварийные режимы и аэродинамические особенности: например, вихревое кольцо, земной резонанс и т. д. Пилот вертолёта должен иметь твёрдые знания и практические навыки для предотвращения возможных аварийных ситуаций из-за этих особенностей вертолёта. -------------------------------------------------------------------------------- /data/морж-корж.txt: -------------------------------------------------------------------------------- 1 | Морж[1] (кильд. mоršа, норв. morššâ, лат. Odobenus rosmarus) — морское млекопитающее, единственный современный вид семейства моржовых клады ластоногих отряда хищных. 2 | 3 | Взрослый морж легко узнаваем по своим видным бивням. Морж — один из крупнейших представителей ластоногих, по размерам тела среди ластоногих уступает лишь морским слонам[2]. Ареалы этих видов не пересекаются, то есть морж является крупнейшим из ластоногих в своей среде обитания. 4 | 5 | Зимнее плавание в России называется «моржеванием». 6 | 7 | В 2008 году, по инициативе Всемирного фонда дикой природы (WWF), утверждён День моржа, который отмечается ежегодно 24 ноября. 8 | 9 | Морж — крупный морской зверь с очень толстой кожей. Верхние клыки чрезвычайно развиты, удлинённы и направлены вниз. Очень широкая морда усажена многочисленными толстыми, жёсткими, сплющенными щетинами-усами (вибриссами), их у моржа на верхней губе может быть от 400 до 700, расположены они в 13—18 рядов[4]. Наружных ушей нет, глаза маленькие. 10 | 11 | Кожа покрыта короткими прилегающими жёлто-бурыми волосами, но с возрастом их становится меньше, и у старых моржей кожа почти совершенно голая. Конечности более приспособлены для движения на суше, чем у настоящих тюленей, и моржи могут ходить, а не ползать; подошвы мозолистые. Хвост зачаточный. 12 | 13 | Кожа моржей очень морщинистая и толстая, до 10 см на шее и плечах самцов. Слой жира — до 15 см. Молодые моржи имеют тёмно-коричневый цвет кожи, а по мере взросления светлеют и бледнеют. Старые самцы становятся почти розовыми. Так как кровеносные сосуды кожи сужаются в холодной воде, моржи могут стать почти белого цвета во время купания. В качестве вторичных половых признаков для самцов (в естественных условиях) характерны наросты на коже шеи, груди и плеч. 14 | 15 | Наиболее характерной особенностью моржа являются его длинные бивни. Это удлинённые клыки, которые присутствуют у обоих полов и могут достигать в длину 1 м и весить до 5,4 кг. Бивни немного длиннее и толще у самцов, которые используют их для схваток. Самцы с крупнейшими бивнями обычно доминируют в социальной группе. Бивни также используются для формирования и поддержания отверстий во льду и помогают моржам вылезать из воды на лёд. Возможно, бивни также используются, чтобы искать еду на дне. 16 | 17 | Выделяют два или три подвида моржа[5]: 18 | 19 | Тихоокеанский морж (Odobenus rosmarus divergens Illiger, 1811), 20 | Атлантический морж (Odobenus rosmarus rosmarus Linnaeus, 1758). 21 | Часто из тихоокеанского подвида выделяют третий подвид — лаптевского моржа (Odobenus rosmarus laptevi Chapskii, 1940), но его самостоятельность многими подвергается сомнению. В Красную книгу России лаптевская популяция включена на правах отдельного подвида. 22 | 23 | Согласно данным МСОП[6], по результатам недавних исследований митохондриальной ДНК и изучения морфометрических данных, следует отказаться от рассмотрения лаптевского моржа как самостоятельного подвида, признав его крайней западной популяцией тихоокеанского моржа. 24 | 25 | По последней оценке, основанной на результатах российско-американского учёта численности, проведённого в 1990 году и повторенного в 2006 году, современная численность популяции тихоокеанского моржа составляет от 129[7] до 200 тыс. особей[8][9]. 26 | 27 | Большая часть тихоокеанских моржей проводит лето севернее Берингова пролива, в Чукотском море вдоль северного побережья восточной Сибири, возле острова Врангеля, в море Бофорта вдоль северного побережья Аляски, а также встречается в водах между указанными местами. Небольшое число самцов встречается в летний период в Анадырском заливе, на южном побережье Чукотского полуострова, а также в Бристольском заливе. Весной и осенью они концентрируются от западного побережья Аляски до Анадырского залива. Они зимуют в южных частях Берингова моря, вдоль восточного побережья Сибири на юг к северной части полуострова Камчатка, а также вдоль южного побережья Аляски[2]. Фоссилизованные останки моржа возрастом 28 тыс. лет были найдены недалеко от залива Сан-Франциско, что показывает распространение моржа вплоть до берегов северной Калифорнии во времена последнего ледникового периода[10]. 28 | 29 | Атлантический морж был почти истреблён в результате бесконтрольного коммерческого промысла, и численность популяции его значительно ниже. Точно оценить численность в настоящее время нелегко, но, вероятно, она не превышает 20 тыс. особей[11][12]. Эта популяция распространена от Арктической Канады, Гренландии, Шпицбергена, а также в западном регионе Российской Арктики. На основании огромного географического распространения и данных по перемещениям, предполагается наличие восьми субпопуляций атлантического моржа — пять на западе и три на востоке от Гренландии[13]. Атлантический морж раньше занимал пределы, протянувшиеся на юг до мыса Код, и в большом числе встречался в заливе Святого Лаврентия. В апреле 2006 северо-западная популяция атлантического моржа была внесена в список Канадского акта по угрожаемым видам (англ. Canadian Species at Risk Act) (Квебек, Нью-Брансуик, Новая Шотландия, Ньюфаундленд и Лабрадор) как почти исчезнувшая в Канаде[14]. В ноябре 2018 года атлантические моржи были замечены в Белом море, где они не появлялись несколько столетий[15]. 30 | 31 | Изолированная лаптевская популяция моржа расположена в течение всего года в центральном и западном регионах Моря Лаптевых, в самом восточном регионе Карского моря, а также в самой западной части Восточно-Сибирского моря. Современная численность оценивается в 5—10 тыс. особей[16]. 32 | -------------------------------------------------------------------------------- /data/синт_неоднозначность.txt: -------------------------------------------------------------------------------- 1 | RUS 2 | 3 | Он из Германии туманной привез учености плоды. 4 | Эти типы стали есть на складе. 5 | Портрет из кости Екатерины Второй. 6 | Пете звонить нельзя. 7 | Нужно будет переизбрать заместителя. 8 | Парламент защищает правительство. 9 | Фонд социальной защиты Самарского района. 10 | Дом культуры лакокрасочного завода имени М.В.Ломоносова. 11 | Я люблю многозначность сильнее, чем большинство людей. 12 | Чужим телефоном пользоваться нельзя. 13 | 14 | ENG 15 | Squad helps dog bite victim 16 | Helicopter powered by human flies 17 | Flying planes can be dangerous 18 | I saw Grand Canyon flying to LA 19 | I made her duck 20 | Teacher strikes idle kids 21 | Milk drinkers are turning to powder 22 | Drunk gets nine months in violin case 23 | -------------------------------------------------------------------------------- /homework/HW3.md: -------------------------------------------------------------------------------- 1 | Третье дз выполнено в форме теста. 2 | 3 | ## [его можно пройти по этой ссылке](https://forms.gle/jjkr6WEsHQ3MLpEw5) 4 | 5 | Вопросы в тесте -- multiple choice, а в паре вопросов нужно отметить все (на Ваш взгляд) правильные варианты. 6 | 7 | Максимально за тест можно набрать 10 баллов 8 | 9 | Тест проверится автоматически, после сабмита ответов откроется фидбек 10 | 11 | Удачи! 12 | -------------------------------------------------------------------------------- /homework/ДЗ-1.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Задание 1: (условия if-elif-else)\n", 8 | "\n", 9 | "В ячейке ниже - код \"определителя усталости\". Давайте его улучшим:\n", 10 | "\n", 11 | "- добавьте условие для случаев,если пользователь вводит число больше 10\n", 12 | "\n", 13 | "- добавьте еще одно или два условия, чтобы разделение на категории усталости было еще точнее\n", 14 | "\n", 15 | "Подсказка: может помочь нарисовать себе схему условий на бумаге\n" 16 | ] 17 | }, 18 | { 19 | "cell_type": "code", 20 | "execution_count": 3, 21 | "metadata": {}, 22 | "outputs": [ 23 | { 24 | "name": "stdin", 25 | "output_type": "stream", 26 | "text": [ 27 | "по шкале от 0 до 10, напишите, насколько Вы устали: 3.9\n" 28 | ] 29 | }, 30 | { 31 | "name": "stdout", 32 | "output_type": "stream", 33 | "text": [ 34 | "Вы немного устали\n" 35 | ] 36 | } 37 | ], 38 | "source": [ 39 | "# определитель усталости\n", 40 | "\n", 41 | "a = float(input('по шкале от 0 до 10, напишите, насколько Вы устали: '))\n", 42 | "if a < 0.7:\n", 43 | " print('Кажется, Вы совсем не устали')\n", 44 | "elif 0.7 <= a <= 4.8:\n", 45 | " print('Вы немного устали')\n", 46 | "# Ваш код дальше:\n" 47 | ] 48 | }, 49 | { 50 | "cell_type": "markdown", 51 | "metadata": {}, 52 | "source": [ 53 | "### Задача 2 (списки и циклы)\n", 54 | "Робот, выбирающий пользователю коктейль:\n", 55 | "\n", 56 | "Представьте, что Вы разрабатываете (фрагмент) электронного помощника для ресторана. \n", 57 | "\n", 58 | "У Вас есть список коктейлей, где каждый коктейль представлен в виде списка ингридиентов (у нас получается список списков). Программа рандомным образом должна выбрать один из коктейлей (т.е. один из списков в общем списке) и вывести на экран сообщение: \"Сегодня в вашем коктейле будет: \" и сам список ингридиентов\n", 59 | "\n", 60 | "Но есть одно условие: в некоторые из списков по ошибке попал \"лосось\". Строку \"лосось\" нужно убрать *(здесь вам поможет один метод работы со списками)* ,но так как лосось есть не везде, нужно предварительно проверить его наличие в списке." 61 | ] 62 | }, 63 | { 64 | "cell_type": "code", 65 | "execution_count": 19, 66 | "metadata": {}, 67 | "outputs": [], 68 | "source": [ 69 | "import random\n", 70 | "\n", 71 | "cocktails = [\n", 72 | " [\"мартини\",\"грейпфрутовый сок\",\"жасмин\",\"тоник\",\"лосось\"],\n", 73 | " [\"клубника\",\"какао\",\"мята\",\"марсала\"],\n", 74 | " [\"водка\",\"томатный сок\",\"лимонный сок\",\"вустерширский соус\",\"черный перец\",\"сельдерей\",\"лосось\"],\n", 75 | " [\"джин\",\"вермут\",\"ликер мараскино\",\"апельсины\",\"коктейльная вишня\",\"лосось\"],\n", 76 | " [\"ром\",\"авокадо\",\"сахарный сироп\",\"сливки\",\"лимонный сок\",\"лед\"],\n", 77 | " [\"красный вермут\",\"тоник\",\"апельсины\",\"лосось\"],\n", 78 | " [\"только чай\"]\n", 79 | " ]\n", 80 | "\n", 81 | "#Ваш код\n" 82 | ] 83 | }, 84 | { 85 | "cell_type": "markdown", 86 | "metadata": {}, 87 | "source": [ 88 | "### Задание 3 (словари)" 89 | ] 90 | }, 91 | { 92 | "cell_type": "markdown", 93 | "metadata": {}, 94 | "source": [ 95 | "Алиса коллекционирует открыткм, которые она получила из разных стран от друзей. Она знает, что Мария прислала ей открытку из Лондона, Лоренцо -- из Милана, Олег - из Канберры, Ханс -- из Кальгари, Марк -- тоже из Милана, Алекс - из Кракова, и совсем недавно пришла открытка от Юлии из Мурманска. \n", 96 | "\n", 97 | "Сейчас ее архив выглядит вот так:\n", 98 | "```\n", 99 | "postcards = {\n", 100 | " \"Maria\":\"London\",\n", 101 | " \"Lorenzo\":\"Milan\",\n", 102 | " \"Oleg\":\"Canberra\",\n", 103 | " \"Hans\":\"Calgary\",\n", 104 | " \"Mark\":\"Milan\",\n", 105 | " \"Alex\":\"Krakow\",\n", 106 | " \"Julia\":\"Murmansk\"\n", 107 | " \n", 108 | "}\n", 109 | "```\n", 110 | "\n", 111 | "Однажды Алиса показала Вам свою бумажную коллекцию, и Вы заметили неточности: \n", 112 | "\n", 113 | "- в архиве не хватает двух открыток: от Петры из Парижа и от Ивана из Москвы. Добавьте их в архив Алисы.\n", 114 | "\n", 115 | "- открытка, присланная Олегом на самом деле не из Канберры, а из Сиднея.\n", 116 | "Исправьте город на верный, изменив значение по ключу в словаре.\n", 117 | "\n", 118 | "- Алиса говорит, что в ее коллекции более 10 уникальных городов. Сколько их на самом деле? Выведите названия этих городов." 119 | ] 120 | }, 121 | { 122 | "cell_type": "code", 123 | "execution_count": 15, 124 | "metadata": {}, 125 | "outputs": [], 126 | "source": [] 127 | }, 128 | { 129 | "cell_type": "code", 130 | "execution_count": 17, 131 | "metadata": {}, 132 | "outputs": [], 133 | "source": [] 134 | }, 135 | { 136 | "cell_type": "code", 137 | "execution_count": null, 138 | "metadata": {}, 139 | "outputs": [], 140 | "source": [] 141 | } 142 | ], 143 | "metadata": { 144 | "kernelspec": { 145 | "display_name": "Python 3 (ipykernel)", 146 | "language": "python", 147 | "name": "python3" 148 | }, 149 | "language_info": { 150 | "codemirror_mode": { 151 | "name": "ipython", 152 | "version": 3 153 | }, 154 | "file_extension": ".py", 155 | "mimetype": "text/x-python", 156 | "name": "python", 157 | "nbconvert_exporter": "python", 158 | "pygments_lexer": "ipython3", 159 | "version": "3.10.0" 160 | } 161 | }, 162 | "nbformat": 4, 163 | "nbformat_minor": 4 164 | } 165 | -------------------------------------------------------------------------------- /homework/ДЗ-2.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "d1c933ad-9f22-4881-b511-316a06b2d28c", 6 | "metadata": {}, 7 | "source": [ 8 | "## Работа с файлами, pandas + парсинг" 9 | ] 10 | }, 11 | { 12 | "cell_type": "markdown", 13 | "id": "48fba6f4-7e82-4623-a85e-487a173967c9", 14 | "metadata": {}, 15 | "source": [ 16 | "Давайте соберем корпус эко-новостей с сайта новостного издания \"Ведомости\". \n", 17 | "\n", 18 | "[По этой ссылке можно найти главную страницу](https://www.vedomosti.ru/ecology?utm_source=vedomosti.ru%2Fgorod&utm_medium=main&utm_campaign=desktop_main\n", 19 | ")\n", 20 | "\n", 21 | "Что нам предстоит сделать:\n", 22 | "- достать все заголовки новостей в главной страницы + текст каждой новости\n", 23 | "- сохранить в датафрейм с колонками \"источник\", \"дата\", \"заголовок\", \"текст\"\n", 24 | "\n", 25 | "- сохранить датафрейм в файл\n", 26 | "- положить код и получившийся файл в свой репозиторий на гитхабе\n", 27 | "\n" 28 | ] 29 | }, 30 | { 31 | "cell_type": "code", 32 | "execution_count": null, 33 | "id": "7926e4e3-8359-41f6-8dfb-39b2c194d66a", 34 | "metadata": {}, 35 | "outputs": [], 36 | "source": [] 37 | } 38 | ], 39 | "metadata": { 40 | "kernelspec": { 41 | "display_name": "Python 3 (ipykernel)", 42 | "language": "python", 43 | "name": "python3" 44 | }, 45 | "language_info": { 46 | "codemirror_mode": { 47 | "name": "ipython", 48 | "version": 3 49 | }, 50 | "file_extension": ".py", 51 | "mimetype": "text/x-python", 52 | "name": "python", 53 | "nbconvert_exporter": "python", 54 | "pygments_lexer": "ipython3", 55 | "version": "3.10.0" 56 | } 57 | }, 58 | "nbformat": 4, 59 | "nbformat_minor": 5 60 | } 61 | -------------------------------------------------------------------------------- /notebooks/OOP-2_libraries.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 14, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "class Preprocessing(object):\n", 10 | " def __init__(self,text):\n", 11 | " self.text = text\n", 12 | "# self.text2 = text_words\n", 13 | "\n", 14 | " def tokenize_default(self):\n", 15 | " \n", 16 | " from string import punctuation\n", 17 | "\n", 18 | " text_words = [word.strip(punctuation) for word in self.text.split()]\n", 19 | " text_words = [word.lower() for word in text_words if word]\n", 20 | " \n", 21 | " return text_words\n", 22 | " \n", 23 | " def lem_default(self, spacy_model): # 'en_core_web_sm'\n", 24 | " import spacy\n", 25 | " nlp = spacy.load(spacy_model)\n", 26 | "\n", 27 | "# def lemmatizing_bow(preprocessed_text):\n", 28 | "\n", 29 | " text_beforelemma = list(nlp(tokenize_default(self.text)))\n", 30 | "\n", 31 | " text_lemmatized=\"\"\n", 32 | "\n", 33 | " for token in text_beforelemma:\n", 34 | " text_lemmatized=text_lemmatized+\" \" +str(token.lemma_)\n", 35 | "\n", 36 | " text_lemmatized=text_lemmatized.replace(\"-PRON- \", \" \")\n", 37 | "\n", 38 | " text_lemmatized=text_lemmatized.replace(\" \", \" \")\n", 39 | " \n", 40 | " return text_lemmatized\n", 41 | " \n", 42 | " " 43 | ] 44 | }, 45 | { 46 | "cell_type": "markdown", 47 | "metadata": {}, 48 | "source": [ 49 | "Давайте создадим кастомную NLP-библиотеку из всего, что мы умеем делать. \n", 50 | "\n", 51 | "Для этого создадим файл с расширением ```.py```, в который будем добавлять необходимые классы (назовем его ```classes.py```), а в эту тетрадку будем импортировать необходимые компоненты из него\n", 52 | "\n", 53 | "*(для удобства, положим тетрадку и файл в одну директорию)*\n", 54 | "\n", 55 | "Пробовать нашу библиотеку можем на тестовом тексте (рус, англ) или на любом, который Вам нравится" 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": 9, 61 | "metadata": {}, 62 | "outputs": [], 63 | "source": [ 64 | "# ячейка импортов\n", 65 | "from classes import test_func, Preprocessing, Analysis, Viz" 66 | ] 67 | }, 68 | { 69 | "cell_type": "code", 70 | "execution_count": null, 71 | "metadata": {}, 72 | "outputs": [], 73 | "source": [ 74 | "test_func()" 75 | ] 76 | }, 77 | { 78 | "cell_type": "code", 79 | "execution_count": 15, 80 | "metadata": {}, 81 | "outputs": [], 82 | "source": [ 83 | "nlp = Preprocessing(\"HELLO! These were tests?\")\n", 84 | "\n", 85 | "# type(nlp)" 86 | ] 87 | }, 88 | { 89 | "cell_type": "code", 90 | "execution_count": 4, 91 | "metadata": {}, 92 | "outputs": [ 93 | { 94 | "data": { 95 | "text/plain": [ 96 | "['hello', 'these', 'were', 'tests']" 97 | ] 98 | }, 99 | "execution_count": 4, 100 | "metadata": {}, 101 | "output_type": "execute_result" 102 | } 103 | ], 104 | "source": [ 105 | "# tokenized = nlp.tokenize_default()\n", 106 | "\n", 107 | "# print(tokenized)\n", 108 | "\n", 109 | "nlp.tokenize_default()" 110 | ] 111 | }, 112 | { 113 | "cell_type": "code", 114 | "execution_count": 16, 115 | "metadata": {}, 116 | "outputs": [ 117 | { 118 | "ename": "NameError", 119 | "evalue": "name 'tokenize_default' is not defined", 120 | "output_type": "error", 121 | "traceback": [ 122 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 123 | "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", 124 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mnlp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlem_default\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'en_core_web_sm'\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 2\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;31m# nlp.lem_default('en_core_web_sm')\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 125 | "\u001b[0;32m\u001b[0m in \u001b[0;36mlem_default\u001b[0;34m(self, spacy_model)\u001b[0m\n\u001b[1;32m 19\u001b[0m \u001b[0;31m# def lemmatizing_bow(preprocessed_text):\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 20\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 21\u001b[0;31m \u001b[0mtext_beforelemma\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlist\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnlp\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtokenize_default\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtext\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[0m\u001b[1;32m 22\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 23\u001b[0m \u001b[0mtext_lemmatized\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", 126 | "\u001b[0;31mNameError\u001b[0m: name 'tokenize_default' is not defined" 127 | ] 128 | } 129 | ], 130 | "source": [ 131 | "nlp.lem_default('en_core_web_sm')\n", 132 | " \n", 133 | "\n", 134 | "# nlp.lem_default('en_core_web_sm')" 135 | ] 136 | }, 137 | { 138 | "cell_type": "markdown", 139 | "metadata": {}, 140 | "source": [ 141 | "## часть2" 142 | ] 143 | }, 144 | { 145 | "cell_type": "code", 146 | "execution_count": null, 147 | "metadata": {}, 148 | "outputs": [], 149 | "source": [ 150 | "tmp = Analysis()" 151 | ] 152 | }, 153 | { 154 | "cell_type": "code", 155 | "execution_count": null, 156 | "metadata": {}, 157 | "outputs": [], 158 | "source": [ 159 | "tmp2 = Viz()" 160 | ] 161 | }, 162 | { 163 | "cell_type": "code", 164 | "execution_count": null, 165 | "metadata": {}, 166 | "outputs": [], 167 | "source": [] 168 | } 169 | ], 170 | "metadata": { 171 | "kernelspec": { 172 | "display_name": "Python 3", 173 | "language": "python", 174 | "name": "python3" 175 | }, 176 | "language_info": { 177 | "codemirror_mode": { 178 | "name": "ipython", 179 | "version": 3 180 | }, 181 | "file_extension": ".py", 182 | "mimetype": "text/x-python", 183 | "name": "python", 184 | "nbconvert_exporter": "python", 185 | "pygments_lexer": "ipython3", 186 | "version": "3.8.2" 187 | } 188 | }, 189 | "nbformat": 4, 190 | "nbformat_minor": 4 191 | } 192 | -------------------------------------------------------------------------------- /notebooks/Python functions.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "tags": [] 7 | }, 8 | "source": [ 9 | "## Функции\n", 10 | "\n", 11 | "\n", 12 | "Мы с вами написали много небольших программ. А что если вам нужно будет использовать эти программы снова и снова? Например, вы написали код, который хорошо обрабатывает и токенизирует текст. И у вас 1000 текстов. Придется писать одни и те же строки кода снова?\n", 13 | "\n", 14 | "\n", 15 | "\n" 16 | ] 17 | }, 18 | { 19 | "cell_type": "markdown", 20 | "metadata": { 21 | "colab_type": "text", 22 | "id": "6kMhXS8lKSam" 23 | }, 24 | "source": [ 25 | "нас спасут функции! \n", 26 | "\n", 27 | "Функция в python - это такой объект, который выполняет какое-то действие c данными, которые она принимает на вход.\n", 28 | "\n", 29 | "- То, что функция принимает, называется *аргументом* и записывается в скобках. У функции может быть как один, ноль или несколько аргументов.\n", 30 | "\n", 31 | "- То, что функция возвращает, называется *значением*.\n", 32 | "\n", 33 | "\n", 34 | "Обычно функция определяется с помощью инструкции ```def```, за которым следует название функции со скобками и двоеточием. \n", 35 | "\n", 36 | "Давайте создадим самую простую функцию:" 37 | ] 38 | }, 39 | { 40 | "cell_type": "code", 41 | "execution_count": 3, 42 | "metadata": { 43 | "colab": {}, 44 | "colab_type": "code", 45 | "id": "L2cPPSNm8xaw" 46 | }, 47 | "outputs": [], 48 | "source": [ 49 | "def hello():\n", 50 | "\n", 51 | " print (\"hello =^_^=\")" 52 | ] 53 | }, 54 | { 55 | "cell_type": "code", 56 | "execution_count": 4, 57 | "metadata": { 58 | "colab": { 59 | "base_uri": "https://localhost:8080/", 60 | "height": 34 61 | }, 62 | "colab_type": "code", 63 | "id": "nOu2GAWXN9b1", 64 | "outputId": "9982f7b3-141d-47c7-93c2-c3b0c6e79e93" 65 | }, 66 | "outputs": [ 67 | { 68 | "name": "stdout", 69 | "output_type": "stream", 70 | "text": [ 71 | "hello =^_^=\n" 72 | ] 73 | } 74 | ], 75 | "source": [ 76 | "hello() # чтобы функция cработала, ее надо вызвать" 77 | ] 78 | }, 79 | { 80 | "cell_type": "code", 81 | "execution_count": 5, 82 | "metadata": { 83 | "colab": {}, 84 | "colab_type": "code", 85 | "id": "4bNVEzUnOFPZ" 86 | }, 87 | "outputs": [], 88 | "source": [ 89 | "# усложним функцию\n", 90 | "\n", 91 | "def personal_hello():\n", 92 | " name = input(\"Как Вас зовут?\")\n", 93 | " print (\"Добрый день,\", name)\n" 94 | ] 95 | }, 96 | { 97 | "cell_type": "code", 98 | "execution_count": 6, 99 | "metadata": { 100 | "colab": { 101 | "base_uri": "https://localhost:8080/", 102 | "height": 51 103 | }, 104 | "colab_type": "code", 105 | "id": "hrzq20zGOxX9", 106 | "outputId": "e63cdbd7-ef8d-4f46-985e-4da9cdf06550" 107 | }, 108 | "outputs": [ 109 | { 110 | "name": "stdin", 111 | "output_type": "stream", 112 | "text": [ 113 | "Как Вас зовут? N\n" 114 | ] 115 | }, 116 | { 117 | "name": "stdout", 118 | "output_type": "stream", 119 | "text": [ 120 | "Добрый день, N\n" 121 | ] 122 | } 123 | ], 124 | "source": [ 125 | "personal_hello()" 126 | ] 127 | }, 128 | { 129 | "cell_type": "markdown", 130 | "metadata": {}, 131 | "source": [ 132 | "Можно написать функцию так, чтобы она не только совершала действие, но и возвращала некоторый результат. Понадобится ключевое слово ```return```" 133 | ] 134 | }, 135 | { 136 | "cell_type": "code", 137 | "execution_count": 7, 138 | "metadata": { 139 | "colab": {}, 140 | "colab_type": "code", 141 | "id": "3nt1yPVfOz6E" 142 | }, 143 | "outputs": [], 144 | "source": [ 145 | "# функция с возвратом значения\n", 146 | "\n", 147 | "def add(x,y):\n", 148 | " res = x+y\n", 149 | " return res" 150 | ] 151 | }, 152 | { 153 | "cell_type": "code", 154 | "execution_count": 16, 155 | "metadata": { 156 | "colab": { 157 | "base_uri": "https://localhost:8080/", 158 | "height": 34 159 | }, 160 | "colab_type": "code", 161 | "id": "Mi1_v9yKPNHu", 162 | "outputId": "8c4be812-afc5-47a5-8e16-da580cde1ae8" 163 | }, 164 | "outputs": [ 165 | { 166 | "data": { 167 | "text/plain": [ 168 | "'hi'" 169 | ] 170 | }, 171 | "execution_count": 16, 172 | "metadata": {}, 173 | "output_type": "execute_result" 174 | } 175 | ], 176 | "source": [ 177 | "add(\"h\",\"i\") # так мы вызвали функцию и передали аргументы в скобках" 178 | ] 179 | }, 180 | { 181 | "cell_type": "code", 182 | "execution_count": 17, 183 | "metadata": {}, 184 | "outputs": [ 185 | { 186 | "data": { 187 | "text/plain": [ 188 | "8.6" 189 | ] 190 | }, 191 | "execution_count": 17, 192 | "metadata": {}, 193 | "output_type": "execute_result" 194 | } 195 | ], 196 | "source": [ 197 | "add(0.6,8) " 198 | ] 199 | }, 200 | { 201 | "cell_type": "markdown", 202 | "metadata": {}, 203 | "source": [ 204 | "а вот пример работы с текстом" 205 | ] 206 | }, 207 | { 208 | "cell_type": "code", 209 | "execution_count": 18, 210 | "metadata": { 211 | "colab": {}, 212 | "colab_type": "code", 213 | "id": "HbIrUegGQj5M" 214 | }, 215 | "outputs": [], 216 | "source": [ 217 | "def unique(x): # простая функция, выдающая уникальный набор элементов в объекте\n", 218 | " x = set(x)\n", 219 | " return x" 220 | ] 221 | }, 222 | { 223 | "cell_type": "code", 224 | "execution_count": 20, 225 | "metadata": {}, 226 | "outputs": [ 227 | { 228 | "data": { 229 | "text/plain": [ 230 | "{'e', 'h', 'l', 'o'}" 231 | ] 232 | }, 233 | "execution_count": 20, 234 | "metadata": {}, 235 | "output_type": "execute_result" 236 | } 237 | ], 238 | "source": [ 239 | "unique(\"hello\")" 240 | ] 241 | }, 242 | { 243 | "cell_type": "code", 244 | "execution_count": 24, 245 | "metadata": { 246 | "colab": { 247 | "base_uri": "https://localhost:8080/", 248 | "height": 34 249 | }, 250 | "colab_type": "code", 251 | "id": "RO-7hY7dRlF3", 252 | "outputId": "f0cfd290-d844-489a-f8e1-2a3c536e6f27" 253 | }, 254 | "outputs": [ 255 | { 256 | "name": "stdout", 257 | "output_type": "stream", 258 | "text": [ 259 | "{'n', '.', 'w', 's', 'o', 'a', 'T', ' ', 'h', 'R', 'd', 'l', 'i', 'y', 'e', 'r'}\n" 260 | ] 261 | }, 262 | { 263 | "data": { 264 | "text/plain": [ 265 | "{'a', 'always', 'and', 'is', 'rose', 'the', 'was'}" 266 | ] 267 | }, 268 | "execution_count": 24, 269 | "metadata": {}, 270 | "output_type": "execute_result" 271 | } 272 | ], 273 | "source": [ 274 | "poem = \"The Rose is a rose and was always a rose.\"\n", 275 | "\n", 276 | "print(unique(poem))\n", 277 | "\n", 278 | "poem = poem.strip(\".-:!?–,\").lower().split() #предобратобка\n", 279 | "\n", 280 | "unique(poem) # множество уникальных токенов " 281 | ] 282 | }, 283 | { 284 | "cell_type": "code", 285 | "execution_count": 37, 286 | "metadata": { 287 | "colab": {}, 288 | "colab_type": "code", 289 | "id": "FUN_ywNqU-Cl" 290 | }, 291 | "outputs": [], 292 | "source": [ 293 | "# функция, убирающая пунктуацию\n", 294 | "\n", 295 | "import string\n", 296 | "\n", 297 | "def normalize(text):\n", 298 | " normalized = text.lower().translate(str.maketrans('','',string.punctuation)).split()\n", 299 | " return normalized" 300 | ] 301 | }, 302 | { 303 | "cell_type": "code", 304 | "execution_count": 39, 305 | "metadata": { 306 | "colab": { 307 | "base_uri": "https://localhost:8080/", 308 | "height": 697 309 | }, 310 | "colab_type": "code", 311 | "id": "TZ5Zkha9c0uk", 312 | "outputId": "db5692da-7a61-4048-cd0c-d274ee07e7c0" 313 | }, 314 | "outputs": [ 315 | { 316 | "name": "stdout", 317 | "output_type": "stream", 318 | "text": [ 319 | "['i', 'had', 'heard', 'that', 'mcdonalds', 'never', 'decompose', 'so', 'i', 'just', 'wanted', 'to', 'see', 'if', 'it', 'was', 'true', 'or', 'not', 'hjortur', 'smarason', 'told', 'afp', 'this', 'week', 'its', '10', 'years', 'since', 'the', 'seemingly', 'indestructible', 'meal', 'was', 'purchased', 'and', 'it', 'barely', 'looks', 'a', 'day', 'older']\n" 320 | ] 321 | } 322 | ], 323 | "source": [ 324 | "# попробуем на тексте: \n", 325 | "\n", 326 | "news = \"\"\" \"\\I had heard that McDonald\\'s never decompose so I just wanted to see if it was true or not,\\\" Hjortur Smarason told AFP. This week, it's 10 years since the seemingly indestructible meal was purchased, and it barely looks a day older.\"\"\"\n", 327 | "\n", 328 | "print(normalize(news))" 329 | ] 330 | }, 331 | { 332 | "cell_type": "markdown", 333 | "metadata": { 334 | "colab_type": "text", 335 | "id": "kt9JszRTgh4-" 336 | }, 337 | "source": [ 338 | "### Аргументы функции\n", 339 | "Функция может принимать произвольное количество аргументов (или не принимать вообще). \n", 340 | "\n", 341 | "Существуют функции с произвольным числом аргументов, функции с позиционными и именованными аргументами, обязательными и необязательными.\n", 342 | "\n", 343 | "давайте разбираться\n", 344 | "\n", 345 | "1. позиционные и именованные аргументы" 346 | ] 347 | }, 348 | { 349 | "cell_type": "code", 350 | "execution_count": 40, 351 | "metadata": { 352 | "colab": {}, 353 | "colab_type": "code", 354 | "id": "dVnd5e7Ge_M4" 355 | }, 356 | "outputs": [], 357 | "source": [ 358 | "def birthday1(name, age):\n", 359 | " print( \"С днем рождения , \", name , \"!\", \" Вам сегодня исполняется\", age)" 360 | ] 361 | }, 362 | { 363 | "cell_type": "markdown", 364 | "metadata": { 365 | "colab_type": "text", 366 | "id": "X9CQVWnpoGzF" 367 | }, 368 | "source": [ 369 | "**позиционные аргументы**\n", 370 | "\n", 371 | "важен порядок ввода" 372 | ] 373 | }, 374 | { 375 | "cell_type": "code", 376 | "execution_count": 41, 377 | "metadata": { 378 | "colab": { 379 | "base_uri": "https://localhost:8080/", 380 | "height": 34 381 | }, 382 | "colab_type": "code", 383 | "id": "kdwjGqLQmduF", 384 | "outputId": "c9abcb8e-afa2-4319-af28-b54f0609ef74" 385 | }, 386 | "outputs": [ 387 | { 388 | "name": "stdout", 389 | "output_type": "stream", 390 | "text": [ 391 | "С днем рождения , дорогой друг ! Вам сегодня исполняется 1\n" 392 | ] 393 | } 394 | ], 395 | "source": [ 396 | "birthday1(\"дорогой друг\" , 1)" 397 | ] 398 | }, 399 | { 400 | "cell_type": "code", 401 | "execution_count": 42, 402 | "metadata": { 403 | "colab": { 404 | "base_uri": "https://localhost:8080/", 405 | "height": 34 406 | }, 407 | "colab_type": "code", 408 | "id": "igl8L9MvnmLk", 409 | "outputId": "0b4c9313-9be7-43a7-bd9f-3e0816fb51d9" 410 | }, 411 | "outputs": [ 412 | { 413 | "name": "stdout", 414 | "output_type": "stream", 415 | "text": [ 416 | "С днем рождения , 1 ! Вам сегодня исполняется дорогой друг\n" 417 | ] 418 | } 419 | ], 420 | "source": [ 421 | "# Проблема позиционных аргументов\n", 422 | "\n", 423 | "birthday1(1, \"дорогой друг\")" 424 | ] 425 | }, 426 | { 427 | "cell_type": "markdown", 428 | "metadata": { 429 | "colab_type": "text", 430 | "id": "o-xxHvGSn3a4" 431 | }, 432 | "source": [ 433 | "**именные аргументы**\n", 434 | "\n", 435 | "Вне зависимости от порядка, все хорошо." 436 | ] 437 | }, 438 | { 439 | "cell_type": "code", 440 | "execution_count": 43, 441 | "metadata": { 442 | "colab": { 443 | "base_uri": "https://localhost:8080/", 444 | "height": 34 445 | }, 446 | "colab_type": "code", 447 | "id": "atGOHsObmoGy", 448 | "outputId": "dee6d4c3-cd25-4d78-a352-c23811cc568c" 449 | }, 450 | "outputs": [ 451 | { 452 | "name": "stdout", 453 | "output_type": "stream", 454 | "text": [ 455 | "С днем рождения , дорогой друг ! Вам сегодня исполняется 1\n" 456 | ] 457 | } 458 | ], 459 | "source": [ 460 | "birthday1(name = \"дорогой друг\", age = 1) " 461 | ] 462 | }, 463 | { 464 | "cell_type": "code", 465 | "execution_count": 46, 466 | "metadata": { 467 | "colab": { 468 | "base_uri": "https://localhost:8080/", 469 | "height": 34 470 | }, 471 | "colab_type": "code", 472 | "id": "oHbEHLVKmxnw", 473 | "outputId": "a7642b6d-14ef-4920-c914-ae0e1720047d" 474 | }, 475 | "outputs": [ 476 | { 477 | "name": "stdout", 478 | "output_type": "stream", 479 | "text": [ 480 | "С днем рождения , Настя ! Вам сегодня исполняется 270\n" 481 | ] 482 | } 483 | ], 484 | "source": [ 485 | "birthday1(age = 270, name = \"Настя\")" 486 | ] 487 | }, 488 | { 489 | "cell_type": "markdown", 490 | "metadata": { 491 | "colab_type": "text", 492 | "id": "Kjx2bycnsi9p" 493 | }, 494 | "source": [ 495 | "### бонус: lambda func" 496 | ] 497 | }, 498 | { 499 | "cell_type": "markdown", 500 | "metadata": { 501 | "colab_type": "text", 502 | "id": "-AjT1BdWsvvx" 503 | }, 504 | "source": [ 505 | "Анонимные функции:\n", 506 | "* могут содержать лишь одно действие\n", 507 | "* выполняются быстрее\n", 508 | "* не обязательно присваивать переменной (не нужен def)\n", 509 | "* не требуется return\n", 510 | "\n", 511 | "\n", 512 | "обычно используются для одноразовых функций \n", 513 | "\n", 514 | "создаются с помощью ключевого слова ```lambda```" 515 | ] 516 | }, 517 | { 518 | "cell_type": "code", 519 | "execution_count": 47, 520 | "metadata": { 521 | "colab": {}, 522 | "colab_type": "code", 523 | "id": "tQoxZXdPsWFc" 524 | }, 525 | "outputs": [], 526 | "source": [ 527 | "lambda x, y: x + y # задали (до двоеточия аргументы, после - действие с ними)" 528 | ] 529 | }, 530 | { 531 | "cell_type": "code", 532 | "execution_count": null, 533 | "metadata": {}, 534 | "outputs": [], 535 | "source": [ 536 | "func = lambda x, y: x + y #так можно сохранить в переменную" 537 | ] 538 | }, 539 | { 540 | "cell_type": "code", 541 | "execution_count": 50, 542 | "metadata": { 543 | "colab": { 544 | "base_uri": "https://localhost:8080/", 545 | "height": 34 546 | }, 547 | "colab_type": "code", 548 | "id": "XKyQxTNVtTML", 549 | "outputId": "7796ece3-5ad5-48c3-cc34-bad7991aea0f" 550 | }, 551 | "outputs": [ 552 | { 553 | "data": { 554 | "text/plain": [ 555 | "11" 556 | ] 557 | }, 558 | "execution_count": 50, 559 | "metadata": {}, 560 | "output_type": "execute_result" 561 | } 562 | ], 563 | "source": [ 564 | "func(4, 7) # вызываем, подав аргументы" 565 | ] 566 | }, 567 | { 568 | "cell_type": "code", 569 | "execution_count": 51, 570 | "metadata": { 571 | "colab": { 572 | "base_uri": "https://localhost:8080/", 573 | "height": 34 574 | }, 575 | "colab_type": "code", 576 | "id": "vOoz51D-tgTP", 577 | "outputId": "e1c067e5-90ea-4143-c293-9a58046ed895" 578 | }, 579 | "outputs": [ 580 | { 581 | "data": { 582 | "text/plain": [ 583 | "'i write code in Python'" 584 | ] 585 | }, 586 | "execution_count": 51, 587 | "metadata": {}, 588 | "output_type": "execute_result" 589 | } 590 | ], 591 | "source": [ 592 | "func(\"i write\",\" code in Python\") # подаем строки как аргументы, их тоже можно конкатенировать" 593 | ] 594 | }, 595 | { 596 | "cell_type": "code", 597 | "execution_count": null, 598 | "metadata": {}, 599 | "outputs": [], 600 | "source": [] 601 | } 602 | ], 603 | "metadata": { 604 | "colab": { 605 | "collapsed_sections": [], 606 | "include_colab_link": true, 607 | "name": "Sat_02Nov_19.ipynb", 608 | "provenance": [] 609 | }, 610 | "kernelspec": { 611 | "display_name": "Python 3", 612 | "language": "python", 613 | "name": "python3" 614 | }, 615 | "language_info": { 616 | "codemirror_mode": { 617 | "name": "ipython", 618 | "version": 3 619 | }, 620 | "file_extension": ".py", 621 | "mimetype": "text/x-python", 622 | "name": "python", 623 | "nbconvert_exporter": "python", 624 | "pygments_lexer": "ipython3", 625 | "version": "3.8.2" 626 | } 627 | }, 628 | "nbformat": 4, 629 | "nbformat_minor": 4 630 | } 631 | -------------------------------------------------------------------------------- /notebooks/classes.py: -------------------------------------------------------------------------------- 1 | def test_func(): 2 | print("successfully imported") 3 | 4 | class NLP(object): 5 | def __init__(self,text): 6 | self.text = text 7 | 8 | def preprocess(self): 9 | return self.text.lower().strip().split() -------------------------------------------------------------------------------- /notebooks/files_OS.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "colab_type": "text", 7 | "id": "kIZidEDRSGBg" 8 | }, 9 | "source": [ 10 | "Часто, чтобы поработать над какой-то задачей, нам нужно работать с файлами, в которых хранятся данные, перемещаться среди папок и тд. Для решениях этих задач, в питоне существует [модуль os](https://pythonworld.ru/moduli/modul-os.html)." 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": null, 16 | "metadata": { 17 | "colab": {}, 18 | "colab_type": "code", 19 | "id": "0321FMiWSGBp" 20 | }, 21 | "outputs": [], 22 | "source": [ 23 | "import os" 24 | ] 25 | }, 26 | { 27 | "cell_type": "markdown", 28 | "metadata": {}, 29 | "source": [ 30 | "### Рассмотрим основные методы" 31 | ] 32 | }, 33 | { 34 | "cell_type": "code", 35 | "execution_count": null, 36 | "metadata": { 37 | "colab": {}, 38 | "colab_type": "code", 39 | "id": "Dt59vqBHSGB6" 40 | }, 41 | "outputs": [], 42 | "source": [ 43 | "# текущая рабочая директория (cwd = current working directory)\n", 44 | "\n", 45 | "x = os.getcwd() " 46 | ] 47 | }, 48 | { 49 | "cell_type": "markdown", 50 | "metadata": {}, 51 | "source": [ 52 | "Для следующих методов в скобках нужно указывать желаемый путь" 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": null, 58 | "metadata": { 59 | "tags": [] 60 | }, 61 | "outputs": [], 62 | "source": [ 63 | "list(os.walk(x)) # перечисляет все папки от топа вниз, в виде кортежа" 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": null, 69 | "metadata": { 70 | "colab": { 71 | "base_uri": "https://localhost:8080/", 72 | "height": 34 73 | }, 74 | "colab_type": "code", 75 | "id": "-6u6RCLESGCA", 76 | "outputId": "c1a73ca5-c105-45d8-fafb-288a9a852c17", 77 | "tags": [] 78 | }, 79 | "outputs": [], 80 | "source": [ 81 | "os.listdir(x) # список файлов и директорий в папке" 82 | ] 83 | }, 84 | { 85 | "cell_type": "code", 86 | "execution_count": null, 87 | "metadata": { 88 | "colab": {}, 89 | "colab_type": "code", 90 | "id": "o192KEJHSGCE" 91 | }, 92 | "outputs": [], 93 | "source": [ 94 | "os.mkdir(\"new\") # создаёт новую директорию" 95 | ] 96 | }, 97 | { 98 | "cell_type": "code", 99 | "execution_count": null, 100 | "metadata": { 101 | "colab": {}, 102 | "colab_type": "code", 103 | "id": "pj9svtYtSGB9" 104 | }, 105 | "outputs": [], 106 | "source": [ 107 | "os.chdir(\"new\") # сменяет текущую рабочую директорию" 108 | ] 109 | }, 110 | { 111 | "cell_type": "code", 112 | "execution_count": null, 113 | "metadata": { 114 | "colab": { 115 | "base_uri": "https://localhost:8080/", 116 | "height": 34 117 | }, 118 | "colab_type": "code", 119 | "id": "L0VYBoD6TF64", 120 | "outputId": "ae26aab1-aaad-4d13-d287-25e58a04a182" 121 | }, 122 | "outputs": [], 123 | "source": [ 124 | "os.getcwd() # проверим текущую директорию" 125 | ] 126 | }, 127 | { 128 | "cell_type": "code", 129 | "execution_count": null, 130 | "metadata": { 131 | "colab": { 132 | "base_uri": "https://localhost:8080/", 133 | "height": 34 134 | }, 135 | "colab_type": "code", 136 | "id": "L8WzXb7USGCL", 137 | "outputId": "bc9ea53f-c98b-4569-eb2e-f4535b38bf55" 138 | }, 139 | "outputs": [], 140 | "source": [ 141 | "os.listdir(\"/content/new\") # посмотрим, что в новой директории" 142 | ] 143 | }, 144 | { 145 | "cell_type": "code", 146 | "execution_count": null, 147 | "metadata": { 148 | "colab": { 149 | "base_uri": "https://localhost:8080/", 150 | "height": 34 151 | }, 152 | "colab_type": "code", 153 | "id": "MwRp_Bt6SGCa", 154 | "outputId": "17ce6ead-4734-49ee-b93f-084e9b2d8821" 155 | }, 156 | "outputs": [], 157 | "source": [ 158 | "#os.chdir(\"/content\")\n", 159 | "os.rmdir('/content/new') # удаляет пустую директорию. Чтобы удалить, из нее сначала надо выйти \n", 160 | "# (например, на шаг назад, это делает предыдущая строка)\n", 161 | "os.listdir() # посмотрим на список файлов снова, new уже нет" 162 | ] 163 | }, 164 | { 165 | "cell_type": "code", 166 | "execution_count": null, 167 | "metadata": { 168 | "colab": {}, 169 | "colab_type": "code", 170 | "id": "CihvMLrkSGCV" 171 | }, 172 | "outputs": [], 173 | "source": [ 174 | "os.remove('new') # удаляет путь к файлу." 175 | ] 176 | }, 177 | { 178 | "cell_type": "code", 179 | "execution_count": null, 180 | "metadata": { 181 | "colab": {}, 182 | "colab_type": "code", 183 | "id": "ppZeXif6SGCd", 184 | "outputId": "e21ef6ae-242e-4072-a65d-dfd2c5bed512" 185 | }, 186 | "outputs": [], 187 | "source": [ 188 | "os.listdir(x) # посмотрим на список еще раз, исчез ли new2" 189 | ] 190 | }, 191 | { 192 | "cell_type": "markdown", 193 | "metadata": { 194 | "colab_type": "text", 195 | "id": "EKBeg_6NSGCn" 196 | }, 197 | "source": [ 198 | "### в модуле os есть свой под-модуль: os.path ( реализует некоторые полезные функции для работы с путями)" 199 | ] 200 | }, 201 | { 202 | "cell_type": "code", 203 | "execution_count": null, 204 | "metadata": { 205 | "colab": {}, 206 | "colab_type": "code", 207 | "id": "LQ_mGKAj5gzo" 208 | }, 209 | "outputs": [], 210 | "source": [ 211 | "import os.path # импортим модуль" 212 | ] 213 | }, 214 | { 215 | "cell_type": "code", 216 | "execution_count": null, 217 | "metadata": { 218 | "colab": { 219 | "base_uri": "https://localhost:8080/", 220 | "height": 34 221 | }, 222 | "colab_type": "code", 223 | "id": "CWEZNUXoSGCo", 224 | "outputId": "8f7fd8a2-7898-4bdd-da91-e5b6f4fab965" 225 | }, 226 | "outputs": [], 227 | "source": [ 228 | "os.path.abspath(\"new\") # возвращает нормализованный абсолютный путь" 229 | ] 230 | }, 231 | { 232 | "cell_type": "code", 233 | "execution_count": null, 234 | "metadata": { 235 | "colab": { 236 | "base_uri": "https://localhost:8080/", 237 | "height": 34 238 | }, 239 | "colab_type": "code", 240 | "id": "YBcWrovC6yRj", 241 | "outputId": "16aca1a5-08cb-4a1a-e2b1-d08f2eb26f36" 242 | }, 243 | "outputs": [], 244 | "source": [ 245 | "os.path.isabs(\"new\") # является ли путь абсолютным" 246 | ] 247 | }, 248 | { 249 | "cell_type": "code", 250 | "execution_count": null, 251 | "metadata": { 252 | "colab": { 253 | "base_uri": "https://localhost:8080/", 254 | "height": 34 255 | }, 256 | "colab_type": "code", 257 | "id": "olWeC3bf6yHg", 258 | "outputId": "2d0bc56d-68dd-4c0c-ddc6-368197e0aced" 259 | }, 260 | "outputs": [], 261 | "source": [ 262 | "os.path.isfile(\"new\") # является ли путь файлом" 263 | ] 264 | }, 265 | { 266 | "cell_type": "code", 267 | "execution_count": null, 268 | "metadata": { 269 | "colab": { 270 | "base_uri": "https://localhost:8080/", 271 | "height": 34 272 | }, 273 | "colab_type": "code", 274 | "id": "-FdpVPhx6x-G", 275 | "outputId": "65477a3c-86a6-44c0-c8fb-d2fb1c648c17" 276 | }, 277 | "outputs": [], 278 | "source": [ 279 | "os.path.isdir(\"new\") # является ли путь директорией(папкой)" 280 | ] 281 | }, 282 | { 283 | "cell_type": "code", 284 | "execution_count": null, 285 | "metadata": { 286 | "colab": { 287 | "base_uri": "https://localhost:8080/", 288 | "height": 34 289 | }, 290 | "colab_type": "code", 291 | "id": "0qKfXUzASGCw", 292 | "outputId": "c6b4a06b-6ba0-402c-f5c3-9cd4eaae2535" 293 | }, 294 | "outputs": [], 295 | "source": [ 296 | "os.path.split(\"/content/new\") #разбивает путь на кортеж (голова, хвост), где хвост - последний компонент пути, а голова - всё остальное. \n", 297 | "#Хвост никогда не начинается со слеша (если путь заканчивается слешем, то хвост пустой).\n", 298 | "#Если слешей в пути нет, то пустой будет голова." 299 | ] 300 | }, 301 | { 302 | "cell_type": "markdown", 303 | "metadata": { 304 | "colab_type": "text", 305 | "id": "ovviRXtCSGC8" 306 | }, 307 | "source": [ 308 | "**А также:**\n", 309 | "1. [shutil](https://www.journaldev.com/20536/python-shutil-module)\n", 310 | "(модуль для работы с файлами, их копирования, перемещения, удаления и тд)\n", 311 | "\n", 312 | "2. [piclke](https://www.datacamp.com/community/tutorials/pickle-python-tutorial) (модуль для сохранения и загрузки объектов)\n" 313 | ] 314 | }, 315 | { 316 | "cell_type": "markdown", 317 | "metadata": { 318 | "colab_type": "text", 319 | "id": "pilnXnWUAgaI" 320 | }, 321 | "source": [ 322 | "## загрузка данных в колаб" 323 | ] 324 | }, 325 | { 326 | "cell_type": "markdown", 327 | "metadata": { 328 | "colab_type": "text", 329 | "id": "hrWIEDeAAkQ_" 330 | }, 331 | "source": [ 332 | "в колабе есть смециальный модуль ```google.colab```, который позволяет загрузить файлы с компьютера. Вызовем его:" 333 | ] 334 | }, 335 | { 336 | "cell_type": "code", 337 | "execution_count": null, 338 | "metadata": { 339 | "colab": { 340 | "base_uri": "https://localhost:8080/", 341 | "height": 344 342 | }, 343 | "colab_type": "code", 344 | "id": "vpNBfG9oEo9c", 345 | "outputId": "72f37d0a-6ca7-41a0-9c02-8332fa36087c", 346 | "tags": [] 347 | }, 348 | "outputs": [], 349 | "source": [ 350 | "from google.colab import files #строка импорта\n", 351 | "files.upload() # откроется окно загрузки" 352 | ] 353 | }, 354 | { 355 | "cell_type": "code", 356 | "execution_count": null, 357 | "metadata": { 358 | "colab": { 359 | "base_uri": "https://localhost:8080/", 360 | "height": 34 361 | }, 362 | "colab_type": "code", 363 | "id": "Nzc6W_CkFBSC", 364 | "outputId": "8b1843b2-8c29-4451-a324-88e5eee14efa" 365 | }, 366 | "outputs": [], 367 | "source": [ 368 | "os.listdir() #проверяем, что файл действительно на месте" 369 | ] 370 | }, 371 | { 372 | "cell_type": "markdown", 373 | "metadata": { 374 | "colab_type": "text", 375 | "id": "B1WOL-zjAFKU" 376 | }, 377 | "source": [ 378 | "## работа с файлами\n", 379 | "\n", 380 | "Мы оказались в нужной директории, нашли нужный файл. Давайте его прочитаем" 381 | ] 382 | }, 383 | { 384 | "cell_type": "code", 385 | "execution_count": null, 386 | "metadata": { 387 | "colab": {}, 388 | "colab_type": "code", 389 | "id": "_f5fP_CX91RK", 390 | "tags": [] 391 | }, 392 | "outputs": [], 393 | "source": [ 394 | "with open(\"city_smells.txt\", \"r\") as file: # воспользуемся встроенной функцией open()\n", 395 | " pass" 396 | ] 397 | }, 398 | { 399 | "cell_type": "markdown", 400 | "metadata": { 401 | "colab_type": "text", 402 | "id": "AM7jQ6BKGtNQ" 403 | }, 404 | "source": [ 405 | "давайте посмотрим на аргументы функции: \n", 406 | "* первый = путь к файлу, который хотим открыть.\n", 407 | "\n", 408 | "* второй аргумент - это режим открытия файла: для чтения, записи, дозаписи, все вместе и тд. \n", 409 | "\n", 410 | "\n", 411 | "
РежимОбозначение
'r'открытие на чтение (является значением по умолчанию).
'w'открытие на запись, содержимое файла удаляется, если файла не существует, создается новый.
'x'открытие на запись, если файла не существует, иначе исключение.
'a'открытие на дозапись, информация добавляется в конец файла.
'b'открытие в двоичном режиме.
't'открытие в текстовом режиме (является значением по умолчанию).
'+'открытие на чтение и запись
\n", 412 | "\n", 413 | "\n", 414 | "\n", 415 | "Режимы могут быть объединять: например,'ra' - открытие для чтения и дозаписи.\n", 416 | "\n", 417 | "По умолчанию режим равен 'rt'\n", 418 | "\n", 419 | "Последний аргумент (опциональный, его можно не указывать), encoding, нужен только в текстовом режиме чтения файла. Этот аргумент задает кодировку. Чтобы стандантные .txt-файлы читались без проблем, ставим ```encoding = utf-8```\n", 420 | "\n", 421 | "\n", 422 | "Мы открыли файл с режимом для чтения (пока еще не читали его), сохранили в переменную значение. Давайте прочтем содержимое. Читать тоже можно несколькими методами: \n", 423 | "* .read()\n", 424 | "* .readline()\n", 425 | "* .readlines()\n", 426 | "\n", 427 | "\n" 428 | ] 429 | }, 430 | { 431 | "cell_type": "code", 432 | "execution_count": null, 433 | "metadata": { 434 | "tags": [] 435 | }, 436 | "outputs": [], 437 | "source": [ 438 | "with open(\"city_smells.txt\", \"r\") as file:\n", 439 | " file.read()\n", 440 | " # file.readline()\n", 441 | " # file.readlines()" 442 | ] 443 | }, 444 | { 445 | "cell_type": "markdown", 446 | "metadata": { 447 | "colab_type": "text", 448 | "id": "rgJ-oIYzUGLX" 449 | }, 450 | "source": [ 451 | "С прочитанным текстом, который мы сохранили в переменную, теперь можем делать любые операции: измерять длину слов, заменять слова, убирать пунктуацию, проводить подсчеты элементов и тд (это попробуем позже)\n", 452 | "\n", 453 | "### Часть2\n", 454 | "Теперь попробуем создать файл и записать в него что-то:" 455 | ] 456 | }, 457 | { 458 | "cell_type": "code", 459 | "execution_count": 19, 460 | "metadata": { 461 | "colab": {}, 462 | "colab_type": "code", 463 | "id": "7xkPeSW1TPL4" 464 | }, 465 | "outputs": [], 466 | "source": [ 467 | "with open('new_text.txt', 'w') as file: \n", 468 | " file.write(\"hi this is a test\\n\")\n", 469 | " \n", 470 | "# если такого файла не существовало, но создастся автоматически" 471 | ] 472 | }, 473 | { 474 | "cell_type": "code", 475 | "execution_count": 20, 476 | "metadata": { 477 | "colab": { 478 | "base_uri": "https://localhost:8080/", 479 | "height": 34 480 | }, 481 | "colab_type": "code", 482 | "id": "b_UFW6kdVr6C", 483 | "outputId": "baec79bc-913e-46fc-fe43-c2d2ea3ecf34" 484 | }, 485 | "outputs": [ 486 | { 487 | "name": "stdout", 488 | "output_type": "stream", 489 | "text": [ 490 | "hi this is a test\n", 491 | "\n" 492 | ] 493 | } 494 | ], 495 | "source": [ 496 | "# откроем и проверим, что в нем дейсвительно записан текст:\n", 497 | "with open(\"new_text.txt\",'r') as file:\n", 498 | " print(file.read())\n", 499 | " " 500 | ] 501 | }, 502 | { 503 | "cell_type": "markdown", 504 | "metadata": {}, 505 | "source": [ 506 | "Чтобы предыдущая информация не стиралась из файла при записи, откроем с режимом \"а\" " 507 | ] 508 | }, 509 | { 510 | "cell_type": "code", 511 | "execution_count": 22, 512 | "metadata": {}, 513 | "outputs": [ 514 | { 515 | "name": "stdout", 516 | "output_type": "stream", 517 | "text": [ 518 | "hi this is a test\n", 519 | "new line\n", 520 | "\n", 521 | "\n" 522 | ] 523 | } 524 | ], 525 | "source": [ 526 | "with open(\"new_text.txt\",'r+') as file:\n", 527 | " print(file.read())\n", 528 | " file.write(\"new line\\n\")\n", 529 | " res = file.read()\n", 530 | "print(res)" 531 | ] 532 | }, 533 | { 534 | "cell_type": "code", 535 | "execution_count": null, 536 | "metadata": {}, 537 | "outputs": [], 538 | "source": [] 539 | }, 540 | { 541 | "cell_type": "code", 542 | "execution_count": null, 543 | "metadata": {}, 544 | "outputs": [], 545 | "source": [] 546 | }, 547 | { 548 | "cell_type": "code", 549 | "execution_count": null, 550 | "metadata": {}, 551 | "outputs": [], 552 | "source": [] 553 | }, 554 | { 555 | "cell_type": "code", 556 | "execution_count": null, 557 | "metadata": {}, 558 | "outputs": [], 559 | "source": [] 560 | }, 561 | { 562 | "cell_type": "code", 563 | "execution_count": null, 564 | "metadata": {}, 565 | "outputs": [], 566 | "source": [] 567 | }, 568 | { 569 | "cell_type": "code", 570 | "execution_count": null, 571 | "metadata": {}, 572 | "outputs": [], 573 | "source": [] 574 | } 575 | ], 576 | "metadata": { 577 | "colab": { 578 | "collapsed_sections": [ 579 | "pilnXnWUAgaI" 580 | ], 581 | "include_colab_link": true, 582 | "name": "09Nov_19.ipynb", 583 | "provenance": [] 584 | }, 585 | "kernelspec": { 586 | "display_name": "Python 3", 587 | "language": "python", 588 | "name": "python3" 589 | }, 590 | "language_info": { 591 | "codemirror_mode": { 592 | "name": "ipython", 593 | "version": 3 594 | }, 595 | "file_extension": ".py", 596 | "mimetype": "text/x-python", 597 | "name": "python", 598 | "nbconvert_exporter": "python", 599 | "pygments_lexer": "ipython3", 600 | "version": "3.8.2" 601 | } 602 | }, 603 | "nbformat": 4, 604 | "nbformat_minor": 4 605 | } 606 | -------------------------------------------------------------------------------- /notebooks/generators.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "colab_type": "text", 7 | "id": "Yhw8-87X8s-J", 8 | "tags": [] 9 | }, 10 | "source": [ 11 | "## генераторы" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": { 17 | "colab_type": "text", 18 | "id": "LOYUfNvgLoWa" 19 | }, 20 | "source": [ 21 | "**вспомним из предыдущих занятий:** когда мы создаём список, мы можем брать его элементы один за другим — это называется *итерацией*:" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": null, 27 | "metadata": { 28 | "colab": { 29 | "base_uri": "https://localhost:8080/", 30 | "height": 68 31 | }, 32 | "colab_type": "code", 33 | "id": "W2vnkjMhMAXy", 34 | "outputId": "d37031b0-0c17-4139-997c-29bacb8859bc" 35 | }, 36 | "outputs": [], 37 | "source": [ 38 | "test1 = [1, 2, 3]\n", 39 | "for i in test1 :\n", 40 | " print(i)\n" 41 | ] 42 | }, 43 | { 44 | "cell_type": "markdown", 45 | "metadata": { 46 | "colab_type": "text", 47 | "id": "DULLPnQsOdzE" 48 | }, 49 | "source": [ 50 | "это же можно сделать, создав генератор функцией ```range()```: \n", 51 | "\n", 52 | " у функции три аргумента: (начало,конец,шаг), конечный элемент не включается. \n", 53 | " \n", 54 | " Сейчас мы записали без шага, поэтому он по дефолту =1. " 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": null, 60 | "metadata": { 61 | "colab": { 62 | "base_uri": "https://localhost:8080/", 63 | "height": 85 64 | }, 65 | "colab_type": "code", 66 | "id": "rZSDKVCcOiua", 67 | "outputId": "0a44a4fe-2cd4-4484-c02c-b94bb8cf04ee" 68 | }, 69 | "outputs": [], 70 | "source": [ 71 | "test2 = range(1,4) \n", 72 | "for i in test2 :\n", 73 | " print(i)\n", 74 | "type(test2)\n" 75 | ] 76 | }, 77 | { 78 | "cell_type": "code", 79 | "execution_count": null, 80 | "metadata": { 81 | "colab": { 82 | "base_uri": "https://localhost:8080/", 83 | "height": 119 84 | }, 85 | "colab_type": "code", 86 | "id": "5cDhW-64PyGw", 87 | "outputId": "b797b124-222c-4e76-8640-eaa14b363750" 88 | }, 89 | "outputs": [], 90 | "source": [ 91 | "# давайте зададим шаг\n", 92 | "\n", 93 | "test3 = range (1,10,2) # от 1 до 10 с шагом в 2\n", 94 | "for i in test3 :\n", 95 | " print(i)\n", 96 | "type(test3)" 97 | ] 98 | }, 99 | { 100 | "cell_type": "markdown", 101 | "metadata": { 102 | "colab_type": "text", 103 | "id": "g5WIfV1babNL" 104 | }, 105 | "source": [ 106 | "Заметим, что в предыдущих ячейках переменные test2 и test3 не были листами, в отличие от test1\n", 107 | "\n", 108 | "тип объектов test2 и test3 - это генератор.\n", 109 | "\n", 110 | "Но мы можем превратить генератор в нужный тип: лист, множество или (даже!) строку" 111 | ] 112 | }, 113 | { 114 | "cell_type": "code", 115 | "execution_count": null, 116 | "metadata": { 117 | "colab": { 118 | "base_uri": "https://localhost:8080/", 119 | "height": 153 120 | }, 121 | "colab_type": "code", 122 | "id": "el_UbysU8vCb", 123 | "outputId": "69a33e80-fb16-4706-8cd4-0c379cde6fbb" 124 | }, 125 | "outputs": [], 126 | "source": [ 127 | "new1 = range(0,20,5) # генератор, от нуля до 20 с шагом 5\n", 128 | "for i in new1:\n", 129 | " print(i)\n", 130 | "\n", 131 | "print(\"сначала new1 - это\",type(new1)) # проверяем тип\n", 132 | "\n", 133 | "new1 = list(new1) # превращаем в лист\n", 134 | "print(\"теперь new1 - это\",type(new1), new1) # проверяем тип" 135 | ] 136 | }, 137 | { 138 | "cell_type": "code", 139 | "execution_count": null, 140 | "metadata": {}, 141 | "outputs": [], 142 | "source": [ 143 | "# превратим во множество\n", 144 | "new1 = range(0,20,5)\n", 145 | "new1 = set(new1)\n", 146 | "print(\"затем new1 - это\",type(new1), new1) # проверяем тип" 147 | ] 148 | }, 149 | { 150 | "cell_type": "code", 151 | "execution_count": null, 152 | "metadata": { 153 | "colab": { 154 | "base_uri": "https://localhost:8080/", 155 | "height": 85 156 | }, 157 | "colab_type": "code", 158 | "id": "sC20y9iaB11n", 159 | "outputId": "fa8f110a-28fe-4991-c8a4-569e2710ed5f" 160 | }, 161 | "outputs": [], 162 | "source": [ 163 | "# классический способ использовать генератор\n", 164 | "for i in range(100): #чтобы не писать 100 значений вручную\n", 165 | " if i%30 == 0:\n", 166 | " print (i, \"делится на 30 без остатка\")" 167 | ] 168 | }, 169 | { 170 | "cell_type": "code", 171 | "execution_count": null, 172 | "metadata": { 173 | "colab": { 174 | "base_uri": "https://localhost:8080/", 175 | "height": 34 176 | }, 177 | "colab_type": "code", 178 | "id": "NgBAUfDRjlh8", 179 | "outputId": "ee80ad4b-394a-4155-b5bf-03fe091cf3f8" 180 | }, 181 | "outputs": [], 182 | "source": [ 183 | "# генератор паролей\n", 184 | "\n", 185 | "import random\n", 186 | "passw = '' # предварительно создаем переменную для пароля, с типом \"строка\"\n", 187 | "\n", 188 | "#пусть в ней будет 12 символов: цифры и латинские буквы двух регистров\n", 189 | "\n", 190 | "for x in range(12): \n", 191 | " passw = passw + random.choice('123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM')\n", 192 | " # на каждом из 12 шагов выбираем рандомный символ из списка с букво-цифрами и добавляем в строку\n", 193 | "print(passw)\n", 194 | "\n", 195 | "# запустите ячейку несклько раз: пароли меняются" 196 | ] 197 | }, 198 | { 199 | "cell_type": "markdown", 200 | "metadata": { 201 | "colab_type": "text", 202 | "id": "5C1viYNBKBxc" 203 | }, 204 | "source": [ 205 | "**подводя итог:**\n", 206 | "\n", 207 | "генераторы обычно используются, когда:\n", 208 | "* нужно создать объект из большого количества элементов (чтобы не задавать их вручную)\n", 209 | "* надо единожды пройтись по итерируемому объекту\n", 210 | "* есть потребность использовать \"шаги\" для повторения операции с элементами некоторого контецнера (списка, множества и тд)\n", 211 | "\n", 212 | "их особое свойство:\n", 213 | "- они сохраняют свое состояние между итерациями, но по ним можно итерироваться всего один раз\n", 214 | "\n", 215 | "- хранят только предыдущий элемент, предел и формулу, по которой вычисляется следующий элемент\n", 216 | "\n", 217 | "(подробнее о генераторах можно почитать [здесь](https://realpython.com/introduction-to-python-generators/). [И здесь](https://www.geeksforgeeks.org/use-yield-keyword-instead-return-keyword-python/))\n" 218 | ] 219 | }, 220 | { 221 | "cell_type": "code", 222 | "execution_count": null, 223 | "metadata": { 224 | "colab": {}, 225 | "colab_type": "code", 226 | "id": "Mm3FYaIJ99GJ" 227 | }, 228 | "outputs": [], 229 | "source": [] 230 | } 231 | ], 232 | "metadata": { 233 | "kernelspec": { 234 | "display_name": "Python 3", 235 | "language": "python", 236 | "name": "python3" 237 | }, 238 | "language_info": { 239 | "codemirror_mode": { 240 | "name": "ipython", 241 | "version": 3 242 | }, 243 | "file_extension": ".py", 244 | "mimetype": "text/x-python", 245 | "name": "python", 246 | "nbconvert_exporter": "python", 247 | "pygments_lexer": "ipython3", 248 | "version": "3.8.2" 249 | } 250 | }, 251 | "nbformat": 4, 252 | "nbformat_minor": 4 253 | } 254 | -------------------------------------------------------------------------------- /notebooks/get_your_dataset.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "colab_type": "text", 7 | "id": "W2LDC-PbXhtR" 8 | }, 9 | "source": [ 10 | "В этой тетрадке мы поговорим о способах собрать свой датасет для исследований: откуда брать данные, как их собирать и как хранить." 11 | ] 12 | }, 13 | { 14 | "cell_type": "markdown", 15 | "metadata": {}, 16 | "source": [ 17 | "Существует несколько библиотек(модулей) для работы с веб-страничками, сегодня мы будем использовать requests для доступа к веб-страничкам и Beautiful Soup для работы с содержимым html-документов" 18 | ] 19 | }, 20 | { 21 | "cell_type": "code", 22 | "execution_count": null, 23 | "metadata": { 24 | "ExecuteTime": { 25 | "end_time": "2020-12-19T07:43:42.215240Z", 26 | "start_time": "2020-12-19T07:43:42.162193Z" 27 | }, 28 | "colab": { 29 | "base_uri": "https://localhost:8080/", 30 | "height": 122 31 | }, 32 | "colab_type": "code", 33 | "id": "ncJ-uAqjDNkC", 34 | "outputId": "b58e536a-5828-42b5-8cbd-ba766ee76384", 35 | "scrolled": true, 36 | "tags": [] 37 | }, 38 | "outputs": [], 39 | "source": [ 40 | "! pip3 install requests #ставим модуль requests" 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "execution_count": null, 46 | "metadata": { 47 | "ExecuteTime": { 48 | "end_time": "2020-12-19T07:11:35.137512Z", 49 | "start_time": "2020-12-19T07:11:33.589516Z" 50 | }, 51 | "colab": { 52 | "base_uri": "https://localhost:8080/", 53 | "height": 34 54 | }, 55 | "colab_type": "code", 56 | "id": "fFcBQ25GZBCO", 57 | "outputId": "4d52810c-2a47-486a-f79b-1ed4621c8793", 58 | "tags": [] 59 | }, 60 | "outputs": [], 61 | "source": [ 62 | "# ставим модуль beautifulsoup, самая последняя версия - четвертая\n", 63 | "! pip3 install beautifulsoup4 " 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": 1, 69 | "metadata": { 70 | "ExecuteTime": { 71 | "end_time": "2020-12-19T08:18:38.198003Z", 72 | "start_time": "2020-12-19T08:18:38.186002Z" 73 | }, 74 | "colab": {}, 75 | "colab_type": "code", 76 | "id": "XT5G41FYnr7a" 77 | }, 78 | "outputs": [], 79 | "source": [ 80 | "# импортируем модули в тетрадку\n", 81 | "\n", 82 | "import requests as rq\n", 83 | "\n", 84 | "from bs4 import BeautifulSoup" 85 | ] 86 | }, 87 | { 88 | "cell_type": "markdown", 89 | "metadata": { 90 | "colab_type": "text", 91 | "id": "cIvQNBqUYwE8" 92 | }, 93 | "source": [ 94 | "# Как работать с веб-страничками" 95 | ] 96 | }, 97 | { 98 | "cell_type": "markdown", 99 | "metadata": { 100 | "colab_type": "text", 101 | "id": "28Oy0NnLnk0L" 102 | }, 103 | "source": [ 104 | "### Шаг 1. \n", 105 | "\n", 106 | "Создадим переменную ```url``` и сохраним в нее адрес какой-нибудь html-страницы\n", 107 | "\n", 108 | "например, [сайта CNN](http://lite.cnn.io/en)\n", 109 | "\n", 110 | "обратите внимание, что адрес прописываем в кавычках, как строку" 111 | ] 112 | }, 113 | { 114 | "cell_type": "code", 115 | "execution_count": 2, 116 | "metadata": { 117 | "ExecuteTime": { 118 | "end_time": "2020-12-19T08:22:23.420826Z", 119 | "start_time": "2020-12-19T08:22:23.416822Z" 120 | }, 121 | "colab": {}, 122 | "colab_type": "code", 123 | "id": "WzqN6Ss_aujY" 124 | }, 125 | "outputs": [], 126 | "source": [ 127 | "url = 'https://edition.cnn.com/'" 128 | ] 129 | }, 130 | { 131 | "cell_type": "markdown", 132 | "metadata": { 133 | "colab_type": "text", 134 | "id": "Ysgl6VmpKjxu" 135 | }, 136 | "source": [ 137 | "В модуле requests есть метод request.get(), который сохраняет ответ сервера на наш реквест. Мы применим его к переменной url, куда сохранен путь к странице. \n", 138 | "Сохраним результат в переменную page" 139 | ] 140 | }, 141 | { 142 | "cell_type": "code", 143 | "execution_count": 3, 144 | "metadata": { 145 | "ExecuteTime": { 146 | "end_time": "2020-12-19T08:46:54.806718Z", 147 | "start_time": "2020-12-19T08:46:54.506720Z" 148 | }, 149 | "colab": {}, 150 | "colab_type": "code", 151 | "id": "O8AH4kDxqKvF" 152 | }, 153 | "outputs": [ 154 | { 155 | "data": { 156 | "text/plain": [ 157 | "" 158 | ] 159 | }, 160 | "execution_count": 3, 161 | "metadata": {}, 162 | "output_type": "execute_result" 163 | } 164 | ], 165 | "source": [ 166 | "page = rq.get(url) \n", 167 | "\n", 168 | "page # посмотрим на код ответа, если 200, все хорошо" 169 | ] 170 | }, 171 | { 172 | "cell_type": "markdown", 173 | "metadata": { 174 | "colab_type": "text", 175 | "id": "J5Y2C39Gp0yK" 176 | }, 177 | "source": [ 178 | "код 200 сообщает, что страница загружена успешно \n", 179 | "*(коды, начинающиеся с 2, обычно указывают на успешное выполнение операции, а коды, начинающиеся с 4 или 5, сообщают об ошибке)*\n", 180 | "\n", 181 | "Узнать больше о кодах состояния HTTP можно [по этой ссылке.](https://www.w3.org/Protocols/HTTP/1.1/draft-ietf-http-v11-spec-01#Status-Codes)" 182 | ] 183 | }, 184 | { 185 | "cell_type": "markdown", 186 | "metadata": { 187 | "colab_type": "text", 188 | "id": "9Gg53fJKNObR" 189 | }, 190 | "source": [ 191 | "Следующим шагом нужно получить доступ к текстовому содержимому веб-файлов.\n", 192 | "\n", 193 | "Здесь нам поможет page.text *(или page.content, чтобы получить значение в байтах)*" 194 | ] 195 | }, 196 | { 197 | "cell_type": "code", 198 | "execution_count": null, 199 | "metadata": { 200 | "ExecuteTime": { 201 | "end_time": "2020-12-19T08:47:01.231718Z", 202 | "start_time": "2020-12-19T08:47:01.108719Z" 203 | }, 204 | "colab": {}, 205 | "colab_type": "code", 206 | "id": "md61SNPYu_jL", 207 | "tags": [] 208 | }, 209 | "outputs": [], 210 | "source": [ 211 | "page.text" 212 | ] 213 | }, 214 | { 215 | "cell_type": "markdown", 216 | "metadata": { 217 | "colab_type": "text", 218 | "id": "X5cEfTSEYhcY" 219 | }, 220 | "source": [ 221 | "### Шаг2\n", 222 | "\n", 223 | "Поработаем с текстом на страничке" 224 | ] 225 | }, 226 | { 227 | "cell_type": "markdown", 228 | "metadata": { 229 | "colab_type": "text", 230 | "id": "vcVMhwpHNxE5" 231 | }, 232 | "source": [ 233 | "Мы получили текст страницы (со всеми html-тегами), однако его неудобно прочитать в таком виде. \n", 234 | "\n", 235 | "Здесь нам понадобится Beautiful Soup, модуль для html-парсинга: он сделает текст веб-страницы, извлеченный с помощью Requests, более читаемым, потому что создает дерево синтаксического разбора из проанализированных HTML (или XML) документов." 236 | ] 237 | }, 238 | { 239 | "cell_type": "code", 240 | "execution_count": 4, 241 | "metadata": { 242 | "ExecuteTime": { 243 | "end_time": "2020-12-19T09:20:00.809844Z", 244 | "start_time": "2020-12-19T09:20:00.351849Z" 245 | }, 246 | "colab": {}, 247 | "colab_type": "code", 248 | "id": "GOBPlBro3AQR" 249 | }, 250 | "outputs": [], 251 | "source": [ 252 | "soup = BeautifulSoup(page.text, 'html.parser') #сохраним результат в переменную soup" 253 | ] 254 | }, 255 | { 256 | "cell_type": "code", 257 | "execution_count": null, 258 | "metadata": { 259 | "ExecuteTime": { 260 | "end_time": "2020-12-19T08:47:09.815788Z", 261 | "start_time": "2020-12-19T08:47:09.553787Z" 262 | }, 263 | "colab": {}, 264 | "colab_type": "code", 265 | "id": "HigX0lNr3P1Z", 266 | "tags": [] 267 | }, 268 | "outputs": [], 269 | "source": [ 270 | "print(soup.prettify()) # показывает нашу страницу в красивом виде" 271 | ] 272 | }, 273 | { 274 | "cell_type": "markdown", 275 | "metadata": {}, 276 | "source": [ 277 | "### Шаг3 \n", 278 | "время доставать всякие тэги " 279 | ] 280 | }, 281 | { 282 | "cell_type": "markdown", 283 | "metadata": { 284 | "colab_type": "text", 285 | "id": "bVR8OVuRUaO1" 286 | }, 287 | "source": [ 288 | "предыдущие шаги позволили привести веб-страничку к виду, где содержание каждого тега написано с новой строки. \n", 289 | "\n", 290 | "Некоторые теги полезны для конкретной задачи (там текст), некоторые - не очень (например, мета-данные,картинки и тд)\n", 291 | "\n", 292 | "Извлечь один тег со страницы можно с помощью метода find_all(). Он похож на метод регулярок, с которым мы работали: он вернет все экземпляры данного тега в документе. Нужно прописать в скобках метода нужный тег. \n", 293 | "\n", 294 | "### Самые популярные теги:\n", 295 | " - заголовки\n", 296 | "
для целых \"блоков\" странички\n", 297 | "
  • список с перечислением\n", 298 | "

    для текста\n", 299 | " для гиперссылок\n", 300 | " для изображений" 301 | ] 302 | }, 303 | { 304 | "cell_type": "code", 305 | "execution_count": 5, 306 | "metadata": { 307 | "tags": [] 308 | }, 309 | "outputs": [ 310 | { 311 | "data": { 312 | "text/plain": [ 313 | "[CNN International - Breaking News, US News, World News and Video,\n", 314 | " Search CNN,\n", 315 | " Open Menu]" 316 | ] 317 | }, 318 | "execution_count": 5, 319 | "metadata": {}, 320 | "output_type": "execute_result" 321 | } 322 | ], 323 | "source": [ 324 | "soup.find_all(\"title\") # тег нужно записать без треугольных скобочек\n", 325 | "\n", 326 | "# попробуйте теги head, body, title, div и др" 327 | ] 328 | }, 329 | { 330 | "cell_type": "markdown", 331 | "metadata": {}, 332 | "source": [ 333 | "А так можно достать нужные части тега (напимер, текст)" 334 | ] 335 | }, 336 | { 337 | "cell_type": "code", 338 | "execution_count": 6, 339 | "metadata": { 340 | "ExecuteTime": { 341 | "end_time": "2020-12-19T08:50:08.027471Z", 342 | "start_time": "2020-12-19T08:50:08.007477Z" 343 | }, 344 | "colab": { 345 | "base_uri": "https://localhost:8080/", 346 | "height": 71 347 | }, 348 | "colab_type": "code", 349 | "id": "N0RXeVL33W7I", 350 | "outputId": "03346e7c-dc54-4183-a943-35c61ba969a6", 351 | "tags": [] 352 | }, 353 | "outputs": [ 354 | { 355 | "name": "stdout", 356 | "output_type": "stream", 357 | "text": [ 358 | "CNN International - Breaking News, US News, World News and Video\n", 359 | "Search CNN\n", 360 | "Open Menu\n" 361 | ] 362 | } 363 | ], 364 | "source": [ 365 | "for x in soup.find_all('title'):\n", 366 | " print(x.text)" 367 | ] 368 | }, 369 | { 370 | "cell_type": "code", 371 | "execution_count": null, 372 | "metadata": {}, 373 | "outputs": [], 374 | "source": [ 375 | "# Весь текст на страничке за раз можно достать еще и так\n", 376 | "soup.text" 377 | ] 378 | }, 379 | { 380 | "cell_type": "markdown", 381 | "metadata": {}, 382 | "source": [ 383 | "## Как создать корпус" 384 | ] 385 | }, 386 | { 387 | "cell_type": "markdown", 388 | "metadata": {}, 389 | "source": [ 390 | "Итак, мы определили нужные теги и напарсили необходимые данные. Пора сохранить их в файл. " 391 | ] 392 | }, 393 | { 394 | "cell_type": "code", 395 | "execution_count": null, 396 | "metadata": {}, 397 | "outputs": [], 398 | "source": [ 399 | "# в .txt\n", 400 | "\n", 401 | "with open(\"../data/CNN.txt\", \"a\") as file:\n", 402 | " for x in soup.find_all(\"title\"):\n", 403 | " file.write(x.text)" 404 | ] 405 | }, 406 | { 407 | "cell_type": "code", 408 | "execution_count": null, 409 | "metadata": {}, 410 | "outputs": [], 411 | "source": [ 412 | "# или в .csv\n", 413 | "\n", 414 | "import pandas as pd\n", 415 | "\n", 416 | "data = {} # создадим словарь, а из него датафрейм\n", 417 | "\n", 418 | "for idx, x in enumerate(soup.find_all(\"title\")):\n", 419 | " data.update({idx:[x.text,url]})\n", 420 | "\n", 421 | " \n", 422 | "df = pd.DataFrame.from_dict(data,columns=[\"content\",\"source\"], orient=\"index\")\n", 423 | "\n", 424 | "\n", 425 | "df" 426 | ] 427 | }, 428 | { 429 | "cell_type": "code", 430 | "execution_count": null, 431 | "metadata": {}, 432 | "outputs": [], 433 | "source": [ 434 | "# сохраняем\n", 435 | "df.to_csv(\"../data/CNN.csv\")" 436 | ] 437 | }, 438 | { 439 | "cell_type": "markdown", 440 | "metadata": { 441 | "colab_type": "text", 442 | "id": "tF72_zk5ak4g" 443 | }, 444 | "source": [ 445 | "# полезные ссылки" 446 | ] 447 | }, 448 | { 449 | "cell_type": "markdown", 450 | "metadata": {}, 451 | "source": [ 452 | "Что почитать об использовании данных\n", 453 | "- [как устроен сбор данных](https://en.wikipedia.org/wiki/Web_scraping)\n", 454 | "\n", 455 | "\n", 456 | "- закон об авторском праве ([в деталях](http://www.consultant.ru/document/cons_doc_LAW_64629/0b318126c43879a845405f1fb1f4342f473a1eda/), [вкратце](https://ru.wikipedia.org/wiki/%D0%90%D0%B2%D1%82%D0%BE%D1%80%D1%81%D0%BA%D0%BE%D0%B5_%D0%BF%D1%80%D0%B0%D0%B2%D0%BE_%D0%B2_%D0%A0%D0%BE%D1%81%D1%81%D0%B8%D0%B8))\n", 457 | "- [закон о персональных данных](http://www.consultant.ru/document/cons_doc_LAW_61801/)\n", 458 | "\n", 459 | "\n", 460 | "- [типы лицензирования данных](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/licensing-a-repository)\n", 461 | "- [FAIR data](https://en.wikipedia.org/wiki/FAIR_data)\n", 462 | "- [OpenData](https://en.wikipedia.org/wiki/Open_data)\n", 463 | "\n" 464 | ] 465 | }, 466 | { 467 | "cell_type": "markdown", 468 | "metadata": {}, 469 | "source": [ 470 | "Гайды и туториалы\n", 471 | "\n", 472 | "- [документация requests и быстрый гайд](https://requests.readthedocs.io/en/master/user/quickstart/)\n", 473 | "\n", 474 | "\n", 475 | "- [документация Beautiful Soup](https://www.crummy.com/software/BeautifulSoup/bs4/doc/)\n", 476 | "\n", 477 | "- [text-only](https://sjmulder.nl/en/textonly.html) веб-сайты, чтобы легко начать парсить\n", 478 | "\n", 479 | "\n", 480 | "\n", 481 | "- [здесь](https://www.york.ac.uk/teaching/cws/wws/webpage1.html) можно почитать про структуру html подробнее\n", 482 | "\n", 483 | "\n", 484 | "- [здесь](https://www.w3schools.com/html/html_examples.asp) еще и потренироваться в режиме онлайн" 485 | ] 486 | }, 487 | { 488 | "cell_type": "markdown", 489 | "metadata": { 490 | "colab_type": "text", 491 | "id": "ILp0Ke2daokq" 492 | }, 493 | "source": [ 494 | "Чем парсить соцсети (не исчерпывающий список)\n", 495 | "\n", 496 | "- [Twitter](https://developer.twitter.com/en/docs/twitter-api/tools-and-libraries/v2)\n", 497 | "- [Meta](https://developers.facebook.com/docs/graph-api/)\n", 498 | "- [VK](https://vk-api.readthedocs.io/en/latest/), [положения о прайваси](https://vk.com/dev/uprivacy)" 499 | ] 500 | }, 501 | { 502 | "cell_type": "markdown", 503 | "metadata": {}, 504 | "source": [ 505 | "## Практика\n", 506 | "\n", 507 | "давайте попарсим другой адрес и вытащим оттуда весь текст" 508 | ] 509 | }, 510 | { 511 | "cell_type": "code", 512 | "execution_count": 8, 513 | "metadata": {}, 514 | "outputs": [], 515 | "source": [ 516 | "url = \"https://en.wikipedia.org/wiki/Welsh_Corgi\"" 517 | ] 518 | }, 519 | { 520 | "cell_type": "code", 521 | "execution_count": null, 522 | "metadata": {}, 523 | "outputs": [], 524 | "source": [] 525 | } 526 | ], 527 | "metadata": { 528 | "colab": { 529 | "collapsed_sections": [], 530 | "include_colab_link": true, 531 | "name": "get_your_dataset.ipynb", 532 | "provenance": [] 533 | }, 534 | "kernelspec": { 535 | "display_name": "Python 3 (ipykernel)", 536 | "language": "python", 537 | "name": "python3" 538 | }, 539 | "language_info": { 540 | "codemirror_mode": { 541 | "name": "ipython", 542 | "version": 3 543 | }, 544 | "file_extension": ".py", 545 | "mimetype": "text/x-python", 546 | "name": "python", 547 | "nbconvert_exporter": "python", 548 | "pygments_lexer": "ipython3", 549 | "version": "3.10.0" 550 | } 551 | }, 552 | "nbformat": 4, 553 | "nbformat_minor": 4 554 | } 555 | -------------------------------------------------------------------------------- /notebooks/input,output.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# функции ввода/вывода, списки, условия, циклы" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": { 13 | "colab_type": "text", 14 | "id": "OtLfEjtTf88R" 15 | }, 16 | "source": [ 17 | "## функции ввода и вывода" 18 | ] 19 | }, 20 | { 21 | "cell_type": "markdown", 22 | "metadata": { 23 | "colab_type": "text", 24 | "id": "RVp8eISaqTLp" 25 | }, 26 | "source": [ 27 | "### 1. Вывод на экран нескольких значений\n", 28 | "\n", 29 | " Одним вызовом функции ```print ( ) ```можно печатать на экране несколько значений. Для этого перечислите их через запятую:" 30 | ] 31 | }, 32 | { 33 | "cell_type": "code", 34 | "execution_count": 1, 35 | "metadata": { 36 | "colab": { 37 | "base_uri": "https://localhost:8080/", 38 | "height": 34 39 | }, 40 | "colab_type": "code", 41 | "id": "E5uJKzVzeWxg", 42 | "outputId": "5463e600-6887-458b-c558-eccde193bdd1" 43 | }, 44 | "outputs": [ 45 | { 46 | "name": "stdout", 47 | "output_type": "stream", 48 | "text": [ 49 | "Три аргумента успешно напечатаны\n" 50 | ] 51 | } 52 | ], 53 | "source": [ 54 | "print(\"Три\",\"аргумента\",\"успешно напечатаны\")" 55 | ] 56 | }, 57 | { 58 | "cell_type": "markdown", 59 | "metadata": { 60 | "colab_type": "text", 61 | "id": "ux6R_K_8rR3Y" 62 | }, 63 | "source": [ 64 | " Иногда аргументы функции (любой, и принта тоже) легче разбить на несколько строк кода, это делается для удобства чтения кода:" 65 | ] 66 | }, 67 | { 68 | "cell_type": "code", 69 | "execution_count": 2, 70 | "metadata": { 71 | "colab": { 72 | "base_uri": "https://localhost:8080/", 73 | "height": 34 74 | }, 75 | "colab_type": "code", 76 | "id": "rXTXwIoos4_g", 77 | "outputId": "f5252faa-45ef-492a-9598-1b10f55a72a0" 78 | }, 79 | "outputs": [ 80 | { 81 | "name": "stdout", 82 | "output_type": "stream", 83 | "text": [ 84 | "ddd Три 56 успешно напечатаны\n" 85 | ] 86 | } 87 | ], 88 | "source": [ 89 | "x = \"ddd\"\n", 90 | "print(x,\"Три\", # аргументы могут быть любого типа\n", 91 | " 56,\n", 92 | " \"успешно напечатаны\")" 93 | ] 94 | }, 95 | { 96 | "cell_type": "markdown", 97 | "metadata": { 98 | "colab_type": "text", 99 | "id": "pRHZzBBQthM6" 100 | }, 101 | "source": [ 102 | "### 2. экранирование\n", 103 | "\n", 104 | "esсаре-последователыюсти (экранированные последовательности) позволяют вставлять в строки специальные символы.\n", 105 | "\n", 106 | "Типичную еsсаре-последовательность образуют два символа: обратный слеш (\\\\) и дополнительный символ.\n", 107 | "\n", 108 | " Какими они бывают? \n", 109 | " * \\\\\\ Обратный слеш. Выводит :\\\\\n", 110 | " * \\\\' Апостроф, или одиночная кавычка. Выводит : '\n", 111 | " * \\\\\" Кавычка. Выводит : \"\n", 112 | " * \\n Новая строка . Перемещает курсор в начало следующей строки\n", 113 | " * \\t Горизонтальный отступ - символ табуляции. Перемещает курсор вправо на один отступ\n", 114 | "\n", 115 | "Давайте попробуем напечатать строку с разными режимами экранирования\n", 116 | "\n", 117 | "NB! символы экранирования пишем внутри строки, в её кавычках" 118 | ] 119 | }, 120 | { 121 | "cell_type": "code", 122 | "execution_count": 3, 123 | "metadata": { 124 | "colab": { 125 | "base_uri": "https://localhost:8080/", 126 | "height": 153 127 | }, 128 | "colab_type": "code", 129 | "id": "2EBSJ26ywq3w", 130 | "outputId": "ddf28347-9871-431c-a3ac-526e91620abd" 131 | }, 132 | "outputs": [ 133 | { 134 | "name": "stdout", 135 | "output_type": "stream", 136 | "text": [ 137 | "1: wow i can modify output now\n", 138 | "2: \\wow i can modify output now\n", 139 | "3: he said \"wow i can modify output now\"\n", 140 | "4: wow i can \"modify\" output now\n", 141 | "5: wow i can modify output now\n", 142 | "6: \twow i can \tmodify output \n", 143 | "now\n" 144 | ] 145 | } 146 | ], 147 | "source": [ 148 | "print(\"1:\", \"wow i can modify output now\") # классика\n", 149 | "print(\"2:\",\"\\wow i can modify output now\") # добавили бэкслеш\n", 150 | "print(\"3:\",'he said \"wow i can modify output now\"') # добавили кавычки (кавычки в кавычках, we need to go deeper!)\n", 151 | "print(\"4:\",\"wow i can \\\"modify\\\" output now\") # еще один вариант с кавычками\n", 152 | "print(\"5:\",\"wow i can modify output now\") # перенос строки\n", 153 | "print(\"6:\",\"\\twow i can \\tmodify output \\nnow\") # табуляция\n" 154 | ] 155 | }, 156 | { 157 | "cell_type": "markdown", 158 | "metadata": { 159 | "colab_type": "text", 160 | "id": "JXDTrGHNz8I2" 161 | }, 162 | "source": [ 163 | "3. альтернатива для ```print()```\n", 164 | "\n", 165 | " иногда Вас может ожидать ситуация, когда Вы хотите посмотреть на данные, но печатать их полностью очень долго, а частями - неинформативно. На помощь приходит функция ```display()```. Помогает в случаях работы с большими данными" 166 | ] 167 | }, 168 | { 169 | "cell_type": "code", 170 | "execution_count": 4, 171 | "metadata": { 172 | "cellView": "both", 173 | "colab": { 174 | "base_uri": "https://localhost:8080/", 175 | "height": 34 176 | }, 177 | "colab_type": "code", 178 | "id": "y8QdaNWpz-So", 179 | "outputId": "02839b1e-49b1-4fec-e723-09396bd04bb1" 180 | }, 181 | "outputs": [ 182 | { 183 | "data": { 184 | "text/plain": [ 185 | "'i am text'" 186 | ] 187 | }, 188 | "metadata": {}, 189 | "output_type": "display_data" 190 | } 191 | ], 192 | "source": [ 193 | "text = \"i am text\" #наши данные пока не очень большие, но все впереди\n", 194 | "display(text)" 195 | ] 196 | }, 197 | { 198 | "cell_type": "markdown", 199 | "metadata": { 200 | "colab_type": "text", 201 | "id": "yaUt0Chfzk_Z" 202 | }, 203 | "source": [ 204 | "Хорошо, выводить текст (красиво) мы теперь умеем. А как вводить? Для этого есть функция ```input()```\n", 205 | "\n", 206 | "Функция принимает текст, который пользователь вводит с клавиатуры. После запуска ячейки *(или нажатия Run, если Вы в PyCharm, или нажатия Enter, если вы в интерактивном режиме питона из терминала).* \n", 207 | "\n", 208 | "Результат работы функции ```input()``` -- объект типа ```str```" 209 | ] 210 | }, 211 | { 212 | "cell_type": "code", 213 | "execution_count": 9, 214 | "metadata": { 215 | "colab": { 216 | "base_uri": "https://localhost:8080/", 217 | "height": 34 218 | }, 219 | "colab_type": "code", 220 | "id": "GcM3830AzkF2", 221 | "outputId": "5600e02a-d7eb-4b83-c168-d47ccf12f8bc" 222 | }, 223 | "outputs": [ 224 | { 225 | "name": "stdin", 226 | "output_type": "stream", 227 | "text": [ 228 | " hello\n" 229 | ] 230 | } 231 | ], 232 | "source": [ 233 | "name = input()" 234 | ] 235 | }, 236 | { 237 | "cell_type": "code", 238 | "execution_count": 12, 239 | "metadata": {}, 240 | "outputs": [ 241 | { 242 | "name": "stdin", 243 | "output_type": "stream", 244 | "text": [ 245 | "Здравствуйте! Как Вас зовут? 780\n" 246 | ] 247 | } 248 | ], 249 | "source": [ 250 | "# В инпут можно передавать свои строки, если есть необходимость:\n", 251 | "\n", 252 | "name = input(\"Здравствуйте! Как Вас зовут? \")" 253 | ] 254 | }, 255 | { 256 | "cell_type": "code", 257 | "execution_count": 14, 258 | "metadata": {}, 259 | "outputs": [ 260 | { 261 | "name": "stdout", 262 | "output_type": "stream", 263 | "text": [ 264 | "\n" 265 | ] 266 | } 267 | ], 268 | "source": [ 269 | "print(type(name))" 270 | ] 271 | }, 272 | { 273 | "cell_type": "markdown", 274 | "metadata": { 275 | "colab_type": "text", 276 | "id": "CX-aPirI4IGC" 277 | }, 278 | "source": [ 279 | "Давайте используем это, чтобы сделать персонализированное приветствие" 280 | ] 281 | }, 282 | { 283 | "cell_type": "code", 284 | "execution_count": 23, 285 | "metadata": { 286 | "colab": { 287 | "base_uri": "https://localhost:8080/", 288 | "height": 51 289 | }, 290 | "colab_type": "code", 291 | "id": "rixeKn1o4XSr", 292 | "outputId": "0ac25497-c4cd-47b3-9848-f219b44bc815" 293 | }, 294 | "outputs": [ 295 | { 296 | "name": "stdin", 297 | "output_type": "stream", 298 | "text": [ 299 | "Здравствуйте! Как Вас зовут? N\n" 300 | ] 301 | }, 302 | { 303 | "name": "stdout", 304 | "output_type": "stream", 305 | "text": [ 306 | "Приятно познакомиться, N\n" 307 | ] 308 | } 309 | ], 310 | "source": [ 311 | "name = input(\"Здравствуйте! Как Вас зовут? \")\n", 312 | "\n", 313 | "print(\"Приятно познакомиться, \",name) # передаем в print() два аргумента: строка и переменная" 314 | ] 315 | }, 316 | { 317 | "cell_type": "markdown", 318 | "metadata": { 319 | "colab_type": "text", 320 | "id": "kt2nYlkcgCnu" 321 | }, 322 | "source": [ 323 | "Отлично! Теперь мы умеем печатать и вводить информацию в виде строк, а также работать со строками с помощью стандартных методов.\n", 324 | "\n", 325 | "" 326 | ] 327 | }, 328 | { 329 | "cell_type": "code", 330 | "execution_count": null, 331 | "metadata": {}, 332 | "outputs": [], 333 | "source": [] 334 | } 335 | ], 336 | "metadata": { 337 | "colab": { 338 | "collapsed_sections": [], 339 | "include_colab_link": true, 340 | "name": "26oct_19.ipynb", 341 | "provenance": [] 342 | }, 343 | "kernelspec": { 344 | "display_name": "Python 3", 345 | "language": "python", 346 | "name": "python3" 347 | }, 348 | "language_info": { 349 | "codemirror_mode": { 350 | "name": "ipython", 351 | "version": 3 352 | }, 353 | "file_extension": ".py", 354 | "mimetype": "text/x-python", 355 | "name": "python", 356 | "nbconvert_exporter": "python", 357 | "pygments_lexer": "ipython3", 358 | "version": "3.8.2" 359 | } 360 | }, 361 | "nbformat": 4, 362 | "nbformat_minor": 4 363 | } 364 | -------------------------------------------------------------------------------- /notebooks/intro_to_OOP.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "id": "3PK6XiSZiGEE" 7 | }, 8 | "source": [ 9 | "## Введение в ООП в питоне\n", 10 | "\n", 11 | "ООП (объектно-ориентированное программирование) -- это парадигма, которая фокусируется на создании кода как набора взаимосвязанных \"блоков\" и описании их работы. \n", 12 | "\n", 13 | "Два основных термина в парадигме ООП -- это объекты и классы. Классы -- это такие \"шаблоны\", по которым создаются объекты *(представьте план построения дома и готовый дом)*\n", 14 | "\n", 15 | "Объекты удобны, потому что ими можно управлять, масштабировать и изменять при необходимости \n", 16 | "\n", 17 | "Чтобы создать объект, сначала нужен его \"шаблон\", класс. Класс описывает, что объект умеет делать и какими характеристиками обладает.\n", 18 | "\n", 19 | "Объект -- это некоторая абстракция, объектом может быть что угодно. Например, виртуальный котик.\n", 20 | "\n", 21 | "Давайте создадим класс, который опишет его умения и характеристики:\n", 22 | "\n" 23 | ] 24 | }, 25 | { 26 | "cell_type": "code", 27 | "execution_count": null, 28 | "metadata": { 29 | "id": "93tj76rHiGEV" 30 | }, 31 | "outputs": [], 32 | "source": [ 33 | "# Simple Virtual Cat\n", 34 | "# Demonstrates a basic class and object\n", 35 | "\n", 36 | "#создаем класс:\n", 37 | "class Cat(object): # в скобках указывается класс-родитель, или универсальный встроенный тип object\n", 38 | " \"\"\"A virtual pet\"\"\" # здесь идет документация класса, какого рода объекты можно создавать с помощью класса\n", 39 | " \n", 40 | " # самое время определить методы (= что объекты этого класса смогут делать). Метод = функция, принадлежащая объекту\n", 41 | "\n", 42 | " # первый навык \n", 43 | " def talk(self): # объявляем метод\n", 44 | "\n", 45 | " print(\"\\nHi. I'm an instance of class Cat.\\n\")\n", 46 | "\n", 47 | " # return # методы могут что-то возвращать, при необходимости\n", 48 | "\n", 49 | " # второй навык \n", 50 | " def sleep(self):\n", 51 | " # try:\n", 52 | " # x = float(input('insert a number:')) # условие, напишем через try-except чтобы исключить неверные типы ввода\n", 53 | " # print(\"\\nI'm off to sleep for\", x, \"hours, bye!\\n\") #what to do if no exceptions arise\n", 54 | " # except:\n", 55 | " # print('\\nthis is not a number, I need a number\\n') # ветка для ситуаций, если пользователь ввел не число\n", 56 | " print(\"*sleeping*\") #what to do if no exceptions arise\n", 57 | " \n", 58 | " " 59 | ] 60 | }, 61 | { 62 | "cell_type": "markdown", 63 | "metadata": { 64 | "id": "RZe8SQxy7Akj" 65 | }, 66 | "source": [ 67 | "ссылочка на try-except" 68 | ] 69 | }, 70 | { 71 | "cell_type": "markdown", 72 | "metadata": { 73 | "id": "7GT5nQqmcWbT" 74 | }, 75 | "source": [ 76 | "**про self** \n", 77 | "\n", 78 | "Как первый параметр любого метода, self автоматически\n", 79 | "становится ссылкой на объект, по отношению к которому вызван\n", 80 | "метод. Это значит, что через self метод получает доступ к вызывающему объекту,\n", 81 | "к его атрибутам и методам (он может, в частности, создавать у объекта новые атрибуты).\n", 82 | "\n", 83 | "Мы прописали два начальных метода для класса. Теперь все котики (=объекты), созданные от этого класса, будут уметь говорить (```.talk()```) и спать(```.sleep()```)\n", 84 | "\n", 85 | "Самое время создать первый объект:" 86 | ] 87 | }, 88 | { 89 | "cell_type": "code", 90 | "execution_count": null, 91 | "metadata": { 92 | "colab": { 93 | "base_uri": "https://localhost:8080/" 94 | }, 95 | "id": "DzKmQF-DiGFI", 96 | "outputId": "2d435b45-ff94-43d7-bf61-5b6433f8882a" 97 | }, 98 | "outputs": [ 99 | { 100 | "name": "stdout", 101 | "output_type": "stream", 102 | "text": [ 103 | "\n", 104 | "Hi. I'm an instance of class Cat.\n", 105 | "\n" 106 | ] 107 | } 108 | ], 109 | "source": [ 110 | "# создаем объект класса Cat, сохраняем в какую-нибудь переменную\n", 111 | "gatto = Cat()\n", 112 | "\n", 113 | "# у этого объекта есть все методы родительского класса \n", 114 | "gatto.talk()" 115 | ] 116 | }, 117 | { 118 | "cell_type": "code", 119 | "execution_count": null, 120 | "metadata": { 121 | "colab": { 122 | "base_uri": "https://localhost:8080/" 123 | }, 124 | "id": "0elZeUIydU3I", 125 | "outputId": "45052153-47ca-4846-9762-9263d39e441b" 126 | }, 127 | "outputs": [ 128 | { 129 | "name": "stdout", 130 | "output_type": "stream", 131 | "text": [ 132 | "*sleeping*\n" 133 | ] 134 | } 135 | ], 136 | "source": [ 137 | "gatto.sleep()" 138 | ] 139 | }, 140 | { 141 | "cell_type": "markdown", 142 | "metadata": { 143 | "id": "VnZldnosiGF5" 144 | }, 145 | "source": [ 146 | "### метод-конструктор aka метод ```__init__``` (метод инициализации)\n", 147 | "\n", 148 | "Иногда методы удобно вызывать не вручную, а сразу при создании нового объекта (обычно это нужно, чтобы установить начальные значения атрибутов объекта)
    \n", 149 | "В Python есть специальный синтаксис*, метод-конструктор ```__init__``` . \n", 150 | "\n", 151 | " ```__init__()``` будет автоматически вызываться при возникновении каждого очередного объекта заданного класса. \n", 152 | " \n", 153 | "------------------\n", 154 | "*В Python есть [набор встроенных «специальных методов»](https://www.tutorialsteacher.com/python/magic-methods-in-python), имена которых начинаются и заканчиваются\n", 155 | "двумя знаками подчеркивания. Метод-конструктор __init__ - один из них.*" 156 | ] 157 | }, 158 | { 159 | "cell_type": "code", 160 | "execution_count": null, 161 | "metadata": { 162 | "id": "kSOjBE5diGGJ" 163 | }, 164 | "outputs": [], 165 | "source": [ 166 | "\n", 167 | "# вот так работает метод-конструктор\n", 168 | "\n", 169 | "class Cat(object): # задали класс\n", 170 | " \"\"\"A virtual pet\"\"\"\n", 171 | " \n", 172 | " def __init__ (self): #init-метод, он вызовется автоматом\n", 173 | " print(\"New cat is created!\")\n", 174 | " \n", 175 | " # задаем остальные методы\n", 176 | " def talk(self): # объявляем метод\n", 177 | " print(\"\\nHi. I'm an instance of class Cat.\\n\")\n", 178 | " \n", 179 | " def sleep(self):\n", 180 | " try:\n", 181 | " x = float(input('insert a number:')) #a piece of code where eceptions may appear\n", 182 | " except:\n", 183 | " print('\\nthis is not a number, I need a number\\n') #what to do in cade of exception\n", 184 | " else:\n", 185 | " print(\"\\nI'm off to sleep for\", x, \"hours, bye!\\n\") #what to do if no exceptions arise" 186 | ] 187 | }, 188 | { 189 | "cell_type": "code", 190 | "execution_count": null, 191 | "metadata": { 192 | "colab": { 193 | "base_uri": "https://localhost:8080/" 194 | }, 195 | "id": "djMJ77mGiGHE", 196 | "outputId": "8b4e4bd5-2d74-46e0-ea65-83d56ac896fc" 197 | }, 198 | "outputs": [ 199 | { 200 | "name": "stdout", 201 | "output_type": "stream", 202 | "text": [ 203 | "New cat is created!\n" 204 | ] 205 | } 206 | ], 207 | "source": [ 208 | "# основная часть - создаем объекты\n", 209 | "gatto2 = Cat()\n" 210 | ] 211 | }, 212 | { 213 | "cell_type": "code", 214 | "execution_count": null, 215 | "metadata": { 216 | "colab": { 217 | "base_uri": "https://localhost:8080/" 218 | }, 219 | "id": "BDv5cFdUiGIT", 220 | "outputId": "a1a096c5-0c79-4aea-9420-b139e59f25a6", 221 | "scrolled": true 222 | }, 223 | "outputs": [ 224 | { 225 | "name": "stdout", 226 | "output_type": "stream", 227 | "text": [ 228 | "\n", 229 | "Hi. I'm an instance of class Cat.\n", 230 | "\n", 231 | "insert a number:14\n", 232 | "\n", 233 | "I'm off to sleep for 14.0 hours, bye!\n", 234 | "\n" 235 | ] 236 | } 237 | ], 238 | "source": [ 239 | "#методы в классах, которые мы вызываем вручную\n", 240 | "gatto2.talk()\n", 241 | "gatto2.sleep()" 242 | ] 243 | }, 244 | { 245 | "cell_type": "markdown", 246 | "metadata": { 247 | "id": "kLsehRTziGJT" 248 | }, 249 | "source": [ 250 | "**У классов, помимо методов, есть свойства**\n", 251 | "\n", 252 | "Свойства (иногда \"аттрибуты\", в английском -- \"class properties\") -- это информация, которая характеризует объекты заданного класса\n", 253 | "\n" 254 | ] 255 | }, 256 | { 257 | "cell_type": "code", 258 | "execution_count": null, 259 | "metadata": { 260 | "id": "N3qphMj9iGJZ" 261 | }, 262 | "outputs": [], 263 | "source": [ 264 | "# creating and accessing object attributes\n", 265 | "\n", 266 | "class Cat(object): # задали класс\n", 267 | " \"\"\"A virtual pet class\"\"\" \n", 268 | " \n", 269 | " def __init__(self, name): # метод-конструктор \n", 270 | " self.name = name # self.name -- это свойство для объекта класса \n", 271 | " # Его значение будет равно параметру \"name\" который запрашивается при вызове метода\n", 272 | " # так как метод обращается к объекту, значение для параметра name передаем сразу в скобочках при создании объекта\n", 273 | " print(\"A new cat is created, called \",name)\n", 274 | "\n", 275 | " \n", 276 | " def talk(self): # the talk() method receives the automatically sent reference to the object into its self parameter\n", 277 | " print(\"Hi. I'm\", self.name, \"\\n\") # the print function displays the text \n", 278 | " # by accessing the attribute name of the object through self.name\n", 279 | "\n", 280 | " def sleep(self):\n", 281 | " try:\n", 282 | " x = float(input('insert a number:')) #a piece of code where eceptions may appear\n", 283 | " except:\n", 284 | " print('\\nthis is not a number, I need a number\\n') #what to do in cade of exception\n", 285 | " else:\n", 286 | " print(\"\\nI'm off to sleep for\", x, \"hours, bye!\\n\") #what to do if no exceptions arise \n", 287 | " " 288 | ] 289 | }, 290 | { 291 | "cell_type": "code", 292 | "execution_count": null, 293 | "metadata": { 294 | "colab": { 295 | "base_uri": "https://localhost:8080/", 296 | "height": 52 297 | }, 298 | "id": "RhiDdDv8pM9f", 299 | "outputId": "f3d0843d-20f2-4c68-fba6-4b148cba6e33" 300 | }, 301 | "outputs": [ 302 | { 303 | "name": "stdout", 304 | "output_type": "stream", 305 | "text": [ 306 | "A new cat is created, called Python\n" 307 | ] 308 | }, 309 | { 310 | "data": { 311 | "application/vnd.google.colaboratory.intrinsic+json": { 312 | "type": "string" 313 | }, 314 | "text/plain": [ 315 | "'Python'" 316 | ] 317 | }, 318 | "execution_count": 39, 319 | "metadata": { 320 | "tags": [] 321 | }, 322 | "output_type": "execute_result" 323 | } 324 | ], 325 | "source": [ 326 | "# main\n", 327 | "\n", 328 | "gatto2 = Cat(\"Python\") # создали объект, передали значение имени\n", 329 | "# gatto2.talk() # вызовем метод, теперь он подскажет имя конкретного объекта\n", 330 | "\n", 331 | "# а так осуществляется прямой доступ к свойству\n", 332 | "gatto2.name # свойства вызываются без скобочек \n" 333 | ] 334 | }, 335 | { 336 | "cell_type": "code", 337 | "execution_count": null, 338 | "metadata": { 339 | "colab": { 340 | "base_uri": "https://localhost:8080/" 341 | }, 342 | "id": "ot53ZtknAin4", 343 | "outputId": "063b1abe-d0d7-4d54-c046-9462ed519aeb" 344 | }, 345 | "outputs": [ 346 | { 347 | "name": "stdout", 348 | "output_type": "stream", 349 | "text": [ 350 | "Hi. I'm Python \n", 351 | "\n" 352 | ] 353 | } 354 | ], 355 | "source": [ 356 | "gatto2.talk()" 357 | ] 358 | }, 359 | { 360 | "cell_type": "markdown", 361 | "metadata": { 362 | "id": "apwoF4GStaGA" 363 | }, 364 | "source": [ 365 | "котики -- это конечно хорошо, но как это связано с комплингом?" 366 | ] 367 | }, 368 | { 369 | "cell_type": "code", 370 | "execution_count": 1, 371 | "metadata": { 372 | "id": "SXN8s8GYtYW8" 373 | }, 374 | "outputs": [], 375 | "source": [ 376 | "example = \"TODAY I have received a lot of telephone calls!\"" 377 | ] 378 | }, 379 | { 380 | "cell_type": "code", 381 | "execution_count": 2, 382 | "metadata": { 383 | "id": "gr5-mBgxHqzc" 384 | }, 385 | "outputs": [], 386 | "source": [ 387 | "class NLP(object):\n", 388 | " def __init__(self,text):\n", 389 | " self.text = text\n", 390 | "\n", 391 | " def preprocess(self):\n", 392 | " return self.text.lower().strip().split()\n", 393 | " \n" 394 | ] 395 | }, 396 | { 397 | "cell_type": "code", 398 | "execution_count": 4, 399 | "metadata": { 400 | "colab": { 401 | "base_uri": "https://localhost:8080/" 402 | }, 403 | "id": "L50fDzcRCXtJ", 404 | "outputId": "1e18de2e-b45b-47b5-8748-d42fd39c172c" 405 | }, 406 | "outputs": [ 407 | { 408 | "data": { 409 | "text/plain": [ 410 | "['today', 'i', 'have', 'received', 'a', 'lot', 'of', 'telephone', 'calls!']" 411 | ] 412 | }, 413 | "execution_count": 4, 414 | "metadata": {}, 415 | "output_type": "execute_result" 416 | } 417 | ], 418 | "source": [ 419 | "# from my_classes.py import NLP() as nlp \n", 420 | "\n", 421 | "# from nltk import *\n", 422 | "\n", 423 | "\n", 424 | "\n", 425 | "res = NLP(example)\n", 426 | "\n", 427 | "\n", 428 | "# res.text\n", 429 | "res.preprocess()" 430 | ] 431 | }, 432 | { 433 | "cell_type": "markdown", 434 | "metadata": { 435 | "id": "nkXTSanaC24n" 436 | }, 437 | "source": [ 438 | "### дополнительные возможности\n", 439 | "\n", 440 | "Аттрибуты позволяют определять уникальные характеристики объектов: наприер, можно создать 10 котиков, каждый с уникальным именем\n", 441 | "\n", 442 | "Однако иногда нам может потребоваться информация о чем-то внутри класса. Например, общее количество созданных объектов. Нам понадобится class attribute и static method\n", 443 | "\n", 444 | "Аттрибут класса (**class attribute**) -- это такой специальный аттрибут, универсальный для всех объектов класса (о нем можно думать как об универсальной печати)\n", 445 | "\n", 446 | "**Static method** -- метод, связанный с классом, недоступный объектам класса\n", 447 | "\n" 448 | ] 449 | }, 450 | { 451 | "cell_type": "code", 452 | "execution_count": null, 453 | "metadata": { 454 | "id": "AKkWsYDePyxQ" 455 | }, 456 | "outputs": [], 457 | "source": [ 458 | "# class attributes and static methods\n", 459 | "\n", 460 | "class Cat(object):\n", 461 | " \"\"\"A virtual pet\"\"\"\n", 462 | " total = 0 # count objects for the 1st time (there're no objects yet)\n", 463 | " \"\"\"create a class attribute total and assign value of 0 to it.\n", 464 | " !!! any new variable assigned a value outside of a method creates a class attribute\n", 465 | " The assignment statement is executed only once, when Python first sees the class definition. \n", 466 | " This means that the class attribute exists even before a single object is created. \n", 467 | " \"\"\"\n", 468 | "\n", 469 | " @staticmethod # a decorator for a static method. \n", 470 | " # Static method appears in all the objects of a class\n", 471 | " def status(): # no self here\n", 472 | " \"\"\"\n", 473 | " doesn't have 'self' because, like all static methods, it’s designed to be invoked through a class and\n", 474 | " not an object. So, the method won’t be passed a reference to an object\n", 475 | " and therefore won’t need a parameter, like self , to receive such a reference.\n", 476 | " Self is only needed in object methods to denote reference to which object the method is applied\n", 477 | " Static methods can have parameters in general\"\"\"\n", 478 | " \n", 479 | " print(\"\\nThe total number of cats now is\", Cat.total) # count objects again \n", 480 | " # this func prints the value of the Critter class attribute 'total'\n", 481 | " \n", 482 | " \n", 483 | " def __init__(self, name): #a constructor method, is called automatically when a new object is created\n", 484 | " print(\"A new cat is created!\") #this line will be printed automatically\n", 485 | " self.name = name # Wut is here\n", 486 | " Cat.total += 1 \n", 487 | " # In the constructor method, we also increment the value of this class attribute \n", 488 | " # works whenever a new object of this class is created" 489 | ] 490 | }, 491 | { 492 | "cell_type": "code", 493 | "execution_count": null, 494 | "metadata": { 495 | "colab": { 496 | "base_uri": "https://localhost:8080/" 497 | }, 498 | "id": "0wpS1nNm88D_", 499 | "outputId": "7eeb9031-4c85-4d0d-830d-3f4cb9f64548" 500 | }, 501 | "outputs": [ 502 | { 503 | "name": "stdout", 504 | "output_type": "stream", 505 | "text": [ 506 | "Counting cats. Current amount of cats is 0\n", 507 | "\tCreating cats.\n", 508 | "A new cat is created!\n", 509 | "A new cat is created!\n", 510 | "A new cat is created!\n", 511 | "\n", 512 | "The total number of cats now is 3\n" 513 | ] 514 | } 515 | ], 516 | "source": [ 517 | "#main\n", 518 | "print(\"Counting cats. Current amount of cats is \", Cat.total) #initial count\n", 519 | "\n", 520 | "print(\"\\tCreating cats.\")\n", 521 | "\n", 522 | "gatto1 = Cat(\"Pusheen\")\n", 523 | "gatto2 = Cat(\"Daisy\")\n", 524 | "gatto3 = Cat(\"Bob\")\n", 525 | "\n", 526 | "Cat.status() # invoke the static method 'status' for a class Cat (shows current number of objects)" 527 | ] 528 | }, 529 | { 530 | "cell_type": "code", 531 | "execution_count": null, 532 | "metadata": { 533 | "colab": { 534 | "base_uri": "https://localhost:8080/" 535 | }, 536 | "id": "yOsPoiUMsGec", 537 | "outputId": "ab2cb29c-79f2-43fa-eb02-e7e142fe9d6d" 538 | }, 539 | "outputs": [ 540 | { 541 | "name": "stdout", 542 | "output_type": "stream", 543 | "text": [ 544 | "3\n" 545 | ] 546 | } 547 | ], 548 | "source": [ 549 | "# а вот альтернативный метод просмотра этого же параметра\n", 550 | "print(gatto1.total) # вызов через аттрибут класса" 551 | ] 552 | }, 553 | { 554 | "cell_type": "markdown", 555 | "metadata": { 556 | "id": "MMAqkZstxoru" 557 | }, 558 | "source": [ 559 | "\n", 560 | "Сегодня мы начали знакомиться с ООП, задав класс, его методы, и создав объекты этого класса. ООП -- это целая парадигма, впереди нас ждет много нового (наследование, инкапсуляция и тд)\n", 561 | "([а здесь более развернутый гайд](https://www.datacamp.com/community/tutorials/python-oop-tutorial))" 562 | ] 563 | }, 564 | { 565 | "cell_type": "code", 566 | "execution_count": null, 567 | "metadata": { 568 | "id": "HR-W7bEwyosJ" 569 | }, 570 | "outputs": [], 571 | "source": [] 572 | } 573 | ], 574 | "metadata": { 575 | "colab": { 576 | "collapsed_sections": [], 577 | "name": "OOP.ipynb", 578 | "provenance": [] 579 | }, 580 | "kernelspec": { 581 | "display_name": "Python 3", 582 | "language": "python", 583 | "name": "python3" 584 | }, 585 | "language_info": { 586 | "codemirror_mode": { 587 | "name": "ipython", 588 | "version": 3 589 | }, 590 | "file_extension": ".py", 591 | "mimetype": "text/x-python", 592 | "name": "python", 593 | "nbconvert_exporter": "python", 594 | "pygments_lexer": "ipython3", 595 | "version": "3.8.2" 596 | } 597 | }, 598 | "nbformat": 4, 599 | "nbformat_minor": 1 600 | } 601 | -------------------------------------------------------------------------------- /notebooks/morphology.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "colab_type": "text", 7 | "id": "qUCeat3VZWY6" 8 | }, 9 | "source": [ 10 | "Сегодня мы поговорим о морфологических анализаторах для русского языка. Важно отметить, что (в основном) для каждого естественного языка нужен свой морфоанализатор.\n", 11 | "\n", 12 | "* шаг 1: установим пайморфи и майстем" 13 | ] 14 | }, 15 | { 16 | "cell_type": "code", 17 | "execution_count": null, 18 | "metadata": { 19 | "colab": { 20 | "base_uri": "https://localhost:8080/", 21 | "height": 326 22 | }, 23 | "colab_type": "code", 24 | "id": "tP2ugs4qYMIO", 25 | "outputId": "21a7fa9d-c127-43b8-9f60-2f804e38aa9d", 26 | "tags": [] 27 | }, 28 | "outputs": [], 29 | "source": [ 30 | "# !pip3 install pymystem3\n", 31 | "# !pip3 install pymorphy2[fast]\n", 32 | "\n", 33 | "# ! pip3 install gensim" 34 | ] 35 | }, 36 | { 37 | "cell_type": "code", 38 | "execution_count": 1, 39 | "metadata": { 40 | "colab": { 41 | "base_uri": "https://localhost:8080/", 42 | "height": 54 43 | }, 44 | "colab_type": "code", 45 | "id": "K_EYd7mJanYb", 46 | "outputId": "41b8f3a1-b8fd-42e9-a8a5-020f05b952df" 47 | }, 48 | "outputs": [], 49 | "source": [ 50 | "# импортируем нужные части библиотек\n", 51 | "from pymorphy2 import MorphAnalyzer\n", 52 | "from pymystem3 import Mystem\n", 53 | "\n", 54 | "# сохраняем класс в переменную\n", 55 | "mystem = Mystem() \n", 56 | "morph = MorphAnalyzer() \n" 57 | ] 58 | }, 59 | { 60 | "cell_type": "code", 61 | "execution_count": 2, 62 | "metadata": { 63 | "colab": {}, 64 | "colab_type": "code", 65 | "id": "sAm6HB5hfS-A" 66 | }, 67 | "outputs": [], 68 | "source": [ 69 | "# сэмпл-текст, на котором все будем пробовать\n", 70 | "text = \"\"\"Зрелый фрукт на вкус очень сладок и обладает приятным сладковатым ароматом. В нём много витаминов и сахаров, но мало кислот.\"\"\"" 71 | ] 72 | }, 73 | { 74 | "cell_type": "markdown", 75 | "metadata": { 76 | "colab_type": "text", 77 | "id": "BBDkyu6kdeQO" 78 | }, 79 | "source": [ 80 | "## нормализация" 81 | ] 82 | }, 83 | { 84 | "cell_type": "markdown", 85 | "metadata": { 86 | "colab_type": "text", 87 | "id": "YJ05gNGxkY4I" 88 | }, 89 | "source": [ 90 | "давайте приведем текст к нижнему регистру" 91 | ] 92 | }, 93 | { 94 | "cell_type": "code", 95 | "execution_count": 3, 96 | "metadata": { 97 | "colab": { 98 | "base_uri": "https://localhost:8080/", 99 | "height": 54 100 | }, 101 | "colab_type": "code", 102 | "id": "y1dUzBYcdiNk", 103 | "outputId": "0c1efc14-36f9-4361-b796-52a4aacf31f8" 104 | }, 105 | "outputs": [ 106 | { 107 | "data": { 108 | "text/plain": [ 109 | "'зрелый фрукт на вкус очень сладок и обладает приятным сладковатым ароматом. в нём много витаминов и сахаров, но мало кислот.'" 110 | ] 111 | }, 112 | "execution_count": 3, 113 | "metadata": {}, 114 | "output_type": "execute_result" 115 | } 116 | ], 117 | "source": [ 118 | "text = text.lower()\n", 119 | "text" 120 | ] 121 | }, 122 | { 123 | "cell_type": "markdown", 124 | "metadata": { 125 | "colab_type": "text", 126 | "id": "hr9pnX59bD3Q" 127 | }, 128 | "source": [ 129 | "## токенизация" 130 | ] 131 | }, 132 | { 133 | "cell_type": "markdown", 134 | "metadata": { 135 | "colab_type": "text", 136 | "id": "5evdBA7CkeRC" 137 | }, 138 | "source": [ 139 | "иногда текст нужно предварительно разбить на токены, отдельные элементы. Токенизаторов много, каждый делает это, руководствуясь своими правилами\n", 140 | "\n", 141 | "* токенизация нужна, если морофоанализатор не умеет токенизировать сам (Mystem умеет, Pymorphy не умеет)" 142 | ] 143 | }, 144 | { 145 | "cell_type": "code", 146 | "execution_count": 4, 147 | "metadata": { 148 | "colab": {}, 149 | "colab_type": "code", 150 | "id": "VTGeMdVzb1h9" 151 | }, 152 | "outputs": [], 153 | "source": [ 154 | "# два примера токенизации\n", 155 | "from nltk.tokenize import word_tokenize\n", 156 | "from gensim.utils import tokenize" 157 | ] 158 | }, 159 | { 160 | "cell_type": "code", 161 | "execution_count": null, 162 | "metadata": { 163 | "tags": [] 164 | }, 165 | "outputs": [], 166 | "source": [ 167 | "list(tokenize(text))" 168 | ] 169 | }, 170 | { 171 | "cell_type": "code", 172 | "execution_count": null, 173 | "metadata": {}, 174 | "outputs": [], 175 | "source": [ 176 | "word_tokenize(text)" 177 | ] 178 | }, 179 | { 180 | "cell_type": "markdown", 181 | "metadata": { 182 | "colab_type": "text", 183 | "id": "myoMhGgKjk1d" 184 | }, 185 | "source": [ 186 | "## лемматизация и морфоанализ" 187 | ] 188 | }, 189 | { 190 | "cell_type": "markdown", 191 | "metadata": { 192 | "colab_type": "text", 193 | "id": "FK0Zwx3FSfug" 194 | }, 195 | "source": [ 196 | "### Mystem" 197 | ] 198 | }, 199 | { 200 | "cell_type": "markdown", 201 | "metadata": { 202 | "colab_type": "text", 203 | "id": "Uei-SLNwSfuh" 204 | }, 205 | "source": [ 206 | "\n", 207 | "Майстем работает немного лучше и сам токенизирует,\n", 208 | "поэтому можно ему подавать сырой текст." 209 | ] 210 | }, 211 | { 212 | "cell_type": "code", 213 | "execution_count": 5, 214 | "metadata": { 215 | "colab": { 216 | "base_uri": "https://localhost:8080/", 217 | "height": 88 218 | }, 219 | "colab_type": "code", 220 | "id": "uDQbEwUaSfui", 221 | "outputId": "2397f16d-2559-40d5-dddc-e5dcb37bb524" 222 | }, 223 | "outputs": [ 224 | { 225 | "name": "stdout", 226 | "output_type": "stream", 227 | "text": [ 228 | "зрелый фрукт на вкус очень сладок и обладает приятным сладковатым ароматом. в нём много витаминов и сахаров, но мало кислот. \n", 229 | "\n", 230 | "['зрелый', ' ', 'фрукт', ' ', 'на', ' ', 'вкус', ' ', 'очень', ' ', 'сладкий', ' ', 'и', ' ', 'обладать', ' ', 'приятный', ' ', 'сладковатый', ' ', 'аромат', '.', ' ', 'в', ' ', 'он', ' ', 'много', ' ', 'витамин', ' ', 'и', ' ', 'сахаров', ', ', 'но', ' ', 'мало', ' ', 'кислота', '.', '\\n']\n" 231 | ] 232 | } 233 | ], 234 | "source": [ 235 | "# сначала лемматизируем слова методом .lemmatize()\n", 236 | "import string\n", 237 | "print(text, \"\\n\")\n", 238 | "\n", 239 | "print(mystem.lemmatize(text))\n" 240 | ] 241 | }, 242 | { 243 | "cell_type": "code", 244 | "execution_count": 6, 245 | "metadata": { 246 | "colab": {}, 247 | "colab_type": "code", 248 | "id": "4foA60oJSfur" 249 | }, 250 | "outputs": [], 251 | "source": [ 252 | "# метод .analyze() даст грамматическую информацию о словах\n", 253 | "\n", 254 | "ms_analyzed = mystem.analyze(text)\n", 255 | "\n", 256 | "print(ms_analyzed) # попробуйте разные индексы в этой переменной" 257 | ] 258 | }, 259 | { 260 | "cell_type": "markdown", 261 | "metadata": { 262 | "colab_type": "text", 263 | "id": "I-AaAvpyLcsI" 264 | }, 265 | "source": [ 266 | "метод .analyze() возвращает список словарей\n", 267 | "\n", 268 | "\n", 269 | "каждый словарь имеет либо одно поле 'text' (когда попался пробел или пунктуация), либо analysis и text\n", 270 | "\n", 271 | "* в analysis снова список словарей с вариантами разбора (первый самый вероятный)\n", 272 | "* поля в analysis - 'gr' - грамматическая информация, 'lex' - лемма\n", 273 | "* analysis - может быть пустым списком" 274 | ] 275 | }, 276 | { 277 | "cell_type": "code", 278 | "execution_count": 7, 279 | "metadata": {}, 280 | "outputs": [ 281 | { 282 | "name": "stdout", 283 | "output_type": "stream", 284 | "text": [ 285 | "Слово из текста - зрелый\n", 286 | "Разбор слова - {'lex': 'зрелый', 'wt': 1, 'gr': 'A=(вин,ед,полн,муж,неод|им,ед,полн,муж)'}\n", 287 | "Лемма слова - зрелый\n", 288 | "Грамматическая информация слова - A=(вин,ед,полн,муж,неод|им,ед,полн,муж)\n" 289 | ] 290 | } 291 | ], 292 | "source": [ 293 | "# сделаем все красиво с индексами и доступом по ключам\n", 294 | "# посмотрим на примере первого слова в тексте, поэтому индекс [0]\n", 295 | "\n", 296 | "\n", 297 | "print('Слово из текста - ',ms_analyzed[0]['text'])\n", 298 | "print('Разбор слова - ', ms_analyzed[0]['analysis'][0])\n", 299 | "print('Лемма слова - ', ms_analyzed[0]['analysis'][0]['lex'])\n", 300 | "print('Грамматическая информация слова - ', ms_analyzed[0]['analysis'][0]['gr'])\n" 301 | ] 302 | }, 303 | { 304 | "cell_type": "code", 305 | "execution_count": null, 306 | "metadata": { 307 | "colab": { 308 | "base_uri": "https://localhost:8080/", 309 | "height": 85 310 | }, 311 | "colab_type": "code", 312 | "id": "zbbCXnFbSfuw", 313 | "outputId": "cd7f46c2-9582-470f-a874-7156a090d98f", 314 | "tags": [] 315 | }, 316 | "outputs": [], 317 | "source": [ 318 | "# такое же, но циклом, для всех слов в тексте\n", 319 | "\n", 320 | "for idx,x in enumerate(ms_analyzed): # enumerate выдает элемент и его индекс\n", 321 | "\n", 322 | " if x.get('analysis'): # если есть словарь с морфо-разбором\n", 323 | " \n", 324 | " print('Слово из текста - ',ms_analyzed[idx]['text']) # получаем элементы по индексам\n", 325 | " print('Разбор слова - ', ms_analyzed[idx]['analysis'][0])\n", 326 | " print('Лемма слова - ', ms_analyzed[idx]['analysis'][0]['lex'])\n", 327 | " print('Грамматическая информация слова - ', ms_analyzed[idx]['analysis'][0]['gr'])\n", 328 | " print(\"\\n\")\n", 329 | " \n", 330 | " else: continue\n", 331 | " # если элемент без словаря с морфо-разбором, переходим к следующему элементу" 332 | ] 333 | }, 334 | { 335 | "cell_type": "code", 336 | "execution_count": 8, 337 | "metadata": { 338 | "colab": { 339 | "base_uri": "https://localhost:8080/", 340 | "height": 187 341 | }, 342 | "colab_type": "code", 343 | "id": "FHs_zUYySfuz", 344 | "outputId": "f5472fb6-d873-45a1-bc09-34d14eca00c6", 345 | "tags": [] 346 | }, 347 | "outputs": [ 348 | { 349 | "data": { 350 | "text/plain": [ 351 | "['зрелый',\n", 352 | " 'фрукт',\n", 353 | " 'на',\n", 354 | " 'вкус',\n", 355 | " 'очень',\n", 356 | " 'сладкий',\n", 357 | " 'и',\n", 358 | " 'обладать',\n", 359 | " 'приятный',\n", 360 | " 'сладковатый',\n", 361 | " 'аромат',\n", 362 | " 'в',\n", 363 | " 'он',\n", 364 | " 'много',\n", 365 | " 'витамин',\n", 366 | " 'и',\n", 367 | " 'сахаров',\n", 368 | " 'но',\n", 369 | " 'мало',\n", 370 | " 'кислота']" 371 | ] 372 | }, 373 | "execution_count": 8, 374 | "metadata": {}, 375 | "output_type": "execute_result" 376 | } 377 | ], 378 | "source": [ 379 | "# леммы можно достать в одну строчку\n", 380 | "\n", 381 | "[elem['analysis'][0]['lex'] for elem in ms_analyzed if elem.get('analysis')]" 382 | ] 383 | }, 384 | { 385 | "cell_type": "code", 386 | "execution_count": null, 387 | "metadata": { 388 | "colab": {}, 389 | "colab_type": "code", 390 | "id": "G_9QmDvEi-2y", 391 | "tags": [] 392 | }, 393 | "outputs": [], 394 | "source": [ 395 | "# то же самое, что в предыдущей ячейке, но циклом\n", 396 | "\n", 397 | "res = []\n", 398 | "\n", 399 | "for elem in ms_analyzed:\n", 400 | " if elem.get('analysis'):\n", 401 | " res.append(elem['analysis'][0]['lex'])\n", 402 | "\n", 403 | "res" 404 | ] 405 | }, 406 | { 407 | "cell_type": "markdown", 408 | "metadata": { 409 | "colab_type": "text", 410 | "id": "prpnW0kWjtdg" 411 | }, 412 | "source": [ 413 | "#### дополнительные возможности Mystem" 414 | ] 415 | }, 416 | { 417 | "cell_type": "markdown", 418 | "metadata": { 419 | "colab_type": "text", 420 | "id": "U8fThMyuSfu2" 421 | }, 422 | "source": [ 423 | "Mystem умеет разбивать текст на предложения, но через питоновский интерфейс это сделать не получится. Нужно скачать mystem отсюда - https://yandex.ru/dev/mystem/ и использовать в командной строке" 424 | ] 425 | }, 426 | { 427 | "cell_type": "markdown", 428 | "metadata": { 429 | "colab_type": "text", 430 | "id": "iInXST2ASfvF" 431 | }, 432 | "source": [ 433 | "Недостатки Mystem: это продукт Яндекса с некоторыми ограничениями на использование, больше он не развивается." 434 | ] 435 | }, 436 | { 437 | "cell_type": "markdown", 438 | "metadata": { 439 | "colab_type": "text", 440 | "id": "xmGbPTt9SfvH" 441 | }, 442 | "source": [ 443 | "### Pymorphy" 444 | ] 445 | }, 446 | { 447 | "cell_type": "markdown", 448 | "metadata": { 449 | "colab_type": "text", 450 | "id": "AmEOXgExSfvK" 451 | }, 452 | "source": [ 453 | "Pymorphy - открытый и развивается ([можно поучаствовать на гитхабе](https://github.com/kmike/pymorphy2))\n", 454 | "\n", 455 | "\n", 456 | "* [документация pymorphy](https://pythonhosted.org/pymorphy/)" 457 | ] 458 | }, 459 | { 460 | "cell_type": "markdown", 461 | "metadata": { 462 | "colab_type": "text", 463 | "id": "kacinkpvSfvL" 464 | }, 465 | "source": [ 466 | "У него нет встроенной токенизации и он расценивает всё как слово. Когда есть несколько вариантов, он выдает их с вероятностостями, которые расчитатны на корпусе со снятой неоднозначностью. Это лучше стемминга, но хуже майстема." 467 | ] 468 | }, 469 | { 470 | "cell_type": "code", 471 | "execution_count": 9, 472 | "metadata": { 473 | "colab": {}, 474 | "colab_type": "code", 475 | "id": "vLAH4hFGSfvM" 476 | }, 477 | "outputs": [], 478 | "source": [ 479 | "# основная функция - pymorphy.parse\n", 480 | "\n", 481 | "pm_analyzed = [morph.parse(token) for token in list(tokenize(text))]" 482 | ] 483 | }, 484 | { 485 | "cell_type": "code", 486 | "execution_count": null, 487 | "metadata": { 488 | "colab": {}, 489 | "colab_type": "code", 490 | "id": "Xczi9QqikC3w", 491 | "tags": [] 492 | }, 493 | "outputs": [], 494 | "source": [ 495 | "pm_analyzed" 496 | ] 497 | }, 498 | { 499 | "cell_type": "code", 500 | "execution_count": null, 501 | "metadata": { 502 | "colab": { 503 | "base_uri": "https://localhost:8080/", 504 | "height": 88 505 | }, 506 | "colab_type": "code", 507 | "id": "7EmhCkUfSfvT", 508 | "outputId": "2bcfb5e1-05f5-4312-a988-88cec85b0806" 509 | }, 510 | "outputs": [], 511 | "source": [ 512 | "# пример с морфологической неоднозначностью\n", 513 | "\n", 514 | "morph.parse(\"сахаров\")" 515 | ] 516 | }, 517 | { 518 | "cell_type": "markdown", 519 | "metadata": { 520 | "colab_type": "text", 521 | "id": "LpQ98mZtNf2w" 522 | }, 523 | "source": [ 524 | "Она похожа на analyze в майстеме только возвращает список объектов Parse\n", 525 | "* Первый в списке - самый вероятный разбор (у каждого есть score)\n", 526 | "* Информация достается через атрибут (Parse.word)\n", 527 | "* Грамматическая информация хранится в объекте OpencorporaTag и из него удобно доставать\n", 528 | "части речи или другие категории" 529 | ] 530 | }, 531 | { 532 | "cell_type": "code", 533 | "execution_count": 11, 534 | "metadata": { 535 | "colab": { 536 | "base_uri": "https://localhost:8080/", 537 | "height": 173 538 | }, 539 | "colab_type": "code", 540 | "id": "2MVvEeqmSfvX", 541 | "outputId": "cd878f2e-44ed-4c03-93f8-c44fca964d58" 542 | }, 543 | "outputs": [ 544 | { 545 | "name": "stdout", 546 | "output_type": "stream", 547 | "text": [ 548 | "Первое слово - зрелый\n", 549 | "Лемма первого слова - зрелый\n", 550 | "Грамматическая информация первого слова - ADJF,Qual masc,sing,nomn\n", 551 | "Часть речи первого слова - ADJF\n", 552 | "Род первого слова - masc\n", 553 | "Число первого слова - sing\n", 554 | "Падеж первого слова - nomn\n" 555 | ] 556 | } 557 | ], 558 | "source": [ 559 | "# сделаем красиво\n", 560 | "print('Первое слово - ', pm_analyzed[0][0].word)\n", 561 | "print('Лемма первого слова - ', pm_analyzed[0][0].normal_form)\n", 562 | "print('Грамматическая информация первого слова - ', pm_analyzed[0][0].tag)\n", 563 | "print('Часть речи первого слова - ', pm_analyzed[0][0].tag.POS)\n", 564 | "print('Род первого слова - ', pm_analyzed[0][0].tag.gender)\n", 565 | "print('Число первого слова - ',pm_analyzed[0][0].tag.number)\n", 566 | "print('Падеж первого слова - ', pm_analyzed[0][0].tag.case)" 567 | ] 568 | }, 569 | { 570 | "cell_type": "code", 571 | "execution_count": null, 572 | "metadata": { 573 | "tags": [] 574 | }, 575 | "outputs": [], 576 | "source": [ 577 | "# такое же, но циклом, для всех слов в тексте\n", 578 | "\n", 579 | "for idx,x in enumerate(pm_analyzed): # enumerate выдает элемент и его индекс\n", 580 | "\n", 581 | " print('Первое слово - ', pm_analyzed[idx][0].word)\n", 582 | " print('Лемма первого слова - ', pm_analyzed[idx][0].normal_form)\n", 583 | " print('Грамматическая информация первого слова - ', pm_analyzed[idx][0].tag)\n", 584 | " print('Часть речи первого слова - ', pm_analyzed[idx][0].tag.POS)\n", 585 | " print('Род первого слова - ', pm_analyzed[idx][0].tag.gender)\n", 586 | " print('Число первого слова - ',pm_analyzed[idx][0].tag.number)\n", 587 | " print('Падеж первого слова - ', pm_analyzed[idx][0].tag.case)\n", 588 | " print(\"\\n\")\n", 589 | " " 590 | ] 591 | }, 592 | { 593 | "cell_type": "markdown", 594 | "metadata": { 595 | "colab_type": "text", 596 | "id": "lY4sSWT-UCE7" 597 | }, 598 | "source": [ 599 | "### что можно дальше" 600 | ] 601 | }, 602 | { 603 | "cell_type": "markdown", 604 | "metadata": { 605 | "colab_type": "text", 606 | "id": "HRYDeot6UKym" 607 | }, 608 | "source": [ 609 | "Pymorphy и Mystem - не единственные морфоанализаторы для русского языка. Можно, например, посмотреть на [RNNmorph](https://github.com/IlyaGusev/rnnmorph) и [deeppavlov](http://docs.deeppavlov.ai/en/master/features/models/morphotagger.html).\n", 610 | "\n", 611 | "А еще есть исследование, где сравнивали морфоанализаторы для русского ([краткая версия](http://web-corpora.net/wsgi/mystemplus.wsgi/mystemplus/compare_table/), [статья](http://www.dialog-21.ru/media/3473/dereza.pdf))\n", 612 | "\n", 613 | " \n", 614 | "И на последок, морфо-анализаторы для других яззыков:\n", 615 | "- [UralicNLP](https://github.com/mikahama/uralicNLP)\n", 616 | "- [hfst от Apertium](https://wiki.apertium.org/wiki/Hfst)\n", 617 | "- [Stanza](https://stanfordnlp.github.io/stanza/)\n", 618 | "- [SpaCy](https://spacy.io/usage/linguistic-features#morphology)\n", 619 | "- [Trankit](https://trankit.readthedocs.io/en/latest/posdep.html)" 620 | ] 621 | }, 622 | { 623 | "cell_type": "code", 624 | "execution_count": null, 625 | "metadata": {}, 626 | "outputs": [], 627 | "source": [] 628 | } 629 | ], 630 | "metadata": { 631 | "colab": { 632 | "collapsed_sections": [ 633 | "prpnW0kWjtdg" 634 | ], 635 | "include_colab_link": true, 636 | "name": "morphology.ipynb", 637 | "provenance": [] 638 | }, 639 | "kernelspec": { 640 | "display_name": "Python 3 (ipykernel)", 641 | "language": "python", 642 | "name": "python3" 643 | }, 644 | "language_info": { 645 | "codemirror_mode": { 646 | "name": "ipython", 647 | "version": 3 648 | }, 649 | "file_extension": ".py", 650 | "mimetype": "text/x-python", 651 | "name": "python", 652 | "nbconvert_exporter": "python", 653 | "pygments_lexer": "ipython3", 654 | "version": "3.10.0" 655 | } 656 | }, 657 | "nbformat": 4, 658 | "nbformat_minor": 4 659 | } 660 | -------------------------------------------------------------------------------- /notebooks/regexes_class.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "colab_type": "text", 7 | "id": "jodqgEHypY9h" 8 | }, 9 | "source": [ 10 | "## логика регулярных выржений и зачем они нужны" 11 | ] 12 | }, 13 | { 14 | "cell_type": "markdown", 15 | "metadata": { 16 | "colab_type": "text", 17 | "id": "3WzefC6ZGUri" 18 | }, 19 | "source": [ 20 | "регулярное выражение — это последовательность символов, используемая для поиска и(или) замены некоторого паттерна в строке (тексте или файле) \n", 21 | "\n", 22 | "регулярные выражения хороши, когда нам нужно вытащить из текста *повторяющийся паттерн*: номер телефона, конкретную фразу, адреса и тд.\n", 23 | "\n", 24 | "" 25 | ] 26 | }, 27 | { 28 | "cell_type": "markdown", 29 | "metadata": { 30 | "colab_type": "text", 31 | "id": "HJoXkRLhKEvv" 32 | }, 33 | "source": [ 34 | "регулярные выражения можно использовать не только в питоне! Можно везде, где поддерживается их синтаксис
    \n", 35 | "- терминал (командная строка, смотрите команду [grep для Unix*](https://www.cyberciti.biz/faq/howto-use-grep-command-in-linux-unix/) и [для Windows](https://www.shellhacks.com/windows-grep-equivalent-cmd-powershell/))\n", 36 | "- Excel/[Google Sheets]((https://www.distilled.net/how-to-use-regex-in-google-sheets/))\n", 37 | "- текстовые редакторы ([Sublime Text](http://webcache.googleusercontent.com/search?q=cache:http://docs.sublimetext.info/en/latest/search_and_replace/search_and_replace_overview.html), Notepad++ и тд)" 38 | ] 39 | }, 40 | { 41 | "cell_type": "markdown", 42 | "metadata": { 43 | "colab_type": "text", 44 | "id": "BACXu7q0KEnE" 45 | }, 46 | "source": [ 47 | "**онлайн-редкаторы для регулярных выражений:**\n", 48 | "\n", 49 | "- [1](https://regexr.com/)\n", 50 | "\n", 51 | "- [2](https://www.debuggex.com/) (не забудьте выбрать Python в выпадающем окне!)\n", 52 | "\n", 53 | "- [3](https://regex101.com/r/F8dY80/3)" 54 | ] 55 | }, 56 | { 57 | "cell_type": "markdown", 58 | "metadata": { 59 | "colab_type": "text", 60 | "id": "INpFaKXMyL61" 61 | }, 62 | "source": [ 63 | "подсказки по синтаксису регулярных выражений:\n", 64 | "\n" 65 | ] 66 | }, 67 | { 68 | "cell_type": "markdown", 69 | "metadata": { 70 | "colab_type": "text", 71 | "id": "pDFe64llXr2j" 72 | }, 73 | "source": [ 74 | "
    ОператорОписание
    .Один любой символ, кроме новой строки \\n.
    ?0 или 1 вхождение шаблона слева
    +1 и более вхождений шаблона слева
    *0 и более вхождений шаблона слева
    \\wЛюбая цифра или буква (\\W — все, кроме буквы или цифры)
    \\dЛюбая цифра [0-9] (\\D — все, кроме цифры)
    \\sЛюбой пробельный символ (\\S — любой непробельный символ)
    \\bГраница слова
    [..]Один из символов в скобках ([^..] — любой символ, кроме тех, что в скобках)
    \\Экранирование специальных символов (\\. означает точку или \\+ — знак «плюс»)
    ^ и $Начало и конец строки соответственно
    {n,m}От n до m вхождений ({,m} — от 0 до m)
    a|bСоответствует a или b
    ()Группирует выражение и возвращает найденный текст
    \\t, \\n, \\rСимвол табуляции, новой строки и возврата каретки соответственно
    \n", 75 | "\n", 76 | "\n", 77 | "[здесь](https://www.rexegg.com/regex-quickstart.html) развернутая таблица синтаксиса" 78 | ] 79 | }, 80 | { 81 | "cell_type": "markdown", 82 | "metadata": { 83 | "colab_type": "text", 84 | "id": "4prv6TmgpU3n", 85 | "tags": [] 86 | }, 87 | "source": [ 88 | "## Регулярные выражения в питоне" 89 | ] 90 | }, 91 | { 92 | "cell_type": "markdown", 93 | "metadata": { 94 | "colab_type": "text", 95 | "id": "Fl18DOLrKEpC" 96 | }, 97 | "source": [ 98 | "чтобы начать работать с регулярными выражениями в питоне, нам нужно импортировать модуль ``re`` [или скачать библиотеку regex](https://pypi.org/project/regex/)\n", 99 | "\n", 100 | "\n", 101 | "* здесь [ссылка](https://docs.python.org/3/library/re.html) на его документацию и [ссылка на тьюториал](https://docs.python.org/3/howto/regex.html#regex-howto) \n", 102 | "\n", 103 | "а так выглядят основные функции модуля re \n", 104 | "\n", 105 | "

    \n", 106 | "\n", 107 | "\n", 108 | "\n", 109 | "\n", 110 | "\n", 111 | "\n", 112 | "\n", 113 | "\n", 114 | "\n", 115 | "\n", 116 | "\n", 117 | "\n", 118 | "\n", 119 | "\n", 120 | "\n", 121 | "\n", 122 | "\n", 123 | "\n", 124 | "\n", 125 | "\n", 126 | "\n", 127 | "\n", 128 | "\n", 129 | "\n", 130 | "\n", 131 | "\n", 132 | "\n", 133 | "\n", 134 | "\n", 135 | "\n", 136 | "\n", 137 | "\n", 138 | "
    ФункцияЧто делает
    re.match(pattern, string)Найти по заданному шаблону pattern первое совпадение в начале строкиstring
    re.search(pattern, string)Найти в строке string первую строчку, подходящую под шаблон pattern
    ищет по всей строке, но возвращает только первое найденное совпадение
    re.fullmatch(pattern, string)Проверить, подходит ли строка string под шаблон pattern
    re.split(pattern, string, maxsplit=0)Аналог str.split(), только разделение происходит по подстрокам, подходящим под шаблон pattern
    re.findall(pattern, string)Найти в строке string все непересекающиеся шаблоны pattern
    re.sub(pattern, replace, string)Заменить в строке string все непересекающиеся шаблоны pattern на replace
    \n", 139 | "\n", 140 | "\n", 141 | "Давайте попробуем!" 142 | ] 143 | }, 144 | { 145 | "cell_type": "code", 146 | "execution_count": 1, 147 | "metadata": {}, 148 | "outputs": [ 149 | { 150 | "name": "stdout", 151 | "output_type": "stream", 152 | "text": [ 153 | "Requirement already satisfied: regex in /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages (2021.11.10)\n" 154 | ] 155 | } 156 | ], 157 | "source": [ 158 | "! pip3 install regex" 159 | ] 160 | }, 161 | { 162 | "cell_type": "code", 163 | "execution_count": 2, 164 | "metadata": { 165 | "colab": {}, 166 | "colab_type": "code", 167 | "id": "UUklQAWjxxhN" 168 | }, 169 | "outputs": [], 170 | "source": [ 171 | "import re, regex" 172 | ] 173 | }, 174 | { 175 | "cell_type": "code", 176 | "execution_count": 19, 177 | "metadata": {}, 178 | "outputs": [ 179 | { 180 | "name": "stdout", 181 | "output_type": "stream", 182 | "text": [ 183 | "Hello my dear friend Amy.\n", 184 | "Hello again!\n" 185 | ] 186 | } 187 | ], 188 | "source": [ 189 | "text = \"Hello my dear friend Amy.\\nHello again!\"\n", 190 | "\n", 191 | "print(text)" 192 | ] 193 | }, 194 | { 195 | "cell_type": "markdown", 196 | "metadata": { 197 | "colab_type": "text", 198 | "id": "GJtLYetTJSW3", 199 | "tags": [] 200 | }, 201 | "source": [ 202 | "## .match(pattern, string)\n", 203 | "\n", 204 | "метод ищет подстроку по заданному шаблону в начале строки " 205 | ] 206 | }, 207 | { 208 | "cell_type": "code", 209 | "execution_count": 23, 210 | "metadata": { 211 | "colab": { 212 | "base_uri": "https://localhost:8080/", 213 | "height": 34 214 | }, 215 | "colab_type": "code", 216 | "id": "M-mkKdmyJLWR", 217 | "outputId": "8db70fa9-bcc8-4379-f9c1-0a09d10b9bb4" 218 | }, 219 | "outputs": [ 220 | { 221 | "name": "stdout", 222 | "output_type": "stream", 223 | "text": [ 224 | "\n" 225 | ] 226 | } 227 | ], 228 | "source": [ 229 | "result = re.match(r'Hello', text)\n", 230 | "# («r» перед строкой шаблона показывает, что это «сырая» строка в Python)\n", 231 | "\n", 232 | "print (result)\n", 233 | "# попробуйте найти hello вместо Hello" 234 | ] 235 | }, 236 | { 237 | "cell_type": "code", 238 | "execution_count": 25, 239 | "metadata": {}, 240 | "outputs": [], 241 | "source": [ 242 | "res2 = regex.match(r\"Hello\", text)" 243 | ] 244 | }, 245 | { 246 | "cell_type": "markdown", 247 | "metadata": { 248 | "colab_type": "text", 249 | "id": "RSyQ68BZKjyu" 250 | }, 251 | "source": [ 252 | "Строка найдена, но не показывается. По умолчанию, print покажет сам объект (найденный паттерн) и его мета-данные.\n", 253 | "\n", 254 | "Чтобы вывести содержимое, используем метод ```.group()``` Он показывает вхождения искомого паттерна" 255 | ] 256 | }, 257 | { 258 | "cell_type": "code", 259 | "execution_count": 26, 260 | "metadata": { 261 | "colab": { 262 | "base_uri": "https://localhost:8080/", 263 | "height": 34 264 | }, 265 | "colab_type": "code", 266 | "id": "XwSoK-3wK4Rb", 267 | "outputId": "003ad842-43e3-42b1-d62f-f612e33b0a4e" 268 | }, 269 | "outputs": [ 270 | { 271 | "name": "stdout", 272 | "output_type": "stream", 273 | "text": [ 274 | "Hello\n" 275 | ] 276 | } 277 | ], 278 | "source": [ 279 | "print (result.group())" 280 | ] 281 | }, 282 | { 283 | "cell_type": "markdown", 284 | "metadata": { 285 | "colab_type": "text", 286 | "id": "fq8kKTH4SswS", 287 | "tags": [] 288 | }, 289 | "source": [ 290 | "## .fullmatch(pattern, string)\n", 291 | "\n", 292 | "проверяет, является ли паттерн полным совпадением со строкой" 293 | ] 294 | }, 295 | { 296 | "cell_type": "code", 297 | "execution_count": 27, 298 | "metadata": { 299 | "colab": { 300 | "base_uri": "https://localhost:8080/", 301 | "height": 68 302 | }, 303 | "colab_type": "code", 304 | "id": "8I0s5_ieRq4b", 305 | "outputId": "6306be70-98f5-4dc3-cd42-5100cf830c93" 306 | }, 307 | "outputs": [ 308 | { 309 | "name": "stdout", 310 | "output_type": "stream", 311 | "text": [ 312 | "\n", 313 | " Hello my dear friend Amy\n" 314 | ] 315 | } 316 | ], 317 | "source": [ 318 | "result = re.fullmatch(r'Hello my dear friend Amy', 'Hello my dear friend Amy')\n", 319 | "\n", 320 | "# print (result)\n", 321 | "\n", 322 | "print (\"\\n\",result.group())" 323 | ] 324 | }, 325 | { 326 | "cell_type": "code", 327 | "execution_count": 28, 328 | "metadata": {}, 329 | "outputs": [ 330 | { 331 | "name": "stdout", 332 | "output_type": "stream", 333 | "text": [ 334 | "Hello my dear friend Amy.\n", 335 | "Hello again!\n" 336 | ] 337 | } 338 | ], 339 | "source": [ 340 | "res2 = regex.fullmatch(r'Hello my dear friend Amy.\\nHello again!', text)\n", 341 | "\n", 342 | "print(res2.group())" 343 | ] 344 | }, 345 | { 346 | "cell_type": "markdown", 347 | "metadata": { 348 | "colab_type": "text", 349 | "id": "0T_q0k3oOY4f" 350 | }, 351 | "source": [ 352 | "## .search(pattern, string)\n", 353 | "\n", 354 | "ищет паттерн по всей длине строки" 355 | ] 356 | }, 357 | { 358 | "cell_type": "code", 359 | "execution_count": 29, 360 | "metadata": { 361 | "colab": { 362 | "base_uri": "https://localhost:8080/", 363 | "height": 34 364 | }, 365 | "colab_type": "code", 366 | "id": "ZgPVsxO-Nysf", 367 | "outputId": "13ecdfb5-6a8c-4f66-c497-806818dc42eb" 368 | }, 369 | "outputs": [ 370 | { 371 | "name": "stdout", 372 | "output_type": "stream", 373 | "text": [ 374 | "Hello\n" 375 | ] 376 | } 377 | ], 378 | "source": [ 379 | "result = re.search(r'Hello', text)\n", 380 | "# print (result)\n", 381 | "\n", 382 | "print(result.group())" 383 | ] 384 | }, 385 | { 386 | "cell_type": "code", 387 | "execution_count": 30, 388 | "metadata": {}, 389 | "outputs": [ 390 | { 391 | "name": "stdout", 392 | "output_type": "stream", 393 | "text": [ 394 | "Hello\n" 395 | ] 396 | } 397 | ], 398 | "source": [ 399 | "res2 = regex.search(r'Hello', text)\n", 400 | "\n", 401 | "print(res2.group())" 402 | ] 403 | }, 404 | { 405 | "cell_type": "markdown", 406 | "metadata": {}, 407 | "source": [ 408 | "[о разнице search и match](https://docs.python.org/3/library/re.html#search-vs-match)" 409 | ] 410 | }, 411 | { 412 | "cell_type": "markdown", 413 | "metadata": { 414 | "colab_type": "text", 415 | "id": "LdVX17AJTA0Y" 416 | }, 417 | "source": [ 418 | "## .split(pattern, string, maxsplit=0)\n", 419 | "\n", 420 | "Похож на знакомый нам ```.split()```. Метод разделяет строку по заданному шаблону" 421 | ] 422 | }, 423 | { 424 | "cell_type": "code", 425 | "execution_count": 35, 426 | "metadata": { 427 | "colab": { 428 | "base_uri": "https://localhost:8080/", 429 | "height": 34 430 | }, 431 | "colab_type": "code", 432 | "id": "tByLaitkTJI8", 433 | "outputId": "7b1e1c9e-5846-495f-ad25-48b453d65ea7" 434 | }, 435 | "outputs": [ 436 | { 437 | "name": "stdout", 438 | "output_type": "stream", 439 | "text": [ 440 | "['Hello', 'my', 'dear', 'friend', 'Amy.', 'Hello', 'again!']\n" 441 | ] 442 | } 443 | ], 444 | "source": [ 445 | "result = re.split(r'\\s',text)\n", 446 | "print (result)" 447 | ] 448 | }, 449 | { 450 | "cell_type": "code", 451 | "execution_count": 34, 452 | "metadata": {}, 453 | "outputs": [ 454 | { 455 | "name": "stdout", 456 | "output_type": "stream", 457 | "text": [ 458 | "['Hello my dear friend Amy', 'Hello again!']\n" 459 | ] 460 | } 461 | ], 462 | "source": [ 463 | "res2 = regex.split(\"\\.\\s\", text)\n", 464 | "\n", 465 | "print(res2)" 466 | ] 467 | }, 468 | { 469 | "cell_type": "markdown", 470 | "metadata": { 471 | "colab_type": "text", 472 | "id": "QDGPsfqpW0j4" 473 | }, 474 | "source": [ 475 | "* maxsplit= - опциональный аргумент. \n", 476 | "* Если его указать, то разделение будет произведено не более указанного количества раз" 477 | ] 478 | }, 479 | { 480 | "cell_type": "code", 481 | "execution_count": 40, 482 | "metadata": { 483 | "colab": { 484 | "base_uri": "https://localhost:8080/", 485 | "height": 34 486 | }, 487 | "colab_type": "code", 488 | "id": "PVqvdKnkXNMj", 489 | "outputId": "89793d6d-0903-409a-89e1-dd0b1f4a648c" 490 | }, 491 | "outputs": [ 492 | { 493 | "name": "stdout", 494 | "output_type": "stream", 495 | "text": [ 496 | "['H', 'llo my d', 'ar fri', 'nd Amy.\\nH', 'llo again!']\n" 497 | ] 498 | } 499 | ], 500 | "source": [ 501 | "result = re.split(r'e', text ,maxsplit=5)\n", 502 | "print (result)" 503 | ] 504 | }, 505 | { 506 | "cell_type": "markdown", 507 | "metadata": { 508 | "colab_type": "text", 509 | "id": "QVbO7LXqQpVs" 510 | }, 511 | "source": [ 512 | "## .findall(pattern, string)\n", 513 | "\n", 514 | "возвращает список всех найденных совпадений" 515 | ] 516 | }, 517 | { 518 | "cell_type": "code", 519 | "execution_count": 41, 520 | "metadata": { 521 | "colab": { 522 | "base_uri": "https://localhost:8080/", 523 | "height": 34 524 | }, 525 | "colab_type": "code", 526 | "id": "1l3YV7RDQvuK", 527 | "outputId": "5da50ae8-edc1-4c45-c0f3-aa5ce6da8946" 528 | }, 529 | "outputs": [ 530 | { 531 | "name": "stdout", 532 | "output_type": "stream", 533 | "text": [ 534 | "['my', 'my']\n" 535 | ] 536 | } 537 | ], 538 | "source": [ 539 | "result = re.findall(r'my', text)\n", 540 | "print (result) # обратите внимание, здесь мы не используем .group()\n", 541 | "\n", 542 | "# попробуйте с буквой e или r" 543 | ] 544 | }, 545 | { 546 | "cell_type": "code", 547 | "execution_count": 44, 548 | "metadata": {}, 549 | "outputs": [ 550 | { 551 | "name": "stdout", 552 | "output_type": "stream", 553 | "text": [ 554 | "['my dear friend Amy.']\n" 555 | ] 556 | } 557 | ], 558 | "source": [ 559 | "res2 = regex.findall(r\"m.*\", text)\n", 560 | "\n", 561 | "print(res2)" 562 | ] 563 | }, 564 | { 565 | "cell_type": "markdown", 566 | "metadata": { 567 | "colab_type": "text", 568 | "id": "FBVElU_FT8Hl" 569 | }, 570 | "source": [ 571 | "## .sub(pattern, repl, string)\n", 572 | "\n", 573 | "метод ищет шаблон в строке и заменяет его на указанную подстроку.\n", 574 | "\n", 575 | "Если шаблон не найден, строка остается неизменной." 576 | ] 577 | }, 578 | { 579 | "cell_type": "code", 580 | "execution_count": 45, 581 | "metadata": { 582 | "colab": { 583 | "base_uri": "https://localhost:8080/", 584 | "height": 34 585 | }, 586 | "colab_type": "code", 587 | "id": "kWAvfu_PT2ok", 588 | "outputId": "92f917e0-2b40-48cf-901e-ef7c2358ca82" 589 | }, 590 | "outputs": [ 591 | { 592 | "name": "stdout", 593 | "output_type": "stream", 594 | "text": [ 595 | "Hello my dear friend Jack. Jack smiled.\n" 596 | ] 597 | } 598 | ], 599 | "source": [ 600 | "text = 'Hello my dear friend Amy. Amy smiled.'\n", 601 | "\n", 602 | "result = re.sub(r'Amy','Jack', text ) \n", 603 | "# третьим аргументом может быть не только строка сама по себе, но и переменная, в которую сохранена строка\n", 604 | "\n", 605 | "print (result)" 606 | ] 607 | }, 608 | { 609 | "cell_type": "code", 610 | "execution_count": 50, 611 | "metadata": {}, 612 | "outputs": [ 613 | { 614 | "name": "stdout", 615 | "output_type": "stream", 616 | "text": [ 617 | "Hello my dear friend Alice. Alice smiled.\n" 618 | ] 619 | } 620 | ], 621 | "source": [ 622 | "res2 = regex.sub(r\"Amy\",\"Alice\", text)\n", 623 | "\n", 624 | "\n", 625 | "print(res2)" 626 | ] 627 | }, 628 | { 629 | "cell_type": "markdown", 630 | "metadata": { 631 | "colab_type": "text", 632 | "id": "RKUVRQWKKEZ1" 633 | }, 634 | "source": [ 635 | "# classwork" 636 | ] 637 | }, 638 | { 639 | "cell_type": "markdown", 640 | "metadata": { 641 | "colab_type": "text", 642 | "id": "iAU3H093Zl-M" 643 | }, 644 | "source": [ 645 | "1. (```re.findall```) Напишите регулярное выражение, которое вытаскивало бы все адреса из документа **addresses.txt**\n", 646 | "2. (```re.sub```) Из текта в файле \"морж-корж.txt\" возьмите текст и замените все вхождения слова \"морж\" на слово \"корж\"" 647 | ] 648 | }, 649 | { 650 | "cell_type": "code", 651 | "execution_count": null, 652 | "metadata": {}, 653 | "outputs": [], 654 | "source": [] 655 | } 656 | ], 657 | "metadata": { 658 | "colab": { 659 | "collapsed_sections": [], 660 | "include_colab_link": true, 661 | "name": "13Nov2019.ipynb", 662 | "provenance": [] 663 | }, 664 | "kernelspec": { 665 | "display_name": "Python 3", 666 | "language": "python", 667 | "name": "python3" 668 | }, 669 | "language_info": { 670 | "codemirror_mode": { 671 | "name": "ipython", 672 | "version": 3 673 | }, 674 | "file_extension": ".py", 675 | "mimetype": "text/x-python", 676 | "name": "python", 677 | "nbconvert_exporter": "python", 678 | "pygments_lexer": "ipython3", 679 | "version": "3.8.2" 680 | } 681 | }, 682 | "nbformat": 4, 683 | "nbformat_minor": 4 684 | } 685 | -------------------------------------------------------------------------------- /notebooks/syntax_analysis_DeepPavlov.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "[DeepPavlov](http://docs.deeppavlov.ai/en/0.7.0/index.html) - это библиотека для решения различных NLP-задач от МФТИ, у них есть свой синтаксический анализатор\n", 8 | "\n", 9 | "[документация](http://docs.deeppavlov.ai/en/0.7.0/features/models/syntaxparser.html)\n", 10 | "\n", 11 | "модель выдает результат в CONLL-U формате и обучена на [UD-трибанках](http://universaldependencies.org/format.html)" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": null, 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "# установка (может быть долгой)\n", 21 | "!pip3 install deeppavlov\n", 22 | "!pip3 install russian-tagsets\n", 23 | "!python3 -m deeppavlov install syntax_ru_syntagrus_bert" 24 | ] 25 | }, 26 | { 27 | "cell_type": "code", 28 | "execution_count": null, 29 | "metadata": {}, 30 | "outputs": [], 31 | "source": [ 32 | "import deeppavlov" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": null, 38 | "metadata": {}, 39 | "outputs": [], 40 | "source": [ 41 | "# импортим модель (здесь тоже долго..)\n", 42 | "from deeppavlov import build_model, configs \n", 43 | "dpavlov_model = build_model(\"ru_syntagrus_joint_parsing\", download=True)" 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": null, 49 | "metadata": {}, 50 | "outputs": [], 51 | "source": [ 52 | "sentences = [\"Собянин открыл новый парк и детскую площадку\"]\n", 53 | "#model['main'].to_output_string = False\n", 54 | "#model['main'].output_format = 'dict'\n", 55 | "\n", 56 | "for parse in dpavlov_model(sentences): # аргумент должен быть списком\n", 57 | " print(parse)" 58 | ] 59 | }, 60 | { 61 | "cell_type": "markdown", 62 | "metadata": { 63 | "colab_type": "text", 64 | "id": "fcqE7FFbitjo" 65 | }, 66 | "source": [ 67 | "### шаг3 текст\n", 68 | "\n", 69 | "создадим какой-нибудь небольшой текст, на котором будем тестить модель:\n", 70 | "\n", 71 | " 1\tСобянин\t_\tNOUN\t_\tAnimacy=Anim|Case=Nom|Gender=Masc|Number=Sing|fPOS=NOUN++\t2\tnsubj\t_\t_\n", 72 | " 2\tоткрыл\t_\tVERB\t_\tAspect=Perf|Gender=Masc|Mood=Ind|Number=Sing|Tense=Past|VerbForm=Fin|Voice=Act|fPOS=VERB++\t0\tROOT\t_\t_\n", 73 | " 3\tновый\t_\tADJ\t_\tAnimacy=Inan|Case=Acc|Degree=Pos|Gender=Masc|Number=Sing|fPOS=ADJ++\t4\tamod\t_\t_\n", 74 | " 4\tпарк\t_\tNOUN\t_\tAnimacy=Inan|Case=Acc|Gender=Masc|Number=Sing|fPOS=NOUN++\t2\tdobj\t_\t_\n", 75 | " 5\tи\t_\tCONJ\t_\tfPOS=CONJ++\t4\tcc\t_\t_\n", 76 | " 6\tдетскую\t_\tADJ\t_\tCase=Acc|Degree=Pos|Gender=Fem|Number=Sing|fPOS=ADJ++\t7\tamod\t_\t_\n", 77 | " 7\tплощадку\t_\tNOUN\t_\tAnimacy=Inan|Case=Acc|Gender=Fem|Number=Sing|fPOS=NOUN++\t4\tconj\t_\t_\n", 78 | " 8\t.\t_\tPUNCT\t.\tfPOS=PUNCT++.\t2\tpunct\t_\t_" 79 | ] 80 | }, 81 | { 82 | "cell_type": "markdown", 83 | "metadata": {}, 84 | "source": [ 85 | "## визуализация\n", 86 | "\n", 87 | "В nltk есть DependencyGraph, который умеет рисовать деревья (и ещё многое другое). Для того, чтобы визуализация работала корректно, ему нужна зависимость: graphviz." 88 | ] 89 | }, 90 | { 91 | "cell_type": "code", 92 | "execution_count": null, 93 | "metadata": {}, 94 | "outputs": [], 95 | "source": [ 96 | "# ! pip3 install graphviz\n", 97 | "# ! pip3 install pydot \n", 98 | "# ! brew install graphviz" 99 | ] 100 | }, 101 | { 102 | "cell_type": "markdown", 103 | "metadata": {}, 104 | "source": [ 105 | "Бибилиотеку grapghviz нужно поставить не только через pip, но и добавить в систему ([см этот тред](https://stackoverflow.com/questions/35064304/runtimeerror-make-sure-the-graphviz-executables-are-on-your-systems-path-aft))\n", 106 | "\n", 107 | "Если возникает ошибка, попробуйте следующие команды:\n", 108 | "* (Win) запустите в ячейке код \n", 109 | "```import os\n", 110 | "os.environ[\"PATH\"] += os.pathsep + 'D:/Program Files (x86)/Graphviz2.38/bin/' ```\n", 111 | "\n", 112 | "* (Mac) в терминале: ```brew install graphviz ``` (проверьте, что у Вас стоит [homebrew](https://brew.sh/))\n", 113 | "\n", 114 | "* (Linux) в терминале: ```sudo apt-get install graphviz```" 115 | ] 116 | }, 117 | { 118 | "cell_type": "code", 119 | "execution_count": null, 120 | "metadata": {}, 121 | "outputs": [], 122 | "source": [ 123 | "from nltk import DependencyGraph, Tree \n", 124 | "# вызываем классы, которые нарисуют нам деревья зависимостей" 125 | ] 126 | }, 127 | { 128 | "cell_type": "markdown", 129 | "metadata": {}, 130 | "source": [ 131 | "Для построения дерева нам нужно превратить файл в conllu-формате в список\n", 132 | "
    \n", 133 | "Еще нужно сделать тег ROOT в верхнем регистре, иначе он не находится\n", 134 | "\n", 135 | "Создадим функцию, которую попробуем на результате UDPipe и на результате DeepPavlov" 136 | ] 137 | }, 138 | { 139 | "cell_type": "code", 140 | "execution_count": null, 141 | "metadata": {}, 142 | "outputs": [], 143 | "source": [ 144 | "def conllu_to_list(parser_result): \n", 145 | "# аргумент - это conllu-файл, который получили в результате синтаксического анализа \n", 146 | " sents = []\n", 147 | " for sent in parser_result.split('\\n\\n'):\n", 148 | " # убираем коменты\n", 149 | " sent = '\\n'.join([line for line in sent.split('\\n') if not line.startswith('#')])\n", 150 | " # заменяем регистр для root\n", 151 | " sent = sent.replace('\\troot\\t', '\\tROOT\\t')\n", 152 | " sents.append(sent)\n", 153 | " return sents" 154 | ] 155 | }, 156 | { 157 | "cell_type": "code", 158 | "execution_count": null, 159 | "metadata": {}, 160 | "outputs": [], 161 | "source": [ 162 | "#теперь - применяем к модели deeppavlov\n", 163 | "\n", 164 | "dp = conllu_to_list(dpavlov_model(sentences)[0])" 165 | ] 166 | }, 167 | { 168 | "cell_type": "code", 169 | "execution_count": null, 170 | "metadata": {}, 171 | "outputs": [], 172 | "source": [ 173 | "dp[0]" 174 | ] 175 | }, 176 | { 177 | "cell_type": "code", 178 | "execution_count": null, 179 | "metadata": {}, 180 | "outputs": [], 181 | "source": [ 182 | "# нарисуем граф для DeepPavlov\n", 183 | "dp_graph = DependencyGraph(tree_str=dp[0])\n", 184 | "dp_graph" 185 | ] 186 | }, 187 | { 188 | "cell_type": "code", 189 | "execution_count": null, 190 | "metadata": {}, 191 | "outputs": [], 192 | "source": [ 193 | "# дерево для DeepPavlov\n", 194 | "dp_tree = dp_graph.tree()\n", 195 | "print(dp_tree.pretty_print())" 196 | ] 197 | }, 198 | { 199 | "cell_type": "code", 200 | "execution_count": null, 201 | "metadata": {}, 202 | "outputs": [], 203 | "source": [ 204 | "# посмотрим как можно разбить предложение\n", 205 | "list(dp_graph.triples())" 206 | ] 207 | }, 208 | { 209 | "cell_type": "markdown", 210 | "metadata": {}, 211 | "source": [ 212 | "### Тройки глагол-объект-субьект:\n", 213 | "Предположим, нам нужно вытащить только ту тройку, которая расскажет о предикате (сказуемом), субъекте (подлежащем) и объекте (дополнении)" 214 | ] 215 | }, 216 | { 217 | "cell_type": "code", 218 | "execution_count": null, 219 | "metadata": {}, 220 | "outputs": [], 221 | "source": [ 222 | "def get_sov(sent): # зададим функцию, которая будет вытаскивать нужную тройку\n", 223 | " dp_graph = DependencyGraph(tree_str=dp[0]) \n", 224 | " sov = {} # пустой словарь, будем в него складывать\n", 225 | " for triple in graph.triples(): # для каждого триплета из всех\n", 226 | " if triple:\n", 227 | " if triple[0][1] == 'VERB': # если тег первого элемента - VERB\n", 228 | " sov[triple[0][0]] = {'subj':'','obj':''}\n", 229 | " for triple in graph.triples():\n", 230 | " if triple:\n", 231 | " if triple[1] == 'nsubj':\n", 232 | " if triple[0][1] == 'VERB':\n", 233 | " sov[triple[0][0]]['subj'] = triple[2][0]\n", 234 | " if triple[1] == 'obj':\n", 235 | " if triple[0][1] == 'VERB':\n", 236 | " sov[triple[0][0]]['obj'] = triple[2][0]\n", 237 | " return sov\n", 238 | "\n", 239 | "sov = get_sov(sent)\n", 240 | "print(sov)" 241 | ] 242 | }, 243 | { 244 | "cell_type": "markdown", 245 | "metadata": {}, 246 | "source": [ 247 | "улучшим функцию, теперь она находит однородные дополнения *(парк и площадку)*" 248 | ] 249 | }, 250 | { 251 | "cell_type": "code", 252 | "execution_count": null, 253 | "metadata": {}, 254 | "outputs": [], 255 | "source": [ 256 | "from collections import defaultdict as dd\n", 257 | "\n", 258 | "\n", 259 | "def get_sov(sent):\n", 260 | " graph = DependencyGraph(tree_str=dp[0])\n", 261 | "\n", 262 | " subjects = dd(lambda : {\"subject\": \"\", \"verb\": \"\", \"objects\": []})\n", 263 | " verbs = dd(lambda : {\"subject\": \"\", \"verb\": \"\", \"objects\": []})\n", 264 | " \n", 265 | " for triple in graph.triples():\n", 266 | " if triple:\n", 267 | " \n", 268 | " if triple[1] == 'conj':\n", 269 | " subjects[triple[0][0]][\"objects\"].append(triple[2][0])\n", 270 | " \n", 271 | " if triple[1] == 'nsubj':\n", 272 | " if triple[0][1] == 'VERB':\n", 273 | " verbs[triple[0][0]][\"subject\"] = triple[2][0]\n", 274 | " if triple[1] == 'obj':\n", 275 | " if triple[0][1] == 'VERB':\n", 276 | " subjects[triple[2][0]][\"verb\"] = triple[0][0]\n", 277 | " subjects[triple[2][0]][\"objects\"].append(triple[2][0])\n", 278 | "\n", 279 | " \n", 280 | " sovs = []\n", 281 | "\n", 282 | " print(subjects, verbs)\n", 283 | " \n", 284 | " for v in subjects.values():\n", 285 | " for obj in v[\"objects\"]:\n", 286 | " sovs.append((verbs[v[\"verb\"]][\"subject\"], v[\"verb\"], obj))\n", 287 | " return sovs\n", 288 | "\n", 289 | "sov = get_sov(sent)\n", 290 | "print(\"\\n\",sov[-2:])" 291 | ] 292 | } 293 | ], 294 | "metadata": { 295 | "kernelspec": { 296 | "display_name": "Python 3", 297 | "language": "python", 298 | "name": "python3" 299 | }, 300 | "language_info": { 301 | "codemirror_mode": { 302 | "name": "ipython", 303 | "version": 3 304 | }, 305 | "file_extension": ".py", 306 | "mimetype": "text/x-python", 307 | "name": "python", 308 | "nbconvert_exporter": "python", 309 | "pygments_lexer": "ipython3", 310 | "version": "3.8.2" 311 | } 312 | }, 313 | "nbformat": 4, 314 | "nbformat_minor": 4 315 | } 316 | -------------------------------------------------------------------------------- /practice/func-practice.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": { 13 | "colab_type": "text", 14 | "id": "ylixGHVOvAqB" 15 | }, 16 | "source": [ 17 | "## Classwork\n", 18 | "\n", 19 | "*Сделайте одну задачу на выбор. Выполнение больше одной приветствуется*" 20 | ] 21 | }, 22 | { 23 | "cell_type": "markdown", 24 | "metadata": { 25 | "colab_type": "text", 26 | "id": "WbpgWXdHvgV8" 27 | }, 28 | "source": [ 29 | "**Задача 1.** Напишите генератор названий компаний (почти как генератор паролей). \n", 30 | "Пусть в названии компании будет 6 частей, рандомно выбирающихся из списка names.\n", 31 | "\n", 32 | "Сделайте это функцией" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": null, 38 | "metadata": { 39 | "colab": { 40 | "base_uri": "https://localhost:8080/", 41 | "height": 34 42 | }, 43 | "colab_type": "code", 44 | "id": "lIwa6cOqvcTs", 45 | "outputId": "9ab23b6b-f4ce-4597-ec6c-88c3f1d29ff8" 46 | }, 47 | "outputs": [], 48 | "source": [ 49 | "# генератор названий компаний\n", 50 | "\n", 51 | "import random\n", 52 | "\n", 53 | "names = [\"пром\",\"агро\",\"торг\",\"урал\",\"север\",\"юг\",\"техно\",\n", 54 | "\"экспо\",\"метал\",\"нефть\",\"сельхоз\",\"фарм\",\"строй\",\n", 55 | "\"кредит\",\"алмаз\",\"-девелопмент\",\"развитие\",\"мос\",\n", 56 | "\"рос\",\"кубань\",\"сибирь\",\"восток\",\"нано\",\"софт\",\n", 57 | "\"микро\",\"онлайн\",\"инвест\",\"текстиль\",\"цемент\"]\n", 58 | "\n", 59 | "# Ваш код ниже\n", 60 | "\n" 61 | ] 62 | }, 63 | { 64 | "cell_type": "markdown", 65 | "metadata": {}, 66 | "source": [ 67 | "**Задача 2.** Генератор паролей\n", 68 | "\n", 69 | "Пароли, получаемые в результате, должны удовлетворять следующим условиям: \n", 70 | "\n", 71 | " - в пароле есть 3 заглавные буквы (любые, в любом месте пароля)\n", 72 | " - в пароле есть 4 цифры (любые, в любом месте)\n", 73 | " - оставшиеся символы пароля - строчные латинские буквы\n", 74 | " \n", 75 | "Создайте функцию, которая генерирует пароли, пользователь задает число символов в пароле (как аргумент функции)" 76 | ] 77 | }, 78 | { 79 | "cell_type": "code", 80 | "execution_count": null, 81 | "metadata": { 82 | "colab": {}, 83 | "colab_type": "code", 84 | "id": "Mm3FYaIJ99GJ" 85 | }, 86 | "outputs": [], 87 | "source": [] 88 | } 89 | ], 90 | "metadata": { 91 | "kernelspec": { 92 | "display_name": "Python 3 (ipykernel)", 93 | "language": "python", 94 | "name": "python3" 95 | }, 96 | "language_info": { 97 | "codemirror_mode": { 98 | "name": "ipython", 99 | "version": 3 100 | }, 101 | "file_extension": ".py", 102 | "mimetype": "text/x-python", 103 | "name": "python", 104 | "nbconvert_exporter": "python", 105 | "pygments_lexer": "ipython3", 106 | "version": "3.10.0" 107 | } 108 | }, 109 | "nbformat": 4, 110 | "nbformat_minor": 4 111 | } 112 | -------------------------------------------------------------------------------- /practice/Отзывы_к_фильмам.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "colab_type": "text", 7 | "id": "Sl2iWnGs23DL" 8 | }, 9 | "source": [ 10 | "### Тренировочная задача\n", 11 | "\n", 12 | "\n", 13 | "Определяем лучшего писателя отзывов. \n", 14 | "У вас есть четрые отзыва на фильм С.Кубрика \"Сияние\". Вам нужно определить, кто из авторов отзывов написал отзыв с наибольшим количеством уникальных слов.\n", 15 | " \n", 16 | " Для определения вам нужно: (для каждого автора)\n", 17 | "\n", 18 | " 1. Предобработать строку (см методы строк), сведя все к нижнему регистру, убрать пунктуацию.\n", 19 | "\n", 20 | " 2. Превратить строку в список \n", 21 | " 3. Оставить уникальные элементы в списке (превратить список во множество)\n", 22 | " 4. Определить размер такого множества\n", 23 | " \n", 24 | "У кого из авторов количество уникальных слов наибольшее?\n", 25 | "\n" 26 | ] 27 | }, 28 | { 29 | "cell_type": "code", 30 | "execution_count": 2, 31 | "metadata": { 32 | "colab": {}, 33 | "colab_type": "code", 34 | "id": "j5Nv1se228QQ" 35 | }, 36 | "outputs": [], 37 | "source": [ 38 | "paul = \"\"\"When this film first came out in 1980, I remember going to see it on opening night. This movie just scared the life out of me, which is what still happens every time\n", 39 | "I rent the video for a re-watch.I have seen The Shining at least six or seven times, and I still believe it to be simultaneously and paradoxically one of the most frightening and yet funniest films I've ever seen. Frightening because of the extraordinarily effective use of long shots to create feelings of isolation, convex lens shots to enhance surrealism, and meticulously scored music to bring tension levels to virtually unbearable levels. And \\\"funny\\\" because of Jack Nicholson's outrageous and in many cases ad-libbed onscreen antics. It never ceases to amaze me how The Shining is actually two films in one, both a comedy AND a horror flick. Ghostly apparitions of a strikingly menacing nature haunt much of the first half of the film, which gradually evolve into ever more serious physical threats as time progresses. Be that as it may, there is surprisingly little violence given the apparent intensity, but that is little comfort \n", 40 | "for the feint of heart as much of the terror is more implied than manifest. The Shining is a truly frightening movie that works symbolically on many levels, but is basically about human shortcomings and the way they can be exploited by unconscious forces combined with weakness of will. This film scares the most just by using suggestion to turn your own imagination against you. The Shining is a brilliant cinematic masterpiece, the likes of which have never been seen before or since. Highly, highly recommended.\"\"\"\n", 41 | "\n", 42 | "jane = \"\"\"Chilling, majestic piece of cinematic fright, this film combines all the great elements of an intellectual thriller, with the grand vision of a director who has the instinctual capacity to pace a moody horror flick within the realm of his filmmaking genius that includes an eye for the original shot, an ice-cold soundtrack and an overall sense of dehumanization. This movie cuts through all the typical horror\n", 43 | "movies like a red-poker through a human eye, as it allows the viewer to not only feel the violence and psychosis of its protagonist, but appreciate the seed from which the derangement stems. One of the scariest things for people\n", 44 | "to face is the unknown and this film presents its plotting with just that thought in mind. The setting is perfect, in a desolate winter hideaway. The quietness of the moment is a character in itself, as the fermenting aggressor in Jack Torrance's mind wallows in this idle time, and breeds the devil's new playground. I always felt like the presence of evil was dormant in all of our minds, with only the circumstances of the moment, and the reasons given therein, needed to wake its violent ass and pounce over its unsuspecting victims. This film is a perfect example of this very thought.\"\"\"\n", 45 | "\n", 46 | "kate = \"\"\"What can I say about the scariest movie I have ever seen that has not already been said by others more articulate than yours truly? Do not view this film expecting to see a screen version of the Stephen King novel.\n", 47 | "Rather, this is a Stanley Kubrick film, and to fully appreciate it one should judge it within the context of Kubrick's entire body of work as a serious filmmaker. Thematically, THE SHINING relates most closely to 2001:\n", 48 | "A SPACE ODYSSEY, though flourishes of PATHS OF GLORY, A CLOCKWORK ORANGE and BARRY LYNDON do manage to figure prominently in the film's overall technique. In a nutshell (no pun intended), Jack Nicholson and Shelly Duvall co-star with Oregon's Timberline Lodge - enlisted to portray the exterior of the Overlook Hotel - in a story that appears on the surface to be about ghosts and insanity, but deals with issues of child abuse, \n", 49 | "immortality and duality. What the film might lack initially in terms of coherence is more than made up for in technique. Garrett Brown (the male voice in those old Molson Golden commercials), inventor of the Steadicam,chases young Danny Lloyd through hotel corridors and an amazing snow maze, providing magic-carpet-ride fluidity to scenes that ten years earlier would have been impossible to accomplish. If the film starts off too slow, remember who the director is. This man likes to take his time, and the results are well worth it: incredible aerial shots of the Overlook Hotel; horrific Diane Arbus-inspired twins staring directly at us; portentous room 237 and its treasure trove of terrible secrets; elevators that gush rivers of blood in slow-motion; Jack Torrance's immortality found via the hotel (akin to David Bowman's journey through the Space Gate); and some of the best use of pre-existing music ever assembled for a motion picture.\"\"\"\n", 50 | "\n", 51 | "\n", 52 | "nick = \"\"\"I was never a big fan of horror movies. They usually try cheap tricks to scare their audiences like loud noises and creepy children. They usually lack originality and contain overacting galore. The only horror movie i\n", 53 | "like was Stir of Echoes with Kevin Bacon. It was well-acted, and had a great story. But it has been joined and maybe even surpassed by Stanley Kubrick's The Shining, quite possibly the scariest movie ever. The movie follows a writer (Jack Nicholson) and his family who agree to watch over a hotel while it is closed for the winter. There were rumors of the place being haunted and the last resident went crazy and murdered his family. But Jack is convinced it will be OK and he can use the quiet to overcome his writer's block. After months of solitude and silence however, Jack becomes a grumpy and later violent. Is it cabin fever or is there something in the hotel that is driving him mad? One of the creepiest parts about the movie is the feeling of isolation that Kubrick makes. The hotel is very silent, and the rooms are huge, yet always empty. It is also eerily calm when Jack's son is riding his bike through the barren hallways. Jack Nicholson's performance is also one of his very best, scaring the hell out of me and making me sure to get out once in awhile. My favorite scene is when he is talking to a ghost from inside a walk-in refrigerator. The Shining is tops for horror movies in my opinion, beating the snot out of crap like the Ring and The Blair Witch Project. It may be a oldie, but is definitely a goodie.\"\"\"" 54 | ] 55 | }, 56 | { 57 | "cell_type": "code", 58 | "execution_count": 2, 59 | "metadata": {}, 60 | "outputs": [ 61 | { 62 | "name": "stdout", 63 | "output_type": "stream", 64 | "text": [ 65 | "Long lowset dogs with sturdy bone short legs and a deep chest Cardigans are powerful workers of deceptive speed and grace\n" 66 | ] 67 | } 68 | ], 69 | "source": [ 70 | "# Подсказка: как быстро убрать всю пунктуацию из текста\n", 71 | "\n", 72 | "import string\n", 73 | "\n", 74 | "test = \"Long, low-set dogs with sturdy bone, short legs, and a deep chest, Cardigans are powerful workers of deceptive speed and grace.\"\n", 75 | "\n", 76 | "test_clean = test.translate(str.maketrans(\"\",\"\",string.punctuation))\n", 77 | "print(test_clean)\n", 78 | "\n", 79 | "# подробнее о методе .maketrans()\n", 80 | "# https://www.w3schools.com/python/ref_string_maketrans.asp " 81 | ] 82 | }, 83 | { 84 | "cell_type": "markdown", 85 | "metadata": {}, 86 | "source": [ 87 | "**Как это работает?**\n", 88 | "\n", 89 | "Метод ```.maketrans()``` имеет три аргумента и создает таблицу перевода:\n", 90 | "- какие символы переводить (первый аргумент)\n", 91 | "- **в** какие переводить (второй аргумент)\n", 92 | "- какие символы удалять (третий аргумент)\n", 93 | "\n", 94 | "Метод ```.translate()``` использует таблицу перевода, чтобы превратить символы в новые символы. \n", 95 | "\n", 96 | "В нашем случае, в методе ```.maketrans()``` первые два аргумента мы оставляем пустыми (ничто переводится в ничто), а аргумент для удаления определяем как строку ```punctuation```, в которой содержатся все символы пунктуации.\n", 97 | "\n", 98 | "Именно это удалит пунктуацию, но не затронет остальные символы в строке.\n", 99 | "\n", 100 | "\n", 101 | "[Подробнее о методе ```.maketrans()```](https://www.w3schools.com/python/ref_string_maketrans.asp) " 102 | ] 103 | }, 104 | { 105 | "cell_type": "code", 106 | "execution_count": null, 107 | "metadata": {}, 108 | "outputs": [], 109 | "source": [] 110 | } 111 | ], 112 | "metadata": { 113 | "kernelspec": { 114 | "display_name": "Python 3 (ipykernel)", 115 | "language": "python", 116 | "name": "python3" 117 | }, 118 | "language_info": { 119 | "codemirror_mode": { 120 | "name": "ipython", 121 | "version": 3 122 | }, 123 | "file_extension": ".py", 124 | "mimetype": "text/x-python", 125 | "name": "python", 126 | "nbconvert_exporter": "python", 127 | "pygments_lexer": "ipython3", 128 | "version": "3.10.0" 129 | } 130 | }, 131 | "nbformat": 4, 132 | "nbformat_minor": 4 133 | } 134 | -------------------------------------------------------------------------------- /slides/Pandas_Cheat_Sheet.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anklowait/python_for_CL/685d52838288001606f2635637b603b008cef537/slides/Pandas_Cheat_Sheet.pdf -------------------------------------------------------------------------------- /slides/Python & Git - лекция1 (2021).pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anklowait/python_for_CL/685d52838288001606f2635637b603b008cef537/slides/Python & Git - лекция1 (2021).pdf -------------------------------------------------------------------------------- /slides/git_instruction.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anklowait/python_for_CL/685d52838288001606f2635637b603b008cef537/slides/git_instruction.pdf --------------------------------------------------------------------------------