Category: Python

17
Янв
2020

Веб-скрапинг по расписанию с Django и Heroku

Создаём Django-приложение, ежедневно проверяющее доску объявлений о работе. Парсим в BeautifulSoup, сохраняем в PostgreSQL, развёртываем на сервере Heroku.

Веб-скрапинг используется для сбора различной информации, в том числе для таких видов данных, которые регулярно обновляются, например, сообщений с досок объявлений о новых вакансиях. В этом проекте мы развернём на сервере Heroku приложение Django, которое посылает соответствующие уведомления о публикации новых мест работы.


План рассказа:

  1. Создаём Django приложение
  2. Создаём и настраиваем модель вакансии
  3. Настраиваем базу данных
  4. Тестируем приложение
  5. Настраиваем команды django-admin
  6. Разёрываем приложение на Heroku
  7. Планируем расписание скрапинг

1. Создаём Django приложение

Создаём каталог приложения и переходим в него.

            mkdir jobs && cd jobs 
        

Создаём и запускаем виртуальную среду. Устанавливаем необходимые пакеты.

            python -m venv env
source env/bin/activate
pip3 install django psycopg2 django-heroku bs4 gunicorn 
        

Создаём проект Django.

            django-admin startproject jobs 
        

Заходим в проект и создаём приложение для скрапинга.

            cd jobs
django-admin startapp scraping 
        

2. Создаём и настраиваем модель

Теперь нужно определить единственную модель нашего приложения – модель работы. Она соответствует записям о вакансиях, которые мы будем собирать.

Файл /scraping/models.py перезаписываем со следующим содержанием.

            from django.db import models
from django.utils import timezone

class Job(models.Model):
    url = models.CharField(max_length=250, unique=True)
    title = models.CharField(max_length=250)
    location = models.CharField(max_length=250)
    created_date = models.DateTimeField(default=timezone.now)

    def __str__(self):
        return self.title

    class Meta:
        ordering = ['title']
   
    class Admin:
        pass 
        

Зарегистрируем модель в /scraping/admin.py. Это позволит просматривать записи в стандартной панели администратора Django (скоро мы к этому вернёмся):

            from scraping.models import Job
admin.site.register(Job) 
        

Добавялем scraping в установленные приложения в /jobs/settings.py.

            INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'scraping'
] 
        

3. Настраиваем базу данных

Настраиваем базу данных. В нашем примере это будет PostgreSQL (Библиотека программиста писала о том, как начать разбираться в PostgreSQL).

Создаём базу данных для проекта в командной строке. Открываем консоль PostgreSQL:

            psql -d template1 
        

Создаём пользователя и базу данных, выходим:

            create user django_user;
create database django_jobs owner django_user;
\q 
        

В /jobs/settings.py обновите константу DATABASES:

            DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'django_jobs',
        'USER': 'django_user',
        'HOST': '',
        'PORT': ''
    }
} 
        

Создаём файлы для миграции и переносим базу данных.

            python manage.py makemigrations
python manage.py migrate 
        

Это создаст таблицу с именем scraping_job. Название соответствует соглашению Django о пространстве имён.

Создаём суперпользователя и пароль:

            python manage.py createsuperuser --email admin@example.com --username admin 
        

4. Тестируем приложение

Мы уже что-то сделали, но пока понятия не имеем, работает ли оно. Давайте проверим, прежде чем идти дальше:

            python manage.py runserver 
        

Переходом в браузере по адресу http://127.0.0.1:8000/admin. Входим в систему под суперпользователем, которого только что создали. После входа в систему, нажимаем jobs в разделе scraping, затем add job в правом верхнем углу. Заполняем пример информации и жмём save. Если вы видите созданную вами запись, то всё работает.

5. Настраиваем команды django-admin

Теперь настроим кастомную команду django-admin, которая производит скрапинг доски с вакансиями. Это то, что мы планируем на уровне инфраструктуры, чтобы автоматизировать скрапинг.

Внутри каталога /scraping создаём каталог с именем /management и каталог внутри /management с именем /commands. В папке /commands создаём два файла Python: _private.py и scrape.py.


Ниже идёт код скрапера, записанный в scrape.py. При необходимости перепишете его под страницу, с которой нужно собирать информацию. Здесь это вакансии фирмы, в которой автору интересно работать.

            from django.core.management.base import BaseCommand

from urllib.request import urlopen
from bs4 import BeautifulSoup
import jsonfrom scraping.models import Job

class Command(BaseCommand):
    help = "collect jobs"   

    # определяем логику команд
    def handle(self, *args, **options):

        # собираем html
        html = urlopen('https://jobs.lever.co/opencare')

        # преобразуем в soup-объект
        soup = BeautifulSoup(html, 'html.parser')

        # собираем все посты
        postings = soup.find_all("div", class_="posting")

        for p in postings:
            url = p.find('a', class_='posting-btn-submit')['href']
            title = p.find('h5').text
            location = p.find('span', class_='sort-by-location').text        # check if url in db
            try:
                # сохраняем в базе данных
                Job.objects.create(
                    url=url,
                    title=title,
                    location=location)
                print('%s added' % (title,))
            except:
                print('%s already exists' % (title,))

        self.stdout.write( 'job complete' )

 
        

Функция handle в определении класса Command сообщает Django, что это пользовательская команда django-admin. Для самого скрапинга используем BeautifulSoup. В Библиотеке программиста есть популярный видеокурс по парсингу сайтов со ссылками на видео и листингом кода.

Запускаем свежесозданную пользовательскую команду:

            python manage.py scrape 
        

Видим следующий вывод:


Запустив снова, увидим следующее:


Разный вывод связан с тем, что в scrape.py мы запретили добавлять дубликаты записей.

Если у вас установлена ​​программа администрирования баз данных (например, dbeaver), вы также можете проверить строки в БД. Это должно выглядеть приблизительно так, как показано ниже.


6. Развёртываем на Heroku

Перенесём получившийся результат на Heroku. Заморозим зависимости, чтобы Heroku знал, что устанавливать при развёртывании.

            pip3 freeze > requirements.txt 
        

Предотвратим перенос ненужных файлов. В .gitignore запишем следующее:

            .DS_Store
jobs/__pycache__
scraping/__pycache__ 
        

Создаём файл с именем Procfile в корне и вставляем приведённые ниже строки:

            web: gunicorn jobs.wsgi
release: python manage.py migrate 
        

Первая строка говорит Heroku о запуске web dyno, вторая команда переносит базу данных.

Дерево файлов будет выглядеть так.


Заходим в heroku из командной строки (heroku login). Создаём приложение с любым подходящим именем. Имя обязано быть уникальным среди всех приложений Heroku. Вводим heroku create имя-приложения .

Теперь добавляем следующие строки в самый конец файла settings.py. Модуль heroku_django позаботится за вас о настройках конфигурации.

            import django_heroku
django_heroku.settings(locals()) 
        

Обновляем в настройках DEBUG, если не хотим развертывать в режиме отладки.

            DEBUG = False 
        

Добавляет файлы в Git.

            git init
git add . -A
git commit -m 'first commit' 
        

Пушим приложение в Heroku.

            git push heroku master 
        

7. Планируем расписание скрапинга

Конечно, можно вручную запускать задание из командной строки

            heroku run python manage.py scrape 
        

Но мы же хотим автоматизировать процесс! Входим в консоль Heroku, идём в Resources, затем find more add-ons.


Находим и нажимаем на дополнение, ищем scheduler .




Нажимаем, выбираем время, например, everyday at... 12am UTC. Не пингуем сайты больше чем нужно. Вводим созданную команду и сохраняем.


Теперь просто дожидаем 12:00 UTC или другого времени, и проверяем базу данных.

Заключение

Мы коснулись здесь многих разных вещей: Django, Heroku, веб-скрапинг, PostgreSQL. О всех этих инструмента по отдельности Библиотека программиста уже писала, а объединяющего практического материала – ещё не было. Если что-то оказалось сложным, воспользуйтесь приведёнными ссылками.

Конечно, у вас могут быть другие идеи для использования отложенного скрапинга. Например:

  • Компании электронной коммерции хотят отслеживать цены конкурентов..
  • Разработчики отслеживают IT-мероприятия и курсы из разных источников.
  • Аналитики собирают информацию о конкурсах по анализу данных с нескольких платформ.

Это пособие лишь конкретный пример использования подхода. Дайте нам знать, если вам интересны подобные проекты.

17
Янв
2020

Наглядная шпаргалка по операциям с DataFrame в pandas для data wrangling и не только

Удобная и наглядная шпаргалка по основным операциям с DataFrame в pandas. Подходит для data wrangling и не только.
— Читать дальше «Наглядная шпаргалка по операциям с DataFrame в pandas для data wrangling и не только»

15
Янв
2020

Опыт разработки: почему мы пишем инфраструктуру машинного обучения на Go, а не на Python

Разработчик Cortex Калеб Кайзер делится соображениями о преимуществах применения Go для инфраструктурных решений в ML-проектах и о том, как два языка могут дополнять друг друга.

Python – самый популярный яз…

13
Янв
2020

Python умер, да здравствует Python. Видеокурс по программированию на Python 3

Учимся программировать простые графические приложения на Python 3. Параллельно узнаём о Git и принципах качественного кода.
— Читать дальше «Python умер, да здравствует Python. Видеокурс по программированию на Python 3»

12
Янв
2020

Иллюстрированное руководство по изменению формы массивов NumPy

Рассказываем, как перекраивать массивы NumPy в трех измерениях. Шпаргалка в конце руководства обобщает приемы работы с методами reshape, stack и ravel.

Трудность NumPy в том, что операции над многомерными массивами бывает сложно представить. Хаус Лин подготовил шпаргалки, которые сделают преобразование массивов нагляднее. Руководство подойдёт и для знакомства с NumPy.

1. Создаем массив NumPy

Аналог range для массивов. Чтобы создать простой массив, используем функцию np.arange(). Удобно взять небольшое составное число, например, 12.

            import numpy as np

a1 = np.arange(1, 13)  # числа от 1 до 12

print(a1.shape)
> (12,)

print(a1)
> [ 1  2  3  4  5  6  7  8  9 10 11 12] 
        
Создан одномерный массив из 12 чисел.

2. Изменяем форму с помощью метода reshape()

Оси и измерения. Чтобы изменить форму массива a1 , используем метод reshape(). Преобразуем одномерный массив из 12 чисел в двумерную таблицу размером 3×4. Первое число – количество строк, второе – столбцов. Строки соответствуют оси (англ. axis) 0, столбцы – оси 1. Ещё их называют измерениями (англ. dimensions).

            a1_2d = a1.reshape(3, 4)

print(a1_2d.shape)
> (3, 4)

print(a1_2d)
> [[ 1  2  3  4]
   [ 5  6  7  8]
   [ 9 10 11 12]] 
        

Автоматическое вычисление размерности. Если нужно, чтобы NumPy сам определил размер незаданного измерения, передайте на этой позиции значение -1:

            a1.reshape(3, 4)
a1.reshape(-1, 4)  # то же самое, что a1.reshape(3, 4)

a1.reshape(3, 4)
a1.reshape(3, -1)  # то же самое, что a1.reshape(3, 4)

a1.reshape(2, 6)
a1.reshape(2, -1)  # то же самое, что a1.reshape(2, 6) 
        

3. Изменяем форму по разным направлениям

Порядок переноса С. По умолчанию reshape() перестраивает исходный массив по оси 0. То есть в нашем примере отдельные числа из одномерного массива «переносятся» в двумерный построчно. Поведение можно изменить, передав значение параметру order. Дефолтный метод похож на то, как преобразование реализовано в C. Параметр order по умолчанию имеет значение 'C':

            a1.reshape(3, 4)
a1.reshape(3, 4, order='C') # даст идентичный результат
 
        

Порядок переноса Fortran. Если вы привыкли к тому, как преобразуются массивы в MATLAB, то это делается так же, как в Fortran. Поэтому используйте значение 'F':

            a1.reshape(3, 4, order='F')  # столбец за столбцом
> [[ 1  4  7 10]
   [ 2  5  8 11]
   [ 3  6  9 12]] 
        

Какую размерность имеет исходный массив a1? Может показаться, что массив a1 имеет размерность (1, 12). Но это одномерный массив с размерностью(12, ). Чтобы преобразовать одномерный массив к двумерному, используем метод reshape():

            print(a1)  # какая форма?
> [ 1  2  3  4  5  6  7  8  9 10 11 12]

print(a1.shape)
> (12,)

a1_1_by_12 = a1.reshape(1, -1)  # преобразуем к 1x12

print(a1_1_by_12)  # обратите внимание на двойные скобки
> [[ 1  2  3  4  5  6  7  8  9 10 11 12]]

print(a1_1_by_12.shape)  # двумерный массив
> (1, 12) 
        

4. Схлопываем массив до одномерного

Из 2D в 1D. Метод ravel() преобразует многомерные массивы в одномерные. Тот же параметр order определяет, «схлопнется» ли массив построчно или столбец за столбцом:

            print(a1_2d)
> [[ 1  2  3  4]
   [ 5  6  7  8]
   [ 9 10 11 12]]

print(a1_2d.ravel())  # строка за строкой
> [ 1  2  3  4  5  6  7  8  9 10 11 12]

print(a1_2d.ravel(order='F'))  # столбец за столбцом
> [ 1  5  9  2  6 10  3  7 11  4  8 12] 
        

5. Повышаем размерность, сшивая массивы друг с другом


Создадим два массива:

            a1 = np.arange(1, 13)
print(a1)
> [ 1  2  3  4  5  6  7  8  9 10 11 12]

a2 = np.arange(13, 25)
print(a2)
> [13 14 15 16 17 18 19 20 21 22 23 24] 
        

Чтобы соединить два одномерных масива в двумерный, используем метод np.stack(). Параметр axis указывает индекс оси в результирующем массиве, по которой соединяются входные. По умолчанию axis = 0, и массивы стыкуются строка к строке:

            stack0 = np.stack((a1, a1, a2, a2))
print(stack0.shape)
> (4, 12)

print(stack0)
> [[ 1  2  3  4  5  6  7  8  9 10 11 12]
   [ 1  2  3  4  5  6  7  8  9 10 11 12]
   [13 14 15 16 17 18 19 20 21 22 23 24]
   [13 14 15 16 17 18 19 20 21 22 23 24]] 
        

Чтобы соединить массивы столбец к столбцу, явным образом передаем axis = 1:

            stack1 = np.stack((a1, a1, a2, a2), axis=1)
print(stack1.shape)
> (12, 4)
print(stack1)
> [[ 1  1 13 13]
   [ 2  2 14 14]
   [ 3  3 15 15]
   [ 4  4 16 16]
   [ 5  5 17 17]
   [ 6  6 18 18]
   [ 7  7 19 19]
   [ 8  8 20 20]
   [ 9  9 21 21]
   [10 10 22 22]
   [11 11 23 23]
   [12 12 24 24]] 
        

Как не повышать число измерений? Функция hstack() соединяет массивы горизонтально без изменения размерности. Если применить ее к одномерным массивам, получится длинный одномерный массив:

            stack_long = np.hstack((a1, a2))

print(stack_long.shape)
> (24,)

print(stack_long)
> [ 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24] 
        

6. Создаем трехмерный массив

Где применяются многомерные массивы? Массивы, живущие в трёх и более измерениях, активно используются в глубоком обучении. Например, для операций с изображениями. В работе с нейросетями преобразование многомерных массивов – обычное дело.

Для начала создадим два двумерных массива размером 3×4:

            a1 = np.arange(1, 13).reshape(3, -1)
a2 = np.arange(13, 25).reshape(3, -1)

print(a1)
> [[ 1  2  3  4]
   [ 5  6  7  8]
   [ 9 10 11 12]]

print(a2)
> [[13 14 15 16]
   [17 18 19 20]
   [21 22 23 24]] 
        

Теперь соберём из них трёхмерный массив:

            a3_0 = np.stack((a1, a2))  # дефолтное axis=0, одна плоскость ложится на другую
a3_1 = np.stack((a1, a2), axis=1)
a3_2 = np.stack((a1, a2), axis=2)

print(a3_0.shape)
> (2, 3, 4)

print(a3_1.shape)
> (3, 2, 4)

print(a3_2.shape)
> (3, 4, 2) 
        

Как выглядят массивы:

            print(a3_0)
> [[[ 1  2  3  4]
    [ 5  6  7  8]
    [ 9 10 11 12]]

   [[13 14 15 16]
    [17 18 19 20]
    [21 22 23 24]]]

print(a3_1)
> [[[ 1  2  3  4]
    [13 14 15 16]]

   [[ 5  6  7  8]
    [17 18 19 20]]

   [[ 9 10 11 12]
    [21 22 23 24]]]

print(a3_2)
> [[[ 1 13]
    [ 2 14]
    [ 3 15]
    [ 4 16]]

   [[ 5 17]
    [ 6 18]
    [ 7 19]
    [ 8 20]]

   [[ 9 21]
    [10 22]
    [11 23]
    [12 24]]] 
        

Чтобы извлечь плоскость массива a1 из трехмерного, нужно передать 0 по соответствующему индексу оси:

            print(a1)
> [[ 1  2  3  4]
   [ 5  6  7  8]
   [ 9 10 11 12]]

a3_0[0, :, :]
a3_1[:, 0, :]
a3_2[:, :, 0] 
        

Чтобы то же самое сделать для двумерного массива a2, на тех же позициях вместо 0 отправляем индекс 1. Символы двоеточия указывают, что нужно взять все элементы соответствующей оси.

7. Схлопываем многомерные массивы

Метод ravel() действует и для массивов с числом размерностей больше 2:


            print(a3_0)
> [[[ 1  2  3  4]
    [ 5  6  7  8]
    [ 9 10 11 12]]

   [[13 14 15 16]
    [17 18 19 20]
    [21 22 23 24]]]

print(a3_0.ravel())
> [ 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24]

print(a3_0.ravel(order='F'))
> [ 1 13  5 17  9 21  2 14  6 18 10 22  3 15  7 19 11 23  4 16  8 20 12 24] 
        

8. Изменяем форму многомерных массивов

Метод reshape() также работает с массивами любой размерности. Главное условие, которое нужно соблюдать – количество элементов в массиве не должно меняться:

            print(a3_0)  # исходный размер 2x3x4
> [[[ 1  2  3  4]
    [ 5  6  7  8]
    [ 9 10 11 12]]

   [[13 14 15 16]
    [17 18 19 20]
    [21 22 23 24]]]

print(a3_0.reshape(4, -1))  # преобразуем к 4x6
> [[ 1  2  3  4  5  6]
   [ 7  8  9 10 11 12]
   [13 14 15 16 17 18]
   [19 20 21 22 23 24]]

print(a3_0.reshape(4, -1, order='F'))  # делаем то же самое, но в F-стиле
> [[ 1  9  6  3 11  8]
   [13 21 18 15 23 20]
   [ 5  2 10  7  4 12]
   [17 14 22 19 16 24]]

print(a3_0.reshape(4, 2, 3))  # преобразуем к трехмерному массиву другой формы
> [[[ 1  2  3]
    [ 4  5  6]]
   [[ 7  8  9]
    [10 11 12]]
   [[13 14 15]
    [16 17 18]]
   [[19 20 21]
    [22 23 24]]] 
        

Заключение

Напоследок приведем изображение со всеми элементами рассказа вместе (оригинальный pdf). Напишите нам в комментариях, если что-то осталось непонятным и требует пояснений.


30
Дек
2019

5 полезных фич Python, о которых знают не все

Python – один из самых популярных и мощных ЯП, скрывающих массу полезностей и фич. Пять из них мы осветили в статье.

Даже если ты
программист, перешедший с других языков, таких как C, в программирование
на Python с более высоким уровнем абстракции – не стоит
пугаться и отступать перед “не таким” кодом. Погнали!

List comprehensions –
компактный код

Многие назвали бы lambda,
map и filter “трюками” Python, которым должен научиться каждый новичок.
Принято считать, что эти функции большую часть времени, не особенно полезны,
поскольку им не хватает гибкости.

Лямбда – это метод
составления функции в одну строку для одноразового использования. Если он
вызывается несколько раз, страдает производительность. С другой стороны, map
применяет функцию ко всем элементам списка, в то время как filter получает
подмножество элементов в наборе, удовлетворяющем пользовательскому условию.

            add_func = lambda z: z ** 2
is_odd = lambda z: z%2 == 1
multiply = lambda x,y: x*y

aList = list(range(10))
print(aList)
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
        

List comprehensions – это
лаконичный метод для создания списков из других списков с гибкими выражениями и
условиями. Он выделяется квадратными скобками, в которых определено выражение
или функция. Когда элемент удовлетворяет условию, только в этом
случае действие применяется к каждому элементу списка. Метод также может обрабатывать
вложенные списки продуктивнее, чем использование мапы и фильтра.

            # Syntax of list comprehension
[ expression(x) for x in aList if optional_condition(x) ] 
        
            print(list(map(add_func, aList)))
print([x ** 2 for x in aList])
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

print(list(filter(is_odd, aList)))
print([x for x in aList if x%2 == 1])
# [1, 3, 5, 7, 9]
# [1, 3, 5, 7, 9] 
        

Манипуляции со списками
– циклические списки

Python поддерживает
отрицательную индексацию, где aList[-1] == aList[len(aList)-1]. Исходя из этого,
можно получить второй последний элемент в списке – aList[-2] и так далее.

Также можно нарезать
списки с помощью записи aList[start:end: step], где начальный элемент указан, а
конечный – нет. Поэтому вызов aList[2:5] вернет [2, 3, 4], а вызвав aList[::
-1]
, ты сможешь переставить элементы в списке в обратном порядке – очень элегантная техника.


А еще списки могут
быть распакованы в отдельные элементы или сливать элементы, которые
не влезли в лимит переменных, в подсписок, используя звездочку.

            a, b, c, d = aList[0:4]
print(f'a = {a}, b = {b}, c = {c}, d = {d}')
# a = 0, b = 1, c = 2, d = 3

a, *b, c, d = aList
print(f'a = {a}, b = {b}, c = {c}, d = {d}')
# a = 0, b = [1, 2, 3, 4, 5, 6, 7], c = 8, d = 9 
        

zip, enumerate и for-loops

Функция zip создает итератор, который агрегирует элементы из
нескольких списков. Он позволяет выполнять параллельный обход списков в цикле for и
параллельную сортировку. Обратное действие (unzip) совершается с помощью звездочки.

            numList = [0, 1, 2]
engList = ['zero', 'one', 'two']
espList = ['cero', 'uno', 'dos']
print(list(zip(numList, engList, espList)))
# [(0, 'zero', 'cero'), (1, 'one', 'uno'), (2, 'two', 'dos')]

for num, eng, esp in zip(numList, engList, espList):
    print(f'{num} is {eng} in English and {esp} in Spanish.')
# 0 is zero in English and cero in Spanish.
# 1 is one in English and uno in Spanish.
# 2 is two in English and dos in Spanish. 
        
            Eng = list(zip(engList, espList, numList))
Eng.sort() # sort by engList
a, b, c = zip(*Eng)

print(a)
print(b)
print(c)
# ('one', 'two', 'zero')
# ('uno', 'dos', 'cero')
# (1, 2, 0) 
        

enumerate может
показаться немного пугающим, но данную функцию удобно
применять во многих ситуациях. Наиболее популярный вариант – автоматический
счетчик для цикла for: больше нет
необходимости создавать и инициализировать переменную счетчика с помощью counter = 0 и counter
+= 1
. enumerate и zip – это два самых мощных инструмента при построении
цикла for.

            upperCase = ['A', 'B', 'C', 'D', 'E', 'F']
lowerCase = ['a', 'b', 'c', 'd', 'e', 'f']
for i, (upper, lower) in enumerate(zip(upperCase, lowerCase), 1):
    print(f'{i}: {upper} and {lower}.')
# 1: A and a.
# 2: B and b.
# 3: C and c.
# 4: D and d.
# 5: E and e.
# 6: F and f. 
        

Генератор –
эффективность использования памяти

Генераторы используются,
когда нужно вычислить большой набор результатов, но необходимо избежать одновременного
выделения памяти под все результаты. Другими словами, они генерируют значения
на лету и не хранят предыдущие значения в памяти, поэтому их можно итерировать
только раз.

Они часто используются
при чтении больших файлов или создании бесконечной последовательности при
помощи ключевого слова yield.

            def gen(n):    # an infinite sequence generator that generates integers >= n
    while True:
        yield n
        n += 1
        
G = gen(3)     # starts at 3
print(next(G)) # 3
print(next(G)) # 4
print(next(G)) # 5
print(next(G)) # 6 
        

Виртуальная среда –
изоляция

Самая интересная и
увлекательная штука из подборки.


Приложения Python часто
используют множество пакетов от различных разработчиков со сложными
зависимостями. Разные приложения создаются с использованием определенных наборов
библиотек, в которых выходные данные не могут быть использованы другими
версиями библиотеки. Не существует единой установки, которая удовлетворяла бы
требованиям всех приложений.

            conda create -n venv pip python=3.7  # select python version
source activate venv
...
source deactivate 
        

Поэтому крайне важно
создать отдельные автономные виртуальные среды venv для каждого приложения, что
и можно сделать с помощью pip или conda.

А
какие фичи в Python
любишь ты?

26
Ноя
2019

Тест на знание самых необычных особенностей Python

За что разработчики любят Python? Например, за ясный синтаксис. Но в этом тесте мы собрали редкие несуразности языка. Новички о них не знают, профессионалы – не помнят. Те неочевидные вещи, которых нужно избегать в разработке. Ос-с-стерегай…

31
Окт
2019

Гвидо ван Россум покинул Dropbox и вышел на пенсию

В компании он помогал совершенствовать практики написания кода, отлаживать инструменты для тестирования, создавать систему проверки типов Mypy.
— Читать дальше «Гвидо ван Россум покинул Dropbox и вышел на пенсию»

29
Окт
2019

Наперегонки со временем: на что способен Python в однопоточных вычислениях?

Многие знают, что Python в чистом виде — не лучший язык для научных вычислений. Однако никто не мешает провести эксперимент по его ускорению.
— Читать дальше «Наперегонки со временем: на что способен Python в однопоточных вычислениях?»

16
Окт
2019

Вышел Python 3.8

У него появился новый оператор присваивания, новый признак для задания аргументов функции, новые вызовы в Runtime Audit Hooks.
— Читать дальше «Вышел Python 3.8»

15
Окт
2019

Недоработка в Python-коде поставила под сомнение результаты 100 исследований по химии

Из-за неё результаты вычислений менялись в зависимости от операционной системы.
— Читать дальше «Недоработка в Python-коде поставила под сомнение результаты 100 исследований по химии»

26
Сен
2019

Установка и настройка IDE Geany для Python

Программирование на языке Python очень популярно и это не удивительно: он легкий для изучения (на нем учат программировать даже в школе), Python портирован и работает почти на всех известных платформах, применим как для WEB разработки, так и для анализ…

26
Сен
2019

6 октября, Москва: Moscow Programming Contest 2019

Международные соревнования по программированию для студентов, владеющих любым из следующих языков: C#, C++, Java, Python или Kotlin. Пройдут в 2 тура: квалификация и финал.
— Читать дальше «Moscow Programming Contest 2019»

21
Сен
2019

Сколько стоят операции над list, set и dict в Python? Разбираемся с временной сложностью

Временная сложность алгоритма часто обозначается нотацией «О» большое. Разбираемся, что это и какова сложность операций над коллекциями в Python.
— Читать дальше «Сколько стоят операции над list, set и dict в Python? Разбираемся с временной сложностью»…

09
Сен
2019

Онлайн-курс «CS50’s Web Programming with Python and JavaScript»

Научитесь полному циклу веб-разработки на Python и JavaScript. В программе изучение современных инструментов и много самостоятельной работы.
— Читать дальше «Курс «CS50’s Web Programming with Python and JavaScript»»

09
Сен
2019

13 сентября, Санкт-Петербург: олимпиада Proggy-Buggy

Международная олимпиада для тех, кто владеет любым из следующих языков программирования: C++, Free Pascal, Java, C#, Python, Ruby, PHP, JavaScript.
— Читать дальше «Олимпиада по программированию Proggy-Buggy»

09
Сен
2019

Онлайн-курс «Web-технологии»

Научитесь разработке на Python и Django, изучите HTML, погрузитесь в тематику web-разработки и сможете выбрать технологии для дальнейшего изучения.
— Читать дальше «Курс «Web-технологии»»

03
Сен
2019

Специализация Full Stack Web Developer

Изучите серверное программирование на Python, инструменты современной веб-разработки и администрирования Unix-систем под руководством специалистов.
— Читать дальше «Специализация Full Stack Web Developer»

29
Авг
2019

Луковое ПО: используем TOR для анонимного парсинга

Луковое ПО: используем TOR для анонимного парсингаПришло время для анонимного парсинга веб-страниц. В этом тебе поможет мощная команда: TOR, Privoxy, Python, Linux и наша статья. Где можно использовать? В случаях, когда нужно изменить свой IP-адрес при выполнении нескольких запросов за единицу времени без блокировки соединения. Настройка Для успешной разработки парсинг-агента на прокси-сервере нужно установить Linux с такими инструментами: TOR: распределенная, анонимная […]

Запись Луковое ПО: используем TOR для анонимного парсинга впервые появилась Библиотека программиста.

25
Авг
2019

13 проектов для Python-разработчиков среднего уровня

Изучив основы Python, вам наверняка захочется закрепить знания и поработать над каким-нибудь проектом. Однако не всегда сразу приходит в голову, что можно сделать, а проекты в интернете часто или слишком простые, или слишком сложные. Поэтому в этой статье будут собраны идеи, подходящие для разработчиков среднего уровня.

16
Авг
2019

9 сентября – 27 октября, Санкт-Петербург: курс «Python: основы программирования»

На вводном занятии расскажут о работе компьютера, а также об основах синтаксиса Python. Разберут учебную программу курса и ответят на вопросы слушателей.
— Читать дальше «Открытый урок курса «Python: основы программирования»»