Typo in word python что это
Автоматизированная сборка документа «Текст программы» по ЕСПД с помощью python-docx
Статья не имеет цели доказать важность и необходимость существования документа «Текст программы» и, тем более, необходимость его разработки в виде документа, которым кто-то когда-либо воспользуется. Цель статьи показать основы автоматизации обработки документов формата *.doc (*.docx) с использованием скриптов, написанных на языке Python.
Документ «Текст программы» (далее – Документ) входит в состав комплекта программных документов, перечень которых определен ГОСТ 19.101-77. ГОСТ, бесспорно, достаточно старый, однако его требования до сих пор востребованы при разработке программной продукции, соответственно требуется и разработка рассматриваемого Документа.
Содержание Документа определено ГОСТ 19.401-78 и должно включать в себя либо символическую запись на исходном языке, либо символическую запись на промежуточных языках, либо символическое представление машинных кодов (и т.п.).
Учитывая объемы современных веб приложений, разрабатываемых с использованием нескольких фреймворков, подготовить данный документ без использования автоматизации достаточно сложно.
Возможно два варианта создания документа:
разработчики собирают содержание всех файлов проекта в один текстовый файл и передают техническому писателю на обработку;
разработчики передают техническому писателю архив с файлами проекта, которые технический писатель должен обработать сам.
Первый вариант зависим от загруженности разработчиков. Чтобы сформировать текстовый файл с кодом программы, кто-то из команды разработчиков должен отвлечься, выгрузить код проекта из репозитория, написать программу, которая обработает выгруженный код и выдаст текстовый файл. Файл может быть размером как в пару мегабайт, так и в пару сотен мегабайт, его нужно вставить в Документ и как-то оформить. Вставка такого объема информации в файл Microsoft Word может занять как 30 минут, так и несколько часов. При этом, когда вставка будет завершена, Документ будет не структурирован и не читаем.
Второй вариант зависим от технических навыков исполнителя, но предпочтителен с точки зрения отсутствия необходимости привлечения людей, не имеющих отношения к разработке документации, вследствие чего будем автоматизировать именно этот вариант.
Автоматизация рассматриваемого Документа заключается в том, чтобы перенести текст кода программы в документ с заданным форматированием и структурой, чтобы в дальнейшем им можно было воспользоваться (маловероятный, но имеющий право на жизнь вариант использования).
Файл формата Microsoft Word (*.doc, *.docx) представляет собой набор данных в разметке xml. Файл имеет такие атрибуты, как параграф, рисунок, таблица, стиль. Для доступа к файлу и его атрибутам Microsoft в свое время была разработана технология OLE (Object Linking and Embedding). OLE позволяет передавать часть работы от одной программы редактирования к другой и возвращать результаты назад.
Библиотеки, осуществляющие взаимодействие с файлами офисного пакета Microsoft Office с использованием технологии OLE, есть практически для всех языков программирования. Для Python это библиотека python-docx. Описание библиотеки доступно по ссылке. Установить библиотеку можно командой:
Общий алгоритм разработки Документа представляет собой последовательность шагов:
Подготовка шаблона документа;
Подготовка скрипта сборки на Python;
Обновление содержания и числа страниц;
Шаг 1
Конечный Документ проще сформировать на основе заранее подготовленного шаблона (например файл с именем template.docx). Форматирование и атрибуты (наименование программы, разработчик, децимальный номер, аннотация, текст основной части) шаблона Документа должны соответствовать ГОСТ 19.104-78.
Кроме требований ГОСТ шаблон Документа должен удовлетворять следующим требованиям (последовательность шагов описана для Microsoft Word 2019):
иметь поле автоматического подсчета числа страниц в строке «Листов …»:
иметь предопределенные стили для заголовков уровня 1, 2, 3, а также для кода:
иметь поле автоматической сборки содержания:
заголовки уровня 1, 2, 3 должны переноситься в содержание (Ссылки→Оглавление→Настраиваемое оглавление→Параметры→Выбрать созданные стили и присвоить им уровень);
шаблон документа должен содержать фразу, на место которой будет вставлен код программы, выполненную в необходимом стиле, например « ».
Шаг 2
Папка с проектом содержит значительное число файлов, часть которых не являются кодом. К ним относятся графические файлы интерфейса программы, файлы фреймворков, а также файлы программ, используемых в процессе разработки и оставляющих после себя следы (GIT, SVN, Docker). Все эти файлы необходимо отфильтровать.
Функция, которая будет отфильтровывать только файлы, удовлетворяющие условию, выглядит следующим образом:
Чтобы получить список файлов, удовлетворяющих условиям фильтра, сначала необходимо получить список всех каталогов в директории проекта:
Из полученного списка каталогов читаем имена всех файлов во всех директориях проекта, и те, которые удовлетворяют условиям фильтра, складываем в отдельный список:
Перед обработкой полученного списка файлов необходимо подготовить функцию, которая будет считывать содержимое файла в одну строку с сохранением разметки переносов строк. Это необходимо для дальнейшего ускорения вставки кода в Word.
Используя функцию read_file, считываем содержимое отфильтрованных файлов, попутно вставляя строки-разделители каталогов и файлов. Это понадобится для автоматического формирования содержания.
Для переноса полученного кода программы подключаемся к документу, ищем контрольную фразу, заменяем ее на пустую строку и начинаем вставлять полученный код. Если код содержит слово «Каталог», форматируем его в стиле заголовка 2 уровня, если содержит слово «Файл» – в стиле заголовка 3 уровня, остальной текст форматируем в стиле кода программы:
По завершении сохраняем документ. Программная обработка документа завершена.
Шаг 3
После вставки текста программы в Документ необходимо открыть его в Microsoft Word, выделить все (Ctrl+A) и обновить автозаполняемые поля (F9). Данную операцию необходимо выполнить дважды, так как поля обновляются последовательно, и после формирования содержания итоговое число страниц изменится.
Данная операция занимает время, так как Word выполняет расчет страниц, последовательно обрабатывая документ до конца.
Шаг 4
После завершения обновления автозаполняемых полей необходимо сохранить Документ в формате *.pdf средствами Word. Это необходимо, чтобы зафиксировать форматирование и исключить дальнейшую работу с файлом в Word, так как Word будет выполнять пересчет числа страниц при каждом открытии файла или его изменении. С *.pdf такой проблемы не будет.
*.pdf имеет больший размер, но легко открывается любой подходящей программой. Ссылки в содержании после сохранения работают.
Полный код проекта доступен по ссылке.
Описанный вариант автоматизации не обрабатывает ошибки, связанные с разными кодировками файлов, и имеет варианты развития:
обработка ошибок, связанных с кодировкой файлов;
автоматическая выгрузка архива проекта;
программный запуск пересчета полей автозаполнения.
Введение в Python
В данной статье мы затронем основы Python. Мы все ближе и ближе к цели, в общем, скоро приступим к работе с основными библиотеками для Data Science и будем использовать TensorFlow (для написания и развертывания нейросетей, тобишь Deep Learning).
Установка
Python можно скачать с python.org. Однако если он еще не установлен, то вместо
него рекомендую дистрибутивный пакет Anaconda, который уже включает в себя большинство библиотек, необходимых для работы в области науки о данных.
Если вы не используете дистрибутив Anaconda, то не забудьте установить менеджер пакетов pip, позволяющий легко устанавливать сторонние пакеты, поскольку некоторые из них нам понадобятся. Стоит также установить намного более удобную для работы интерактивную оболочку IPython. Следует учитывать, что дистрибутив Anaconda идет вместе с pip и IPython.
Пробельные символы
Во многих языках программирования для разграничения блоков кода используются
фигурные скобки. В Python используются отступы:
Это делает код легко читаемым, но в то же время заставляет следить за форматированием. Пробел внутри круглых и квадратных скобок игнорируется, что облегчает написание многословных выражений:
и легко читаемого кода:
Для продолжения оператора на следующей строке используется обратная косая черта, впрочем, такая запись будет применяться редко:
В следствие форматирования кода пробельными символами возникают трудности при копировании и вставке кода в оболочку Python. Например, попытка скопировать следующий код:
в стандартную оболочку Python вызовет ошибку:
потому что для интерпретатора пустая строка свидетельствует об окончании блока кода с циклом for.
Оболочка IPython располагает «волшебной» функцией %paste, которая правильно вставляет все то, что находится в буфере обмена, включая пробельные символы.
Модули (Импортирование библиотек)
Некоторые библиотеки среды программирования на основе Python не загружаются по умолчанию. Для того чтобы эти инструменты можно было использовать, необходимо импортировать модули, которые их содержат.
Один из подходов заключается в том, чтобы просто импортировать сам модуль:
Здесь re — это название модуля, содержащего функции и константы для’ работы с регулярными выражениями. Импортировав таким способом весь модуль, можно обращаться к функциям, предваряя их префиксом re.
Если в коде переменная с именем re уже есть, то можно воспользоваться псевдонимом модуля:
Псевдоним используют также в тех случаях, когда импортируемый модуль имеет громоздкое имя или когда в коде происходит частое обращение к модулю.
Например, при визуализации данных на основе модуля matplotlib для него обычно
используют следующий стандартный псевдоним:
Если из модуля нужно получить несколько конкретных значений, то их можно импортировать в явном виде и использовать без ограничений:
Функции
Функция — это правило, принимающее ноль или несколько входящих аргументов и возвращающее соответствующий результат. В Python функции обычно определяются при помощи оператора def:
Функции в Python рассматриваются как объекты первого класса. Это означает, что их можно присваивать переменным и передавать в другие функции так же, как любые другие аргументы:
Кроме того, можно легко создавать короткие анонимные функции или лямбда выражения:
Лямбда-выражения можно присваивать переменным. Однако рекомендуют пользоваться оператором def:
Параметрам функции, помимо этого, можно передавать аргументы по умолчанию, которые следует указывать только тогда, когда ожидается значение, отличающееся от значения по умолчанию:
Иногда целесообразно указывать аргументы по имени:
В дальнейшем функции будут использоваться очень часто.
Строки
Символьные строки (или последовательности символов) с обеих сторон ограничиваются одинарными или двойными кавычками (они должны совпадать):
Обратная косая черта используется для кодирования специальных символов. Например:
Если требуется непосредственно сама обратная косая черта, которая встречается
в именах каталогов в операционной системе Windows, то при помощи r ‘»‘ можно создать неформатированную строку:
Многострочные блоки текста создаются при помощи тройных одинарных (или
двойных) кавычек:
Исключения
Когда что-то идет не так, Python вызывает исключение. Необработанные исключения приводят к непредвиденной остановке программы. Исключения обрабатываются при помощи операторов try и except:
Хотя во многих языках программирования использование исключений считается плохим стилем программирования, в Python нет ничего страшного, если он используется с целью сделать код чище, и мы будем иногда поступать именно так.
Списки
Наверное, наиважнейшей структурой данных в Python является список. Это просто упорядоченная совокупность (или коллекция), похожая на массив в других языках программирования, но с дополнительными функциональными возможностями.
Устанавливать значение и получать доступ к n-му элементу списка можно при помощи квадратных скобок:
Помимо этого, квадратные скобки применяются для «нарезки» списков:
В Python имеется оператор ln, который проверяет принадлежность элемента списку:
Проверка заключается в поочередном просмотре всех элементов, поэтому пользоваться им стоит только тогда, когда точно известно, что список небольшой или неважно, сколько времени уйдет на проверку.
Списки легко сцеплять друг с другом:
Если нужно оставить список х без изменений, то можно воспользоваться сложением списков:
Обычно к спискам добавляют по одному элементу за одну операцию:
Нередко бывает удобно распаковать список, если известно, сколько элементов в нем содержится:
Если с обеих сторон выражения число элементов не одинаково, то будет выдано сообщение об ошибке ValueError.
Для отбрасываемого значения обычно используется символ подчеркивания:
Кортежи
Кортежи — это неизменяемые (или иммутабельные) двоюродные братья списков.
Практически все, что можно делать со списком, не внося в него изменения, можно делать и с кортежем. Вместо квадратных скобок кортеж оформляют круглымискобками, или вообще обходятся без них:
Кортежи обеспечивают удобный способ для возвращения из функций нескольких значений:
Кортежи (и списки) также используются во множественном присваивании:
Словари
Словарь или ассоциативный список — это еще одна основная структура данных.
В нем значения связаны с ключами, что позволяет быстро извлекать значение, соответствующее конкретному ключу:
Доступ к значению по ключу можно получить при помощи квадратных скобок:
При попытке запросить значение, которое в словаре отсутствует, будет выдано сообщение об ошибке KeyError:
Проверить наличие ключа можно при помощи оператора in:
Словари имеют метод get(), который при поиске отсутствующего ключа вместо вызова исключения возвращает значение по умолчанию:
Присваивание значения по ключу выполняется при помощи тех же квадратных скобок:
Словари часто используются в качестве простого способа представить структурные
данные:
Помимо поиска отдельных ключей можно обратиться ко всем сразу:
Ключи должны быть неизменяемыми; в частности, в качестве ключей нельзя использовать списки. Если нужен составной ключ, то лучше воспользоваться кортежем или же найти способ, как преобразовать ключ в строку.
Словарь defaultdict
Пусть в документе необходимо подсчитать слова. Очевидным решением задачи является создание словаря, в котором ключи — это слова, а значения — частотности слов (или количества вхождений слов в текст). Во время проверки слов в случае, если текущее слово уже есть в словаре, то его частотность увеличивается, а если отсутствует, то оно добавляется в словарь:
Кроме этого, можно воспользоваться nриемом под названием «лучше просить прощения, чем разрешения» и перехватывать ошибку при попытке обратиться к отсутствующему ключу:
Третий прием — использовать метод get(), который изящно выходит из ситуации с отсутствующими ключами:
Все перечисленные приемы немного громоздкие, и по этой причине целесообразно использовать словарь defaultdict (который еще называют словарем со: значением по умолчанию). Он похож на обычный словарь за исключением одной особенности — при попытке обратиться к ключу, которого в нем нет, он сперва добавляет для него значение, используя функцию без аргументов, которая предоставляется при его создании. Чтобы воспользоваться словарями defaultdict, их необходимо импортировать из модуля collections:
Кроме того, использование словарей defaultdict имеет практическую пользу во время работы со списками, словарями и даже с пользовательскими функциями:
Эти возможности понадобятся, когда словари будут использоваться для «сбора»
результатов по некоторому ключу и когда необходимо избежать повторяющихся
проверок на присутствие ключа в словаре.
Словарь Counter
Подкласс словарей counter трансформирует последовательность значений в похожий на словарь defaultdict(int) объект, где ключам поставлены в соответствие частотности или, выражаясь более точно, ключи отображаются (map) в частотности.
Он в основном будет применяться при создании гистограмм:
Его функционал позволяет достаточно легко решить задачу подсчета частотностей слов:
Словарь counter располагает методом most_common( ), который нередко бывает полезен:
Множества
Структура данных set или множество представляет собой совокупность неупорядоченных элементов без повторов:
Множества будут использоваться по двум причинам. Во-первых, операция in на множествах очень быстрая. Если необходимо проверить большую совокупность элементов на принадлежность некоторой последовательности, то структура данных set подходит для этого лучше, чем список:
Вторая причина — получение уникальных элементов в наборе данных:
Множества будут применяться намного реже словарей и списков.
Управляющие конструкции
Как и в большинстве других языков программирования, действия можно выполнять по условию, применяя оператор if:
Кроме того, можно воспользоваться однострочным трехместным оператором if-then-else, который будет иногда использоваться в дальнейшем:
В Python имеется цикл whlle:
Однако чаще будет использоваться цикл for совместно с оператором in:
Если требуется более сложная логика управления циклом, то можно воспользоваться операторами
В результате будет напечатано 0, 1, 2 и 4.
Истинность
Булевы переменные в Python работают так же, как и в большинстве других языков программирования лишь с одним исключением — они пишутся с заглавной буквы:
Для обозначения несуществующего значения применяется специальный объект None, который соответствует значению null в других языках:
В Python может использоваться любое значение там, где ожидается логический тип Boolean. Все следующие элементы имеют логическое значение False:
Вот более простой способ сделать то же самое:
поскольку логический оператор and возвращает второе значение, в случае если первое истинное, и первое значение, в случае если оно ложное. Аналогичным образом, если х в следующем ниже выражении является либо числом, либо, возможно, None, то результат так или иначе будет числом:
Встроенная функция all языка Python берет список и возвращает True только тогда, когда каждый элемент списка истинен, а встроенная функция any возвращает тrue, когда истинен хотя бы один элемент:
Работаем с текстами на Python: кодировки, нормализация, чистка
Зачем эта статья?
Об обработке текстов на естественном языке сейчас знают все. Все хоть раз пробовали задавать вопрос Сири или Алисе, пользовались Grammarly (это не реклама), пробовали генераторы стихов, текстов. или просто вводили запрос в Google. Да, вот так просто. На самом деле Google понимает, что вы от него хотите, благодаря штукам, которые умеют обрабатывать и анализировать естественную речь в вашем запросе.
При анализе текста мы можем столкнуться с ситуациями, когда текст содержит специфические символы, которые необходимо проанализировать наравне с «простым текстом» (взять даже наши горячо любимые вставки на французском из «Война и мир») или формулы, например. В таком случае обработка текста может усложниться.
Вы можете заметить, что если ввести в поисковую строку запрос с символами с ударением (так называемый модифицирующий акут), к примеру «ó», поисковая система может показать результаты, содержащие слова из вашего запроса, символы с ударением уже выглядят как обычные символы.
Обратите внимание на следующий запрос:
Запрос содержит символ с модифицирующим акутом, однако во втором результате мы можем заметить, что выделено найденное слово из запроса, только вот оно не содержит вышеупомянутый символ, просто букву «о».
Конечно, уже есть много готовых инструментов, которые довольно неплохо справляются с обработкой текстов и могут делать разные крутые вещи, но я не об этом хочу вам поведать. Я не буду рассказывать про nltk, стемминг, лемматизацию и т.п. Я хочу опуститься на несколько ступенек ниже и обсудить некоторые тонкости кодировок, байтов, их обработки.
Откуда взялась статья?
Одним из важных составляющих в области ИИ является обработка текстов на естественном языке. В процессе изучения данной тематики я начал задавать себе вопросы, которые в конечном итоге привели меня к изучению кодировок, представлению текстов в памяти, как они преобразуются, приводятся к нормальной форме. Я плохо понимал эту тему в начале, потребовалось немало времени и мозгового ресурса, чтобы понять, принять и запомнить некоторые вещи. Написанием данной статьи я хочу облегчить жизнь людям, которые столкнутся с необходимостью чтения и обработки текстов на Python и самому закрепить изученное. А некоторыми полезными поинтами своего изучения я постараюсь поделиться в данной статье.
Важная ремарка: я не являюсь специалистом в области обработки текстов. Изложенный материал является результатом исключительно любительского изучения.
Проблема чтения файлов
Допустим, у нас есть файл с текстом. Нам нужно этот текст прочитать. Казалось бы, пиши себе такой вот скрипт для чтения из файла да и радуйся:
В файле содержится вот такое вот изречение:
что переводится с испанского как питон. Однако консоль OC Windows 10 покажет нам немного другой результат:
Сейчас мы разберёмся, что именно пошло не так и по какой причине.
Кодировка
Думаю, это не будет сюрпризом, если я скажу, что любой символ, который заносится в память компьютера, хранится в виде числа, а не в виде литерала. Это число определяется как идентификатор или кодовая позиция символа. Кодировка определяет, какое именно число будет ассоциировано с символом.
Предположим, у нас есть некоторый файл с неизвестным содержимым, и нам нужно его прочитать, однако мы не знаем, какая у файла кодировка. Попробуем декодировать содержимое файла.
Посмотрим на результат:
Важный поинт: при записи и чтении из файлов следует указывать конкретную кодировку, это позволит избежать путаницы в дальнейшем.
Ошибки, связанные с кодировками
При возникновении ошибки, связанной с кодировками, интерпретатор выдаст одно из следующих исключений:
Попытка выполнения вот такого кода (в файле всё ещё содержится испанский питон):
даст нам следующий результат:
Обозначение
Суть
Значение по умолчанию. Несоотвествующие кодировке символы возбуждают исключения UnicodeError и наследуемые от него.
Несоответсвующие символы пропускаются без возбуждения исключений.
Только для метода encode :
Несоответствующие символы заменяются на соответсвующие значения XML.
Несоответствующие символы заменяются на определённые последовательности с обратным слэшем.
Несоответствующие символы заменяются на имена этих символов, которые берутся из базы данных Unicode.
Приведём пример использования таких обработчиков:
Важный поинт: если в текстах могут встретиться неожиданные для кодировки символы, во избежание возбуждения исключений можно использовать обработчики.
Cворачивание регистра
И по классике приведём пример:
В результате применённый метод не только привёл весь текст к нижнему регистру, но и преобразовал специфический немецкий символ.
Нормализация
Чтобы обозначить важность нормализации, приведём простой пример:
Внешне два этих символа выглядят абсолютно одинаково. Однако если мы попытаемся вывести имена этих символов, как их видит интерпретатор Python’a, результат нас порядком удивит.
В Python есть отличный встроенный модуль, который содержит данные о символах Unicode, их имена, являются ли они цифрамии и т.п. (методы по типу str.isdigit() берут информацию из этих данных). Воспользуемся данным модулем, чтобы вывести имена символов, исходя из информации, которая содержится в базе данных Unicode.
Результат выполнения данного кода:
Итак, интерпретатор Python’a видит эти символы как два разных, но в стандарте Unicode они имеют одинаковое отображение.Такие символы называют каноническими эквивалентами. Приложения будут считать два этих символа одинаковыми, но не интерпретатор.
Посмотрим на ещё один пример:
Данные символы также будут являться каноническими эквивалентами. Из примера мы видим, что символ «é» в стандарте Unicodeможет быть представлен двумя способами, которые к тому же имеют разную длину. Символ «é» может быть представлен одним или двумя байтами.