Архив рубрики: Python

Замена значений отметок по осям в matplotlib

Допустим, подписи к отметкам на горизонтальной оси у графика выглядят так:

А хочется заменить «4000» на «четыретыщи»:

Для этого перед сохранением файла и перед plt.show() пишем код:

from matplotlib.ticker import FuncFormatterdef my_formatter(x, pos): return str(‘%.0f’ % x).replace(‘4000′, u’четыретыщи’)ax.xaxis.set_major_formatter(FuncFormatter(my_formatter))

Вторая строка определяет функцию my_formatter(x, pos), зависящую от двух переменных: x — значение подписи к отметки, pos — позиция подписи (наверное).

Третья строка описывает, что должна выполнять данная функция, а именно она должна возвращать str(‘%.0f’ % x).replace(‘-‘, u’–’). В моём случае нужно взять ‘%.0f’ % x, т.е. целую часть (чтобы получить 3 цифры после запятой, смените 0 на 3. Однако будьте внимательны, надписи могут заезжать друг на друга, поэтому контролируйте количество цифр после запятой при построении графика). Чтобы можно было делать замену, нужно ещё обратить ‘%.0f’ % x в строку: str(‘%.0f’ % x). В скобках после replace идёт через запятую, что и на что нужно заменить. А заменить мы хотим минус (справа от нуля на клавиатуре) на, например, N-тире (про N-тире, M-тире и дефис см. тут). Можете просто скопировать отсюда: — (дефис), – (N-тире), — (M-тире). Обратите внимание на букву u перед ‘–’, она означает, что надо использовать юникод. Без неё не сработает вставка таких спецсимволов.

Четвёртая строка применяет нашу функцию к горизонтальной оси. Для воздействия на вертикальную ось замените xaxis на yaxis.

Также возможен вариант return str(‘%.0f’ % x).replace(‘-‘, ‘$-$’). То, что внутри долларов, будет обработано LaTeX’ом. Значит, можно там вставить ‘$endash$’, ‘$emdash$’ и т.д. Но тогда по plt.show() при наведении курсора на отрицательную координату будет показано, например, x=$endash$4000, хотя на сохранённом графике всё будет в порядке.

Возможно, чтобы Латех заработал, в начало программы придётся добавить строки:

import matplotlib as mplmpl.rcParams[‘text.usetex’]=Truempl.rcParams[‘text.latex.unicode’]=True
но у меня работает и без них.

Если что-то не заработало, пожалуйста, сообщите, попробуем разобраться.

Транслитерация содержимого файла с Python

У меня есть похожая запись о транслитерации имён файлов. Здесь же будет транслитерировано само содержимое файлов.

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

Транслитерация имён файлов с Python

У меня есть похожая запись о транслитерации содержимого файла. Здесь же будут транслитерированы только имена файлов.

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

Итак, перед нами стоит задача группового переименования файлов. Например, нужно поменять имена всех файлов в директории. Хотим избавиться от пробелов — заменить их на нижние подчёркивания. Все кириллические буквы хотим поменять на латинские (на «транслит»).

Вот скрипт, написанный на питоне, который совершает такое массовое переименование файлов. Надо создать файл renamer.py с приведённым ниже содержанием, положить его в папку с переименовываемыми файлами и выполнить:

user $python3 renamer.py -p

И в выводе программы будет показано, как будут переименованы файлы, но изменений не произойдёт. Если Вы окажетесь довольны результатами, сделайте на всякий случай резервную копию директории и выполните python3 renamer.py. За ключик -p спасибо комментарию от hombit’a.

Файл Русский Текст.TXT переименуется в russkiy_tekst.txt. Поведение скрипта благодаря его простоте очень легко подстроить под свои нужды, даже совсем не разбираясь в питоне. В строках с 13 по 82 в левом столбце в кавычках стоит то, что подлежит замене; в правом столбце — то, на что нужно заменять. Добавляйте свои замены и корректируйте существующие по своему усмотрению.

renamer.py

Скачать

#! /usr/bin/env python#coding=utf8import osfrom sys import argvdef latinizator(letter, dic): for i, j in dic.items(): letter = letter.replace(i, j) return letterlegend = {‘ ‘:’_’,’,’:»,’а’:’a’,’б’:’b’,’в’:’v’,’г’:’g’,’д’:’d’,’е’:’e’,’ё’:’yo’,’ж’:’zh’,’з’:’z’,’и’:’i’,’й’:’y’,’к’:’k’,’л’:’l’,’м’:’m’,’н’:’n’,’о’:’o’,’п’:’p’,’р’:’r’,’с’:’s’,’т’:’t’,’у’:’u’,’ф’:’f’,’х’:’h’,’ц’:’c’,’ч’:’ch’,’ш’:’sh’,’щ’:’shch’,’ъ’:’y’,’ы’:’y’,’ь’:»‘»,’э’:’e’,’ю’:’yu’,’я’:’ya’,’А’:’A’,’Б’:’B’,’В’:’V’,’Г’:’G’,’Д’:’D’,’Е’:’E’,’Ё’:’Yo’,’Ж’:’Zh’,’З’:’Z’,’И’:’I’,’Й’:’Y’,’К’:’K’,’Л’:’L’,’М’:’M’,’Н’:’N’,’О’:’O’,’П’:’P’,’Р’:’R’,’С’:’S’,’Т’:’T’,’У’:’U’,’Ф’:’F’,’Х’:’H’,’Ц’:’Ts’,’Ч’:’Ch’,’Ш’:’Sh’,’Щ’:’Shch’,’Ъ’:’Y’,’Ы’:’Y’,’Ь’:»‘»,’Э’:’E’,’Ю’:’Yu’,’Я’:’Ya’,}for file_old in os.listdir(‘.’): file_new = latinizator(file_old, legend)

#Раскомментируйте, чтобы сделать первую букву в имени файла Прописной

#file_new = file_new.capitalize() if ‘-p’ in argv: if file_old == file_new: print (‘{0: <30}’.format(file_old), ‘не будет переименован’ ) else: print (‘{0: <30}’.format(file_old), ‘будет переименован в ‘, file_new ) else: if file_old != file_new: print (‘{0: <30}’.format(file_old), ‘переименован в ‘, file_new ) os.rename(file_old, file_new)

P.S. Функцию для замены ключа словаря на его значение подсмотрел тут.

Копирование объектов в Python

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

Как же получить копию объекта в Python?

Ответ на этот вопрос, с короткими примерами на Python, читайте в блокноте, подготовленном с помощью jupyter-notebook и опубликованном на github, который умеет показывать такие блокноты.

Автор: Andrei Trofimov

PyPDF2: новый форк pyPdf (Перевод)

Сегодня узнал, проект pyPDF НЕ умер, как я думал раньше. На самом деле он перешёл в PyPDF2 (видите небольшую разницу в написании?). Есть так же вероятность того, что кто-то занимается и оригинальной версией проекта. При желании, за судьбой PyPDF2 можно следить на reddit. Тем временем я решил посмотреть, чем же PyPDF2 отличается от оригинала. Так что если у Вас есть пара свободных минут — милости просим.

Введение в PyPDF2

Два года назад я уже  писал про pyPDF, а совсем недавно мне как раз пришлось погрузиться в различные библиотеки для работы с PDF на Python, так что появление нового форка пришлось кстати. Мы возьмём несколько моих старых примеров, запустим их в PyPDF2 и посмотрим, как они сработают.
# Соединяем два PDF
from PyPDF2 import PdfFileReader, PdfFileWriter
 
output = PdfFileWriter
()
pdfOne = PdfFileReader
(open( "somepathtoaPDf", "rb"))
pdfTwo = PdfFileReader
(open("someotherpathtoaPDf", "rb"))
 
output.
addPage(pdfOne.getPage(0))
output.
addPage(pdfTwo.getPage(0))
 
outputStream =
open(r"output.pdf", "wb")
output.
write(outputStream)
outputStream.
close()
На моём Windows 7 это сработало без проблем. Как Вы можете предположить, всё, что этот код делает — создаёт два объекта PdfFileReader и прочитывает в каждом первую страницу. После этого, он добавляет эти две страницы в наш PdfFileWriter. И, наконец, мы открываем новый файл и записываем в него PDF. Вот и всё! Мы только что создали новый документ из двух разных PDF!
Теперь давайте попробуем скрипт для поворота страницы из другой моей страницы:
from PyPDF2 import PdfFileWriter, PdfFileReader
 
output = PdfFileWriter()
input1 = PdfFileReader(file("document1.pdf", "rb"))
output.addPage(input1.getPage(1).rotateClockwise(90))
# output.addPage(input1.getPage(2).rotateCounterClockwise(90))
 
outputStream = file("output.pdf", "wb")
output.write(outputStream)
outputStream.close()
Этот скрипт так же сработал на моей машине. Очень даже хорошо. Мой последний тест на соответствие должен проверить, можем ли мы вытаскивать данные так же, как мог оригинальный pyPdf. Давайте попробуем прочитать метаданные:
>>> from PyPDF2 import PdfFileReader
 
>>> p = r'C:UsersmdriscollDocumentsreportlab-userguide.pdf'
 
>>> pdf = PdfFileReader(open(p, 'rb'))
 
>>> pdf.documentInfo
 
{'/ModDate': u'D:20120629155504', '/CreationDate': u'D:20120629155504', '/Producer': u'GPL Ghostscript 8.15', '/Title': u'reportlab-userguide.pdf', '/Creator': u'Adobe Acrobat 10.1.3', '/Author': u'mdriscoll'}
>>> pdf.getNumPages()
 
120
>>> info = pdf.getDocumentInfo()
 
>>> info.author
 
u'mdriscoll'
>>> info.creator
 
u'Adobe Acrobat 10.1.3'
>>> info.producer
 
u'GPL Ghostscript 8.15'
>>> info.title
 
u'reportlab-userguide.pdf'
Тоже очень хорошо, кроме поля автора. Я определённо не автор этого документа и я не знаю, почему PyPDF2  решил, что я им являюсь. Всё остальное сработало верно. Теперь давайте посмотрим, что тут нового.

Что нового в PyPDF2

Одна из вещей, которую я сразу заметил как только взглянул на исходники PyPDF2, это то, что он добавляет несколько новых методов в PdfFileReader и PdfFileWriter. Кроме того, я заметил, что появился совершенно новый модуль merger.py, который содержит класс PdfFileMerger. Поскольку никакой нормальной документации нет — придётся лезть «под капот». Единственный новый метод, который был добавлен в reader — это getOutlines, который позволяет получить эскизы документа (outlines), если они есть. В writer появилась возможность добавить bookmarks и named destinations. Не так уж и много, но дарёному коню в зубы не смотрят. Но больше всего меня вдохновил новый класс PdfFileMerger, который мне напомнил почти погибший проект Stapler. PdfFileMerger позволяет нам объединить несколько PDF в один, используя соединение, вставку и вырезку и их комбинации.
Давайте попробуем?
import PyPDF2
 
path = open('path/to/hello.pdf', 'rb')
path2 = open('path/to/another.pdf', 'rb')
 
merger = PyPDF2.PdfFileMerger()
 
merger.merge(position=0, fileobj=path2)
merger.merge(position=2, fileobj=path)
merger.write(open("test_out.pdf", 'wb'))
Тут мы соединяем два файла вместе. В первый файл вместо третьей страницы будет добавлен второй файл, а как только содержание второго файла закончится будет продолжен первый файл. Это проще, чем проходиться по страницам двух документов и соединять их. Команда merge имеет следующую сигнатуру и строку документации, которая хорошо всё это описывает:
>>> merge(position, file, bookmark=None, pages=None, import_bookmarks=True)
 
Сливает страницы из исходного документа, определённого в
"file" в файл вывода на место, определённое в "position".
 
Опционально Вы можете определить закладку, которая будет установлена на начало этого файла. Для этого надо передать текст закладки в параметре
"bookmark".
 
Вы можете запретить импорт закладок из исходного документа если передадите значение False параметру
"import_bookmarks".
 
Вы можете так же использовать параметр "pages" для того, чтобы добавить только некоторые страницы исходного файла. Для этого надо задать их диапазон.
Есть так же метод append, который аналогичен команде merge, но вместо того, чтобы сливать файлы, он добавляет их в конец исходного файла. Вот скрипт для примера:
import PyPDF2
 
path = open('path/to/hello.pdf', 'rb')
path2 = open('path/to/another.pdf', 'rb')
 
merger = PyPDF2.PdfFileMerger()
 
merger.append(fileobj=path2)
merger.append(fileobj=path)
merger.write(open("test_out2.pdf", 'wb'))
И совсем не больно!

Подводим итоги

Мне кажется, это хорошая альтернатива для работы с PDF. Я могу комбинировать и разделять PDF при помощи PyPDF2 даже проще, чем с оригинальным pyPdf. Кроме того, я надеюсь, что PyPDF не умрёт, так как у него есть спонсоры, оплачивающие его разработку. Согласно потокам reddit есть даже шанс, что оригинальный pyPdf будет переработан и в конце концов оба эти проекта сольются в дружеском экстазе. Но, вне зависимости от того, чем всё закончится, я рад, что разработка его возобновилась и надеюсь, что она не скоро прекратится.

Домашнее чтение

Автор: Ishayahu Lastov

Присваивание в Python

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

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

Если в C одной переменной типа int присвоить значение другой переменной того же типа, то мы получим два одинаковых и независимых друг от друга значения, каждое из которых будет занимать свое место в памяти (то есть, лежать в своей отдельной коробке, на которой написано имя переменной). Не так в Python, где все значения являются объектами…

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

Продолжение истории, с короткими примерами на Python, читайте в блокноте, подготовленном с помощью jupyter-notebook и опубликованном на github, который умеет показывать такие блокноты.

Автор: Andrei Trofimov