Python в Latex
Использовать 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 с заданными вами аргументами, второй запускает конкртеный скрипт с аргументами, ну а третий может выполнять однострочный код Пайтона, который потом преаброзовывается маленьким 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
P.S. Обрабатывать такой файл LaTeX нужно с опцией "-shell-escape"