Python — PYTHON https://chel-center.ru/python-yfc курс молодого бойца Tue, 11 Feb 2020 16:50:43 +0000 ru-RU hourly 1 https://wordpress.org/?v=5.9.3 https://chel-center.ru/python-yfc/wp-content/uploads/sites/15/2020/06/cropped-kmb-icon-2-1-32x32.png Python — PYTHON https://chel-center.ru/python-yfc 32 32 Как оформлять код https://chel-center.ru/python-yfc/2019/10/01/kak-oformlyat-kod/ https://chel-center.ru/python-yfc/2019/10/01/kak-oformlyat-kod/#respond Tue, 01 Oct 2019 01:35:18 +0000 http://chel-center.ru/python-yfc/?p=502 Читать далее «Как оформлять код»

]]>
Этот документ описывает соглашение о том, как писать код для языка python, включая стандартную библиотеку, входящую в состав python.

PEP 8 (Python Enhancement Proposals, англ. или предложения по улучшению Python, рус.) создан на основе рекомендаций Гуидо ван Россума с добавлениями от Барри. Если где-то возникал конфликт, мы выбирали стиль Гуидо. И, конечно, этот PEP может быть неполным (фактически, он, наверное, никогда не будет закончен).

Ключевая идея Гуидо такова: код читается намного больше раз, чем пишется. Собственно, рекомендации о стиле написания кода направлены на то, чтобы улучшить читаемость кода и сделать его согласованным между большим числом проектов. В идеале, весь код будет написан в едином стиле, и любой сможет легко его прочесть.

Это руководство о согласованности и единстве. Согласованность с этим руководством очень важна. Согласованность внутри одного проекта еще важнее. А согласованность внутри модуля или функции — самое важное. Но важно помнить, что иногда это руководство неприменимо, и понимать, когда можно отойти от рекомендаций. Когда вы сомневаетесь, просто посмотрите на другие примеры и решите, какой выглядит лучше.

Две причины для того, чтобы нарушить данные правила:

  1. Когда применение правила сделает код менее читаемым даже для того, кто привык читать код, который следует правилам.
  2. Чтобы писать в едином стиле с кодом, который уже есть в проекте и который нарушает правила (возможно, в силу исторических причин) — впрочем, это возможность переписать чужой код.

Внешний вид кода

Отступы

Используйте 4 пробела на каждый уровень отступа.

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

Правильно:

# Выровнено по открывающему разделителю
foo = long_function_name(var_one, var_two,
                         var_three, var_four)

# Больше отступов включено для отличения его от остальных
def long_function_name(
        var_one, var_two, var_three,
        var_four):
    print(var_one)

Неправильно:

# Аргументы на первой линии запрещены, если не используется вертикальное выравнивание
foo = long_function_name(var_one, var_two,
    var_three, var_four)

# Больше отступов требуется, для отличения его от остальных
def long_function_name(
    var_one, var_two, var_three,
    var_four):
    print(var_one)

Опционально:

# Нет необходимости в большем количестве отступов.
foo = long_function_name(
  var_one, var_two,
  var_three, var_four)

Закрывающие круглые/квадратные/фигурные скобки в многострочных конструкциях могут находиться под первым непробельным символом последней строки списка, например:

my_list = [
    1, 2, 3,
    4, 5, 6,
    ]
result = some_function_that_takes_arguments(
    'a', 'b', 'c',
    'd', 'e', 'f',
    )

либо быть под первым символом строки, начинающей многострочную конструкцию:

my_list = [
    1, 2, 3,
    4, 5, 6,
]
result = some_function_that_takes_arguments(
    'a', 'b', 'c',
    'd', 'e', 'f',
)

Табуляция или пробелы?

Пробелы — самый предпочтительный метод отступов.

Табуляция должна использоваться только для поддержки кода, написанного с отступами с помощью табуляции.

Python 3 запрещает смешивание табуляции и пробелов в отступах.

Python 2 пытается преобразовать табуляцию в пробелы.

Когда вы вызываете интерпретатор Python 2 в командной строке с параметром -t, он выдает предупреждения (warnings) при использовании смешанного стиля в отступах, а запустив интерпретатор с параметром -tt, вы получите в этих местах ошибки (errors). Эти параметры очень рекомендуются!

Максимальная длина строки

Ограничьте длину строки максимум 79 символами.

Для более длинных блоков текста с меньшими структурными ограничениями (строки документации или комментарии), длину строки следует ограничить 72 символами.

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

Некоторые команды предпочитают большую длину строки. Для кода, поддерживающегося исключительно или преимущественно этой группой, в которой могут прийти к согласию по этому вопросу, нормально увеличение длины строки с 80 до 100 символов (фактически увеличивая максимальную длину до 99 символов), при условии, что комментарии и строки документации все еще будут 72 символа.

Стандартная библиотека Python консервативна и требует ограничения длины строки в 79 символов (а строк документации/комментариев в 72).

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

Обратная косая черта все еще может быть использована время от времени. Например, длинная конструкция with не может использовать неявные продолжения, так что обратная косая черта является приемлемой:

with open('/path/to/some/file/you/want/to/read') as file_1, \
        open('/path/to/some/file/being/written', 'w') as file_2:
    file_2.write(file_1.read())

Ещё один случай — assert.

Сделайте правильные отступы для перенесённой строки. Предпочтительнее вставить перенос строки после логического оператора, но не перед ним. Например:

class Rectangle(Blob):

    def __init__(self, width, height,
                 color='black', emphasis=None, highlight=0):
        if (width == 0 and height == 0 and
                color == 'red' and emphasis == 'strong' or
                highlight > 100):
            raise ValueError("sorry, you lose")
        if width == 0 and height == 0 and (color == 'red' or
                                           emphasis is None):
            raise ValueError("I don't think so -- values are %s, %s" %
                             (width, height))
        Blob.__init__(self, width, height,
                      color, emphasis, highlight)

Пустые строки

Отделяйте функции верхнего уровня и определения классов двумя пустыми строками.

Определения методов внутри класса разделяются одной пустой строкой.

Дополнительные пустые строки возможно использовать для разделения различных групп похожих функций. Пустые строки могут быть опущены между несколькими связанными однострочниками (например, набор фиктивных реализаций).

Используйте пустые строки в функциях, чтобы указать логические разделы.

Python расценивает символ control+L как незначащий (whitespace), и вы можете использовать его, потому что многие редакторы обрабатывают его как разрыв страницы — таким образом логические части в файле будут на разных страницах. Однако, не все редакторы распознают control+L и могут на его месте отображать другой символ.

Кодировка исходного файла

Кодировка Python должна быть UTF-8 (ASCII в Python 2).

Файлы в ASCII (Python 2) или UTF-8 (Python 3) не должны иметь объявления кодировки.

В стандартной библиотеке, нестандартные кодировки должны использоваться только для целей тестирования, либо когда комментарий или строка документации требует упомянуть имя автора, содержащего не ASCII символы; в остальных случаях использование \x, \u, \U или \N — наиболее предпочтительный способ включить не ASCII символы в строковых литералах.

Начиная с версии python 3.0 в стандартной библиотеке действует следующее соглашение: все идентификаторы обязаны содержать только ASCII символы, и означать английские слова везде, где это возможно (во многих случаях используются сокращения или неанглийские технические термины). Кроме того, строки и комментарии тоже должны содержать лишь ASCII символы. Исключения составляют: (а) test case, тестирующий не-ASCII особенности программы, и (б) имена авторов. Авторы, чьи имена основаны не на латинском алфавите, должны транслитерировать свои имена в латиницу.

Проектам с открытым кодом для широкой аудитории также рекомендуется использовать это соглашение.

Импорты

  • Каждый импорт, как правило, должен быть на отдельной строке.

    Правильно:

    import os
    import sys

    Неправильно:

    import sys, os

    В то же время, можно писать так:

    from subprocess import Popen, PIPE
  • Импорты всегда помещаются в начале файла, сразу после комментариев к модулю и строк документации, и перед объявлением констант.

    Импорты должны быть сгруппированы в следующем порядке:

    1. импорты из стандартной библиотеки
    2. импорты сторонних библиотек
    3. импорты модулей текущего проекта

    Вставляйте пустую строку между каждой группой импортов.

    Указывайте спецификации __all__ после импортов.

  • Рекомендуется абсолютное импортирование, так как оно обычно более читаемо и ведет себя лучше (или, по крайней мере, даёт понятные сообщения об ошибках) если импортируемая система настроена неправильно (например, когда каталог внутри пакета заканчивается на sys.path):

    import mypkg.sibling
    from mypkg import sibling
    from mypkg.sibling import example

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

    from . import sibling
    from .sibling import example

    В стандартной библиотеке следует избегать сложной структуры пакетов и всегда использовать абсолютные импорты.

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

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

    from myclass import MyClass
    from foo.bar.yourclass import YourClass

    Если такое написание вызывает конфликт имен, тогда пишите:

    import myclass
    import foo.bar.yourclass

    И используйте «myclass.MyClass» и «foo.bar.yourclass.YourClass».

  • Шаблоны импортов (from import *) следует избегать, так как они делают неясным то, какие имена присутствуют в глобальном пространстве имён, что вводит в заблуждение как читателей, так и многие автоматизированные средства. Существует один оправданный пример использования шаблона импорта, который заключается в опубликовании внутреннего интерфейса как часть общественного API (например, переписав реализацию на чистом Python в модуле акселератора (и не будет заранее известно, какие именно функции будут перезаписаны).

Пробелы в выражениях и инструкциях

Избегайте использования пробелов в следующих ситуациях:

  • Непосредственно внутри круглых, квадратных или фигурных скобок.

    Правильно:

    spam(ham[1], {eggs: 2})

    Неправильно:

    spam( ham[ 1 ], { eggs: 2 } )
  • Непосредственно перед запятой, точкой с запятой или двоеточием:

    Правильно:

    if x == 4: print(x, y); x, y = y, x

    Неправильно:

    if x == 4 : print(x , y) ; x , y = y , x
  • Сразу перед открывающей скобкой, после которой начинается список аргументов при вызове функции:

    Правильно:

    spam(1)

    Неправильно:

    spam (1)
  • Сразу перед открывающей скобкой, после которой следует индекс или срез:

    Правильно:

    dict['key'] = list[index]

    Неправильно:

    dict ['key'] = list [index]
  • Использование более одного пробела вокруг оператора присваивания (или любого другого) для того, чтобы выровнять его с другим:

    Правильно:

    x = 1
    y = 2
    long_variable = 3

    Неправильно:

    x             = 1
    y             = 2
    long_variable = 3

Другие рекомендации

  • Всегда окружайте эти бинарные операторы одним пробелом с каждой стороны: присваивания (=, +=, -= и другие), сравнения (==, <, >, !=, <>, <=, >=, in, not in, is, is not), логические (and, or, not).
  • Если используются операторы с разными приоритетами, попробуйте добавить пробелы вокруг операторов с самым низким приоритетом. Используйте свои собственные суждения, однако, никогда не используйте более одного пробела, и всегда используйте одинаковое количество пробелов по обе стороны бинарного оператора.

    Правильно:

    i = i + 1
    submitted += 1
    x = x*2 - 1
    hypot2 = x*x + y*y
    c = (a+b) * (a-b)

    Неправильно:

    i=i+1
    submitted +=1
    x = x * 2 - 1
    hypot2 = x * x + y * y
    c = (a + b) * (a - b)
  • Не используйте пробелы вокруг знака =, если он используется для обозначения именованного аргумента или значения параметров по умолчанию.

    Правильно:

    def complex(real, imag=0.0):
        return magic(r=real, i=imag)

    Неправильно:

    def complex(real, imag = 0.0):
        return magic(r = real, i = imag)
  • Не используйте составные инструкции (несколько команд в одной строке).

    Правильно:

    if foo == 'blah':
        do_blah_thing()
    do_one()
    do_two()
    do_three()

    Неправильно:

    if foo == 'blah': do_blah_thing()
    do_one(); do_two(); do_three()
  • Иногда можно писать тело циклов while, for или ветку if в той же строке, если команда короткая, но если команд несколько, никогда так не пишите. А также избегайте длинных строк!

    Точно неправильно:

    if foo == 'blah': do_blah_thing()
    for x in lst: total += x
    while t < 10: t = delay()

    Вероятно, неправильно:

    if foo == 'blah': do_blah_thing()
    else: do_non_blah_thing()
    
    try: something()
    finally: cleanup()
    
    do_one(); do_two(); do_three(long, argument,
                                 list, like, this)
    
    if foo == 'blah': one(); two(); three()

Комментарии

Комментарии, противоречащие коду, хуже, чем отсутствие комментариев. Всегда исправляйте комментарии, если меняете код!

Комментарии должны являться законченными предложениями. Если комментарий — фраза или предложение, первое слово должно быть написано с большой буквы, если только это не имя переменной, которая начинается с маленькой буквы (никогда не изменяйте регистр переменной!).

Если комментарий короткий, можно опустить точку в конце предложения. Блок комментариев обычно состоит из одного или более абзацев, составленных из полноценных предложений, поэтому каждое предложение должно оканчиваться точкой.

Ставьте два пробела после точки в конце предложения.

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

Блоки комментариев

Блок комментариев обычно объясняет код (весь, или только некоторую часть), идущий после блока, и должен иметь тот же отступ, что и сам код. Каждая строчка такого блока должна начинаться с символа # и одного пробела после него (если только сам текст комментария не имеет отступа).

Абзацы внутри блока комментариев разделяются строкой, состоящей из одного символа #.

«Встрочные» комментарии

Старайтесь реже использовать подобные комментарии.

Такой комментарий находится в той же строке, что и инструкция. «Встрочные» комментарии должны отделяться по крайней мере двумя пробелами от инструкции. Они должны начинаться с символа # и одного пробела.

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

x = x + 1                 # Increment x

Впрочем, такие комментарии иногда полезны:

x = x + 1                 # Компенсация границы

Строки документации

  • Пишите документацию для всех публичных модулей, функций, классов, методов. Строки документации необязательны для приватных методов, но лучше написать, что делает метод. Комментарий нужно писать после строки с def.
  • PEP 257 объясняет, как правильно и хорошо документировать. Заметьте, очень важно, чтобы закрывающие кавычки стояли на отдельной строке. А еще лучше, если перед ними будет ещё и пустая строка, например:

    """Return a foobang
    
    Optional plotz says to frobnicate the bizbaz first.
    
    """
  • Для однострочной документации можно оставить закрывающие кавычки на той же строке.

Контроль версий

Если вам нужно использовать Subversion, CVS или RCS в ваших исходных кодах, делайте вот так:

__version__ = "$Revision: 1a40d4eaa00b $"
# $Source$

Вставляйте эти строки после документации модуля перед любым другим кодом и отделяйте их пустыми строками по одной до и после.

Соглашения по именованию

Соглашения по именованию переменных в python немного туманны, поэтому их список никогда не будет полным — тем не менее, ниже мы приводим список рекомендаций, действующих на данный момент. Новые модули и пакеты должны быть написаны согласно этим стандартам, но если в какой-либо уже существующей библиотеке эти правила нарушаются, предпочтительнее писать в едином с ней стиле.

Главный принцип

Имена, которые видны пользователю как часть общественного API должны следовать конвенциям, которые отражают использование, а не реализацию.

Описание: Стили имен

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

Обычно различают следующие стили:

  • b (одиночная маленькая буква)
  • B (одиночная заглавная буква)
  • lowercase (слово в нижнем регистре)
  • lower_case_with_underscores (слова из маленьких букв с подчеркиваниями)
  • UPPERCASE (заглавные буквы)
  • UPPERCASE_WITH_UNDERSCORES (слова из заглавных букв с подчеркиваниями)
  • CapitalizedWords (слова с заглавными буквами, или CapWords, или CamelCase). Замечание: когда вы используете аббревиатуры в таком стиле, пишите все буквы аббревиатуры заглавными — HTTPServerError лучше, чем HttpServerError.
  • mixedCase (отличается от CapitalizedWords тем, что первое слово начинается с маленькой буквы)
  • Capitalized_Words_With_Underscores (слова с заглавными буквами и подчеркиваниями — уродливо!)

Ещё существует стиль, в котором имена, принадлежащие одной логической группе, имеют один короткий префикс. Этот стиль редко используется в python, но мы упоминаем его для полноты. Например, функция os.stat() возвращает кортеж, имена в котором традиционно имеют вид st_mode, st_size, st_mtime и так далее. (Так сделано, чтобы подчеркнуть соответствие этих полей структуре системных вызовов POSIX, что помогает знакомым с ней программистам).

В библиотеке X11 используется префикс Х для всех public-функций. В python этот стиль считается излишним, потому что перед полями и именами методов стоит имя объекта, а перед именами функций стоит имя модуля.

В дополнение к этому, используются следующие специальные формы записи имен с добавлением символа подчеркивания в начало или конец имени:

  • _single_leading_underscore: слабый индикатор того, что имя используется для внутренних нужд. Например, from M import * не будет импортировать объекты, чьи имена начинаются с символа подчеркивания.
  • single_trailing_underscore_: используется по соглашению для избежания конфликтов с ключевыми словами языка python, например:

    Tkinter.Toplevel(master, class_='ClassName')
  • __double_leading_underscore: изменяет имя атрибута класса, то есть в классе FooBar поле __boo становится _FooBar__boo.
  • __double_leading_and_trailing_underscore__ (двойное подчеркивание в начале и в конце имени): магические методы или атрибуты, которые находятся в пространствах имен, управляемых пользователем. Например, __init__, __import__ или __file__. Не изобретайте такие имена, используйте их только так, как написано в документации.

Предписания: соглашения по именованию

Имена, которых следует избегать

Никогда не используйте символы l (маленькая латинская буква «эль»), O (заглавная латинская буква «о») или I (заглавная латинская буква «ай») как однобуквенные идентификаторы.

В некоторых шрифтах эти символы неотличимы от цифры один и нуля. Если очень нужно l, пишите вместо неё заглавную L.

Имена модулей и пакетов

Модули должны иметь короткие имена, состоящие из маленьких букв. Можно использовать символы подчеркивания, если это улучшает читабельность. То же самое относится и к именам пакетов, однако в именах пакетов не рекомендуется использовать символ подчёркивания.

Так как имена модулей отображаются в имена файлов, а некоторые файловые системы являются нечувствительными к регистру символов и обрезают длинные имена, очень важно использовать достаточно короткие имена модулей — это не проблема в Unix, но, возможно, код окажется непереносимым в старые версии Windows, Mac, или DOS.

Когда модуль расширения, написанный на С или C++, имеет сопутствующий python-модуль (содержащий интерфейс высокого уровня), С/С++ модуль начинается с символа подчеркивания, например, _socket.

Имена классов

Имена классов должны обычно следовать соглашению CapWords.

Вместо этого могут использоваться соглашения для именования функций, если интерфейс документирован и используется в основном как функции.

Обратите внимание, что существуют отдельные соглашения о встроенных именах: большинство встроенных имен — одно слово (либо два слитно написанных слова), а соглашение CapWords используется только для именования исключений и встроенных констант.

Имена исключений

Так как исключения являются классами, к исключениями применяется стиль именования классов. Однако вы можете добавить Error в конце имени (если, конечно, исключение действительно является ошибкой).

Имена глобальных переменных

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

Добавляйте в модули, которые написаны так, чтобы их использовали с помощью from M import *, механизм __all__, чтобы предотвратить экспортирование глобальных переменных. Или же, используйте старое соглашение, добавляя перед именами таких глобальных переменных один символ подчеркивания (которым вы можете обозначить те глобальные переменные, которые используются только внутри модуля).

Имена функций

Имена функций должны состоять из маленьких букв, а слова разделяться символами подчеркивания — это необходимо, чтобы увеличить читабельность.

Стиль mixedCase допускается в тех местах, где уже преобладает такой стиль, для сохранения обратной совместимости.

Аргументы функций и методов

Всегда используйте self в качестве первого аргумента метода экземпляра объекта.

Всегда используйте cls в качестве первого аргумента метода класса.

Если имя аргумента конфликтует с зарезервированным ключевым словом python, обычно лучше добавить в конец имени символ подчеркивания, чем исказить написание слова или использовать аббревиатуру. Таким образом, class_ лучше, чем clss. (Возможно, хорошим вариантом будет подобрать синоним).

Имена методов и переменных экземпляров классов

Используйте тот же стиль, что и для имен функций: имена должны состоять из маленьких букв, а слова разделяться символами подчеркивания.

Используйте один символ подчёркивания перед именем для непубличных методов и атрибутов.

Чтобы избежать конфликтов имен с подклассами, используйте два ведущих подчеркивания.

Python искажает эти имена: если класс Foo имеет атрибут с именем __a, он не может быть доступен как Foo.__a. (Настойчивый пользователь все еще может получить доступ, вызвав Foo._Foo__a.) Вообще, два ведущих подчеркивания должны использоваться только для того, чтобы избежать конфликтов имен с атрибутами классов, предназначенных для наследования.

Примечание: есть некоторые разногласия по поводу использования __ имена (см. ниже).

Константы

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

Проектирование наследования

Обязательно решите, каким должен быть метод класса или экземпляра класса (далее — атрибут) — публичный или непубличный. Если вы сомневаетесь, выберите непубличный атрибут. Потом будет проще сделать его публичным, чем наоборот.

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

Мы не используем термин «приватный атрибут», потому что на самом деле в python таких не бывает.

Другой тип атрибутов классов принадлежит так называемому API подклассов (в других языках они часто называются protected). Некоторые классы проектируются так, чтобы от них наследовали другие классы, которые расширяют или модифицируют поведение базового класса. Когда вы проектируете такой класс, решите и явно укажите, какие атрибуты являются публичными, какие принадлежат API подклассов, а какие используются только базовым классом.

Теперь сформулируем рекомендации:

  • Открытые атрибуты не должны иметь в начале имени символа подчеркивания.
  • Если имя открытого атрибута конфликтует с ключевым словом языка, добавьте в конец имени один символ подчеркивания. Это более предпочтительно, чем аббревиатура или искажение написания (однако, у этого правила есть исключение — аргумента, который означает класс, и особенно первый аргумент метода класса (class method) должен иметь имя cls).
  • Назовите простые публичные атрибуты понятными именами и не пишите сложные методы доступа и изменения (accessor/mutator, get/set, — прим. перев.) Помните, что в python очень легко добавить их потом, если потребуется. В этом случае используйте свойства (properties), чтобы скрыть функциональную реализацию за синтаксисом доступа к атрибутам.

    Примечание 1: Свойства (properties) работают только в классах нового стиля (в Python 3 все классы являются таковыми).

    Примечание 2: Постарайтесь избавиться от побочных эффектов, связанным с функциональным поведением; впрочем, такие вещи, как кэширование, вполне допустимы.

    Примечание 3: Избегайте использования вычислительно затратных операций, потому что из-за записи с помощью атрибутов создается впечатление, что доступ происходит (относительно) быстро.

  • Если вы планируете класс таким образом, чтобы от него наследовались другие классы, но не хотите, чтобы подклассы унаследовали некоторые атрибуты, добавьте в имена два символа подчеркивания в начало, и ни одного — в конец. Механизм изменения имен в python сработает так, что имя класса добавится к имени такого атрибута, что позволит избежать конфликта имен с атрибутами подклассов.

    Примечание 1: Будьте внимательны: если подкласс будет иметь то же имя класса и имя атрибута, то вновь возникнет конфликт имен.

    Примечание 2: Механизм изменения имен может затруднить отладку или работу с __getattr__(), однако он хорошо документирован и легко реализуется вручную.

    Примечание 3: Не всем нравится этот механизм, поэтому старайтесь достичь компромисса между необходимостью избежать конфликта имен и возможностью доступа к этим атрибутам.

Общие рекомендации

  • Код должен быть написан так, чтобы не зависеть от разных реализаций языка (PyPy, Jython, IronPython, Pyrex, Psyco и пр.).

    Например, не полагайтесь на эффективную реализацию в CPython конкатенации строк в выражениях типа a+=b или a=a+b. Такие инструкции выполняются значительно медленнее в Jython. В критичных к времени выполнения частях программы используйте ».join() — таким образом склеивание строк будет выполнено за линейное время независимо от реализации python.

  • Сравнения с None должны обязательно выполняться с использованием операторов is или is not, а не с помощью операторов сравнения. Кроме того, не пишите if x, если имеете в виду if x is not None — если, к примеру, при тестировании такая переменная может принять значение другого типа, отличного от None, но при приведении типов может получиться False!
  • При реализации методов сравнения, лучше всего реализовать все 6 операций сравнения (__eq__, __ne__, __lt__, __le__, __gt__, __ge__), чем полагаться на то, что другие программисты будут использовать только конкретный вид сравнения.

    Для минимизации усилий можно воспользоваться декоратором functools.total_ordering() для реализации недостающих методов.

    PEP 207 указывает, что интерпретатор может поменять y > х на х < y, y >= х на х <= y, и может поменять местами аргументы х == y и х != y. Гарантируется, что операции sort() и min() используют оператор <, а max() использует оператор >. Однако, лучше всего осуществить все шесть операций, чтобы не возникало путаницы в других местах.

  • Всегда используйте выражение def, а не присваивание лямбда-выражения к имени.

    Правильно:

    def f(x): return 2*x

    Неправильно:

    f = lambda x: 2*x
  • Наследуйте свой класс исключения от Exception, а не от BaseException. Прямое наследование от BaseException зарезервировано для исключений, которые не следует перехватывать.
  • Используйте цепочки исключений соответствующим образом. В Python 3, «raise X from Y» следует использовать для указания явной замены без потери отладочной информации.

    Когда намеренно заменяется исключение (использование «raise X» в Python 2 или «raise X from None» в Python 3.3+), проследите, чтобы соответствующая информация передалась в новое исключение (такие, как сохранение имени атрибута при преобразовании KeyError в AttributeError или вложение текста исходного исключения в новом).

  • Когда вы генерируете исключение, пишите raise ValueError(‘message’) вместо старого синтаксиса raise ValueError, message.

    Старая форма записи запрещена в python 3.

    Такое использование предпочтительнее, потому что из-за скобок не нужно использовать символы для продолжения перенесенных строк, если эти строки длинные или если используется форматирование.

  • Когда код перехватывает исключения, перехватывайте конкретные ошибки вместо простого выражения except:.

    К примеру, пишите вот так:

    try:
        import platform_specific_module
    except ImportError:
        platform_specific_module = None

    Простое написание «except:» также перехватит и SystemExit, и KeyboardInterrupt, что породит проблемы, например, сложнее будет завершить программу нажатием control+C. Если вы действительно собираетесь перехватить все исключения, пишите «except Exception:».

    Хорошим правилом является ограничение использования «except:», кроме двух случаев:

    1. Если обработчик выводит пользователю всё о случившейся ошибке; по крайней мере, пользователь будет знать, что произошла ошибка.
    2. Если нужно выполнить некоторый код после перехвата исключения, а потом вновь «бросить» его для обработки где-то в другом месте. Обычно же лучше пользоваться конструкцией «try…finally».
  • При связывании перехваченных исключений с именем, предпочитайте явный синтаксис привязки, добавленный в Python 2.6:

    try:
        process_data()
    except Exception as exc:
        raise DataProcessingFailedError(str(exc))

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

  • При перехвате ошибок операционной системы, предпочитайте использовать явную иерархию исключений, введенную в Python 3.3, вместо анализа значений errno.
  • Постарайтесь заключать в каждую конструкцию try…except минимум кода, чтобы легче отлавливать ошибки. Опять же, это позволяет избежать замаскированных ошибок.

    Правильно:

    try:
        value = collection[key]
    except KeyError:
        return key_not_found(key)
    else:
        return handle_value(value)

    Неправильно:

    try:
        # Здесь много действий!
        return handle_value(collection[key])
    except KeyError:
        # Здесь также перехватится KeyError, который может быть сгенерирован handle_value()
        return key_not_found(key)
  • Когда ресурс является локальным на участке кода, используйте выражение with для того, чтобы после выполнения он был очищен оперативно и надёжно.
  • Менеджеры контекста следует вызывать с помощью отдельной функции или метода, всякий раз, когда они делают что-то другое, чем получение и освобождение ресурсов. Например:

    Правильно:

    with conn.begin_transaction():
        do_stuff_in_transaction(conn)

    Неправильно:

    with conn:
        do_stuff_in_transaction(conn)

    Последний пример не дает никакой информации, указывающей на то, что __enter__ и __exit__ делают что-то кроме закрытия соединения после транзакции. Быть явным важно в данном случае.

  • Используйте строковые методы вместо модуля string — они всегда быстрее и имеют тот же API для unicode-строк. Можно отказаться от этого правила, если необходима совместимость с версиями python младше 2.0.

    В Python 3 остались только строковые методы.

  • Пользуйтесь ».startswith() и ».endswith() вместо обработки срезов строк для проверки суффиксов или префиксов.

    startswith() и endswith() выглядят чище и порождают меньше ошибок. Например:

    Правильно:

    if foo.startswith('bar'):

    Неправильно:

    if foo[:3] == 'bar':
  • Сравнение типов объектов нужно делать с помощью isinstance(), а не прямым сравнением типов:

    Правильно:

    if isinstance(obj, int):

    Неправильно:

    if type(obj) is type(1):

    Когда вы проверяете, является ли объект строкой, обратите внимание на то, что строка может быть unicode-строкой. В python 2 у str и unicode есть общий базовый класс, поэтому вы можете написать:

    if isinstance(obj, basestring):

    Отметим, что в Python 3, unicode и basestring больше не существуют (есть только str) и bytes больше не является своего рода строкой (это последовательность целых чисел).

  • Для последовательностей (строк, списков, кортежей) используйте тот факт, что пустая последовательность есть false:

    Правильно:

    if not seq:
    if seq:

    Неправильно:

    if len(seq)
    if not len(seq)
  • Не пользуйтесь строковыми константами, которые имеют важные пробелы в конце — они невидимы, а многие редакторы (а теперь и reindent.py) обрезают их.
  • Не сравнивайте логические типы с True и False с помощью ==:

    Правильно:

    if greeting:

    Неправильно:

    if greeting == True:

    Совсем неправильно:

    if greeting is True:
  • Оригинал

    Специальные требования для оформления текстов для моих курсантов

    В самом начале скрипта с кодом Python необходимо указывать следующие атрибуты:

    #имя проекта: numpy-example
    #номер версии: 1.0
    #имя файла: example_2.py
    #автор и его учебная группа: Е. Волков, ЭУ-142
    #дата создания: 20.03.2019
    #дата последней модификации: 25.03.2019
    #связанные файлы: пакеты numpy, matplotlib
    #описание: простейшие статистические вычисления
    #версия Python: 3.6
    ]]> https://chel-center.ru/python-yfc/2019/10/01/kak-oformlyat-kod/feed/ 0 PyCharm — эффективная разработка на Python https://chel-center.ru/python-yfc/2019/10/01/pycharm-mdash-instrument-effektivnoj-razrabotki-na-python/ https://chel-center.ru/python-yfc/2019/10/01/pycharm-mdash-instrument-effektivnoj-razrabotki-na-python/#respond Tue, 01 Oct 2019 01:43:20 +0000 http://chel-center.ru/python-yfc/?p=155 Читать далее «PyCharm — эффективная разработка на Python»

    ]]>
    Программист должен сосредочить своё внимание на бизнес-логике создаваемого приложения и на его полезности. Именно для этого предназначен такой инструмент, как PyCharm от JetBrains. В нём решены задачи отладки и простой визуализации проектов, он экономит время и избавляет от рутинных операций.

    Оглавление

    В этой статье вы узнаете о том:

    • как установить PyCharm;
    • как записать код в PyCharm;
    • как загрузить код в PyCharm;
    • отладка и тестирование кода в PyCharm;
    • как изменить существующий проект в PyCharm;
    • поиск и навигация в PyCharm;
    • контроль версий в PyCharm;
    • плагины и внешние инструменты в PyCharm;
    • использование возможностей профессиональной версии PyCharm, таких как поддержка Django и режима научной разработки.;

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

    Замечание:

    PyCharm выпускается в трёх редакциях:

    1. PyCharm Edu — бесплатная версия для обучения;
    2. PyCharm Community — бесплатная версия и кроме обучения предназначена, главным образом, для развития Python;
    3. PyCharm Professional — платный вариант, который имеет полный функционал, зрелое сообщество, очень хорошо подходит для научной и Web разработок с поддержкой таких фреймворков, как Django и Flask, Database и SQL, таких научных инструментов, как Jupyter.

    Для более подробной информации о различиях посмотрите PyCharm Editions Comparison Matrix от JetBrains. Кроме того, компания предоставляет бесплатные лицензии на версию Professional специальным предложением для студентов, преподавателей, проектам с открытым исходным кодом и им подобным командам.

    Установка PyCharm

    В этой статья я буду использовать PyCharm Community Edition 2019.1, так как она бесплатна и доступна на любой популярной платформе всем. Но смею вас заверить, что приведённые здесь примеры с успехом работают и на PyCharm Professional Edition 2019.1.

    Для установки PyCharm рекомендую использовать JetBrains Toolbox App. С его помощью вы сможете установить любые продукты JetBrains или несколько версий одного и того же продукта, при необходимости легко обновлять, откатывать и удалять любые инструменты. Вы также сможете быстро открыть любой проект в любой предыдущей версии.

    Для установки Toolbox App прочитайте фирменную документацию от JetBrains. Операционная система будет определена автоматически при загрузке и для вас будут предложены корректные пошаговые инструкции. Если этого не произойдёт, то выберите ОС «в рукопашную» в поле справа вверху:

    Список ОС для установки ПО Jetbrains
    Список ОС для установки ПО Jetbrains

    После установки загрузите приложение и подтвердите своё согласие с условиями использования софта. На закладке Tools посмотрите список доступных продуктов. Выберите PyCharm Community и нажмите Install:

    Установка PyCharm с помощью Toolbox App
    Установка PyCharm с помощью Toolbox App

    Вот и всё! PyCharm уже готов к работе на вашей машине. Если вам не нравится Toolbox app, то воспользуйтесь автономной установкой PyCharm.

    Запустите PyCharm и увидите всплывающее окно настройки импорта:

    Настройки импорта
    Настройки импорта

    PyCharm автоматически определит новую установку и предложит вам Do not import settings (Не импортировать настройки). Согласитесь и нажмите OK, выберите раскладку клавиш PyCharm по умолчанию и нажмите Next: UI Themes (Далее: тема пользовательского интерфейса) справа внизу:

    Схема раскладки клавиш PyCharm
    Схема раскладки клавиш PyCharm

    PyCharm предложит вам тёмную тему под названием Darcula или светлую тему. Выберите то, что вам нравится и нажмите кнопку Next: Launcher Script (Далее: сценарий запуска):

    Страница настройки темы PyCharm
    Страница настройки темы PyCharm

    Здесь на протяжении всего урока будет использоваться тёмная тема Darcula. Однако, вы можете найти и установить другую тему, используя плагины, или импортировать идеальную для вас тему IntelliJ.

    На следующей странице оставьте всё по-умолчанию и нажмите Next: Featured plugins (Далее: Рекомендуемые плагины). Здесь PyCharm покажет вам список плагинов, которые вы можете немедленно установить, большинство пользователей любят это делать. Нажмите Start using PyCharm (Стартовать PyCharm) и теперь можно смело записывать код!

    Запись кода в PyCharm

    В PyCharm всё делается в контексте проекта. Поэтому для начала его надо создать.

    После установки и загрузки PyCharm в окне приветствия нажмите Create New Project (создать новый проект) и вы появится окно для создания нового проекта New Project:

    Создание нового проекта pycharm
    Создание нового проекта pycharm

    Укажите местоположение проекта и раскройте список Project Interpreter. Здесь у вас есть возможность создать новый интерпретатор для своего нового проекта или повторно использовать существующий. Выберите New environment using. Прямо рядом с ним у вас есть выпадающий список для выбора одного из вариантов Virtualenv, Pipenv или Conda, которые являются инструментами поддержки необходимых для разный проектов зависимостей отдельно, создавая для этого изолированные среды Python.

    Если хотите, выберите для этого урока Virtualenv. При желании можно указать местоположение среды и выбрать базовый интерпретатор из списка, в котором должны присутствовать все интерпретаторы Python, например, Python 2.7 и Python 3.6, установленные в вашей операционной системе. Обычно по умолчанию все бывает в порядке, но если Python у вас не установлен, то придётся это сделать. Пройдите на сайт python.org, скачайте дистрибутив и сделайте установку интерпритатора. Затем вы должны выбрать блоки для наследования глобальных пакетов сайтов в вашей новой среде и сделать их доступными для всех других проектов. Пока не обращайте на них внимание и оставьте невыбранными.

    В правом нижнем углу нажмите кнопочку Create и вы увидите созданный новый проект:

    Создание нового проекта в PyCharm
    Создание нового проекта в PyCharm

    Также появится небольшое всплывающее окно Tip of the Day (Совет дня), где при каждом запуске даётся какой-то случайный совет от PyCharm. Прочитайте и просто закройте это окно.

    Настало время начать запись кода на Python. Одновременно нажмите Cmd+N если у вас Mac или Alt+Ins если Windows или Linux. После чего выберите Python File. Это можно сделать воспользовавшись главным меню File → New. Назовите новый файл guess_game.py и нажмите OK. Вы увидите окно PyCharm, похожее на это:

    Создание нового файла в PyCharm
    Создание нового файла в PyCharm

    Давайте быстренько напишем тестовый код, реализующий простую игру на угадывание — программа генерирует секретное число, которое должен угадать человек. На каждое предложенное человеком число программа скажет, было оно меньше или больше секретного. Игра заканчивается, когда человек угадает число. Вот этот код gauss-game.py:

    from random import randint
    
    def play():
        random_int = randint(0, 100)
    
        while True:
            user_guess = int(input("Запишите целое число в диапазоне от 0 до 100?"))
            if user_guess == randint:
                print(f"Вы угадали число ({random_int}). Поздравляю!")
                break
            if user_guess < random_int:
                print("Ваше число меньше секретного.")
                continue
            if user_guess > random_int:
                print("Выше число больше секретного.")
                continue
    
    if __name__ == '__main__':
        play()
    

    Не копируйте, а введите этот код напрямую и увидите что‑то вроде этого:

     Intelligent Coding Assistance — интеллектуальный ассистент кодирования
    Intelligent Coding Assistance — интеллектуальный ассистент кодирования

    Как видите, в PyCharm есть Intelligent Coding Assistance — интеллектуальный ассистент кодирования, который делает автодополнение кода, проверяет синтаксис, сообщает об ошибках и даёт рекомендации по их исправлению. В частности, заметьте, когда вы записали main и нажали Tab, PyCharm автоматически полностью завершил всю конструкцию main за вас.

    Так-же обратите внимание, что если перед if поставить точку .if и нажать Tab, то PyCharm полностью за вас напишет конструкцию if. То же самое верно для True.while — работает PyCharm’s Postfix completions (постфиксное дополнение кода) и не надо лишний раз нажимать на Enter для перехода но новую строку.

    Загрузка кода в PyCharm

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

    У вас есть три способа запуска этой программы:

    1. Используйте клавиши Ctrl+Shift+R на Mac или Ctrl+Shift+F10 на Windows или Linux.
    2. Нажмите правую кнопку мыши в поле редактирования и в меню выберите Run ‘guess_game’.
    3. Поскольку в этой программе есть предложение __main__, то щелкните на маленькую зелёную стрелку слева от фразы __main__ и выберите Run ‘guess_game’отсюда.

    Любой из этих вариантов приведёт к запуска программы, и вы увидите панель «Run Tool» в нижней части окна, с выводом кода, показывающим диалог.

    Запуск приложения в PyCharm
    Запуск приложения в PyCharm

    Немного поиграйте и увидите, что секретное число угадать можно. Совет от профессионала: начните с 50.

    Отладка в PyCharm

    Вы нашли секретное число? Если так, то, возможно, заметили что-то странное, вместо того, чтобы печатать поздравление и завершать игру программа запускается заново. Где‑то прямо здесь есть ошибка. Чтобы узнать, почему программа запускается заново, вы должны её отладить.

    Сначала установите точку останова, нажав на пустое место слева от строки № 8:

    Точки останова для отладки
    Точки останова для отладки

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

    1. Нажмите Ctrl+Shift+D на Mac или Shift+Alt+F9 на Windows или Linux.
    2. Щелчком правой кнопки мыши в поле редактирования выберите Debug ‘guess_game’.
    3. Щёлкните на маленькую зелёную стрелку слева от фразы __main__ и выберите Debug ‘guess_game отсюда.

    После этого вы увидите открывшиеся внизу окно Debugger:

    Старт отладки в PyCharm
    Старт отладки в PyCharm

    Для отладки программы выполните следующие шаги:

    1. Обратите внимание, что текущая строка выделена синим цветом.
    2. Посмотрите, что random_int и его значение перечислены в окне отладки. Запишите это значение. (На рисунке число 85.)
    3. Нажмите F8 для выполнения текущей строки и перехода к следующей. Если в текущей строке вызывается функции, то при необходимости в неё попасть нажмите F7. По-шагово выполняя операторы, в окне отладки вы сможете наблюдать все изменения значений переменных, обновляемые автоматически.
    4. Обратите внимание, что рядом с открывшейся вкладкой «Debugger» находится вкладка «Console», у которых совершенно разное функциональное назначение. На вкладке Console вы будете взаимодействовать со своей программой, а на вкладке Debugger вы будете выполнять действия по отладке.
    5. Переключайтесь на вкладку Console для диалога с вашим guess.
    6. Запишите ваше число и нажмите Enter.
    7. Переключитесь назад на вкладку Debugger.
    8. Нажмите F8 для выполнения оператора if. Заметьте, вы на строке 14. Постойте! Почему не произошёл переход к 11 строке? Причина в том, что условие в операторе if 10 строки приняло значение False. Но почему False если введённое число то, что надо?
    9. Внимательно посмотрите на строчку 10 и заметите, что мы сравниваем user_guess не с тем, что надо. Вместо random_int делается сравнение с функцией randint, импортированной из пакета random.
    10. Измените на random_int, перезапустите и сделайте пошаговое выполнение операторов. Вы видите, произошёл переход к строке 11, а значение условия стало True:

    Debugging Script in PyCharm

    Поздравляю! Ошибка найдена и исправлена.

    Тестирование в PyCharm

    Без тестирования нельзя гарантировать надёжность работы любого приложения. PyCharm помогает быстро и комфортно написать и загрузить тесты. По-умолчанию используется unittest, но кроме него можно использовать такие фреймворки, как pytest, nose, doctest, tox и trial. Например, для своего проекта можно выбрать pytest:

    1. Откройте диалог настройки Settings/Preferences → Tools → Python Integrated Tools.
    2. Выберите pytest в поле Default test runner.
    3. Нажмите OK для сохранения настроек.

    В нашем примере мы будем использовать загрузчик теста по‑умолчанию unittest.

    В том же самом проекте, где записана игра, создайте файл с именем calculator.py и запишите в него код класса Calculator:

    class Calculator:
        def add(self, a, b):
            return a + b
        def multiply(self, a, b):
            return a * b
    

    Для кода, открытого в редакторе, PyCharm позволяет очень легко создавать тесты. С открытым файлом calculator.py выполните любое из следующих действий:

    • Нажмите Shift+Cmd+T на Mac или Ctrl+Shift+T на Windows или Linux.
    • Правой кнопкой мыши в поле редактирования выберите Go To и Test.
    • В основном меню проследуйте Navigate → Test.

    Выберите Create New Test (Создать новый тест) и посмотрите на окно:

    Создание теста в PyCharm
    Создание теста в PyCharm

    Значения полей Target directory (целевой каталог), Test file name (Имя файла теста) и Test class name (Имя класса теста) оставьте по‑умолчанию. Для тестирования отметьте оба метода и нажмите на OK. Вуаля! PyCharm автоматически создаст для вас файл с именем test_calculator.py и заглушки для тестов:

    from unittest import TestCase
    class TestCalculator(TestCase):
        def test_add(self):
            self.fail()
        def test_multiply(self):
            self.fail()
    

    Загрузите тест одним из следующих способов:

    • Нажмите Ctrl+R на Mac или Shift+F10 на Windows или Linux.
    • Щёлкните правой кнопкой мыши в поле редактирования и выберите Run ‘Unittests for test_calculator.py’.
    • Щёлкните на маленькой зелёной стрелке слева от имени класс теста и выберите Run ‘Unittests for test_calculator.py’.

    Вы увидите открытое окно тестов со всеми ошибками:

    Результат тестирования — ошибки
    Результат тестирования — ошибки

    Обратите внимание, что у вас есть иерархия результатов теста слева и терминал для вывода результатов справа.

    Теперь реализуем test_add, изменив код на следующий:

    from unittest import TestCase
    from calculator import Calculator
    class TestCalculator(TestCase):
        def test_add(self):
            self.calculator = Calculator()
            self.assertEqual(self.calculator.add(3, 4), 7)
        def test_multiply(self):
            self.fail()
    

    Запустите тесты еще раз и увидите, что один тест пройден, а другой нет. Изучите настройки теста, чтобы показывать пройденные тесты, проигнорированные тесты, сортировку тестов по алфавиту и по времени исполнения:

    Загрузка тестов в PyCharm
    Загрузка тестов в PyCharm

    Обратите внимание, что метод sleep (0.1), который вы видите на картинке выше, намеренно используется для замедления одного из тестов, чтобы показать, как работает сортировка по времени исполнения.

    Редактирование существующего проекта в PyCharm

    Однофайловые проекты отлично подходят для примеров, но жизнь гораздо сложнее и почти всегда вы длительное время будете работать над гораздо более крупными проектами. В этом разделе вы узнаете, как работать с большим проектом в PyCharm.

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

    После чего разархивируйте и откройте его в PyCharm одним из следующих способов:

    • Нажмите File → Open в главном меню.
    • Нажмите Open в окне Welcome Screen, если вы только что загрузили PyCharm.

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

    Если проект уже содержит виртуальную среду, то PyCharm будет автоматически её использовать и сделает интерпретатором проекта.

    Если вы хотите создать свою virtualenv — виртуальную среду, что обычно и делается, то откройте Preferences, нажав на Mac Cmd+, или Settings на Windows или Linux Ctrl+Alt+S и найдите секцию Project: ProjectName. Откройте выпадающий список и выберите Project Interpreter:

    Определение виртуальной среды проекта в PyCharm
    Определение виртуальной среды проекта в PyCharm

    Выберите virtualenv в выпадающем списке. Если такого выбора в списке нет, то для настройки спарва от выпадающего списка нажмите кнопку Add…. Дальнешие шаги такие же, как при создании нового проекта.

    Поиск и навигация в PyCharm

    В большом проекте одному человеку трудно запомнить что‑где находится, поэтому очень важны механизмы быстрой ориентации и поиска того, что нужно. К нашему удовольствию в PyCharm это есть. Используйте проект, который вы открыли раньше и попрактикуйтесь в нажатии клавиш в следующих сочетаниях:

    • Поиск фрагмента текста в текущем файле: нажмите Cmd+F на Mac или Ctrl+F на Windows или Linux.
    • Поиск фрагмента во всем проекте: нажмите Cmd+Shift+F на Mac или Ctrl+Shift+F на Windows или Linux.
    • Поиск класса: нажмите Cmd+O на Mac или Ctrl+N на Windows или Linux.
    • Поиск файла: нажмите Cmd+Shift+O на Mac или Ctrl+Shift+N на Windows или Linux.
    • Поиск везде, если не знаете, что конкретно ищете — файл, класс или фрагмент кода: нажмите Shift дважды.

    Что касается навигации, шпаргалка ниже сэкономит вам массу времени:

    • Переход к объявлению переменной: нажмите Cmd на Mac или Ctrl на Windows или Linux и щёлкните по переменной.
    • Поиск используемого класса, метода или любого символа: нажмите Alt+F7.
    • Просмотр последних изменений: нажмите Shift+Alt+C или выберите View → Recent Changes в главном меню.
    • Просмотр ваших последних файлов: нажмите Cmd+E на Mac или Ctrl+E на Windows или Linux или в главном меню прйдите View → Recent Files.
    • G>Переход назад и вперед по истории навигации после того, как вы уже что‑то сделали: нажмите Cmd+[ / Cmd+] на Mac или Ctrl+Alt+Left / Ctrl+Alt+Right на Windows или Linux.

    Для более подробного знакомства с этим вопросом читайте официальную документацию.

    Управление версиями в PyCharm

    Система управления версиями, типа, Git или Mercurial является важнейшим инструментом в современном мире разработки программного обеспечения. Поэтому так важна поддержка их в любой IDE. PyCharm делает это очень хорошо, прекрасно интегрируясь с Git (и Github), а так же с другими популярными системами такими, как Mercurial, Perforce и Subversion.

    Настройка систем управления версиями

    Что-бы включить интеграцию с системой управления версиями пройдите VCS → VCS Operations Popup… в верхнем меню или нажмите клавиши Ctrl+V на Mac или Alt+` на Windows или Linux. Выберите Enable Version Control Integration…. Посмотрите на открывшееся окно:

    Интеграция с системами управления версиями в PyCharm
    Интеграция с системами управления версиями в PyCharm

    Выберите Git из выпадающего списка, нажмите OK и в вашем проекте включена система управления версиями. Обратите внимание, что если вы открыли существующий проект с включенным управлением версиями, PyCharm увидит это и автоматически подключится к ней.

    Теперь, если вы пройдете VCS Operations Popup…, то увидите всплывающее окно с опциями git add, git stash, git branch, git commit, git push и много другое:

    Работа с системой управления версиями в PyCharm
    Работа с системой управления версиями в PyCharm

    Если вы не можете найти то, что нужно, то, скорее всего, сможете это сделать, перейдя в верхнем меню в VCS, выбрав Git. Здесь даже можно создавать и просматривать запросы на извлечение.

    Коммиты и разрешение конфликтов

    Есть две особенности интеграции систем управления версиями в PyCharm, которые лично я использую и получаю от этого огромное удовольствие! Допустим, вы закончили свою работу и хотите это как-то отметить. Перейдите VCS → VCS Operations Popup… → Commit… или нажмите Cmd+K на Mac или Ctrl+K на Windows или Linux. Посмотрите на появившееся окно:

    Окно коммита в PyCharm
    Окно коммита в PyCharm

    В этом окне можно:

    1. Выбрать файлы для фиксации;
    2. Записать сообщение о фиксации;
    3. Выполнить все команды проверки и очистки перед фиксацией;
    4. Посмотреть различия в изменениях;
    5. Зафиксировать и нажать стрелку справа от кнопки Commit и выбрать Commit and Push….

    Это кажется молниеносно и магически, особенно если вы привыкли делать все в командной строке и вручную.

    При работе в команде случаются конфликты слияния. Кто-то фиксирует изменения в файле, над которым вы сейчас работаете, но его изменения пересекаются с вашими, потому что вы оба поменяли одни и те же строки. Система управления версиями не сможет самостоятельно выяснить, какие изменения ей зафиксить ваши или вашего товарища по команде. Таким образом, могут получиться эти неудачные стрелки и символы:

    Конфликт в PyCharm
    Конфликт в PyCharm

    Всё это выглядит странно и трудно понять, что надо удалить, а что оставить. PyCharm на помощь! У него гораздо приятнее и чище способ разрешения конфликтов. Перейдите к VCS в верхнем меню, выберите Git, а затем Resolve conflicts…. Выберите файл, конфликты которого вы хотите разрешить, и нажмите Merge. Вы увидите следующее открытое окно:

    Окно разрешения конфликтов в PyCharm
    Окно разрешения конфликтов в PyCharm

    В левой колонке вы увидите свои изменения. Справа — изменения, внесенные вашим товарищем по команде. Наконец, в средней колонке вы увидите результат. Конфликтующие строки подсвечиваются и вы можете видеть маленькие X and >>/<< рядом с этими строками. Нажмите стрелки для того, чтобы принять изменения, а X, что бы отклонить. После того, как вы разрулите все эти конфликты, нажмите кнопку Apply:

    Конфликт разрешен
    Конфликт разрешен

    В приведенной выше картинке в первой противоречивой строке автор отказался от своих изменений и принял изменения своих товарищей по команде. А во второй строке наоборот, автор принял свои собственные изменения и отклонил изменения своих партнеров по команде.

    При интеграции с системами управления версиями в PyCharm есть гораздо больше возможностей, чем здесь показано. Более подробную информацию можно получить в этой документации.

    Плагины и внешние инструменты в PyCharm

    В PyCharm вы найдёте почти все, что нужно для разработки. Если чего‑то нет, то, скорее всего, есть плагин, реализующий ту функциональность, которая вам нужна. Например, с помощью плагинов можно:

    • Добавить поддержку для различных языков и структур;
    • Увеличить свою пропродуктивность, используя быстрые подсказки, средства просмотра файлов и т.д.;
    • Выучить новый язык программирования с помощью упражнений по кодированию

    Например, IdeaVim добавит иммитацию Vim в ваш PyCharm. Ну, если вам нравится Vim, почему-бы это не сделать.

    Измените тему своего PyCharm на Material Theme UI и посмотрите, как это выглядит:

    Тема Material Design в PyCharm
    Тема Material Design в PyCharm

    Vue.js добавляет поддержку проектов Vue.js. Markdown предоставляет возможность редактировать файлы Markdown в среде IDE и просматривать HTML‑код в режиме предварительного просмотра в браузере. Вы можете найти и установить все доступные плагины, выбрав Preferences → Plugins на Mac или Settings → Plugins на Windows или Linux на вкладке Marketplace, но это уже за деньги:

    Маркеплейс плагинов для PyCharm
    Маркеплейс плагинов для PyCharm

    Если вы ничего не нашли, то можете разработать свой плагин.

    Если вы не можете найти нужный плагин и не хотите разрабатывать свой собственный, потому что в PyPI уже есть пакет, то его можно добавить в PyCharm в качестве внешнего инструмента. Так, например, анализатор кода Flake8.

    Сначала установите flake8 в своей virtualenv, используя pip install flake8 в терминале приложения. Так же успешно можно использовать пакет интегрированный в PyCharm:

    Терминал в PyCharm
    Терминал в PyCharm

    Далее пройдите в меню Preferences → Tools на Mac или Settings → Tools для Windows/Linux и выберите External Tools. Щёлкните на маленькую кнопку + (1). В новом всплывающем окне вставьте детали, как показано ниже, и нажмите ОК для обоих окон:

    Установка Flake8 в PyCharm
    Установка Flake8 в PyCharm

    Здесь Program (2) относится к исполняемому файлу Flake8, который находится в папке /bin вашей виртуальной среды. Arguments (3) указывают, какой файл вы хотите проанализировать с помощью Flake8. Working directory — рабочий каталог вашего проекта.

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

    Обратите свой взор на то, что называется Макрос. Макросы позволяют задавать значения переменным в формате $name$, которые могут меняться в зависимости от вашего контекста. Например, $FileName$ — это first.py, когда вы редактируете first.py, а когда вы редактируете second.py, то это second.py. Вы можете просмотреть их список и вставить любой из них, нажав на кнопки Insert Macro…. Поскольку здесь вы использовали макросы, значения будут меняться в зависимости от проекта, над которым вы сейчас работаете, и Flake8 продолжит правильно выполнять свою работу.

    Чтобы это понять, создайте файл example.py и запишите туда следующий код:

    CONSTANT_VAR = 1
    
    def add(a, b):
        c = "hello"
        return a + b
    

    То, что написано, немного не по правилам Flake8. Нажмите правую кнопку ыша на поле редактирования этого файла. Выберите External Tools и Flake8. Вуа‑ля! Результат анализа Flake8 можно посмотреть внизу:

    Результат анализа кода Flake8, выведенный в PyCharm
    Результат анализа кода Flake8, выведенный в PyCharm

    Для ускорения работы с внешними инструментами можно добавить клавиши быстрого доступа. Перейдём к Preferences на Mac или к Settings на Windows или Linux. Затем Keymap → External Tools → External Tools. Дважды щёлкните на Flake8 и выберите Add Keyboard Shortcut. Посмотрите сюда:

    Добавление клавиш быстрого доступа в PyCharm
    Добавление клавиш быстрого доступа в PyCharm

    На картинке выше показано, как назначены клавиши быстрого доступа Ctrl+Alt+A для загрузки этого инструмента. Добавьте свои клавиши быстрого доступа в текстовое поле и нажмите OK для обоих окон. Теперь вы можете использовать эти клавиши для загрузки Flake8 и анализа файла, над которым сейчас работаете.

    Возможности профессиональной версии PyCharm

    PyCharm Professional — это платная версия PyCharm с огромным количеством готовых функций и возможностей интеграции. В этом разделе, в основном, будет представлен обзор главных функций и ссылки на официальную документацию, где каждая функция подробно обсуждается. Помните, что ни одна из следующих функций не доступна в версии Community.

    Поддержка Django

    PyCharm поддерживает Django, один из самых популярных и любимых веб‑фреймворков Python. Что бы убедиться в его доступности проделайте следующее:

    1. Откройте Preferences на Mac или Settings на Windows или Linux.
    2. Выберите Languages and Frameworks.
    3. Выберите Django.
    4. Проверьте установлена ли галочка на Enable Django support?Если нет, установите.
    5. Примените изменения.

    Теперь, когда вы включили поддержку Django, ваше путешествие при разработке с Django станет наиболее приятным с PyCharm:

    • При создании проекта у вас будет выбран тип проекта Django. И это означает, что в проекте такого типа у вас будут все необходимые файлы и настройки. Это эквивалентно использованию django-admin startproject mysite.
    • Вы можете загрузить manage.py непосредственно из PyCharm.
    • Поддержка в шаблоне Django включает:
      • синтаксис и подсветку ошибок.
      • Автозавершение кода.
      • Навигацию.
      • Завершение имен блоков.
      • Завершение пользовательских тегов и фильтров.
      • Быстрый доступ к документации по тегам и фильтрам.
      • Возможность их отладки.
    • Автоавершение кода во всех других частях Django, таких как представления, URL‑адреса и модели, а также поддержка анализа кода для Django ORM.
    • Диаграммы зависимостей для моделей Django.

    Более подробная информация о поддержке Django смотрите в официальной документации.

    Поддержка баз данных

    Современная разработка баз данных — сложная задача со множеством вспомогательных систем и рабочих процессов. Вот почему JetBrains, компания, стоящая за PyCharm, разработала для этого отдельную IDE DataGrip. Это отдельный продукт от PyCharm с отдельной лицензией.

    К счастью, PyCharm поддерживает все функции, доступные в DataGrip через плагин Database tools and SQL, который включен по умолчанию. С его помощью можно запрашивать, создавать и управлять базами данных независимо от того, работают ли они локально, на сервере или в облаке. Плагин поддерживает MySQL, PostgreSQL, Microsoft SQL Server, SQLite, MariaDB, Oracle, Apache Cassandra и другие. Для получения дополнительной информации о том, что вы можете сделать с этим плагином, посмотрите полную документацию по поддержке баз данных.

    Визуализация параллельных потоков

    Django Channels, asyncio и последние фреймворки, такие как Starlette являются примерами растущей популярности асинхронного программирования на Python. Несмотря на то, что асинхронные программы действительно приносят много пользы, известно, что их довольно сложно писать и отлаживать. В таких случаях визуализация параллельных потоков может быть именно тем, что доктор прописал. Она помогает полностью контролировать свои многопоточные приложения и оптимизировать их.

    Проверьте подробную документацию этой функции для получения более подробной информации.

    Более подробная информация содержится в подробной документации об этой функции.

    Профилировщик

    Говоря об оптимизации, профилирование — это еще один метод, который можно использовать для оптимизации кода. С его помощью можно увидеть, какие части кода занимают большую часть времени при выполнении. Профилировщик расставляет следующие приоритеты:

    1. vmprof
    2. yappi
    3. cProfile

    Если у вас не установлен vmprof или yappi, просто вернитесь к стандартному cProfile. Он хорошо документирован и здесь я не буду пересказывать эту документацию.

    Режим научной разработки

    Python — это язык не только для общего и веб‑программирования. За последние годы он стал лучшим инструментом для науки о данных и машинного обучения. Своей популярностью он обязан своим инструментам и библиотекам, таким как NumPy, SciPy, scikit-learn, Matplotlib, Jupyter и другим. При наличии таких мощных библиотек необходима мощная IDE для поддержки всех функций, таких как построение графиков и анализ этих библиотек. PyCharm предоставляет все, что нужно, исчерпывющая документация здесь.

    Удалённая разработка

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

    С помощью PyCharm можно отлаживать свои приложение, используя интерпретатор с другого компьютера, например, на виртуальной машине Linux. В результате вы можете использовать тот же интерпретатор, что и ваша рабочая среда. Это позволяет исправлять и избегать многих ошибок. Прочитайте об этом в официальной документации.

    Заключение

    PyCharm — одна из лучших, если не самая лучшая, полнофункциональная, специализированная и универсальная IDE для разработки на Python. Он обладает массой возможностей, которые экономят время, помогая вам с рутинными задачами. Теперь вы знаете, как быть ним продуктивным!

    Здесь вы узнали о многом, в том числе:

    • Как установить PyCharm;
    • Как записать код в PyCharm;
    • Как загрузить код в PyCharm;
    • Отладка и тестирование кода в PyCharm;
    • Как изменить существующий проект в PyCharm;
    • Поиск и навигация в PyCharm;
    • Контроль версий в PyCharm;
    • Плагины и внешние инструменты в PyCharm;
    • Использование возможностей профессиональной версии PyCharm, таких как поддержка Django и режима научной разработки.;

    Если Вы хотите что-то спросить или поделиться своими замечаниями пишите в комментарии ниже. Для более детального знакомства с документацией перейдите на сайт PyCharm.

    Для визуалов:

    По мотивам: PyCharm for Productive Python Development (Guide)Р

    ]]>
    https://chel-center.ru/python-yfc/2019/10/01/pycharm-mdash-instrument-effektivnoj-razrabotki-na-python/feed/ 0
    13 лучших библиотек глубокого машинного обучения для Python https://chel-center.ru/python-yfc/2019/11/05/13-luchshih-bibliotek-python-dlya-glubokogo-mashinnogo-obucheniya/ https://chel-center.ru/python-yfc/2019/11/05/13-luchshih-bibliotek-python-dlya-glubokogo-mashinnogo-obucheniya/#respond Tue, 05 Nov 2019 07:16:29 +0000 http://waksoft.susu.ru/?p=25174 Читать далее «13 лучших библиотек глубокого машинного обучения для Python»

    ]]>
    Когда дело касается задач машинного обучения, искусственного интеллекта, Deep Learning и данных, Python безусловно продолжает лидировать. Согласно builtwith.com, 45% технологических компаний предпочитают использовать Python для реализации ИИ и машинного обучения.

    Ниже приведен список 13 самых популярных библиотек Python, используемых при решении многочисленных задач глубокого машинного обучения Конечно, список этот субъективен. Многие библиотеки могут быть легко отнесены к нескольких категориям искусственного интеллекта. Например, TensorFlow включен в наш список, а Keras, наоборот, считается библиотекой Machine Learning. Связано это с тем, что Keras скорее библиотека для «конечного пользователя», такая как SKLearn. Что отличает её от TensorFlow, которая больше привлекает исследователей и «инженеров-машинистов».

    ython deep learninig
    Рисунок 1: 13 лучших библиотек Deep Learning на Python, Commits и Contributors. Размер метки пропорционален количеству звезд.

    Теперь давайте перейдем непосредственно к списку (цифры с GitHub получены 23 октября 2018 года):

    1. TensorFlow

    (Contributors — 1 700, Commits — 42 256, ✬✬✬ — 112 591)

    TensorFlow — библиотека с открытым исходным кодом для численного расчета с использованием графов потока данных. Узлы графа представляют собой математические операции, а ребра — многомерные массивы данных (тензоры), которые текут между ними. Такая гибкая архитектура позволяет развернуть вычисления на одном или нескольких процессорах или графических процессорах на рабочем столе, сервере или мобильном устройстве без переписывания кода.

    2. PyTorch

    (Contributors — 806, Commits — 14 022, ✬✬✬ — 20 243)

    PyTorch — это пакет Python, который обеспечивает две функции высокого уровня:

    1. Расчет тензора (например, NumPy) с сильным ускорением GPU
    2. Глубокие нейронные сети, построенные на ленточной автоградной системе

    Вы можете использовать свои любимые пакеты Python, такие как NumPy, SciPy и Cython для расширения PyTorch при необходимости.

    3. Apache MXNet

    (Contributors — 628, Commits — 8 723, ✬✬✬ — 15 447)

    Apache MXNet (инкубация) — база Deep Learning, ориеннтрованная на эффективность и гибкость. Это позволяет сочетать символическое и императивное программирование для увеличения эффективности и производительности. По своей сути MXNet содержит динамический планировщик зависимостей, который «на лету» автоматически распараллеливает как символические, так и императивные операции.

    4. Theano

    (Contributors — 329, Commits — 28 033, ✬✬✬ — 8 536)

    Theano — библиотека Python, которая позволяет эффективно определять, оптимизировать и оценивать математические выражения, содержащие многомерные массивы. Она может использовать графические процессоры и выполнять эффективную символическую дифференциацию.

    5. Caffe

    (Contributors — 270, Commits — 4 152, ✬✬✬ — 25 927)

    Caffe — база Deep Learning, разработанная с учетом выраженности, скорости и модульности. Разработана в Berkeley AI Research (BAIR) / The Berkeley Vision and Learning Center (BVLC) и их сообществами.

    6. fast.ai

    (Contributors — 226, Commits — 2 237, ✬✬✬ — 8 872)

    Библиотека fastai упрощает обучение быстрым и точным нейронным сетям, используя современные передовые методы. Для начала ознакомьтесь с сайтом fast.ai. Библиотека основана на исследованиях в области передовых методов Deep Learning, проводимых на fast.ai, и включает в себя «из коробки» поддержку моделей видения, текста, таблиц и коллабов (совместная фильтрация).

    7. CNTK

    (Contributors — 189, Commits — 15 979, ✬✬✬ — 15 281)

    Инструментарий Microsoft Cognitive Toolkit ( https://cntk.ai ) — унифицированный инструментарий Deep Learning, который описывает нейронные сети как серию вычислительных шагов через ориентированный граф. В этом ориентированном графе листовые узлы представляют входные значения или сетевые параметры, тогда как другие узлы представляют собой матричные операции на своих входах. CNTK позволяет пользователям легко реализовывать и комбинировать популярные типы моделей, такие как DNN прямой линии связи, сверточные сети (CNN) и свёрточные сети (RNNs / LSTM).

    8. TFLearn

    (Contributors — 118, Commits — 599, ✬✬✬ — 8 632)

    TFlearn — модульная и прозрачная библиотека Deep Learning, построенная на основе Tensorflow. Она был разработана для предоставления API для TensorFlow более высокого уровня, облегчающий и ускоряющий эксперименты, оставаясь полностью прозрачным и совместимым.

    9. Lasagne

    (Contributors — 64, Commits — 1 157, ✬✬✬ — 3 534)

    Lasagne — легкая библиотека для создания и обучения нейронных сетей в Теано. Она поддерживает сети передачи данных, такие как сверточные нейронные сети (CNN), свёрточные сети, включая Long Short-Term Memory (LSTM) и любую их комбинацию.

    10. nolearn

    (Contributors — 14, Commits — 389, ✬✬✬ — 909)

    Nolearn содержит множество оберток и абстракций вокруг существующих нейронных сетевых библиотек, в первую очередь Lasagne, а также несколько модулей для машинного обучения. Весь код написан для совместимости с scikit-learn.

    11. Elephas

    (Contributors — 13, Commits — 249, ✬✬✬ — 1 046)

    Elephas — это расширение Keras, которое позволяет вам запускать распределенные модели Deep Learning в масштабе с помощью Spark. В настоящее время Elephas поддерживает ряд приложений, в том числе:

    1. Параллельная подготовка моделей Deep Learning
    2. Распределенная оптимизация гиперпараметров
    3. Распределенное обучение ансамблевым моделям

    12. spark-deep-learning

    (Contributors — 12, Commits — 83, ✬✬✬ — 1 131)

    Deep Learning Pipelines предоставляет высокоуровневые API для масштабируемого Deep Learning на Python с Apache Spark. Библиотека исходит от Databricks и использует Spark для двух самых сильных аспектов:

    1. В духе Spark и Spark MLlib он предоставляет простые в использовании API, которые позволяют осуществлять глубокое обучение в очень немногих строках кода.
    2. Он использует мощный распределенный движок Spark для глубокого изучения массивных наборов данных.

    13. Distributed Keras

    (Contributors — 5, Commits — 1 125, ✬✬✬ — 523)

    Распределенная Keras — это распределенная система Deep Learning, построенная поверх Apache Spark и Keras, с упором на« современные »распределенные алгоритмы оптимизации. Мы разработали структуру таким образом, чтобы новый распределенный оптимизатор мог быть реализован с легкостью, что позволило человеку сосредоточиться на исследованиях.

    Следите за следующей частью этой серии, в которой основное внимание уделяется Укреплению знаний и библиотекам эволюционных вычислений, которые будут опубликованы в течение следующих нескольких недель!

    По мотивам: Top 13 Python Deep Learning Libraries. By Dan Clark, KDnuggets.

    ]]>
    https://chel-center.ru/python-yfc/2019/11/05/13-luchshih-bibliotek-python-dlya-glubokogo-mashinnogo-obucheniya/feed/ 0
    Как написать телеграмм-бота на Python https://chel-center.ru/python-yfc/2019/11/18/kak-napisat-telegramm-bota-na-python/ https://chel-center.ru/python-yfc/2019/11/18/kak-napisat-telegramm-bota-na-python/#respond Mon, 18 Nov 2019 15:11:27 +0000 http://waksoft.susu.ru/?p=24486 Читать далее «Как написать телеграмм-бота на Python»

    ]]>
    Сие есть краткий видеокурс с просторов Youtube, где наблюдается полный цикл разработки бота на Python без лишнего пафоса. Только практика.

    Знакомство с Bot API Телеграмма, рассказ о ботах, как их создавать и как получать сообщения, отправленные ему. Чем отличаются WebHook и GetUpdate, и об остальном понемножку…

     

    Про JSON объекты, работу с документами загрузкой(POST) и по id, getFile, и по быстрому про остальные методы из API

    Код Html формы из урока тут

     

    Про то, как и в чём написать скрипт, управляющий поведением бота. Обработка текстовых сообщений и команд, знакомство с библиотекой telebot и просто примеры кода — всё тут

     

    Наращиваем функционал нашему боту. Отправка фотографий, аудио и всех остальных методов send_. Скачивание и отправка файла по URL, случайный выбор и чат экшены

     

    Внимательное чтение документации хорошо способствует проникновению в процесс botAPI, документация и примеры кода библиотеки telebot на GitHub

    ]]>
    https://chel-center.ru/python-yfc/2019/11/18/kak-napisat-telegramm-bota-na-python/feed/ 0
    Обнаружение объекта на изображении методом цветовой сегментации (Python) https://chel-center.ru/python-yfc/2019/11/26/obnaruzhenie-obekta-na-izobrazhenii-opirajas-na-cvetovuju-segmentacii-python/ https://chel-center.ru/python-yfc/2019/11/26/obnaruzhenie-obekta-na-izobrazhenii-opirajas-na-cvetovuju-segmentacii-python/#respond Tue, 26 Nov 2019 07:19:43 +0000 http://waksoft.susu.ru/?p=27166 Читать далее «Обнаружение объекта на изображении методом цветовой сегментации (Python)»

    ]]>
    Прежде чем говорить о сути вещей, договоримся о терминах . . .

    Контур — просто непрерывная кривая, разделяющая на изображении все точки с одинаковым цветом или интенсивность. Контур является полезным инструментом для анализа форм, а также для обнаружения и распознавания объектов.

    Порог. Применение порогового значения к изображению в градациях серого делает его двоичным черно/белым изображением. Из разумных соображений устанавливается пороговое значение, при котором все значения ниже этого порога становятся черными, а все значения выше становятся белыми.

    Начинаем наши упражнения

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

     Круг Омбре - изображение, сделанное с помощью фотошопа
    Круг Омбре — изображение, сделанное с помощью фотошопа

    Для своих практических упражнений заберите это изображение здесь.

    Разделим изображение на 17 колец по уровням серого, а затем измерим площадь каждого кольца, ограниченного контуром.

    import cv2
    import numpy as np
    
    def viewImage(image):
        cv2.namedWindow('Display', cv2.WINDOW_NORMAL)
        cv2.imshow('Display', image)
        cv2.waitKey(0)
        cv2.destroyAllWindows()
    
    def grayscale_17_levels (image):
        high = 255
        while(true):  
            low = high - 15
            col_to_be_changed_low = np.array([low])
            col_to_be_changed_high = np.array([high])
            curr_mask = cv2.inRange(gray, col_to_be_changed_low,col_to_be_changed_high)
            gray[curr_mask > 0] = (high)
            high -= 15
            if(low == 0 ):
                break
    
    image = cv2.imread('./path/to/image')
    viewImage(image)
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    grayscale_17_levels(gray)
    viewImage(gray)
    
    То же изображение разделено на 17 уровней серого
    То же изображение разделено на 17 уровней серого
    def get_area_of_each_gray_level(im):
    
    ## convert image to gray scale (must br done before contouring)
        image = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
        output = []
        high = 255
        first = True
        while(true):
    
            low = high - 15
            if(first == False):
    
                ## making values that are of a greater gray level black 
                ## so it won't get detected  
                to_be_black_again_low = np.array([high])
                to_be_black_again_high = np.array([255])
                curr_mask = cv2.inRange(image, to_be_black_again_low, 
                to_be_black_again_high)
                image[curr_mask > 0] = (0)
                
            # making values of this gray level white so we can calculate
            # it's area
            ret, threshold = cv2.threshold(image, low, 255, 0)
            contours, hirerchy = cv2.findContours(threshold, 
            cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
    
            if(len(contours) > 0):
                output.append([cv2.contourArea(contours[0])])
                cv2.drawContours(im, contours, -1, (0,0,255), 3)
    
            high -= 15
            first = False
            if(low == 0 ):
    break
    return output
    

    В этой функции я просто преобразую диапазон (интенсивностей) серого, который хочу оконтурить (выделить) на соответствующей итерации, объединяя все, что находятся в этом диапазоне, в одно поле с заданной интенсивностью. Я включаю любую интенсивность кроме черной (в том числе и наибольшую, и наименьшую интенсивности).

    Второй шаг — получение порогового (бинарного) изображения. Теперь поле, которое я хочу обвести контуром надо сделать белым, а все остальные — чёрными. Этот шаг не сильно оригинален, но он необходим, потому как оконтуривание лучше всего делать по черно-белым (пороговым, бинарным) изображениям.

    Получим (пороговое, бинарное) изображение, где белое кольцо заменит серое с интенсивностью 10-го уровня (255–15 * 10), а все остальные кольца сделаем чёрными.

    Выделяем единственный, 10-й сегмент, для вычисления его площади
    Выделяем единственный, 10-й сегмент, для вычисления его площади

    image = cv2.imread('./path/to/image')
    print(get_area_of_each_gray_level(image))
    viewImage(image)
    

     Контуры 17 уровней серого на исходном изображении
    Контуры 17 уровней серого на исходном изображении


     

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

    Зачем всё это?

    Прежде чем продолжить, хочу подчеркнуть важность нашей темы.

    На факультете компьютерной инженерии MTI, с которым у нас активное сотрудничество, ведутся работы над проектом под названием «Машинное обучение» для интеллектуального обнаружения и идентификации опухолей.

    В этом проекте в полный рост используется сегментация цветного изображения для того, чтобы научить компьютер обнаруживать опухоль. При работе с МРТ (Магнитно-резонансная томография) программа должна определять стадию развития рака, что достигается сегментированием сканированных изображений по различным уровням оттенков серого, где самые темные участки наиболее заполнены раковыми клетками, а близкие к белому соответствуют более здоровым частям тела. Далее вычисляется степень развития опухоли, которой соответствует некоторый уровень серого. Именно эта информация позволяет локализовать и определить стадию развития опухоли.

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

    Обнаружение объекта

    Фото Лукаса из Pexels
    Фото Лукаса из Pexels

    Для своих упражнений заберём изображение отсюда, на Pexels, которое нужно будет просто немного обрезать.

    На этом изображении необходимо получить только контур листа. Текстура изображения очень нерегулярна и неровна, хотя цветов не так уж и много. Кроме того, интенсивность зеленого ещё и меняет свою яркость. Поэтому лучше всего будет объединить все оттенки зеленого в один цвет. Таким образом, когда будет построен контур, с листом можно будет работать как с единым целым.

     ПРИМЕЧАНИЕ  Вот результат оконтуриавания без какой-либо предварительной обработки. Здесь я просто хочу показать, как неровномерная природа листа обманывает OpenCV и не позволяет ему понять, что это всего лишь один объект. Кстати, очень полезный мануал по OpenCV

    Контур без предварительной обработки, обнаружен 531 контур
    Контур без предварительной обработки, обнаружен 531 контур

    import cv2
    import numpy as np
    
    def viewImage(image):
        cv2.namedWindow('Display', cv2.WINDOW_NORMAL)
        cv2.imshow('Display', image)
        cv2.waitKey(0)
        cv2.destroyAllWindows()
    

    Первое, что вам необходимо знать — HSV (цветовая модель) ваших цветов, которую можно узнать, сделав преобразование его из RGB в HSV, использовав нижеследующий код.

    ## getting green HSV color representation
    green = np.uint8([0, 255, 0])
    green_hsv = cv2.cvtColor(green,cv2.COLOR_BGR2HSV)
    print( green_hsv)
    
    Зеленый цвет в HSV-представлении
    Зеленый цвет в HSV-представлении

    Преобразование изображения в HSV-представление: с HSV значительно проще получить полный диапазон одного цвета. В HSV H — тон (например, красный, зелёный или сине-голубой), S — насыщенность (варьируется в пределах 0—100 или 0—1. Чем больше этот параметр, тем «чище» цвет, поэтому этот параметр иногда называют чистотой цвета. А чем ближе этот параметр к нулю, тем ближе цвет к нейтральному серому), V — значение или Brightness — яркость (задаётся в пределах 0—100 или 0—1). Мы уже знаем, что зеленому цвету в HSV соответствует [60, 255, 255]. Все зеленые цвета мира расположены в пределах от [45, 100, 50] до [75, 255, 255], то есть от [60–15, 100, 50] до [60+15 , 255, 255]. 15 — только приблизительное значение.

    Мы берем этот диапазон и преобразуем его в [75, 255, 200 ] или любой другой цвет из диапазона зелёных (3-е значение, яркость, должно быть относительно большим), это значение, когда мы перейдём к бинарному изображению, станет белым.

    image = cv2.imread('./path/to/image.jpg')
    hsv_img = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
    viewImage(hsv_img) ## 1
    
    green_low = np.array([45 , 100, 50] )
    green_high = np.array([75, 255, 255])
    curr_mask = cv2.inRange(hsv_img, green_low, green_high)
    hsv_img[curr_mask > 0] = ([75,255,200])
    viewImage(hsv_img) ## 2
    
    ## converting the HSV image to Gray inorder to be able to apply 
    ## contouring
    RGB_again = cv2.cvtColor(hsv_img, cv2.COLOR_HSV2RGB)
    gray = cv2.cvtColor(RGB_again, cv2.COLOR_RGB2GRAY)
    viewImage(gray) ## 3
    
    ret, threshold = cv2.threshold(gray, 90, 255, 0)
    viewImage(threshold) ## 4
    
    contours, hierarchy =  cv2.findContours(threshold,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
    cv2.drawContours(image, contours, -1, (0, 0, 255), 3)
    viewImage(image) ## 5
    

    Изображение сразу после преобразования в HSV (1)
    Изображение сразу после преобразования в HSV (1)

    Изображение после нанесения маски (нормализация цвета) (2)
    Изображение после нанесения маски (нормализация цвета) (2)

    Изображение после преобразования из HSV в серый (3)
    Изображение после преобразования из HSV в серый (3)

    Бинарное изображение, последний шаг (4)
    Бинарное изображение, последний шаг (4)

    Конечный контур (5)
    Конечный контур (5)

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

    Мы можем вычислить индекс контура листа в массиве выделенных контуров по наибольшей площади и центру, близкому к центру листа.

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

    def findGreatesContour(contours):
        largest_area = 0
        largest_contour_index = -1
        i = 0
        total_contours = len(contours)
        while (i  largest_area):
                largest_area = area
                largest_contour_index = i
            i+=1
                
        return largest_area, largest_contour_index
    
    # to get the center of the contour
    cnt = contours[13]
    M = cv2.moments(cnt)
    cX = int(M["m10"] / M["m00"])
    cY = int(M["m01"] / M["m00"])
    
    largest_area, largest_contour_index = findGreatesContour(contours)
    
    print(largest_area)
    print(largest_contour_index)
    
    print(len(contours))
    
    print(cX)
    print(cY)
    

    Результат печати
    Результат печати

     

    Некоторые примеры кода из этой статьи можно загрузить здесь.
     

    По мотивам Object detection via color-based image segmentation using python

    ]]>
    https://chel-center.ru/python-yfc/2019/11/26/obnaruzhenie-obekta-na-izobrazhenii-opirajas-na-cvetovuju-segmentacii-python/feed/ 0
    Визуализация данных в Web с использованием Python https://chel-center.ru/python-yfc/2019/12/21/vizualizacziya-dannyh-v-web-s-ispolzovaniem-python/ https://chel-center.ru/python-yfc/2019/12/21/vizualizacziya-dannyh-v-web-s-ispolzovaniem-python/#respond Sat, 21 Dec 2019 15:31:41 +0000 http://waksoft.susu.ru/?p=29031 Читать далее «Визуализация данных в Web с использованием Python»

    ]]>
      Коллеги-экономисты, вас не тормозят привычные инструменты бизнес-аналитики? Может быть пора уже попробовать встать на правильный путь, изучить Python и заняться более глубоким анализом социально‑экономических процессов, так, как это делается во всём мире?

    Именно так начиналась статья Вас не тормозят привычные инструменты бизнес‑аналитики? в надежде убедить, что в программировании все не так сложно, как кажется. Здесь хотелось бы показать, что все еще проще. Инфографика, которую вы увидите, ниже стимулировала продолжение поиска инструментов визуализации данных и в этой заметке ещё об одном замечательном и абсолютно бесплатном фреймворке Python — Bokeh, и небольшой отчет о проделанных недавно экспериментах, результаты которых представлены серией простейших приложений визуализации, в том числе, и интерактивной визуализации, которая реализуется на удивление просто.

    33 способа визуализации
    33 способа визуализации.

    Тщательнее: Диаграмма, График функции, Блок‑схема, Карта памяти, Облако тегов (Облако слов), Дерево решений, Диаграмма Гантта, Гистограмма, Диаграмма Эйлера, Диаграмма Венна

    Быстрый старт с Bokeh

    Bokeh — интересное такое современное понятие, но для нас это интерактивная библиотека визуализации для современных веб-браузеров. Фреймворк Python обеспечивает шикарную, сжатую конструкцию разнообразных графиков и обеспечивает высокопроизводительную интерактивность с большими или потоковыми наборами данных. Bokeh может помочь всем, кто хочет быстро и легко создавать интерактивные сюжеты, информационные панели, и приложения для передачи и предоставления аналитической информации.

    Это краткое руководство, где внимание сфокусировано на визуализации без использования сервера, т.е. с помощью этих техник сделать онлайн-мониторинг погоды невозможно, данные в нашем случае должны быть статическими. Результатом работы программы является html-файл, который можно просто загрузить на web-сервер. Смею вас заверить, что все приложения, скрипты и ссылки на демонстрашки которых ниже, в том числе и интерактивные приложения, просто положены под Apache на нашем университетском сервере.

    Pycharm и Bokeh

    С инструментарием для разработки мы уже определились и подробнее прочитать о нём можно в статье PyCharm — эффективная разработка на Python. Поэтому невзирая на то, что в оригинальной документации Bokeh предполагается использовать Jupiter Notebook, для своих упражнений будем использовать Pycharm. Для нас подойдёт любая версия от Education до Professional.

    Что бы Bokeh заработал, надо создать новый проект и установить его в виртуальную среду нашего нового демо-проекта.

    Создаём демо-проект
    Создаём демо-проект
    Начинаем настройку виртуального окружения
    Начинаем настройку виртуального окружения
    Назначаем базовый интерпретатор Python 3.8.6
    Назначаем базовый интерпретатор Python 3.8.6
    Подключаем требуемые для проекта пакеты Bokeh, Numpy, pandas. Ну, и связанные с ними
    Подключаем требуемые для проекта пакеты bokeh, numpy, pandas. Ну, и связанные с ними, которые сами встанут благодаря pip

    Теперь всё готово для начала наших экспериментов.

    Создаём файл <code>bars.py</code> и копипастим первый скрипт с этой страницы в окно редактора Pycharm.
    Создаём файл bars.py и копипастим первый скрипт с этой страницы в окно редактора Pycharm.

    Запускаем скрипт bars.py из контекстного меню, но можно и любым другим доступным способом
    Запускаем скрипт bars.py из контекстного меню, но можно и любым другим доступным способом

    И наблюдаем результат в окне браузера, который в вашей системе установлен по умолчанию:

    Окно браузера. Обратите внимание на адрес показываемого ресурса file:///D:/PHYTON/quickstart-bokeh/bars.html
    Окно браузера. Обратите внимание на адрес показываемого ресурса file:///D:/PHYTON/quickstart-bokeh/bars.html

    В папке вашего проекта появился новый файл bars.html, который после работы скрипта вы видите в окне навигатора проекта Pycharm. Его можно прочитать своим браузером и/или загрузить куда-нибудь в интернет на доступные вам ресурсы хостинга. Вот так передаются сообществам результаты своих исследований, просто файл .html и никакого «шаманства».

    В результате работы скрипта появился новый файл bars.tml
    В результате работы скрипта появился новый файл bars.html

    Теперь файл bars.html можно опубликовать на любом сервере, что и сделано, и в чём вы можете убедиться, пройдя по ссылке Live Demo: Строим гистограмму.

    С дальнейшими примера поступаем точно так-же.

    1. Строим Гистограмму:
      from bokeh.io import show, output_file
      from bokeh.plotting import figure
      
      output_file("bars.html")
      
      fruits = ['Яблоки', 'Груши', 'Нектарин', 'Сливы', 'Виноград', 'Клубника']
      counts = [5, 3, 4, 2, 4, 6]
      
      p = figure(x_range=fruits, plot_height=250, title="Фрукты (количество)",
                 toolbar_location=None, tools="")
      
      p.vbar(x=fruits, top=counts, width=0.9)
      
      p.xgrid.grid_line_color = None
      p.y_range.start = 0
      
      show(p)
      

      Live Demo: Строим гистограмму

    2. Строим Отсортированную гистограмму:
      
      from bokeh.io import show, output_file
      from bokeh.plotting import figure
      
      output_file("bar_sorted.html")
      
      fruits = ['Яблоки', 'Груши', 'Нектарин', 'Сливы', 'Виноград', 'Клубника']
      counts = [5, 3, 4, 2, 4, 6]
      
      # sorting the bars means sorting the range factors
      sorted_fruits = sorted(fruits, key=lambda x: counts[fruits.index(x)])
      
      p = figure(x_range=sorted_fruits, plot_height=350, title="Фрукты (количество)",
                 toolbar_location=None, tools="")
      
      p.vbar(x=fruits, top=counts, width=0.9)
      
      p.xgrid.grid_line_color = None
      p.y_range.start = 0
      
      show(p)
      

      Live Demo: Строим отсортированную гистограмму

    3. Строим Цветную гистограмму:
      from bokeh.io import show, output_file
      from bokeh.models import ColumnDataSource
      from bokeh.palettes import Spectral6
      from bokeh.plotting import figure
      
      output_file("color_bars.html")
      
      fruits = ['Яблоки', 'Груши', 'Нектарин', 'Сливы', 'Виноград', 'Клубника']
      counts = [5, 3, 4, 2, 4, 6]
      
      source = ColumnDataSource(data=dict(fruits=fruits, counts=counts, color=Spectral6))
      
      p = figure(x_range=fruits, y_range=(0,9), plot_height=250, title="Количество фруктов",
                 toolbar_location=None, tools="")
      
      p.vbar(x='fruits', top='counts', width=0.9, color='color', legend_field="fruits", source=source)
      
      p.xgrid.grid_line_color = None
      p.legend.orientation = "horizontal"
      p.legend.location = "top_center"
      
      show(p)
      

      Live Demo: Строим цветную гистограмму

    4. Скрип Пример простой линии:
      from bokeh.plotting import figure, output_file, show
      
      # prepare some data
      x = [1, 2, 3, 4, 5]
      y = [6, 7, 2, 4, 5]
      
      # output to static HTML file
      output_file("lines.html")
      
      # create a new plot with a title and axis labels
      p = figure(title="Пример простой линии", x_axis_label='x', y_axis_label='y')
      
      # add a line renderer with legend and line thickness
      p.line(x, y, legend="Обозначение", line_width=2)
      
      # show the results
      show(p)
      

      Live Demo: Пример простой линии

    5. Скрипт Цветные графики с логарифмической шкалой:
      from bokeh.plotting import figure, output_file, show
      
      # prepare some data
      x = [0.1, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0]
      y0 = [i**2 for i in x]
      y1 = [10**i for i in x]
      y2 = [10**(i**2) for i in x]
      
      # output to static HTML file
      output_file("log_lines.html")
      
      # create a new plot
      p = figure(
         tools="pan,box_zoom,reset,save",
         y_axis_type="log", y_range=[0.001, 10**11], title="Пример графиков с логарифмической шкалой",
         x_axis_label='область определения', y_axis_label='значение функций'
      )
      
      # add some renderers
      p.line(x, x, legend="y=x")
      p.circle(x, x, legend="y=x", fill_color="white", size=8)
      p.line(x, y0, legend="y=x^2", line_width=3)
      p.line(x, y1, legend="y=10^x", line_color="red")
      p.circle(x, y1, legend="y=10^x", fill_color="red", line_color="red", size=6)
      p.line(x, y2, legend="y=10^x^2", line_color="orange", line_dash="4 4")
      
      # show the results
      show(p)
      

      Live Demo: Цветные графики с логарифмической шкалой

    6. Аналитика Импорт/Экспорт фруктов по годам:
      from bokeh.io import output_file, show
      from bokeh.models import ColumnDataSource
      from bokeh.palettes import GnBu3, OrRd3
      from bokeh.plotting import figure
      
      output_file("stacked_split.html")
      
      fruits = ['Яблоки', 'Груши', 'Нектарин', 'Сливы', 'Виноград', 'Клубника']
      years = ["2015", "2016", "2017"]
      
      exports = {'fruits' : fruits,
                 '2015'   : [2, 1, 4, 3, 2, 4],
                 '2016'   : [5, 3, 4, 2, 4, 6],
                 '2017'   : [3, 2, 4, 4, 5, 3]}
      imports = {'fruits' : fruits,
                 '2015'   : [-1, 0, -1, -3, -2, -1],
                 '2016'   : [-2, -1, -3, -1, -2, -2],
                 '2017'   : [-1, -2, -1, 0, -2, -2]}
      
      p = figure(y_range=fruits, plot_height=250, x_range=(-16, 16), title="Импорт/Экспорт фруктов по годам",
                 toolbar_location=None)
      
      p.hbar_stack(years, y='fruits', height=0.9, color=GnBu3, source=ColumnDataSource(exports),
                   legend_label=["%s экспорт" % x for x in years])
      
      p.hbar_stack(years, y='fruits', height=0.9, color=OrRd3, source=ColumnDataSource(imports),
                   legend_label=["%s импорт" % x for x in years])
      
      p.y_range.range_padding = 0.1
      p.ygrid.grid_line_color = None
      p.legend.location = "top_left"
      p.axis.minor_tick_line_color = None
      p.outline_line_color = None
      
      show(p)
      

      Live Demo: Импорт/Экспорт фруктов по годам

    7. Комментарии к объектам на рисунках:
      from bokeh.io import output_file, show
      from bokeh.models import GeoJSONDataSource
      from bokeh.plotting import figure
      from bokeh.sampledata.sample_geojson import geojson
      import json
      
      output_file("geojson.html")
      
      data = json.loads(geojson)
      for i in range(len(data['features'])):
          data['features'][i]['properties']['Color'] = ['blue', 'red'][i%2]
      
      geo_source = GeoJSONDataSource(geojson=json.dumps(data))
      
      TOOLTIPS = [
          ('Организация', '@OrganisationName')
      ]
      
      p = figure(background_fill_color="lightgrey", tooltips=TOOLTIPS)
      p.circle(x='x', y='y', size=15, color='Color', alpha=0.7, source=geo_source)
      
      show(p)
      

      Live Demo: Комментарии к объектам на рисунках

    8. Посмотрим на карту Google:
      from bokeh.io import output_file, show
      from bokeh.models import ColumnDataSource, GMapOptions
      from bokeh.plotting import gmap
      
      output_file("gmap.html")
      
      map_options = GMapOptions(lat=30.2861, lng=-97.7394, map_type="roadmap", zoom=11)
      
      # For GMaps to function, Google requires you obtain and enable an API key:
      #
      #     https://developers.google.com/maps/documentation/javascript/get-api-key
      #
      # Replace the value below with your personal API key:
      p = gmap("GOOGLE_API_KEY", map_options, title="Austin")
      
      source = ColumnDataSource(
          data=dict(lat=[ 30.29,  30.20,  30.29],
                    lon=[-97.70, -97.74, -97.78])
      )
      
      p.circle(x="lon", y="lat", size=15, fill_color="blue", fill_alpha=0.8, source=source)
      
      show(p)
      

      Live Demo: Посмотрим на карту Google

      Примечание: карта Google работает коряво, не прописал ключ API. Заведите свой GOOGLE_API_KEY и наслаждайтесь.

    9. Посмотрим как изменяются координаты «мышки»:
      import numpy as np
      from bokeh.io import show, output_file
      from bokeh.plotting import figure
      from bokeh import events
      from bokeh.models import CustomJS, Div, Button
      from bokeh.layouts import column, row
      
      def display_event(div, attributes=[], style = 'float:left;clear:left;font_size=10pt'):
          "Build a suitable CustomJS to display the current event in the div model."
          return CustomJS(args=dict(div=div), code="""
              var attrs = %s; var args = [];
              for (var i = 0; i<attrs.length; i++) {
                  args.push(attrs[i] + '=' + Number(cb_obj[attrs[i]]).toFixed(2));
              }
              var line = "" + cb_obj.event_name + "(" + args.join(", ") + ")\\n";
              var text = div.text.concat(line);
              var lines = text.split("\\n")
              if (lines.length > 35)
                  lines.shift();
              div.text = lines.join("\\n");
          """ % (attributes, style))
      
      x = np.random.random(size=4000) * 100
      y = np.random.random(size=4000) * 100
      radii = np.random.random(size=4000) * 1.5
      colors = ["#%02x%02x%02x" % (int(r), int(g), 150) for r, g in zip(50+2*x, 30+2*y)]
      
      p = figure(tools="pan,wheel_zoom,zoom_in,zoom_out,reset")
      p.scatter(x, y, radius=np.random.random(size=4000) * 1.5,
                fill_color=colors, fill_alpha=0.6, line_color=None)
      
      div = Div(width=400, height=p.plot_height, height_policy="fixed")
      button = Button(label="Кнопка для отправки", button_type="success")
      layout = column(button, row(p, div))
      
      ## Events with no attributes
      button.js_on_event(events.ButtonClick, display_event(div)) # Button click
      p.js_on_event(events.LODStart, display_event(div))         # Start of LOD display
      p.js_on_event(events.LODEnd, display_event(div))           # End of LOD display
      
      ## Events with attributes
      point_attributes = ['x', 'y', 'sx', 'sy']                  # Point events
      wheel_attributes = point_attributes + ['delta']            # Mouse wheel event
      pan_attributes = point_attributes + ['delta_x', 'delta_y'] # Pan event
      pinch_attributes = point_attributes + ['scale']            # Pinch event
      
      point_events = [
          events.Tap, events.DoubleTap, events.Press, events.PressUp,
          events.MouseMove, events.MouseEnter, events.MouseLeave,
          events.PanStart, events.PanEnd, events.PinchStart, events.PinchEnd,
      ]
      
      for event in point_events:
          p.js_on_event(event, display_event(div, attributes=point_attributes))
      
      p.js_on_event(events.MouseWheel, display_event(div, attributes=wheel_attributes))
      p.js_on_event(events.Pan,        display_event(div, attributes=pan_attributes))
      p.js_on_event(events.Pinch,      display_event(div, attributes=pinch_attributes))
      
      output_file("js_events.html", title="Пример JS Events")
      show(layout)
      

      Live Demo: Посмотрим как изменяются координаты «мышки»

    10. Интерактивность — Подвигаем полозок и поменяем график:
       
      from bokeh.layouts import column
      from bokeh.models import CustomJS, ColumnDataSource, Slider
      from bokeh.plotting import Figure, output_file, show
      
      output_file("js_on_change.html")
      
      x = [x*0.005 for x in range(0, 200)]
      y = x
      
      source = ColumnDataSource(data=dict(x=x, y=y))
      
      plot = Figure(plot_width=400, plot_height=400)
      plot.line('x', 'y', source=source, line_width=3, line_alpha=0.6)
      
      callback = CustomJS(args=dict(source=source), code="""
          var data = source.data;
          var f = cb_obj.value
          var x = data['x']
          var y = data['y']
          for (var i = 0; i < x.length; i++) {
              y[i] = Math.pow(x[i], f)
          }
          source.change.emit();
      """)
      
      slider = Slider(start=0.1, end=4, value=1, step=.1, title="Двигаем этот полозок")
      slider.js_on_change('value', callback)
      
      layout = column(slider, plot)
      
      show(layout)
      

      Live Demo: Подвигаем полозок и поменяем график

    11. Интерактивность — Просто карта:
      from bokeh.plotting import figure, show, output_file
      from bokeh.tile_providers import get_provider, Vendors
      
      output_file("tile.html")
      
      tile_provider = get_provider(Vendors.CARTODBPOSITRON)
      
      # range bounds supplied in web mercator coordinates
      p = figure(x_range=(-2000000, 6000000), y_range=(-1000000, 7000000),
                 x_axis_type="mercator", y_axis_type="mercator")
      p.add_tile(tile_provider)
      
      show(p)
      

      Live Demo: Просто карта

    Для ленивых, но любопытных все коды лежат на Github, так что идите туда.

    Ещё одно заимствованное РЕПО с примерами для того, что бы ощутить вкус Bokeh.

    Наслаждайтесь и наращивайте свои компетенции в Python … Счастливого и удачного PY-тонинга!

    ]]>
    https://chel-center.ru/python-yfc/2019/12/21/vizualizacziya-dannyh-v-web-s-ispolzovaniem-python/feed/ 0