<?xml version="1.0" encoding="utf-8" ?><rss version="2.0" xmlns:tt="http://teletype.in/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>Python Academy</title><generator>teletype.in</generator><description><![CDATA[Python Academy — один канал вместо тысячи учебников]]></description><image><url>https://teletype.in/files/21/be/21be2c3b-cc3e-498e-b7cb-42be9e7287ba.jpeg</url><title>Python Academy</title><link>https://teletype.in/@python_academy</link></image><link>https://teletype.in/@python_academy?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=python_academy</link><atom:link rel="self" type="application/rss+xml" href="https://teletype.in/rss/python_academy?offset=0"></atom:link><atom:link rel="next" type="application/rss+xml" href="https://teletype.in/rss/python_academy?offset=10"></atom:link><atom:link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></atom:link><pubDate>Thu, 23 Apr 2026 08:07:17 GMT</pubDate><lastBuildDate>Thu, 23 Apr 2026 08:07:17 GMT</lastBuildDate><item><guid isPermaLink="true">https://teletype.in/@python_academy/ar4hqEA5w4L</guid><link>https://teletype.in/@python_academy/ar4hqEA5w4L?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=python_academy</link><comments>https://teletype.in/@python_academy/ar4hqEA5w4L?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=python_academy#comments</comments><dc:creator>python_academy</dc:creator><title>Области применения Python: что изучать начинающему</title><pubDate>Fri, 04 Jun 2021 18:26:30 GMT</pubDate><category>Python programming</category><description><![CDATA[<img src="https://teletype.in/files/19/c0/19c053c7-3b91-4167-8864-a6bb1d78a1a7.png"></img>Python — один из самых универсальных языков: его используют в своих продуктах топовые IT-компании, включая Microsoft, Google, Facebook и Yandex. В то же время Python часто выбирают новички, потому что язык имеет простой синтаксис и в целом лаконичен.]]></description><content:encoded><![CDATA[
  <figure class="m_column">
    <img src="https://teletype.in/files/19/c0/19c053c7-3b91-4167-8864-a6bb1d78a1a7.png" width="3600" />
  </figure>
  <p>Python — один из самых универсальных языков: его используют в своих продуктах топовые IT-компании, включая Microsoft, Google, Facebook и Yandex. В то же время Python часто выбирают новички, потому что язык имеет простой синтаксис и в целом лаконичен.</p>
  <p>В этой статье мы объясним, в каких сферах стоит начинать обучение и использовать Python в целом. А также покажем <strong>бесплатные ресурсы</strong>, где лучше всего приступить к обучению языка, фреймворков и всего остальное.</p>
  <p>Но для начала покажем статистику роста популярности Python, чтобы у вас отпали все сомнения насчет этого языка:</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/d1/d16946bd-59bd-4de3-9bc3-79695d0b65b5.png" width="1024" />
  </figure>
  <h2>Web Разработка</h2>
  <p>Python может с успехом похвастаться своими backend-фреймворками, в частности <em>Django</em> и <em>Flask</em>. Они сильно облегчают процесс написания кода серверной части приложений: с их помощью упрощается процесс обработки адресов, обращение к базам данный и создание страниц, отображающихся у пользователей.</p>
  <p>К тому же, количество вакансий для backend разработчиков, владеющих одним из этих двух фреймворков, стремительно растёт. Если ваша цель устроиться на работу программистом как можно скорее, то Python и Django — однозначно ваш выбор.</p>
  <p><strong>Ресурсы для изучения:</strong></p>
  <p><a href="https://www.djangoproject.com" target="_blank">Официальная документация Django</a> — если вы решились изучать Django, то начните с официальной документации. У этого фреймворка она написана удивительно хорошо.</p>
  <p><a href="https://tutorial.djangogirls.org/ru/" target="_blank">Django Girls</a> — этот онлайн-учебник является выбором большинства начинающих. Изначально сайт позиционировался как платформа с туториалами для женского пола, но сейчас от концепта осталось только название.</p>
  <p><a href="https://habr.com/ru/post/346306/" target="_blank">Мега-учебник по Flask</a> — онлайн-учебник Мигеля Гринберга всегда был мастхэв ресурсов для тех, кто изучал Flask. И вот на Хабре сделали полный перевод всех его туториалов.</p>
  <p><a href="https://www.youtube.com/user/zaemiel/playlists" target="_blank">Канал Олега Молчанова </a>— одних из лучших авторов по Python на русскоязычном YouTube. У него на канале есть плейлисты и по Flask, и по Django, в которых сразу начинается создание практических проектов.</p>
  <h2><strong>Машинное обучение</strong></h2>
  <p>В Python есть разнообразные модули, позволяющие быстро создавать производительные скрипты в области машинного обучения. Например, <em>Scikit-learn</em> отличается тем, что в него уже встроены самые распространенные алгоритмы обучения. <em>TensorFlow,</em> в свою очередь — это низкоуровневая библиотека, которая открывает возможности для создания алгоритмов пользователя.</p>
  <p>Процессы машинного обучения, основанные на языке программирования Python, помогают реализовывать системы распознавания лиц и голоса, создавать нейронные сети, глубокое обучение и многое другое.</p>
  <p><strong>Ресурсы для изучения:</strong></p>
  <p><a href="https://www.coursera.org/learn/vvedenie-mashinnoe-obuchenie" target="_blank">Введение в машинное обучение</a> — совместный курс от ВШЭ и Школы Анализа Данных от Яндекса. Один из лучших вариантов на русском языке.</p>
  <p><a href="https://www.coursera.org/learn/machine-learning?utm_source=linkshare&siteID=EBOQAYvGY4A-YmLPEZpLj.38BDvlgur7Ow&ranEAID=EBOQAYvGY4A&utm_content=3&ranMID=40328&ranSiteID=EBOQAYvGY4A-YmLPEZpLj.38BDvlgur7Ow&utm_campaign=EBOQAYvGY4A&utm_medium=partners" target="_blank">Машинное обучение от Andrew Ng</a> — полный курс по ML от ведущего преподавателя из Стэнфорда, отличный вариантов для новичков. Кстати, на этот курс записались уже более 4 миллионов человек.</p>
  <p><a href="https://www.coursera.org/specializations/deep-learning" target="_blank">Глубокое обучение от Andrew Ng</a> — курс от того же топового преподавателя, но уже конкретно по глубокому обучению, а не ML в целом.</p>
  <h2>Анализ данных</h2>
  <p>Решения в сфере Big Data и Business Analytic приносят сотни миллиардов каждый год, и доходы постоянно растет. А популярность отрасли постоянно растет. В 2015 только 17% компаний использовали возможности аналитики Big Data, а в 2017 это значение выросло до 53%.</p>
  <p>Сбор, обработка и визуализация — 3 самых популярных сценария использования Python для анализа данных.</p>
  <p><strong>Ресурсы для изучения:</strong></p>
  <p><a href="https://www.khanacademy.org/math/statistics-probability" target="_blank">Статистика и вероятность</a> — мастхэв курс от Khan Academy, который даст весь необходимый теоретический минимум.</p>
  <p><a href="https://www.coursera.org/learn/mathematics-and-python?specialization=machine-learning-data-analysis" target="_blank">Математика и Python для анализа данных</a> — хороший вводный курс от МФТИ и Яндекса, в котором будут разбираться необходимая математика и инструменты для работы с данными.</p>
  <p><a href="https://www.udacity.com/course/intro-to-relational-databases--ud197" target="_blank">Введение в реляционные базы данных</a> — курс от Udacity дает краткое, но вполне достаточное для начала работы представление о базах данных, подобных SQL.</p>
  <h2>Заключение</h2>
  <p>Мы рассмотрели только 3 основные области применения Python, но их намного больше, так как этот язык можно использовать практически везде. Также стоило рассказать про автоматизацию задач, но это уже тема для отдельной статьи.</p>
  <p>Однако далеко не всегда использование Python оправдано: например, в разработке графических интерфейсов, компьютерных игр и мобильных приложений Python точно будет не лучшим выбором.</p>
  <p>Подводя итоги, можно сказать, что Django — лучший вариант для быстрого устройства на работу. А сферы Machine Learning и Data Science хороши в долгосрочной перспективе.</p>
  <hr />
  <p>Статья написана<a href="https://t.me/python_academy" target="_blank"> Python Academy</a></p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@python_academy/first-steps</guid><link>https://teletype.in/@python_academy/first-steps?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=python_academy</link><comments>https://teletype.in/@python_academy/first-steps?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=python_academy#comments</comments><dc:creator>python_academy</dc:creator><title>Первые шаги в Python</title><pubDate>Tue, 23 Feb 2021 03:26:03 GMT</pubDate><media:content medium="image" url="https://teletype.in/files/65/70/6570ca4f-d254-4944-a95b-a69770066b6b.png"></media:content><category>Python programming</category><description><![CDATA[<img src="https://teletype.in/files/ca/bf/cabf14e0-fc21-4b51-b864-6c0ac4364c37.png"></img>Универсальная подборка ресурсов для изучения Python с нуля. Начать с книги, YouTube или онлайн-курса – выбор ваш. Самое важное – начать с чего-то.]]></description><content:encoded><![CDATA[
  <figure class="m_column">
    <img src="https://teletype.in/files/ca/bf/cabf14e0-fc21-4b51-b864-6c0ac4364c37.png" width="4800" />
  </figure>
  <p>Универсальная подборка ресурсов для изучения Python с нуля. Начать с книги, YouTube или онлайн-курса – выбор ваш. Самое важное – начать с чего-то.</p>
  <h3>Книги для изучения</h3>
  <p><a href="https://t.me/probooks404/16" target="_blank">«Изучаем Python»</a> от Марка Лутца – это учебник, написанный понятным языком для программистов с разным уровнем подготовки.</p>
  <p><a href="https://t.me/probooks404/11" target="_blank">«Глубокое обучение на Python»</a> от Франсуа Шолле – столь сложную тему, как глубокое обучение, лучше изучать с помощью этой книги Python.</p>
  <p><a href="https://t.me/probooks404/15" target="_blank">«Изучаем Python. Программирование игр и веб-приложения»</a> от Эрика Мэтиза – из этой книги вы узнаете, как создавать игры, визуализировать данные и научитесь создавать веб-приложения на Django.</p>
  <h3>Youtube каналы</h3>
  <p><a href="https://www.youtube.com/user/PlurrimiTube" target="_blank">Гоша Дударь</a> – канал не только о Python, но и о других языках. Весь материал разжёвывается достаточно для понимания, даже если у вас нулевой уровень знаний. </p>
  <p><a href="https://www.youtube.com/user/zaemiel" target="_blank">Олег Молчанов</a> – самое качественное, что есть на русскоязычном YouTube про Python. На канале есть плейлисты по Django, Flask, асинхронности, веб-парсингу и многому другому.</p>
  <p><a href="https://www.youtube.com/user/moscowdjangoru/featured" target="_blank">Moscow Python</a> – записи конференций и митапов про более продвинутые темы. Сообщество активно сотрудничает с такими компаниями, как Mail.Ru Group, Rambler, Яндекс и другими.</p>
  <h3>Бесплатные курсы</h3>
  <p><a href="https://www.coursera.org/learn/mathematics-and-python?ranMID=40328&ranEAID=ve4RjaCbdEQ&ranSiteID=ve4RjaCbdEQ-MZp5t20hs9zn8MD1MF03vA&siteID=ve4RjaCbdEQ-MZp5t20hs9zn8MD1MF03vA&utm_content=10&utm_medium=partners&utm_source=linkshare&utm_campaign=ve4RjaCbdEQ" target="_blank">Математика и Python для анализа данных</a> – совместный курс от МФТИ и Яндекс на Coursera для изучения языка. Вы также получите знания для анализа данных.</p>
  <p><a href="https://stepik.org/course/67/promo" target="_blank">Stepik</a> – один из самых популярных курсов по Python, в котором вы познакомитесь с базовыми понятиями программирования.</p>
  <p><a href="https://www.codecademy.com/learn/python" target="_blank">Code Academy</a> –бесплатный учебный ресурс для изучения программирования. На этой платформе вы найдете уроки по самым разным языкам, не только по Python.</p>
  <h3>Сайты для практики</h3>
  <p><a href="http://www.codewars.com" target="_blank">Codewars</a> – задачи по написанию кода организованы по типу боевых искусств, каждая задача называется ката.</p>
  <p><a href="https://leetcode.com" target="_blank">LeetCode</a> – подготовка к техническим интервью является основным направлением этого ресурса.</p>
  <p><a href="http://projecteuler.net" target="_blank">Project Euler</a> – ветеран среди подобных платформ. Простой сайт, чтобы быстро начать практиковаться.</p>
  <h3>Другое</h3>
  <p><a href="http://pythonworld.ru" target="_blank">Python World</a> – cамоучитель по Python. Отлично подходит для изучения конкретных тем в программировании.</p>
  <p><a href="https://realpython.com" target="_blank">Real Python</a> – премиальный онлайн-курс. На сайте есть много отличных статей, которые можно читать совершенно бесплатно.</p>
  <hr />
  <p>Статья подготовлена образовательной организацией <a href="https://t.me/python_academy" target="_blank">Python Academy</a>.</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@python_academy/J5J5mioH7</guid><link>https://teletype.in/@python_academy/J5J5mioH7?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=python_academy</link><comments>https://teletype.in/@python_academy/J5J5mioH7?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=python_academy#comments</comments><dc:creator>python_academy</dc:creator><title>Градиентный спуск: просто о сложном</title><pubDate>Wed, 24 Jun 2020 13:36:26 GMT</pubDate><media:content medium="image" url="https://teletype.in/files/90/a0/90a08fd7-48f1-4e50-9bda-74f0a729b498.png"></media:content><description><![CDATA[<img src="https://teletype.in/files/7f/f4/7ff4ff22-1fc8-4363-9a87-dc98e32260a9.png"></img>Одним из самых часто используемых алгоритмов в машинном обучении является градиентный спуск, он применяется практически в каждой модели обучения. По своей сути, градиентный спуск это и есть то, как обучается любая модель машинного обучения. Метод градиентного спуска (с некоторой модификацией) широко используется для обучения глубоких нейронных сетей, и известен как метод обратного распространения ошибки.]]></description><content:encoded><![CDATA[
  <figure class="m_column">
    <img src="https://teletype.in/files/7f/f4/7ff4ff22-1fc8-4363-9a87-dc98e32260a9.png" width="5880" />
  </figure>
  <p>Одним из самых часто используемых алгоритмов в машинном обучении является градиентный спуск, он применяется практически в каждой модели обучения. По своей сути, градиентный спуск это и есть то, как обучается любая модель машинного обучения. Метод градиентного спуска (с некоторой модификацией) широко используется для обучения глубоких нейронных сетей, и известен как метод обратного распространения ошибки.</p>
  <p>В данной статье мы поставим все точки над i в вопросе о градиентном спуске.</p>
  <hr />
  <h1>Что такое градиент</h1>
  <p>Начнем с самых базовых понятий о производных. По сути производная есть тангенс угла наклона касательной (да, она как бы касается графика) к графику в точке, в которой вы ее вычисляете. А поскольку производная в точках минимума (и максимума тоже) всегда обращается в нуль (касательная просто становится параллельна оси ОХ), этот принципе часто используют в задачах оптимизации, или поиска минимального значения. На картинке ниже приведен очень простой пример графика, назовем его графиком функции потерь (или loss function, не будем подробно останавливаться на этом сейчас, это не столь важно). Здесь функция <code>f(x)</code> имеет минимум в точке <code>x = 0</code>, а касательные, построенные в точках <code>x0 = 0, 0.4, 0.6</code>, указывают направление, в котором стоит двигаться, если нужно отыскать минимум (ну или просто наклон функции, чем он меньше, тем мы ближе к локальному минимуму! Как мы видим, касательная функции в точке <code>x = 0</code> проходит точно параллельно оси ОХ, что и подтверждает нашу первоначальную гипотезу о минимуме в этой точке.</p>
  <figure class="m_original">
    <img src="https://teletype.in/files/98/7d/987dd4b7-9109-46ac-b471-ac369b7a3598.png" width="640" />
  </figure>
  <blockquote>Возможно вы уже были знакомы с понятием производной, тогда в принципе градиент не будет чем то новым для вас.</blockquote>
  <p>Если говорить очень упрощенно, то градиент в одномерном случае и есть та самая производная от функции, о которой мы рассуждали выше. Но вообще говоря производная не имеет направления. А градиент должен его иметь, потому что градиент – это вектор. В данном случае все очень просто: направление градиента совпадает с направлением движения касательных, влево или вправо по оси ОХ.</p>
  <blockquote>Кстати, градиент какой-либо функции f в математике обычно обозначают таким забавным значком перевернутого треугольника – ∇f.</blockquote>
  <p>Разумеется, в реальных задачах все чуточку сложнее, и функции будут зависеть не от одной переменной, а например от двух (или более), как эта двумерная поверхность, по сути являющаяся трехмерной параболой.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/81/43/81438504-9678-4d6a-87fc-f09ad1f9ce81.png" width="2880" />
  </figure>
  <p>Но основная идея останется та же самая – для того, чтобы отыскать минимум, нужно двигаться в сторону наискорейшего убывания функции (там где наклон становится очень маленьким), а значит, нужно уметь работать с градиентом.</p>
  <h1><strong>Что такое градиентный спуск</strong></h1>
  <p>Градиентный спуск – это метод нахождения минимального значения функции многих переменных. Такие методы еще иногда называют оптимизацией. Минимизация любой такой функции означает поиск самой глубокой впадины. Например, как видно на графике выше, если начать &quot;скатываться&quot; по стенкам этой параболы, то мы неизбежно достигнем локального минимума в точке 0.</p>
  <p>А поиск минимума в контексте машинного обучения всегда означает попытку получения наименьшей возможной ошибки ну или повышение точности модели. Точность можно увеличить, перебирая набор учебных данных при настройке конкретных параметров модели (весов и смещений).</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/87/e3/87e32ddd-236a-4754-92dd-d34a10dab065.png" width="1106" />
  </figure>
  <p>Как же все таки это работает? Известно, что градиент является направлением наискорейшего роста функции, а градиент со знаком минус (назовем его &quot;антиградиент&quot;) – направлением наискорейшего убывания. Это ключевое свойство градиента, обосновывающее его использование в методах оптимизации.</p>
  <p>Поскольку основное свойство антиградиента состоит в том, что он указывает в сторону наискорейшего убывания функции, будет логично стартовать из некоторой точки (назовем ее точкой начального значения, как на рисунке выше), сдвинуться в сторону &quot;антиградиента&quot;, то есть градиента, но со знаком минус. Далее пересчитать этот самый антиградиент и снова сдвинуться в его сторону и так далее</p>
  <p>Давайте запишем это более формально. Тогда градиентный спуск состоит в повторении следующих шагов. Не волнуйтесь, далее мы разберем их в коде на Python.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/78/6f/786f1e1a-e9cd-4307-83bf-fa4b6001a21a.png" width="1154" />
  </figure>
  <p>Суть каждого такого алгоритма – процесс получения наименьшего значения ошибки.</p>
  <h1><strong>Перейдем к практике</strong></h1>
  <p>Рассмотрим реализацию самого простейшего случая применения градиентного спуска, а именно, поиск минимума заданной функции. Как и было сказано выше, в одномерном случае, градиент функции (в проекции на выбранную ось) представляет собой обычную одномерную производную.</p>
  <p>Для интереса возьмем функцию</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/11/aa/11aa2589-4f40-4170-834d-188838281021.png" width="964" />
  </figure>
  <p>с производной</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/1c/cf/1ccf7a5d-5c5c-4773-b0d8-4d6ad16ea8d6.png" width="862" />
  </figure>
  <blockquote>Вы можете взять любую другую функцию, на ваш выбор, и проверить работу алгоритма.</blockquote>
  <p>Теперь выберем начальную точку <code>x0 = 6</code> (начальная точка может быть практически любой, за исключением концов отрезка, если мы рассматриваем функцию на некотором отрезке).</p>
  <blockquote>Если непонятно, попробуйте выбрать несколько различных значений начальной точки, и проверить результат.</blockquote>
  <p>После этого необходимо выбрать размер шага (или γ, как это было обозначено выше) с которым мы будем &quot;скатываться&quot; в ямку минимума. Если выбрать слишком большой шаг, можно проскочить минимум, а если слишком маленький, то в случае сложной функции с несколькими минимумами, можно оказаться в локальном минимуме вместо глобального.</p>
  <p>Мы выберем <code>gamma = 0.01</code>.</p>
  <blockquote>Попробуйте поиграть с этими двумя параметрами.</blockquote>
  <p>Теперь попробуем реализовать все что мы запланировали в функции <code>get_minumum</code>.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/f2/bf/f2bfd3f5-e6d6-4199-89f0-44891eaf8123.png" width="1134" />
  </figure>
  <p>Ограничим число итераций <code>max_iters</code> значением 10000, чтобы в случае неудачно подобранных значений <code>gamma</code> и <code>x0</code>, нам не пришлось выполнять лишние шаги и ждать сходимости слишком долго.</p>
  <p>Запишем производную <code>df</code> в виде лямбда функции (удобный концепт, позволяющий избавиться от тела функции), и передадим ее в функцию <code>get_minimum</code> вместе с начальным значением <code>x0</code> и шагом <code>gamma</code>.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/30/60/3060de96-4f0e-44a6-aabb-e85b5d7c5203.png" width="1100" />
  </figure>
  <p>Ого, вау. Мы получили искомое значение. Остается только отметить, что в реальности есть несколько различных видов градиентного спуска, например стохастический спуск, или даже более хитрые вещи, позволяющие отыскивать глобальные минимумы более эффективно, избегая мелких ямок.</p>
  <hr />
  <p>Статья подготовлена образовательной организацией <a href="http://t.me/python_academy" target="_blank">Python Academy</a></p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@python_academy/YzdI5z1NUP</guid><link>https://teletype.in/@python_academy/YzdI5z1NUP?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=python_academy</link><comments>https://teletype.in/@python_academy/YzdI5z1NUP?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=python_academy#comments</comments><dc:creator>python_academy</dc:creator><title>Pandas для начинающих</title><pubDate>Fri, 15 May 2020 17:20:26 GMT</pubDate><media:content medium="image" url="https://teletype.in/files/8d/ff/8dffa23d-cbf6-4291-8f19-49a0221c55b7.png"></media:content><description><![CDATA[<img src="https://teletype.in/files/e6/d8/e6d82f75-1330-4357-aecf-a842ed8d6181.jpeg"></img>На сегодняшний день, пакет Pandas – самый важный инструмент во всем, что касается анализа данных. Многие аналитики и data scientist'ы пользуются этим пакетом.]]></description><content:encoded><![CDATA[
  <figure class="m_column">
    <img src="https://teletype.in/files/e6/d8/e6d82f75-1330-4357-aecf-a842ed8d6181.jpeg" width="5880" />
  </figure>
  <p>На сегодняшний день, пакет Pandas – самый важный инструмент во всем, что касается анализа данных. Многие аналитики и data scientist&#x27;ы пользуются этим пакетом.</p>
  <p>Если вы думаете о карьере в области data science, то крайне важно, чтобы вы сначала изучили Pandas. В этой статье мы рассмотрим наиболее важную информацию о Pandas, в том числе о том, как его установить и как его использовать.</p>
  <h2>Для чего нужен Pandas</h2>
  <p>У Pandas так много применений, что проще перечислить то, что он не может делать, вместо того, что он может делать. Шутка конечно. С помощью этого инструмента вы знакомитесь со своими данными, очищая, трансформируя и анализируя их.</p>
  <p>Например, скажем, вы хотите исследовать набор данных, хранящийся в формате CSV на вашем компьютере. Pandas может извлекать данные из CSV в <code>DataFrame</code> – собственный специальный формат данных – и затем позволит вам делать такие вещи, как:</p>
  <ul>
    <li>Рассчитать статистику и ответить на вопросы о данных, например:<br />1. Каково среднее значение, медиана, максимум или минимум каждого столбца?<br />2. Коррелирует ли столбец A со столбцом B?<br />3. Как выглядит распределение данных в столбце C?</li>
    <li>Очистить данные, выполнив такие действия, как удаление пропущенных значений и фильтрацию строк и/или столбцов по некоторым критериям</li>
    <li>Визуализировать данные с помощью <code>Matplotlib</code>. Графики, диаграммы, гистограммы и многое другое</li>
    <li>Сохранить очищенные, преобразованные данные обратно в CSV, другой файл или базу данных</li>
  </ul>
  <p>Прежде чем приступить к моделированию или каким бы то ни было сложным визуализациям, вам необходимо хорошо понять природу вашего набора данных, и Pandas – лучший способ сделать это.<br /></p>
  <h2>Первые шаги в Pandas</h2>
  <p>Для того, чтобы установить пандас, откройте терминал или командную строку и введите следующую команду.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/61/92/6192cc47-47e1-42ba-bc12-66d597f80bb9.png" width="830" />
  </figure>
  <p>Для импортирования пандас обычно используется короткое имя – <code>pd</code>.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/85/1a/851aeff7-3515-441e-ad53-09857c339daf.png" width="798" />
  </figure>
  <p>Теперь перейдем к базовым компонентам этого пакета.</p>
  <h2>Ключевые компоненты: Series и DataFrames</h2>
  <p>Основные компоненты пандас – <code>Series</code> и <code>DataFrame</code>. Series – что-то вроде столбца с данными, <code>DataFrame</code> – это таблица, созданная из столбцов <code>Series</code>.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/0b/cc/0bcc3034-dd91-4b48-93bf-3ee7cccd8e50.png" width="1000" />
  </figure>
  <p>Существует множество способов создания <code>DataFrame</code>, но на мой взгляд самым простым и удобным является использование словаря.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/e0/bc/e0bcd308-c39d-495a-ae0a-5630b9b6b2dd.png" width="950" />
  </figure>
  <p>Теперь создадим <code>DataFrame</code>, в котором содержатся заказы на яблоки и апельсины.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/3c/7a/3c7ab6f8-ad63-48a8-b4bb-5bfc4a2effd2.png" width="982" />
  </figure>
  <p>А теперь поглядим что получилось:</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/fa/cd/facd433c-5e46-4b06-a362-37dbda104931.png" width="1676" />
  </figure>
  <p><strong>Как это работает?</strong></p>
  <p>Каждый элемент (ключ, значение) в данных соответствует столбцу в результирующем <code>DataFrame</code>. Индекс в <code>DataFrame</code> пандас создал автоматически в виде чисел 0-3, но мы также можем создать и собственный индекс, в момент инициализации <code>DataFrame</code>.</p>
  <blockquote>Давайте в качестве индекса попробуем использовать имена.</blockquote>
  <figure class="m_column">
    <img src="https://teletype.in/files/22/66/2266d7be-e929-41cf-a477-4bff36e3ade4.png" width="1706" />
  </figure>
  <p>Вот что получилось:</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/2e/00/2e00fb40-4a48-43ed-a3df-159f7d971658.png" width="1676" />
  </figure>
  <p>Теперь можно запросто найти заказ клиента, используя его имя и функцию <code>loc</code>.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/78/9a/789ad9ef-6163-4355-a50c-f989898b4582.png" width="830" />
  </figure>
  <p>Получаем ожидаемый результат:</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/d9/d9/d9d95bc2-3b7b-43da-8864-ad944ec65986.png" width="1672" />
  </figure>
  <p>Поскольку сейчас мы уже немного знакомы с основами, то можем двигаться дальше. Давайте перейдем к другим быстрым методам создания <code>DataFrame</code> из различных источников.</p>
  <h2>Чтение данных</h2>
  <p>Загрузка данных из различных форматов файлов в <code>DataFrame</code> довольно проста. В следующих примерах мы продолжим использовать данные об яблоках и апельсинах, но на этот раз эти данные будут браться из различных файлов.</p>
  <h3><strong>Чтение данных из CSV</strong></h3>
  <p>Всё, что нам нужно для работы с CSV-файлами, так это одна строка для загрузки данных.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/a1/61/a1611bc8-2bb4-49d0-9c4e-98bf1c191d02.png" width="1034" />
  </figure>
  <p>А вот что получилось:</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/df/86/df865899-5a57-4f46-bc5e-18b2dc40563a.png" width="1676" />
  </figure>
  <p>CSV файлы по умолчанию не имеют индексов, поэтому все что нам нужно сделать, это указать столбец с индексами при помощи <code>index_col</code>.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/db/6a/db6a1686-2161-41bc-ac18-3f7ef3ca20fa.png" width="1252" />
  </figure>
  <p>Теперь индексация работает как надо.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/2e/00/2e00fb40-4a48-43ed-a3df-159f7d971658.png" width="1676" />
  </figure>
  <h3><strong>Чтение данных из JSON</strong></h3>
  <p>Если у вас есть JSON-файл (который по сути является словарем), пандас может прочитать его так же легко.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/1b/20/1b20904b-8d58-4439-9360-37f6837b4cab.png" width="1066" />
  </figure>
  <p>Тот же самый результат:</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/2e/00/2e00fb40-4a48-43ed-a3df-159f7d971658.png" width="1676" />
  </figure>
  <p><em>Обратите внимание, что на этот раз индекс пришел правильно, поскольку мы использовали JSON. Не стесняйтесь открывать файл с данными data.json в блокноте, чтобы видеть как именно он работает.</em></p>
  <p>Pandas попытается выяснить, как создать <code>DataFrame</code>, проанализировав структуру вашего JSON, и иногда это приводит к неправильным результатам. Часто вам будет нужно установить аргумент <code>orient</code> в зависимости от структуры, поэтому обязательно посмотрите документацию <a href="https://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_json.html" target="_blank">read_json</a> об этом аргументе, чтобы узнать, какую ориентацию вы используете.</p>
  <h2>Наиболее важные операции с DataFrame</h2>
  <p>Тип данных <code>DataFrame</code> содержит сотни методов и других операций, которые имеют решающее значение для любого анализа. Новичок в Pandas обязан знать операции, выполняющие простые преобразования данных, но также и те, которые обеспечивают фундаментальный статистический анализ.</p>
  <p>Для начала работы мы воспользуемся датасетом IMDB. Загрузим этот набор данных из CSV и определим столбец с названиями фильмов в качестве индекса.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/c1/2a/c12ae2ac-b37e-495d-92ad-6dd5d2bbc7c5.png" width="1572" />
  </figure>
  <h3>Просмотр данных</h3>
  <p>Первое, что нужно сделать при открытии нового набора данных – это вывести на экран несколько строк, чтобы получить некоторый, скажем так, визуальный отклик.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/48/50/485084ae-0dfd-48cd-aa47-a54aee7a220d.png" width="746" />
  </figure>
  <p>По умолчанию команда <code>.head()</code> выводит первые 5 строчек, но в аргументах функции можно указать, например, вывести первые 10 строчек – <code>.head(10)</code>.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/c9/95/c9950f54-be30-4617-928b-7334ec0bd919.png" width="1680" />
  </figure>
  <p>Последние 5 строчек можно вывести с помощью команды <code>.tail()</code>, опять же, в аргументах функции можно указать необходимое число.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/5f/e8/5fe82bc1-1651-49df-9605-7824a3423b25.png" width="762" />
  </figure>
  <p>Здесь, например, мы выводим всего 2 строчки. Как правило, когда вы работаете с  набором данных, неплохо просмотреть первые пять или около того строчек, чтобы увидеть, что находится &quot;под капотом&quot;. Здесь например мы можем видеть имена каждого столбца, индекс и примеры значений в каждой строке.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/f0/a4/f0a4f48d-652a-45b2-9ebe-82e4838e8468.png" width="1680" />
  </figure>
  <h3>Получение информации о данных</h3>
  <p><code>.info()</code> должна быть одной из первых команд, которую вы запустите сразу после того, как данные будут загружены.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/69/03/69030dd2-c41d-4799-9a79-0a58c5fc557d.png" width="746" />
  </figure>
  <p><code>.info()</code> предоставляет основные сведения о загруженном наборе данных, такие как количество строк и столбцов, количество ненулевых значений, тип данных в каждом столбце и объем памяти, используемый <code>DataFrame</code>.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/2a/d2/2ad2f66f-09e9-4ed5-b957-c7655b3d7488.png" width="1680" />
  </figure>
  <p>Обратите внимание, что в этом наборе данных очевидно есть пропущенные значения в двух последних столбцах. Сейчас мы попробуем обработать эти пропущенные значения.</p>
  <h3>Как работать с пропущенными значениями</h3>
  <p>При изучении данных вы, скорее всего, столкнетесь с отсутствующими или нулевыми значениями, которые по сути являются своего рода &quot;заполнителями&quot; для несуществующих значений. Чаще всего это <code>None</code> или <code>np.nan</code>, каждый из которых обрабатывается по-разному в разных ситуациях.</p>
  <p>Есть два варианта работы с нулями:</p>
  <ol>
    <li>Избавиться от строк или столбцов с нулями;</li>
    <li>Заменить нули ненулевыми значениями.</li>
  </ol>
  <p>Давайте вычислим общее количество нулей в каждом столбце. Первый шаг – проверить, какие ячейки в <code>DataFrame</code> имеют значение <code>null</code>.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/f4/e3/f4e3aaf8-cb3d-46cc-a915-4828b16fe8e1.png" width="778" />
  </figure>
  <p>Обратите внимание, что <code>isnull()</code> возвращает <code>DataFrame</code>, где каждая ячейка имеет значение <code>True</code> или <code>False</code> в зависимости от состояния этой ячейки.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/97/db/97dbccfc-a8cf-4897-83d0-faebdc8fda0d.png" width="1680" />
  </figure>
  <p>Для подсчета количества нулей в каждом столбце воспользуемся функцией для суммирования.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/cc/66/cc66ec2d-28ad-49fd-903c-2e51faff3bba.png" width="882" />
  </figure>
  <p><code>.isnull()</code> сам по себе не настолько полезен, как его сочетание с другими методами, например с <code>sum()</code>.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/47/35/4735dc56-0ebc-4577-95f1-3cfa56764e6b.png" width="1680" />
  </figure>
  <p>Теперь мы четко видим, что в <code>revenue_millions</code> отсутствует <strong>128</strong> значений, и <strong>64</strong> – в <code>metascore</code>.</p>
  <h3>Удаление нулевых значений</h3>
  <p>Data scientist&#x27;ы и аналитики данных регулярно сталкиваются с дилеммой удаления или замены нулевых значений, и это решение всегда требует глубокого знания данных. В целом, удаление нулевых данных рекомендуется только в том случае, если пропущенных данных мало.</p>
  <p>Удалить нули довольно просто.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/2c/29/2c29b675-8f8d-4017-97d7-f5d623fbd654.png" width="778" />
  </figure>
  <p>Эта операция удалит любую строку в которой есть хотя бы одно нулевое значение, а также вернет новый <code>DataFrame</code> без изменения исходного.</p>
  <p>Таким образом, эта операция удалит <strong>128</strong> строк из <code>revenue_millions</code> и <strong>64</strong> строки из <code>metascore</code>. Это, очевидно, кажется не самым хорошим решением, поскольку в других столбцах этих пропущенных строк есть совершенно хорошие данные. Вот почему мы сейчас попробуем заменить эти данные ненулевыми значениями.</p>
  <h3>Замена данных</h3>
  <p>Замена данных (imputation) – это традиционный метод feature engineering, используемый для работы с данными в которых присутствуют нулевые значения.</p>
  <p>Иногда бывает так, что удаление каждой строки с нулевым значением приводит к удалению слишком большого фрагмента из набора данных, поэтому вместо этого мы можем заменить это нулевое значение другим, обычно средним значением или медианой этого столбца.</p>
  <p>Давайте посмотрим на замену пропущенных значений в столбце <code>revenue_millions</code>.</p>
  <p>Сначала извлечем этот столбец в его собственную переменную.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/c2/5f/c25fc0e0-00d6-4eb8-af5a-9fc5dbe94b24.png" width="1134" />
  </figure>
  <p>Использование квадратных скобок – это основной способ выбора столбцов в <code>DataFrame</code>, как если бы нужно было обратиться к значению в словаре <code>dict</code> в Python.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/57/db/57dbaba7-231c-4897-801e-d83d43f24809.png" width="712" />
  </figure>
  <p><code>revenue</code> теперь содержит <code>Series</code>, а не <code>DataFrame</code>.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/d6/0b/d60b876c-2675-4ee1-8527-422f29451177.png" width="1680" />
  </figure>
  <p>Далее мы заменим нулевые значения в <code>revenue</code> используя средние значения <code>mean</code> по столбцу.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/82/16/8216b710-8949-42d2-8b14-8c277d3f1be5.png" width="966" />
  </figure>
  <p>А теперь остается только заменить нулевые значения на средние с помощью функции <code>fillna()</code>.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/c6/eb/c6ebedd7-be2f-4b34-809e-3caef2c5e452.png" width="1186" />
  </figure>
  <p>Теперь все нулевые значения заменены на среднее значение этого столбца. Обратите внимание, что при использовании <code>inplace=True</code> фактически был переписан исходный датафрейм <code>movies_df</code>.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/cc/66/cc66ec2d-28ad-49fd-903c-2e51faff3bba.png" width="882" />
  </figure>
  <p>Конечный результат получится примерно следующий:</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/81/a4/81a45718-da49-4b43-b744-1d68b792060a.png" width="1680" />
  </figure>
  <p>Замена пропущенных значений в целом столбце с помощью <code>mean</code> является конечно же довольно базовым примером.</p>
  <p>Исследование, очистка, преобразование и визуализация данных с помощью Pandas в Python – это важный навык в Data Science. А чистая обработка данных – это целых 80% работы в качестве Data Scientist&#x27;а. Поэтому так важно знать основы работы с данными в Pandas.</p>
  <hr />
  <p>Статья подготовлена образовательной организацией <a href="http://t.me/python_academy" target="_blank">Python Academy</a></p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@python_academy/X5S2WNoo5</guid><link>https://teletype.in/@python_academy/X5S2WNoo5?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=python_academy</link><comments>https://teletype.in/@python_academy/X5S2WNoo5?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=python_academy#comments</comments><dc:creator>python_academy</dc:creator><title>Топ 5 асинхронных веб-фреймворков на Python</title><pubDate>Thu, 30 Apr 2020 12:47:19 GMT</pubDate><media:content medium="image" url="https://teletype.in/files/b8/36/b836e44c-532c-4ba5-a1d6-f8f4d8b431a4.png"></media:content><category>Python programming</category><description><![CDATA[<img src="https://teletype.in/files/42/b2/42b2fe55-dcc8-4ff1-8693-e85a4063713e.png"></img>Асинхронность уже не является просто модным словечком в сообществе Python. После выпуска библиотеки asyncio в версии 3.5, разработчики Python признали влияние Node.js в сфере веб-разработки и ввели в язык два новых ключевых слова – async и await. Это был крайне важный момент, потому что разработчики максимально осторожно относятся к расширению основного синтаксиса, если только нет острой необходимости, что только указывает на то, насколько принципиально необходимыми считались асинхронные возможности.]]></description><content:encoded><![CDATA[
  <figure class="m_column">
    <img src="https://teletype.in/files/42/b2/42b2fe55-dcc8-4ff1-8693-e85a4063713e.png" width="1920" />
  </figure>
  <p>Асинхронность уже не является просто модным словечком в сообществе Python. После выпуска библиотеки <a href="https://docs.python.org/3/library/asyncio.html" target="_blank">asyncio</a> в версии 3.5, разработчики Python признали влияние Node.js в сфере веб-разработки и ввели в язык два новых ключевых слова – <code>async</code> и <code>await</code>. Это был крайне важный момент, потому что разработчики максимально осторожно относятся к расширению основного синтаксиса, если только нет острой необходимости, что только указывает на то, насколько принципиально необходимыми считались асинхронные возможности.</p>
  <p>В результате перед асинхронностью открылись новые границы: новые и старые библиотеки начали использовать функционал корутин, асинхронные фреймворки взорвались популярностью, а на сегодняшний день пишут всё больше и больше новых модулей. Производительность наравне (или даже лучше) c Node.js уже не является чем-то необычным. И нет никаких причин, из-за которых вы не могли бы делать тысячи запросов в секунду, если ваш код не создаёт высокие нагрузки на процессор.</p>
  <p>Пожалуй, хватит мотивации. Давайте лучше глянем на текущую ситуацию в Python и рассмотрим некоторые из лучших асинхронных фреймворков.</p>
  <hr />
  <h1>Tornado</h1>
  <p>На удивление, Tornado – достаточно старый фреймворк. Самый первый релиз был выпущен ещё в далёком 2009 году (более десяти лет назад), и сейчас его основное внимание направлено на обеспечении надежного асинхронного программирования с высоким параллелизмом.</p>
  <figure class="m_original">
    <img src="https://teletype.in/files/f3/88/f3885885-ee81-49e1-9f57-acecf0b8e5d7.png" width="220" />
  </figure>
  <p>Tornado изначально не являлся веб-фреймворком. На самом деле это просто набор асинхронных модулей, которые используются для построения модулей веб-фреймворка. Если более конкретно, то вот эти модули:</p>
  <ul>
    <li>Корутины и другие примитивы (<code>tornado.gen</code>, <code>tornado.locks</code>, <code>tornado.queues</code> и т. д.)</li>
    <li>Сетевые модули (<code>tornado.ioloop</code>, <code>tornado.iostream</code> и т. д.)</li>
    <li>Асинхронные сервера и клиенты (<code>tornado.httpserver</code>, <code>tornado.httpclient</code> и т. д.)</li>
  </ul>
  <p>Они были совмещены для получения финальный модулей фреймворка: <code>tornado.web</code>, <code>tornado.routing</code>, <code>tornado.template</code> и тому подобные.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/fb/4e/fb4e91f5-b078-46f6-a413-6b677afc8eaf.png" width="1252" />
  </figure>
  <p>Tornado имеет сильную и преданную поддержку в сообществе Python и используется опытными архитекторами для создания высокоэффективных систем. Это фреймворк, который уже давно имеет ответ на проблемы параллелизма, но не стал мейнстримом, поскольку он не поддерживает стандарт WSGI. А также важно помнить, что основная часть библиотек Python всё ещё синхронна.</p>
  <h1>Sanic</h1>
  <p><a href="https://sanicframework.org/" target="_blank">Sanic</a> – это &quot;современный&quot; фреймворк в прямом смысле слова: он не работает в Python ниже версии 3.6, поддерживает синтаксис <code>async/await</code> из коробки, и как следствие, это не заставляет вас читать кучу документации и держать в голове все крайние случаи, прежде чем вы сможете написать свой первый обработчик.</p>
  <figure class="m_original">
    <img src="https://teletype.in/files/0a/86/0a869739-ef51-443c-bc7f-788cb982410f.png" width="400" />
  </figure>
  <p>В результате получившийся синтаксис довольно приятен; он напоминает код, который вы написали бы на любом другом микрофреймворке (например, Flask, CherryPy) просто с несколькими асинхронными вставками:</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/29/b2/29b221c7-4b42-48a7-a39c-fde5452f8b5c.png" width="1118" />
  </figure>
  <p>Sanic, пожалуй, является самым популярным и наиболе понравившемся сообществу асинхронным фреймворков в мире Python. Он имеет практически весь функционал, который вам понадобился бы для проекта – маршрутизация, middleware, куки, контроль версий, блупринты, представления на основе классов, статические файлы, streaming, сокеты и многое другое. А то, что он не предоставляет из коробки – шаблоны, поддержка баз данных, I/O операции с файлами, очереди – вы можете добавить сами, так как существует уже достаточно асинхронных библиотек для всего, что душа пожелает.</p>
  <h1>Vibora</h1>
  <p>Фреймворк <a href="https://vibora.io/" target="_blank">Vibora</a> крайне похож на Sanic, за исключением того, что он претендует на звание самого быстрого веб-сервера на Python. Более того, при самом первом посещении официального сайта можно увидеть график сравнения с другими фреймворками:</p>
  <figure class="m_original">
    <img src="https://teletype.in/files/26/19/26199481-5a08-413f-aac2-ed8f0744cb2b.png" width="540" />
  </figure>
  <p>Как вы можете видеть, Vibora заявляет, что она в несколько раз быстрее классических фреймворков и более чем в два раза быстрее Sanic, своего ближайшего конкурента. Конечно, бенчмарки не всегда могут быть объективными показателями. 🙂</p>
  <p>Хотя по синтаксису и функциям Vibora сравнима с Sanic (или, возможно, даже немного лучше, поскольку она объединяет популярные библиотеки и такие вещи, как шаблоны, доступные из коробки), я бы счел Sanic более зрелым, поскольку он существует дольше и имеет более обширное сообщество.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/c9/8a/c98a74af-683e-453c-a815-02063432cc0b.png" width="1202" />
  </figure>
  <p>Но если вы помешаны на производительности, то Vibora может дать вам большие возможности. Тем не менее, на момент написания статьи Vibora кардинально переписывается, чтобы стать ещё быстрее, и <a href="https://docs.vibora.io/v/perf/" target="_blank">ссылка</a> на страницу про производительность говорит нам о том, что фреймворк находится под “тяжелой разработкой&quot;. Однако не спешите выбирать Vibora для своих проектов, иначе вы рано или поздно столкнётесь с критическими изменениями. Но всё-таки это только начало асинхронного мира Python, и не следует ожидать чего-либо железно стабильного.</p>
  <h1>Quart</h1>
  <p>Если вам приятно разрабатывать на Flask, но не хватает асинхронной поддержки, то вам определнно понравится <a href="https://gitlab.com/pgjones/quart" target="_blank">Quart</a>.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/f2/3d/f23da2da-85fb-4ddf-b06d-577b3cdf98ce.png" width="600" />
  </figure>
  <p>Quart соответствует стандарту ASGI, который является преемником знаменитого стандарта WSGI и предлагает асинхронную поддержку. Самое интересное в Quart то, что он не только похож на Flask, но и фактически совместим с Flask API! Автор этого фреймворка хотел сохранить ощущение работы с Flask и просто добавить к нему поддержку асинхронности, WebSockets и HTTP 2. В результате вы можете изучить Quart прямо по документации Flask&#x27;а, просто имея в виду, что функции в Quart являются асинхронными.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/99/e6/99e6d119-2381-409c-a8bd-bca1070ddff9.png" width="864" />
  </figure>
  <p>Выглядит (почти) как Flask, разве не так?</p>
  <p>Поскольку Quart – это эволюция Flask, то и весь функционал из Flask также доступен: маршрутизация, middleware, сессии, шаблоны, блупринты и так далее. Более того, вы даже можете использовать расширения Flask непосредственно внутри Quart. Загвоздка заключается лишь в том, что поддерживается Python только версии 3.7+, но если вы не используете последнюю версию Python, то и использовать асинхронность имеет мало смысла. 🙂</p>
  <p>Документация действительно нужна, если у вас нет предварительного опыта работы с Flask, но я могу всё-таки рекомендовать Quart, поскольку это, вероятно, единственный асинхронный фреймворк, который скоро выйдет в версии 1.0.</p>
  <h1>FastAPI</h1>
  <p>Последним (но самым впечатляющим) фреймворком в этом списке является FastAPI. Нет, это не только API-фреймворк; на самом деле FastAPI, похоже, является самым многофункциональным и богатым документацией фреймворком, с которым я столкнулся при исследовании асинхронных фреймворков в Python.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/4c/45/4c45a66d-fdc3-43c7-9bce-10ada3b651b7.png" width="807" />
  </figure>
  <p>Интересно, что автор фреймворка глубоко изучил несколько других фреймворков, от классических, таких как Django, до более современных, таких как Sanic, а также изучил различные технологии в NestJS (веб-фреймворк Node.js, Typescript). Про их философию развития и масштабные сравнения можно прочитать <a href="https://fastapi.tiangolo.com/alternatives/" target="_blank">здесь</a>.</p>
  <p>Синтаксис довольно приятный; можно даже утверждать, что он гораздо приятнее, чем другие фреймворки, с которыми мы сталкивались:</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/51/74/5174b3c3-5952-4acf-881f-8e865a0df0e3.png" width="1184" />
  </figure>
  <p>А теперь представлю список убийственных функций, которые заставляют FastAPI затмевать другие фреймворки:</p>
  <p><strong>API автоматической генерации документации:</strong> как только ваши конечные точки будут реализованы, вы сможете поиграться с API, используя соответствующий стандартам пользовательский интерфейс. Поддерживаются SwaggerUI, ReDoc и другие.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/fe/50/fe509013-582e-4e76-b9a8-ad41e60d2ef8.png" width="960" />
  </figure>
  <p>Фреймворк также создаёт автоматическую документацию для моделей в JSON формате.</p>
  <p><strong>Современное развитие:</strong> да, слово &quot;современный&quot; часто бросается в глаза, но именно в контексте FastAPI оно уместно. Внедрение зависимостей и аннотация типов – это объекты первого класса, не только позволяющие применять хорошие принципы программирования, но и предотвращающие ошибки и путаницу в долгосрочной перспективе.</p>
  <p><strong>Обширная документация:</strong> не знаю насчёт вас, но я большой любитель хорошей документации. И в этой области FastAPI преуспел лучше других. В нем есть страницы за страницами документации, объясняющие почти каждую тонкость и моменты, в которых нужно быть осторожным, для разработчиков всех уровней. Сразу видно, что в такую документацию вложили сердце и душу. И единственное сравнение, которое можно найти, – это документация Django (да, документация FastAPI настолько хороша).</p>
  <p><strong>Помимо всего прочего:</strong> FastAPI поддерживает WebSockets, Streaming, а также GraphQL, помимо того, что у него есть все традиционные функции, такие как CORS, сессии, куки и многие другие.</p>
  <p>А как насчет производительности? FastAPI построен на удивительной библиотеке Starlette, в результате чего производительность сравнима — с Node.js, а в некоторых случаях даже Go! В целом, у меня сложилось стойкое предчуствие, что FastAPI будет мчаться вперёд как лучший асинхронный фреймворк для Python.</p>
  <h3>Заключение</h3>
  <p>В наши дни очень много событий происходит в асинхронном мире Python. Появляются новые фреймворки, старые переписываются, а библиотеки эволюционируют, чтобы соответствовать асинхронным концепциям. Несмотря на то, что Python имеет встроенную поддержку событийного цикла и можно сделать части вашего приложения асинхронными, у вас всё ещё есть отличная возможность пойти ва-банк и построить приложение на одном из вышеперечисленных фреймворков. Просто не забывайте о долгосрочной перспективе: некоторые из существующих асинхронных фреймворков Python находятся на ранних стадиях и быстро развиваются, что может повредить вашему процессу разработки и повысить бизнес-затраты. Главное – осторожность!</p>
  <p>Но все сказано и сделано; Python готов к продакшну и может обеспечить хорошую производительность, когда речь заходит о веб-фреймворках. Если вы долго думали о переходе на Node.js, то теперь вам этого не требуется! 🙂</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@python_academy/so6LeM2q5</guid><link>https://teletype.in/@python_academy/so6LeM2q5?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=python_academy</link><comments>https://teletype.in/@python_academy/so6LeM2q5?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=python_academy#comments</comments><dc:creator>python_academy</dc:creator><title>Вирус локер на Python и Tkinter</title><pubDate>Sat, 11 Apr 2020 13:14:44 GMT</pubDate><media:content medium="image" url="https://teletype.in/files/18/8c/188c93f7-6d41-4f19-a13c-e41475e4f9f0.png"></media:content><description><![CDATA[<img src="https://teletype.in/files/3e/6e/3e6e4b79-99a0-432c-860a-c845dc0ee9d5.png"></img>Дисклеймер: статья написана в образовательных целях, автор не призывает к плохим деяниям.]]></description><content:encoded><![CDATA[
  <figure class="m_column">
    <img src="https://teletype.in/files/3e/6e/3e6e4b79-99a0-432c-860a-c845dc0ee9d5.png" width="1920" />
  </figure>
  <blockquote>Дисклеймер: статья написана в образовательных целях, автор не призывает к плохим деяниям.</blockquote>
  <p>Локер – популярный вид вирусов, который блокирует компьютер, и чаще всего злоумышленники просят что-либо взамен на разблокировку. Обычно локер еще шифрует все файлы на компьютере, но мы такого делать не будем.</p>
  <h2>Основа программы</h2>
  <p>Для начала импортируем все нужные модули и создадим окно приложения с определенными размерами.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/3a/4e/3a4e5ef4-da0f-463a-8f23-3a7e6f38c3c6.png" width="1084" />
  </figure>
  <p>Дальше сделаем надпись, призывающую ввести пароль. Расположим ее по центру по горизонтали и немного сместим вверх. </p>
  <figure class="m_column">
    <img src="https://teletype.in/files/81/d3/81d39275-ff6f-447a-85d3-8f381382fac5.png" width="1572" />
  </figure>
  <p>Это не обязательно, но я сделаю еще маленькую надпись снизу, указывающую автора.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/d1/38/d13876ff-9127-4ff8-b245-b8f9b813e7de.png" width="1656" />
  </figure>
  <p>Теперь понадобится поле, в которое пользователь будет вводить сам пароль. Зададим размеры и расположим ровно в центре.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/e6/dd/e6dd01ab-93bb-4733-aedc-98861d52900b.png" width="1622" />
  </figure>
  <p>Напоследок пропишем следующее, чтобы курсор мыши фокусировался сразу на поле ввода при запуске.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/e9/59/e95974c0-e51b-432b-8470-8d1675811335.png" width="696" />
  </figure>
  <p>Сейчас уже можно написать <code>root.mainloop()</code> и посмотреть на промежуточный результат.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/a2/1d/a21d4706-26b8-4d52-8f69-8e77f91e4fcb.png" width="1920" />
  </figure>
  <h2>Часть вируса</h2>
  <p>Итак, какое-то приложение уже готово, осталось кое-что добавить и превратить его в вирус.</p>
  <p>Для начала уберем строчки, где мы указывали размер окна и запускали приложение. То есть вот это удаляем из кода.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/cc/c3/ccc3412d-16ff-4e33-a2f7-21e6eace7bfd.png" width="914" />
  </figure>
  <p>Сделаем окно полноэкранным, написав следующее, а также уберем курсор мыши.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/2b/67/2b6708d5-28ea-43a6-913d-908ca1f5d748.png" width="1084" />
  </figure>
  <p><em>Внимание! Чтобы выйти из такого приложения на данном этапе, нужно нажать комбинацию Alt+F4.</em></p>
  <p>Далее напишем цикл, в котором будет проверка ввода и обновление экрана.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/54/a1/54a19bff-e700-49d2-82f4-63f1d758dcef.png" width="948" />
  </figure>
  <p>Думаю, что здесь всё понятно, при вводе &#x27;1234&#x27; программа прекратит своё выполнение при помощи <code>sys.exit()</code></p>
  <p>Примерно такая картина получается на данный момент.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/39/5e/395ecbf7-62fe-435d-90c3-4a9e4d33ddef.png" width="1920" />
  </figure>
  <h3>Последние штрихи</h3>
  <p>Всё вроде бы хорошо, но всё еще есть несколько проблем: окно без проблем закрывается с помощью Alt+F4, курсор можно переместить на соседний монитор (если их 2+), есть возможность переключаться между программами (Alt+Tab) и там спокойно что-то делать. Сейчас мы всё это решим.</p>
  <p>Для предотвращения закрытия окна комбинацией Alt+F4, достаточно написать одну строчку перед циклом.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/54/a9/54a9a396-44a2-49fc-a8a0-8340da964d95.png" width="1268" />
  </figure>
  <p>Вообще вторым параметром передается функция, при которой должно что-то происходить, но мы передали туда бесполезную лямбда-функцию, которая просто возвращает <code>None</code>.</p>
  <p>Далее мы решим две проблемы сразу: бдуем перемещать курсор пользователя в левый верхний угол, чтобы не было возможности что-либо сделать в других окнах, либо переместиться на второй монитор. Для этого в цикле пропишем специальный метод <code>moveTo</code> из модуля <code>pyautogui</code>.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/b7/6d/b76da61e-64e0-44c4-923f-aecf119afe1f.png" width="948" />
  </figure>
  <p>То есть курсор всегда будет перемещать в координаты <code>(0, 0)</code> – левый верхний угол.</p>
  <p>На всякий случай перед циклом надо написать еще вот это.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/32/91/3291f0b7-25b9-40da-b1b9-a311a439a18c.png" width="914" />
  </figure>
  <p>Варианты обойти вирус конечно же остались, но для образовательной статьи этого хватит.</p>
  <p>В теории такую программу можно доработать, скомпилировать в исполняемый файл и закинуть кому-нибудь в автозагрузку, но я вам этого не говорил :)</p>
  <hr />
  <p>Исходный код – https://pastebin.com/2uDCyFT9</p>
  <p>Статья подготовлена образовательной организацией <a href="http://t.me/python_academy" target="_blank">Python Academy</a></p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@python_academy/ZoKNqVaGa</guid><link>https://teletype.in/@python_academy/ZoKNqVaGa?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=python_academy</link><comments>https://teletype.in/@python_academy/ZoKNqVaGa?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=python_academy#comments</comments><dc:creator>python_academy</dc:creator><title>Здоровье программиста</title><pubDate>Sat, 04 Apr 2020 17:26:50 GMT</pubDate><media:content medium="image" url="https://teletype.in/files/82/05/8205cb16-0933-4d96-b9d4-3d678d4cce9d.jpeg"></media:content><description><![CDATA[<img src="https://teletype.in/files/7b/a1/7ba1dbc1-db80-4940-9715-79c3323b8cf9.jpeg"></img>Думаю, абсолютно все программисты и не только сталкиваются с проблемами, связанными со здоровьем, в связи с работой перед монитором. В этой статье мы разберем самые частые ошибки и приведем рекомендации, как поддерживать своё здоровье даже с сидячим образом жизни.]]></description><content:encoded><![CDATA[
  <figure class="m_column">
    <img src="https://teletype.in/files/7b/a1/7ba1dbc1-db80-4940-9715-79c3323b8cf9.jpeg" width="1280" />
  </figure>
  <p>Думаю, абсолютно все программисты и не только сталкиваются с проблемами, связанными со здоровьем, в связи с работой перед монитором. В этой статье мы разберем самые частые ошибки и приведем рекомендации, как поддерживать своё здоровье даже с сидячим образом жизни.</p>
  <h2>Освещение</h2>
  <p>Практически самый важный аспект – это освещение. Очевидно, что обеспечить своё окружение солнечным светом круглосуточно не получится, поэтому стоит повесить большую лампу прямо над столом.</p>
  <p>И да, темные темы в ваших средах разработки тоже играют свою роль, от них глаза устают намного меньше, но, опять же, слишком темный экран и яркое освещение комнаты - тоже не хорошо.</p>
  <blockquote>Нельзя сидеть перед работающим монитором в полной темноте. Яркий экран, окруженный темным фоном – это очень контрастная картинка, которая приводит к перенапряжению глазных мышц.</blockquote>
  <h2>Зрение</h2>
  <p>Исходя из предыдущей части статьи, мы приходим к более общей проблеме. Большая половина дня за компьютером для человека действительно может сильно испортить зрение. Достаточно важно носить правильные линзы или очки, потому что без них глаза будут больше напрягаться, чтобы сфокусироваться, а это утомляет мышцы вокруг глаз, что может приводить к головным болям и еще большим проблемам со зрением.</p>
  <p>Вот небольшой список советов, которые помогут сохранить ваше зрение:</p>
  <ul>
    <li>Моргайте чаще, это не даст глазам пересыхать.</li>
    <li>Делайте перерывы, чтобы глаза смогли отдохнуть.</li>
    <li>Исключите блики на своем мониторе - наклейте на экран матовую или антибликовую пленку или раздобудьте безбликовый монитор, если таковой еще не имеется.</li>
    <li>Следите, чтобы разница между яркостью окружения и монитора была не слишком большой. Также советую установить <a href="https://justgetflux.com/" target="_blank">f.lux</a>, это приложение автоматически изменяет яркость экрана и температуру цвета в течение дня в зависимости от вашей геолокации.</li>
    <li>И самый легкий совет: монитор должен находиться на расстоянии 0.5–1 м от глаз – это примерно длина вытянутой руки.</li>
  </ul>
  <p>А вот вам небольшая подборка упражнений для глаз:</p>
  <ol>
    <li>Для улучшения циркуляции глазной жидкости аккуратно помассируйте подушками указательных и средних пальцев роговицу глаза. Повторить 6-8 раз. </li>
    <li>Сфокусируйте свой взгляд на несколько секунд сначала на ближнем предмете, а затем на дальнем. Рекомендуется сделать 10 подходов. Упражнение отлично подойдет для поддержания хрусталика глаза в тонусе и снизит риск близорукости. </li>
    <li>Водите глазами в разные стороны – снизу вверх и слева направо. Можно выполнить и круговые движения. Повторить не менее 10 раз. Так мы укрепляем глазодвигательные мышцы.</li>
  </ol>
  <h2>Сидение</h2>
  <p>Сидеть на самом деле очень вредно, но не у всех есть продвинутые столы, которые можно поднимать для работы стоя. Однако последствий сидячей работы можно избежать – достаточно каждый час делать пятиминутный перерыв на физическую активность. А чтобы улучшить обмен веществ, достаточно просто пройтись до уборной. </p>
  <p>Звучит банально, но держите спину ровно, чтобы не портить осанку.</p>
  <h2>Спина и шея</h2>
  <p>Во-первых, необходимо подобрать удобное кресло, которое должно регулироваться в соответствии с весом и приспосабливаться к разным позам. Хорошее кресло действительно может значительно улучшить осанку и уменьшить боль в спине – впрочем, у вас, возможно, уже есть безупречное кресло. Но сидите вы в нем, скорее всего, неправильно. Правильная посадка зависит от физических параметров тела. Отрегулируйте высоту кресла так, чтобы оно должным образом поддерживало позвоночник, равномерно распределяло вес тела и чтобы ноги стояли на земле.</p>
  <p>Далее перейдем к упражнениям для спины и шеи: </p>
  <ol>
    <li>Положите сплетенные пальцы рук на затылок, удерживая голову, попробуйте наклонить ее назад.</li>
    <li>Проделайте тоже самое, удерживая руки на лбу.</li>
    <li>Сядьте на стул. Прикоснитесь ладонями к спинке стула, слегка поворачивая корпус. </li>
    <li>Сядьте на стул и максимально прижимайтесь к спинке лопатками и крестцом. Выполняйте упражнение плавно, вы не должны чувствовать боль.</li>
    <li>Встаньте на четвереньки, выгните спину, слегка отклоняя её в стороны.</li>
  </ol>
  <p>И это лишь малая часть упражнения. При желании в интернете можно найти массу способов, чтобы размять свое тело.</p>
  <h2>Запястья</h2>
  <p>Из-за постоянного использования клавиатуры и мыши может появиться боль в запястьях – онемение и покалывание в запястьях и руках. Со временем это может перерасти во что-то хуже, чем просто боль.</p>
  <p>Также привожу пример упражнений, которые лучше делать каждый день:</p>
  <ol>
    <li>Сожмите и разожмите кулаки несколько раз. </li>
    <li>Сожмите кулак и сгибайте всю кисть несколько раз вверх-вниз. </li>
    <li>Сожмите кулак (не очень крепко) и повращайте кистями в разные стороны. </li>
    <li>Сложите пальцы в ровный ряд, отведите большой в сторону и повращайте им.</li>
  </ol>
  <h2>Питание</h2>
  <p>Мы не будем подробно освещать здесь тему правильного питания и диеты, это уже выбор каждого, однако есть и пить всё подряд – это не очень правильно. Для начала советую ограничить себя в потреблении чая и кофе, заменяя простой водой, которую следует пить в большом количестве.</p>
  <p>Про чипсы, фаст-фуд и любую другую калорийную еду стоит напрочь забыть. Чрезмерное употребление жирной пищи ведет к повышению уровня холестерина в крови, появлению на стенках кровеносных сосудов жировых бляшек и развитию атеросклероза. При этом сосуды становятся менее эластичными. Атеросклеротические бляшки сужают просвет сосудов. Кровь по таким сосудам течет с большим трудом. Все эти процессы приводят к повышению уровня артериального давления.</p>
  <p>И да, нерациональное питание и переедание ведут к излишнему весу.</p>
  <h2>Сон</h2>
  <p>Стоит добавить важность правильного сна. Даже небольшое недосыпание (сон 6-7 часов), циркадный сдвиг (изменение времени ухода ко сну на 1-2 часа за одну ночь) или уменьшение фаз глубокого или быстрого сна уменьшают качество умственных способностей следующим образом:</p>
  <ul>
    <li>Ухудшение контроля над эмоциями, уменьшение устойчивости к стрессам, силы воли и способности фокусироваться.</li>
    <li>Гормональное нарушение. Меньше энергии и хуже настроение.</li>
    <li>Существенное снижение иммунитета.</li>
    <li>Существенное ухудшение способности к запоминанию.</li>
    <li>Значительное ухудшение способности видеть нетривиальные решения.</li>
  </ul>
  <p>Несколько советов для лучшего сна:</p>
  <ol>
    <li>Выберите время отхода ко сну так, чтобы провести в кровати 8.5-9 часов, и не сдвигайте его больше, чем на 20 минут в день.</li>
    <li>Ограничьте для себя спектр синего света за 3-4 часа до сна. Используйте фильтры синего цвета для всех экранов.</li>
    <li>Не употребляйте алкоголь.</li>
  </ol>
  <hr />
  <p>Статья подготовлена образовательной организацией <a href="http://t.me/python_academy" target="_blank">Python Academy</a></p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@python_academy/T5DXZot4I</guid><link>https://teletype.in/@python_academy/T5DXZot4I?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=python_academy</link><comments>https://teletype.in/@python_academy/T5DXZot4I?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=python_academy#comments</comments><dc:creator>python_academy</dc:creator><title>Работа с процессами в Python</title><pubDate>Fri, 27 Mar 2020 15:11:53 GMT</pubDate><media:content medium="image" url="https://teletype.in/files/03/94/03942834-1159-4f3f-ad39-68a833105c42.png"></media:content><description><![CDATA[<img src="https://teletype.in/files/60/e5/60e589e5-4245-461b-81c4-2efc31896604.png"></img>С появлением многоядерных процессоров стала общеупотребительной практика распространять нагрузку на все доступные ядра. Существует два основных подхода в распределении нагрузки: использование процессов и потоков. О первом мы как раз сейчас и поговорим.]]></description><content:encoded><![CDATA[
  <figure class="m_column">
    <img src="https://teletype.in/files/60/e5/60e589e5-4245-461b-81c4-2efc31896604.png" width="1920" />
  </figure>
  <p>С появлением многоядерных процессоров стала общеупотребительной практика распространять нагрузку на все доступные ядра. Существует два основных подхода в распределении нагрузки: использование процессов и потоков. О первом мы как раз сейчас и поговорим.</p>
  <h2>Немного истории</h2>
  <p>Модуль <a href="https://docs.python.org/3/library/multiprocessing.html" target="_blank">multiprocessing</a> изначально был добавлен в Python 2.6. Этот модуль позволяет создавать процессы таким же образом, как при создании потоков при помощи модуля <a href="https://docs.python.org/3/library/threading.html" target="_blank">threading</a>.</p>
  <blockquote>Суть в том, что, в связи с тем, что теперь мы создаем процессы, появляется возможность обойти GIL (Global Interpreter Lock) и воспользоваться возможностью использования нескольких процессоров (или даже ядер) на компьютере.</blockquote>
  <p>Пакет <code>multiprocessing</code> также включает ряд API, которых вообще нет в модуле threading. Например, там есть очень удобный класс <code>Pool</code>, который можно использовать для параллельного выполнения функции между несколькими входами. Мы рассмотрим <code>Pool</code> немного позже. А начнем пожалуй с класса <code>Process</code> модуля <code>multiprocessing</code>.</p>
  <h2>Приступим к работе с Multiprocessing</h2>
  <p>Класс <code>Process</code> очень похож на класс <code>Thread</code> модуля <code>threading</code>. Давайте попробуем создать несколько процессов, которые вызывают одну и ту же функцию, и посмотрим, как это сработает.</p>
  <p>Начнем с того, что создадим функцию <code>func</code>. Внутри <code>func</code> возводим переданное число <code>number</code> в квадрат. Мы также используем <a href="https://docs.python.org/3/library/os.html" target="_blank">модуль os</a> для того, чтобы получить <code>id</code> текущего процесса. С помощью него можно определить какой именно процесс вызывает функцию.</p>
  <pre>import os
from multiprocessing import Process


def func(number):
    proc = os.getpid()
    print(f&#x27;{number} squared to {number ** 2} by process id: {proc}&#x27;)</pre>
  <p>Теперь наконец создадим функцию, для создания 5 процессов для 5 целых чисел, и посмотрим что получилось.</p>
  <pre>def main():
    procs = []
    numbers = [1, 2, 3, 4, 5]

    for number in numbers:
        proc = Process(target=func, args=(number,))
        procs.append(proc)
        proc.start()

    for proc in procs:
        proc.join()</pre>
  <blockquote>Здесь хотелось бы обсудить несколько важных моментов. Во-первых, f-строки работают только в версиях Python 3.6 или выше. Во-вторых, аргументы в функции <code>Process</code>это всегда кортеж, даже если там всего один элемент.</blockquote>
  <p>В функции <code>main</code>, в нижнем блоке кода, мы создаем несколько процессов и стартуем их с помощью функции <code>start()</code>.</p>
  <p>Самый последний цикл только вызывает метод <code>join()</code>для каждого из процессов, что говорит Python подождать, пока процесс завершится. Если вам нужно остановить процесс, вы можете вызвать метод <code>terminate()</code>.</p>
  <p>Запускаем полученный скрипт.</p>
  <pre>if __name__ == &#x27;__main__&#x27;:
    main()</pre>
  <p>Вывод будет примерно таким.</p>
  <pre>1 squared to 1 by process id: 1600
2 squared to 4 by process id: 1601
3 squared to 9 by process id: 1602
4 squared to 16 by process id: 1603
5 squared to 25 by process id: 1604</pre>
  <p>Иногда приятно иметь читабельное название процессов. К счастью, <code>multiprocessing</code> дает возможность получить доступ к названию нашего процесса.</p>
  <pre>from multiprocessing import Process, current_process


def func(number):
    proc = current_process().name
    print(f&#x27;{number} squared to {number ** 2} by process {proc}&#x27;)

def main():
    procs = []
    numbers = [1, 2, 3, 4, 5]

    for number in numbers:
        proc = Process(target=func, args=(number,))
        procs.append(proc)
        proc.start()

    for proc in procs:
        proc.join()


if __name__ == &#x27;__main__&#x27;:
    main()</pre>
  <p>Вывод будет таким.</p>
  <pre>1 squared to 1 by process Process-1
2 squared to 4 by process Process-2
3 squared to 9 by process Process-3
4 squared to 16 by process Process-4
5 squared to 25 by process Process-5</pre>
  <p>Кроме того, есть возможность напрямую назначить имя процессу.</p>
  <pre>proc = Process(target=func, name=&#x27;My Process&#x27;, args=(number,))</pre>
  <h2>Класс Pool</h2>
  <p>Класс <code>Pool</code> используется для создания пула рабочих процессов. Он включает в себя методы, которые позволяют вам разгружать задачи к рабочим процессам. Давайте посмотрим на простейший пример.</p>
  <pre>from multiprocessing import Pool


def func(number):
    return number ** 2
    
def main():
    numbers = [1, 2, 3]
    with Pool(processes=3) as pool:
        print(pool.map(func, numbers))
        
        
if __name__ == &#x27;__main__&#x27;:
    main()</pre>
  <p>Здесь я создал экземпляр <code>Pool</code> с помощью контекстного менеджера <code>with...as...</code> и указал ему создать три рабочих процесса. Далее я использовал метод <code>map</code> для отображения функции для каждого процесса. Наконец вывожу результат, который в данном случае является списком <code>[1, 4, 9]</code>.</p>
  <h2>Реальный пример</h2>
  <p>Попробуем применить метод <code>requests.get()</code>к некоторому списку сайтов. Последовательное выполнение задачи отнимет много времени, но что если сделать это параллельно?</p>
  <pre>import requests
from multiprocessing import Pool


def main(processes):
    urls = [
        &#x27;http://www.python.org&#x27;,
        &#x27;http://www.python.org/about/&#x27;,
        &#x27;http://www.onlamp.com/pub/a/python/2003/04/17/metaclasses.html&#x27;,
        &#x27;http://www.python.org/doc/&#x27;,
        &#x27;http://www.python.org/download/&#x27;,
        &#x27;http://www.python.org/getit/&#x27;,
        &#x27;http://www.python.org/community/&#x27;,
        &#x27;https://wiki.python.org/moin/&#x27;,
        &#x27;http://planet.python.org/&#x27;,
        &#x27;https://wiki.python.org/moin/LocalUserGroups&#x27;,
        &#x27;http://www.python.org/psf/&#x27;,
        &#x27;http://docs.python.org/devguide/&#x27;,
        &#x27;http://www.python.org/community/awards/&#x27;
    ]
    
    # создадим пул работников
    with Pool(processes=processes) as pool:
        # получим результат с помощью функции map
        results = pool.map(requests.get, urls)</pre>
  <p>Теперь сравним скорости обработки при различном размере пула.</p>
  <pre>if __name__ == &#x27;__main__&#x27;:
    # -- 13 Pool -- #
    main(processes=13)

    # -- 8 Pool -- #
    main(processes=8)

    # -- 4 Pool -- #
    main(processes=4)

    # -- Single -- #
    main(processes=1)</pre>
  <blockquote>Вообще говоря, скорость выполнения таких процессов сильно зависит от скорости и качества интернет соединения. Кроме того, логически более правильно здесь было бы использовать <code>async</code>, а не <code>multiprocessing</code>. Однако даже в таком примере виде прирост скорости.</blockquote>
  <p>На моей машине получилось вот так:</p>
  <pre>13 Pool: 2.6185 sec
8 Pool: 2.7000 sec
4 Pool: 3.0071 sec
Single: 7.3520 sec</pre>
  <h4>Итог</h4>
  <p>Хотя с помощью этой заметки вы теперь сможете ускорять свои программы, не стоит забывать и об оптимизации собственного кода. Python в целом достаточно быстр, если знать как на нем писать.</p>
  <p>Мы затронули только некоторые простые вопросы, связанные многопроцессорным программированием на Python. Разумеется, в <a href="https://docs.python.org/3/library/multiprocessing.html" target="_blank">документации</a> Python представлено намного больше развернутой информации, так что рекомендую с ней ознакомиться.</p>
  <hr />
  <p>Статья подготовлена образовательной организацией <a href="http://t.me/python_academy" target="_blank">Python Academy</a></p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@python_academy/LCvgj83h</guid><link>https://teletype.in/@python_academy/LCvgj83h?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=python_academy</link><comments>https://teletype.in/@python_academy/LCvgj83h?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=python_academy#comments</comments><dc:creator>python_academy</dc:creator><title>7 фишек Python максимально улучшающие твой код</title><pubDate>Fri, 06 Mar 2020 15:34:46 GMT</pubDate><media:content medium="image" url="https://teletype.in/files/74/cd/74cddbaf-61b6-4efd-b453-145065168de4.jpeg"></media:content><description><![CDATA[<img src="https://teletype.in/files/66/60/6660e0ae-19e4-4bd6-8402-1421c100f309.jpeg"></img>Хочешь писать более лаконичный и читаемый код а также умещать как можно больше смысла в одно выражение? Считаешь, что лучше один раз прочитать об уловках Python, чем провести остаток своих дней за чтением ненужной документации?]]></description><content:encoded><![CDATA[
  <figure class="m_column">
    <img src="https://teletype.in/files/66/60/6660e0ae-19e4-4bd6-8402-1421c100f309.jpeg" width="1280" />
  </figure>
  <p>Хочешь писать более лаконичный и читаемый код а также умещать как можно больше смысла в одно выражение? Считаешь, что лучше один раз прочитать об уловках Python, чем провести остаток своих дней за чтением ненужной документации?</p>
  <p>Тогда ты обратился по адресу. Мы начнем с маленьких уловок, которые ты уже мог где-то видеть, если работал с Python. Но я обещаю, что ближе к концу статьи будет больше безумных вещей.</p>
  <h1>1. Правдивость различных объектов</h1>
  <p>В отличие от некоторых языков программирования, в Python объект считается <code>False</code>, только если он пуст. Это значит, что не нужно проверять длину строки, кортежа или словаря – достаточно проверить его как логическое выражение.</p>
  <blockquote>Кроме того, разумеется, 0 – тоже <code>False</code>, а остальные числа – <code>True</code>.</blockquote>
  <p>Например, следующие выражения эквивалентны:</p>
  <pre>string = &#x27;Test&#x27; # True пример
# string = &#x27;&#x27;   # False пример

if len(string) &gt; 0:
    print(&#x27;Объект string не пуст&#x27;)

if len(string):  # Здесь 0 преобразовывается к False
    print(&#x27;Объект string не пуст&#x27;)

if string != &#x27;&#x27;:
    print(&#x27;Объект string не пуст&#x27;)

if string: # Здесь пустая строка преобразовывается к False
    print(&#x27;Объект string не пуст&#x27;)</pre>
  <p>В данном случае <code>string</code> – это строка, но здесь мог оказаться другой тип (с соответствующими изменениями условий блока <code>if</code>).</p>
  <blockquote>Наиболее элегантным и соответствующим &quot;pythonic&quot; стилю вариантом будет именно <code>if string: ...</code></blockquote>
  <h1>2. <strong>Проверка на вхождение подстроки</strong></h1>
  <p>Это маленькая, довольно очевидная подсказка, но даже я узнал о ней не сразу. Должно быть очевидно, что можно проверить, содержится ли нужный элемент в кортеже, списке, словаре, с помощью конструкции <code>if item in list: ...</code>. Но это может сработать и для строк!</p>
  <p>Можно конечно написать и так:</p>
  <pre>string = &#x27;Hi there&#x27; # True пример
# string = &#x27;Hello&#x27; # False пример
if string.find(&#x27;Hi&#x27;) != -1:
    print(&#x27;Success!&#x27;)</pre>
  <p>Но гораздо понятнее и красивее будет так:</p>
  <pre>string = &#x27;Hi there&#x27; # True example
# string = &#x27;Hello&#x27; # False example
if &#x27;Hi&#x27; in string:
    print(&#x27;Success!&#x27;)</pre>
  <h1>3. <strong>Лямбда-функции</strong></h1>
  <p>Иногда нужно передать функцию в качестве аргумента или сделать короткую, но сложную операцию несколько раз. Можно определить функцию обычным способом, а можно использовать лямбда-функцию – маленькую функцию, возвращающую результат одного выражения.</p>
  <p>Следующие два определения полностью идентичны:</p>
  <pre>def add(a,b):
    return a + b

add = lambda a, b: a + b</pre>
  <p>Преимущество лямбда-функции заключается в том, что она является выражением и может быть использована внутри другого выражения. Например, можно удобно использовать их в функции <code>map</code>, которая вызывает функцию-выражение для каждого элемента списка и возвращает список результатов.</p>
  <pre>squares = map(lambda x: x * x, [1, 2, 3, 4, 5])

# squares = [1, 4, 9, 16, 25]</pre>
  <blockquote>Без лямбда-функций нам конечно же пришлось бы определить эту функцию отдельно. По сути мы сэкономили одну строчку кода и одно имя переменной.</blockquote>
  <h1>4. Списковые включения</h1>
  <p>Возможно где-то до этого ты уже мог слышать понятие «list comprehensions». Это такой способ уместить цикл <code>for</code>, блок <code>if</code> и присваивание в одну строку.</p>
  <p>Начнем с простейшего примера. Допустим, нам снова надо возвести в квадрат все элементы списка.</p>
  <p>Если ты совсем недавно начал писать на Python, то скорее всего напишешь так:</p>
  <pre>numbers = [1, 2, 3, 4, 5]
squares = []
for number in numbers:
    squares.append(number * number)

# squares = [1, 4, 9, 16, 25]</pre>
  <p>Можно воспользоваться предыдущим примером с функцией <code>map</code>:</p>
  <pre>numbers = [1, 2, 3, 4, 5]
squares = map(lambda x: x * x, numbers)

# squares = [1, 4, 9, 16, 25]</pre>
  <p>Да, определенно этот код короче предыдущего, но всё еще некрасив. С первого взгляда сложно сказать, что делает функция <code>map</code> (она принимает в качестве аргументов функцию и список и применяет функцию к каждому элементу списка). К тому же мы вынуждены определять функцию, это выглядит довольно беспорядочно.</p>
  <p>Но, оказывается, можно писать проще и понятнее:</p>
  <pre>numbers = [1, 2, 3, 4, 5]
squares = [number * number for number in numbers]

# squares = [1, 4, 9, 16, 25]</pre>
  <blockquote>Вторая строчка здесь читается практически как исполняемый псевдокод. Чем это хорошо? Даже без знаний Python человек без проблем определит что делает этот код.</blockquote>
  <h1>5. Фильтрация списка</h1>
  <p>А что, если нас интересует фильтрация списка? Например, требуется удалить все четные элементы.</p>
  <p>Новичок в программировании на Python напишет так:</p>
  <pre>numbers = [1, 2, 3, 4, 5]
odds = []
for number in numbers:
    if number % 2:
        odds.append(number)

# odds = [1, 3, 5]</pre>
  <p>Очень просто, не так ли? Но код занимает 5 строк, содержит два уровня отступов и при этом делает совершенно тривиальную вещь.</p>
  <p>Можно уменьшить размер кода с помощью функции <code>filter</code>:</p>
  <pre>numbers = [1, 2, 3, 4, 5]
odds = filter(lambda x: x % 2, numbers)

# odds = [1, 3, 5]</pre>
  <p>Аналогично функции <code>map</code>, о которой мы говорили выше, <code>filter</code> сокращает код, но выглядит довольно уродливо.</p>
  <p>Как работает функция <code>filter</code>? Как и <code>map</code>, <code>filter</code> получает функцию и список. Если функция от элемента возвращает <code>True</code>, элемент включается в результирующий список.</p>
  <p>Ну и а качестве вишенки на торте, мы можем сделать это через списковые включения:</p>
  <pre>numbers = [1, 2, 3, 4, 5]
odds = [number for number in numbers if number % 2]

# odds = [1,3,5]</pre>
  <h1>6. Одновременное использование map и filter</h1>
  <p>Теперь мы можем использовать всю силу списковых включений (их еще кстати называют генераторами списков). Теперь попробуем использовать отображение и фильтрацию списка одновременно. Другими словами, я хочу увидеть нечетные квадраты элементов списка.</p>
  <p>Неопытный программист на Python напишет так:</p>
  <pre>numbers = [1, 2, 3, 4, 5]
odd_squares = []
for number in numbers:
    if number % 4:
        odd_squares.append(number * number)

# odd_squares = [1, 9, 25]</pre>
  <p>Увы, код начал растягиваться вправо. Может, получится упростить его?</p>
  <p>Попробуем использовать <code>map</code> и <code>filter</code>:</p>
  <pre>numbers = [1, 2, 3, 4, 5]
odd_squares = map(lambda x: x * x, filter(lambda x: x % 2, numbers))

# odd_squares = [1, 9, 25]</pre>
  <p>Раньше <code>map</code> и <code>filter</code> было трудно читать, а теперь вообще невозможно. Очевидно, это не лучшая идея.</p>
  <p>Попробуем спасти ситуацию с помощью генератора списков:</p>
  <pre>numbers = [1, 2, 3, 4, 5]
odd_squares = [number * number for number in numbers if number % 2]
# odd_squares = [1, 9, 25]</pre>
  <p>Да, получилось немного длиннее, чем предыдущие примеры со списковым включением, но, мне кажется, вполне читабельно. Определенно лучше, чем цикл <code>for</code>.</p>
  <blockquote>Кстати, генератор списков сначала фильтрует, а затем уже отображает. Если нужно наоборот, получится сложнее. Придется использовать либо вложенные генерации, либо <code>map</code> и <code>filter</code>, либо обычный цикл <code>for</code>, в зависимости от того, что проще.</blockquote>
  <h1>7. Моржовый оператор</h1>
  <p>Новый способ присваивания выражения (<code>:=</code>), или оператор «морж», был самой обсуждаемой функцией, представленной в последней версии Python. Новое дополнение к языку было предложено в <strong>PEP 572.</strong></p>
  <p>Сразу посмотрим, как это выглядит в коде:</p>
  <pre>(x:= 5)
print(x)
# Output: 5</pre>
  <p>Присваивания с помощью моржа требуется делать в круглых скобках, и перед знаком равно пишется двоеточие. Внутри скобок либо создается новая переменная, либо происходит присвоение значения уже существующий переменной.</p>
  <p>Пойдем дальше и рассмотрим пример, в котором раскрывается весь потенциал моржового оператора:</p>
  <pre># пусть a – контейнер или последовательность
if (n:= len(a)) &gt; 10:
    print(f&#x27;Слишком много элементов, а именно {n}&#x27;)</pre>
  <p>То есть мы только что прямо в проверке условия объявили новую переменную n и далее использовали ее вместо того, чтобы вычислять значение заново. Для сравнения посмотрим, как мы это могли сделать раньше:</p>
  <pre>n = len(a)
if n &gt; 10:
    print(f&#x27;Слишком много элементов, а именно {n}&#x27;)

# или

if len(a) &gt; 10:
    print(f&#x27;Слишком много элементов, а именно {len(a)}&#x27;)</pre>
  <p>В первом случае появляется лишняя строка кода, в которой объявляется ненужная переменная. Во втором случае дважды вызвана одна и та же функция, а это потеря в производительности.</p>
  <p>Ну и еще пара примеров на закуску:</p>
  <ul>
    <li>Повторно используем значение в списке:</li>
  </ul>
  <pre>foo = [y:= f(x), y * 2, y * 3]

# вместо

foo = [f(x), f(x) * 2, f(x) * 3]</pre>
  <ul>
    <li>Повторное использование значения из условия в генераторных выражениях:</li>
  </ul>
  <pre>[y for x in data if (y:=f(x))]

# вместо

result = []
for x in data:
    result = f(x)
    if result:
        results.append(result)</pre>
  <ul>
    <li>Чтение данных из файла внутри циклов while:</li>
  </ul>
  <pre>while (block := f.read(256)) != &#x27;&#x27;:
    process(block)

# вместо

while True:
    stuff()
    if fail_condition:
        break</pre>
  <p>Надеюсь тебе понравилась эта статья. Если будет много просмотров, мы подготовим и выпустим вторую часть топ фишек в Python.</p>
  <hr />
  <p>Статья подготовлена образовательной организацией <a href="http://t.me/python_academy" target="_blank">Python Academy</a></p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@python_academy/8NcFrg8R</guid><link>https://teletype.in/@python_academy/8NcFrg8R?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=python_academy</link><comments>https://teletype.in/@python_academy/8NcFrg8R?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=python_academy#comments</comments><dc:creator>python_academy</dc:creator><title>Переносим проект на хостинг</title><pubDate>Fri, 21 Feb 2020 13:08:29 GMT</pubDate><media:content medium="image" url="https://teletype.in/files/04/4a/044a6f8a-8777-4573-a914-80edceaca832.png"></media:content><description><![CDATA[<img src="https://teletype.in/files/76/37/76375daf-9340-4e99-ac02-8e41ee85030f.png"></img>Итак, после того как мы закончили с написанием кода по превращению аватарки Telegram в часы, следующим логическим шагом было бы развёртывание проекта на сервере. Наверняка у вас его нет, да и покупать как-то не хочется... Hо это и необязательно, поскольку сейчас существует множество бесплатных облачных решений, например Heroku.]]></description><content:encoded><![CDATA[
  <figure class="m_column">
    <img src="https://teletype.in/files/76/37/76375daf-9340-4e99-ac02-8e41ee85030f.png" width="1920" />
  </figure>
  <p>Итак, после того как мы закончили с написанием кода по превращению аватарки Telegram в часы, следующим логическим шагом было бы развёртывание проекта на сервере. Наверняка у вас его нет, да и покупать как-то не хочется... Hо это и необязательно, поскольку сейчас существует множество бесплатных облачных решений, например Heroku.</p>
  <h1>Подготавливаем инструменты</h1>
  <p>Сперва давай зарегистрируем тебя на <a href="https://github.com" target="_blank">GitHub</a>. Необходимо создать аккаунт (рано или поздно он точно может пригодиться) и установить Git. После создания аккаунта жмем &quot;<strong>New repository</strong>&quot;. Называем его <strong>TimeChanger</strong>, можем добавить какое-либо описание, и жмем &quot;<strong>Create repository</strong>&quot;.</p>
  <figure class="m_column">
    <img src="https://teletype.in/files/3a/31/3a314763-8cbb-43ca-8dc2-1dec6820313b.png" width="1446" />
    <figcaption>Создаем репозиторий</figcaption>
  </figure>
  <p>Теперь установим Git. На Linux это можно сделать с помощью следующей команды:</p>
  <pre>$ sudo apt-get install git-all</pre>
  <p>На MacOS и Windows его нужно будет <strong>скачать и установить</strong>.</p>
  <p><a href="https://git-scm.com/download/mac" target="_blank">Ссылка для скачивания на MacOS</a></p>
  <p><a href="https://git-scm.com/download/win" target="_blank">Ссылка для скачивания на Windows</a></p>
  <blockquote>Скачиваем Git по ссылкам выше и устанавливаем, это несложно.</blockquote>
  <p>Да, и не забудь конечно же <a href="https://signup.heroku.com/" target="_blank">зарегистрироваться</a> на Heroku.</p>
  <h1>Командная строка</h1>
  <p>Есть много различных способов использования Git. Помимо оригинального клиента, имеющего интерфейс командной строки, существует множество клиентов с графическим интерфейсом, в той или иной степени реализующих функциональность Git.</p>
  <blockquote>В рамках данной статьи мы будем использовать Git в командной строке. Кроме того, с виртуальными средами можно работать только в контексте командной строки.</blockquote>
  <p>Поэтому, предполагается, что ты хотя бы в общих чертах знаешь, как открыть терминал в Mac или командную строку, или Powershell в Windows. Если это непонятно, возможно придётся ненадолго прерваться и изучить эти вопросы.</p>
  <h1>Виртуальные среды</h1>
  <p>Мы будем работать с виртуальной средой <code>virtualenv</code>. Сначала установим ее, выполнив команду в терминале Windows:</p>
  <pre>$ pip install virtualenv</pre>
  <p>Для MacOS или Linux будем использовать:</p>
  <pre>$ pip3 install virtualenv</pre>
  <p>Теперь давай наведем порядок в файлах. Создай новую папку и перейди в неё в терминале или командной строке. Нам нужно инициализировать в ней <code>virtualenv</code>:</p>
  <pre>$ virtualenv my_env</pre>
  <blockquote>Имя среды <code>my_env</code> в принципе не имеет особого значения, но лучше сделать его интуитивно понятным.</blockquote>
  <p>Переходим в папку <code>my_env</code>. Здесь, в принципе и на Windows и на Linux/MacOS синтаксис одинаковый, используем команду <code>cd</code>. Теперь нужно клонировать git-репозиторий.</p>
  <p>Вводим следующую команду:</p>
  <pre>$ git clone https://github.com/adreex/TimeChanger</pre>
  <p>Таким образом мы скопировали в папку проект отсюда: <a href="https://github.com/adreex/TimeChanger" target="_blank">https://github.com/adreex/TimeChanger</a></p>
  <p>В той же папке <code>my_env</code> запустим <code>virtualenv</code>:</p>
  <ul>
    <li>На Windows:  <code>$ scripts\\activate.bat </code></li>
    <li>На Linux/MacOS: <code>$ source bin/activate </code></li>
  </ul>
  <blockquote>Если <code>virtualenv</code> был успешно запущен, приглашение командной строки должно начинаться с (<strong>my_env</strong>).</blockquote>
  <h1>Установка зависимостей</h1>
  <p>Вообще говоря, в скопированном нами репозитории уже есть файл requirements.txt. Но далее нам понадобится рабочий интерпретатор на нашей локальной машине, для создания файла сессии. И кроме того, вдруг когда-нибудь понадобится деплоить собственный код?</p>
  <p>Из терминала переходим в папку репозитория (мы клонировали ее под именем TimeChanger), и устанавливаем все необходимые зависимости:</p>
  <pre>$ pip install Pillow==6.0.0 pyaes==1.6.1 pyasn1==0.4.5 pytz==2019.1 rsa==4.0 Telethon==1.8.0</pre>
  <blockquote>Обрати внимание, если ты деплоишь <strong>своего</strong> бота, то тут должны быть те зависимости, которые необходимы для <strong>твоего</strong> проекта.</blockquote>
  <p>Теперь нужно создать список зависимостей Heroku. Это несложно:</p>
  <pre>$ pip freeze &gt; requirements.txt</pre>
  <h1>Финальные шаги</h1>
  <p>В папке с проектом создадим <code>Procfile</code>. В этом файле необходимо разместить инструкции по работе с нашим скриптом. Имя файла обязательно должно быть <code>Procfile</code> (<code>Procfile.windows</code> в случае с Windows). У него <strong>не должно быть</strong> других расширений.</p>
  <p>Содержимое файла должно быть таким:</p>
  <pre>worker: python main.py</pre>
  <p>Добавим файл <code>__init__.py</code> в папку с проектом. Он может быть пустым (просто оставь там закомменченную строку вида # test), но он должен там быть.</p>
  <p>Добавим все файлы проекта и сделаем коммит в репозиторий:</p>
  <pre>$ git init
$ git add .
$ git commit -m &#x27;initial commit&#x27;
$ git push --set-upstream &lt;https://github.com/имя_вашего_профиля/TimeChanger&gt; master</pre>
  <p>Теперь развернём проект на Heroku. Можно использовать и панель управления на сайте, но мы потренируемся делать всё через консоль.</p>
  <p>Для MacOS или Windows, необходимо установить <a href="https://devcenter.heroku.com/articles/getting-started-with-python#set-up" target="_blank">интерфейс командной строки</a>. Переходим по ссылке и устанавливаем.</p>
  <p>Для установки на Linux достаточно ввести команду:</p>
  <pre>sudo snap install heroku --classic</pre>
  <p>Помнишь мы ставили виртуальную среду и необходимые пакеты? Выполним на локальной машине следующий код:</p>
  <pre>python3 main.py</pre>
  <p>После этого вводим телефон, и создаем новую сессию в Telegram. Нам понадобится файл <code>session.session</code>, который мы зальем (вместе с остальным кодом) с помощью Git на Heroku</p>
  <pre>$ git add .
$ git commit -m &#x27;initial commit&#x27;</pre>
  <p>Логинимся в Heroku, создаем приложение, и делаем пуш кода:</p>
  <pre>$ heroku login
$ heroku create
$ git push heroku master
$ heroku ps:scale worker=1</pre>
  <p>С этого момента приложение должно работать на сервере Heroku. Если что-то пойдёт не так, проверить логи можно следующим образом:</p>
  <pre>$ heroku logs --tail</pre>
  <blockquote>Коды ошибок можно найти <a href="https://devcenter.heroku.com/articles/error-codes" target="_blank">на сайте Heroku</a>.</blockquote>
  <h1>Итог</h1>
  <p>Безусловно, бесплатный аккаунт накладывает некоторые ограничения. Тем не менее, теперь код с часами полностью автоматизирован. Поздравляем!</p>
  <hr />
  <p>Материал подготовлен образовательной организацией Python Academy.</p>

]]></content:encoded></item></channel></rss>