Как стать автором
Обновить

Python в Latex

Время на прочтение 3 мин
Количество просмотров 17K
Использовать Python в LaTeX было бы очень удобно. Сразу предупреждаю, что предложенные методы считаются небезопасными, потому-что Python умеет гадить, если написать соответствующий код, так что проверяйте его (=

Существует готовый метод в виде файла стилей, используется так:
\usepackage{python}
\begin{python}
from math import sin
a = sin(5)
c = sin(9)
b =  max(a,c)
print b
\end{python}


Этот пакет, фактически, создает jobname.py, пишет вывод в jobname.py.out, jobname.py.err, и читает его.
Метод плох тем, что переменные не сохраняются от кода к коду, и для этого приходится использовать pickle, приходиться каждый раз заново всё import`ить и т.п., а еще мне кажется, что удобно иметь все расчеты в одном месте в отдельном файле, поэтому я построил свой лунапарк…

Всё очень просто. Добавляем в преамбулу следующее:
\newcommand{\python}[1]{%
\immediate\write18{python #1 > ./py.out 2> ./py.err}
\immediate\input"py.out"}

\newcommand{\ptn}[1]{%
\python{./path_to_your_scripts/script_name.py #1}}

\newcommand{\peval}[1]{%
\python{-c "print #1" |./path_to_your_scripts/sedder}}

\newcommand{\comments}[1]{}


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

В скрипте у меня есть маленькое ухищрение для красивого вывода(правда исключительно для математического окружения), ну и седом тоже могу поделиться(естественно sed будет работать только если он у вас есть).

sedder:


#!/bin/sh
sed -e 's/\./,/'
#Сделайте его исполняемым.


конец файла "./path_to_your_scripts/script_name.py":


import sys
from re import sub
from __future__ import division

def toStr(num,digitsAfter=2):
    """Num to string with zero stripping"""
    frmt = '%.' + str(digitsAfter) + 'f'
    num = (frmt%num)
    num = num.strip('0')
    if num[0] =='.':
        num = '0'+num
    if num[-1] == '.':
        num = num.strip('.')
    return num

def tenpower(num,maximum=1e3,minimum=1e-2,base=1):
    """converts num to (num1,num2) where num1*10**num2=num
converts when not minimum<num<maximum.
converts until base<num1<2*base"""
    pwr = 0

    while abs(num) > maximum or (abs(num)>2*base and pwr>0):
        pwr +=1
        num = num / 10
    while abs(num) < minimum or (abs(num)<base and pwr<0):
        pwr -=1
        num = num * 10
    return num,pwr

def latexize(num,power=False,delim=','):
    if power:
        return ('%s \\cdot 10^{%d}' %(num,power)).replace('.',delim)
    else:
        return str(num).replace('.',delim)

if __name__ == "__main__":
#try:
    argc = len(sys.argv)
    var = 'Ooopsy-doopsy!'
    digitsAfter = 2
    typ = 10
    if argc >1:
        var = sub('[{}\. ]','',sys.argv[1])
        comment = '\\comments{%s}'%sys.argv[1]
        var = globals()[var]
    else:
        raise ValueError
    if argc >2:
        try:
            digitsAfter = int(sys.argv[2])
        except:
            typ = sys.argv[2]
    if argc >3:
        typ = sys.argv[2]
        digitsAfter = int(sys.argv[3])

    mini=1/10**digitsAfter

    if typ in ('int','i'):
        print comment,int(var)
    elif typ in ['float','f','nomath']:
        print comment+latexize(toStr(var,digitsAfter))
    else:
        strings = tenpower(var,minimum=mini)
        print comment+latexize(toStr(strings[0],digitsAfter),strings[1])

#except Exception:
#    pass


Тоесть набрав в LaTeX "\ptn{varAn1}", в конечный документ подставиться значение переменной «varAn1», если она определена в "./path_to_your_scripts/script_name.py". А написав "\peval{1./5}" получим 0,2. Хотя вот этот \peval я не пользовал, так что не допиливал и работает он паршиво

P.S. Обрабатывать такой файл LaTeX нужно с опцией "-shell-escape"
Теги:
Хабы:
+18
Комментарии 5
Комментарии Комментарии 5

Публикации

Истории

Ближайшие события

Московский туристический хакатон
Дата 23 марта – 7 апреля
Место
Москва Онлайн
Геймтон «DatsEdenSpace» от DatsTeam
Дата 5 – 6 апреля
Время 17:00 – 20:00
Место
Онлайн