This documentation is also available as .pdf- and .tex-file from the project page - see section 'Download'.
In order to use PEng in a Python script include the following
import PEng
doc = PEng.Doc(namespace=globals())
'doc' is the object that processes your equations. The dictionary
handed over to the parameter 'namespace' is the place where all
calculation variables live. In case you use 'globals()' these
variables are directly accessible from the surrounding Python code.
In order to have something calculated and output add
doc.calc("a=1")
doc.text("Hello World")
doc.texify()
save as 'FirstExample.py' and run the script. This results in these
additional files located in the directory of 'FirstExample.py':
- FirstExample.txt - a text representation of the calculation.
- FirstExample.tex - a TeX version of the results document
- FirstExample.pdf - the pdf-file containing the calculation which is
automatically loaded to a pdf-viewer in case you have installed one.
- FirstExample.aux, FirstExample.out, FirstExample.log - These are files generated by MikTex.
The log-file contains a report regarding the generation of the pdf-file and is useful for error tracking.
The file 'FirstExample.py' as well as others can be found in the
example directory of this distribution. Due to different unicode
encodings there are separate versions of the example files for Linux and
Windows.
When working with PEng two kinds of error may occur: Python and
LaTeX errors. If the Python script is incorrect nothing will be
generated. Instead an error message is shown in the window of the
command prompt. This message includes a PEng generated diagnosis as
well as a printout of the program stack. From the first line of that
printout you can detect the line-number of the command that caused
the error. In case that there is some error in the TeX -file MikTex
will refuse to generate the pdf-file. Should this happen you can
either resort to the messages generated by MikTex in the log-file or
load the offending TeX-file into a TeX-editor (e.g. WinEdt) and
use its error-detecting capabilities.
The name of the file to be processed is given to MikTex via a
command line argument. For this to work the filename must not
contain blanks - otherwise a warning is issued and nothing
happens.
When starting a script by double-clicking on it the
console-window with the error message will be closed before you get
a chance of reading anything. In order to prevent this run the
program from a command prompt or an integrated development
environment such as IPython.
Multiple lines, blanks and comments
The method 'calc()'
or shorter 'c()' of the doc-object is used to evaluate formulas and
include them in the final calculation document. The string handed
over to calc() may contain several lines:
doc.calc(ur"""
# This is a comment
a=1 # This is also a comment
b=2
c=3
""")
All text in a line following '#' is ignored. Empty lines or blanks
between the formulas or their components have no impact on the output.
The letters 'ur' preceding the multi-line Python string make it a
unicode raw string: This means that a '\' need not be
escaped like in normal Python strings and that unicode characters
(e.g. 'ü','ö' or 'ä' and so on) can be included. In case you want to
have non-ascii characters in your text be sure to add
# python
# -*- coding: mbcs -*- #
on Windows machines and
# python
# -*- coding: utf-8 -*- #
under Linux at the beginning of the file. This sets the kind of
encoding to be used so that your unicode characters are correctly processed.
Equation arrays
If one line has to accommodate more than
one expression these are separated by semicolons. Such a sequence
of expressions is evaluated from left to right:
doc.c(ur"""
a_1=1; a_2=10; a_3=100
b_1=2; b_2=20; b_3=200
c_1=3; c_2=30; c_3=300
""")
When executing the above you may notice from inspection of the
pdf-file that the formulas handed over to a calc-command are aligned
by their '='-signs and positioned in an array like structure like
this:
Naming conventions for variables
Variable names must
start with a letter and may contain any number of letters (only
ascii), digits, dots or underscores. Dots are used to select
variables that are properties of an object. PEng is case sensitive
with respect to variable names. Therefore 'A' and 'a'
designate different things. When transforming the calculation to
LaTeX the part of the variable names that follows the first
underscore is printed as an index. Any underscores following the
first one are printed as commas:
doc.c(ur"""
a_1_1 = a_1*b_1*c_1
""")
results in:
As you can see PEng by default not only outputs the final result of
a formula but also what the formula looks like with all variables
replaced by their values. This lets you familiarize with the numbers
you actually work with and helps you detect situations where you
have unknowingly redefined a variable somewhere along the way.
Physical units
Sometimes it is useful to have physical units attached to the
numbers: Firstly it spares you from making unit conversions and
secondly it helps to unveil errors in formulas that are due to
incompatible physical dimensions:
doc.c(ur"""
A=50[cm2];h=30[cm]
A*h
""")
comes out as
Physical properties are defined by writing the unit in squared
brackets immediately after the value - no blanks allowed in
between. Units of the form 'property**N' may be abbreviated with
'propertyN' (e.g. 'm**2' and 'm2' mean the same thing). For numbers
with units operations like multiplication, subtraction, and raising
to integer powers are allowed without restriction. In case you want
a quantity to be raised to a non-integer power you have to make sure
that the result can be represented by integer powers of the base
units. Angular functions like sin(), cos() or tan() expect
the type of their argument to be either '[deg]' or '[rad]'. If a
plain number is given as function argument '[deg]' is used by
default. For defining mirco-strains you can use a unit such as [mm/m].
Built-in operators and mathematical functions
This is the list of available functions and operators that can be
used within the calc-string:
- '+','-','*','**','^': basic mathematical operators.
Instead of '**' a '^' may be used to raise some value to
the power of some other value.
- sqrt(x), sqr(y): square root of x and square of y
- sin(x), cos(x), tan(x), 'cot(x)': angular functions
- asin(x), acos(x), atan(x), atan2(x,y), acot(x): inverse angular
functions. The function $atan2(x,y)$ is somewhat special. It returns the angle corresponding to
atan(x/y) taking into account the signs of both x and y
- abs(x): the absolute value of x
- exp(x): ex
- ln(x), log(x): natural logarithm of x
- log10(x): base 10 logarithm of x
- int(x): integer part of x
- min(x1, x2, ... , xn), max(x1, x2, ... , xn):
minimum and maximum of the values x1 to xn
Greek letters
PEng automatically converts the following
parts of variable names to their greek equivalent:
For example:
doc.c(ur"""
alpha_beta_gamma=1
""")
results in
Conditions
Often one has to ensure that the result of an
equation meets a certain condition. PEng provides the usual
comparison operators. The following lines
doc.c(ur"""
1==1; 1>0; 2>=1; 1<2; 1<=2; 1<>2
1==2; 1>2; 2>=3; 2<2; 3<=2; 1<>1
""")
give this output:
Search the results document for the phrase 'Error' to find any
violated conditions.
Adding text within equation arrays
Sometimes the name of a variable is not sufficient to clarify its
meaning. In such situations pictures (see further below) or
additional remarks are useful. These must be of the form "text" or
'text':
doc.c(ur"""
'text1'; a=1; "text2"
b=2;c=3;d=4
""")
he starting position of a text is aligned with the '='-signs of the
formulas. The above code results in
Format options for equations
Number format specifiers: The readability of the
calculation output improves by limiting the results precision to
some meaningful number of digits. This can be done for each
expression individually or by setting a default value for the whole
document. It is to be noted that the actual values used in the
calculation are in no way influenced by the number format.
The line below shows how the number format '.2f' ('.2f' means
that the number is to be printed in floating-point format with two
digits precision. For further information in formatting numbers see
the Python manual) is chosen for the results of two assignments. The
options to be applied follow at the end of each expression and are
inclosed in curly brackets:
doc.c(ur"""
a = 1.2345 {.2f}
b = 1.2 {.2f}
""")
comes out as
In the first case the result is truncated to '1.23' as expected. The
result of the second assignment is not changed though. This reflects
the rule that PEng only applies a number format if the resulting
number-string is shorter than the original one. This aims at
preventing the impression of excessive accuracy. Therefore 1.2 is
not transformed to '1.20'.
As mentioned above number formats can be set for the whole document:
doc.c(ur"""
{.2f}
{[cm],.2f};{[m],.1f}
""")
doc.c(ur"""
a = 1.2345
b = 1.2
c = 1.2345 [cm]
d = 1.2345 [m]
""")
results in
If no unit is supplied the format specifier is the default for all
values without units. As shown above a global default value format
can be defined for each unit as well.
Further formatting options for equations: Formatting options are situated at the end
of an expression being enclosed in curly brackets. If more than one
option is to be used these have to be separated from each other by
','. Besides controlling the output format of numbers PEng offers
these additional options:
Text can but need not be part of an equation array. For longer
passages of pure text use the method .text() of object doc.
Like .calc it accepts multi-line strings with or without the
preceding letters 'ur' which mark unicode raw strings:
doc.text(ur"""
This is text with unicode letters 'äöüß'
on \\ two
lines
""")
comes out as
Notice that carriage returns in the calculation file have no
impact in the results document. Use '\\' for this purpose when
generating LaTeX output. The command .text() may be
abbreviated as .t().
Any text may contain LaTeX-commands. In order to mark a text as
being a chapter heading write '\section{text}'. Go further down the chapter hierarchy by using
'\subsection{text}' or '\subsubsection{text}'. From these chapter headings a table of
contents can be generated automatically - see further below.
This makes the doc-object build txt, tex and pdf-files of the
calculation processed so far. These files are stored in the
same directory under the same name - yet different extension - as the Python-script from which they originate.
In addition to this - when runnning on a Windows machine - the pdf-file is loaded to a pdf-viewer if
such an application is available on your system.
Under Windows I have not worked out a satisfying solution to reloading a
pdf-file that is already displayed. Therefore close the
pdf-viewers window of a document before texifying it again.
Otherwise you will get an error message telling you that the pdf-file
could not be written to disc because of another application using the file at
the same time.
builds all output files just like texify() does. However MikTex
is not started and therefore no pdf-file generated. The command
flush() can be useful if you want to have a quick look at the
computation and the txt-file is sufficient for that.
The command list(n) Shows the last 'n' lines of the output on screen. If 'n' is
omitted all of the output will be shown.
Lets the user choose a picture and picture heading to be
included in the calculation. The following parameters should be
provided:
- path: path to the picture which may be given absolute
or relative. MikTex can handle the PDF, JPG, and PNG graphics formats.
- caption: caption of the figure. The example below shows how to define
a label for the picture by including the LaTeX-statement
'\label{foo}' in the caption text. This lets you
reference the figure from anywhere in the document
by using '\ref{foo}':
doc.picture(path = House.jpg',
caption = '\label{house} This is a house',
width = '10cm')
doc.text('Figure \ref{house} shows a house')
- angle: angle of rotation of the picture in [deg].
If omitted 'angle=0' is the default.
- width: width of the picture (if an angle is given the
picture is first rotated then scaled for width). Can
be of the form "width=10cm" or "width =
r'1.00 /textwidth'". The latter makes the picture
stretch across the whole text area. See a LaTeX
manual for further possibilities of defining a
pictures width.
- additional parameters: Besides the
parameters mentioned above the LaTeX statement
'includegraphics' accepts others as well. In the
example below
doc.picture(path='Example.pdf',
caption = ur'\label{Example 1} Caption of example 1',
width = r'1.00 \textwidth', page = '2')
the parameter 'page' is set to a value of two. This
extracts the second page of the pdf-file 'Example.pdf'
and places it as a picture in the results document.
It is sometimes a good idea to present a set of values in a table.
PEng provides the command table() for these occations. The following
example shows how this can be done in PEng. The code
doc.table(tablecaption = ur'caption',
tablehead = ur'col1 & col2 & col3 \\ \hhline{===}',
tabletail = ur'\hline \multicolumn{3}{r}{next page...} \\',
tablelasttail = ur'\hline',
lineappend = ur'\hline',
columnformat = ur'c|c|c',
cols = [[1,4], [2,5], [3,6]])
results in this output:
The parameters of the table-command have the following meaning:
- tablecaption: text written above the table. The LaTeX-command '\label{foo}' can be included
so that the table can be referenced from somewhere in the document by writing '\ref{foo}'.
- tablehead: specifies the text written above each column.
The column headings are separated by '&'. In the above example the part '\\ \hhline{===}' results in two
horizontal lines below each of the three column headings
- tabletail: in case of tables that stretch over more than one page this text
is written before each pagebreak
- tablelasttail: gets appended at the end of the table
- lineappend: is added at the end of each line of the table. In the above example
'\hline' results in horizontal lines between the table entries
- columnformat: determines the horizontal
justification of the entries in each of the table columns.
Valid descriptors are 'c' for centered, 'r' for right
aligned and 'l' for left aligned. In order to have vertical
lines between columns include the sign '|'.
In case of columns with numbers readability improves by
aligning these values by their fraction point. In LaTeX
(by means of the dcolumn package) this can be done by writing
'D..{n}' as the format information for a column. 'n' is the
maximum number of decimal places after the fraction point the column has to accommodate.
Numbers with more than n fractional digits will overwrite
neighboring cells. Using a negative number for n sets the
column width according to the maximum width of the column
entries. The code segment
doc.c("""a=sqrt(2){.3f}
b=sqrt(3){.3f}""")
doc.table(tablecaption = ur'caption',
tablehead = ur'\multicolumn{1}{c}{col1} \\ \hhline{=}',
tabletail = ur'\hline \multicolumn{1}{r}{next page...} \\',
tablelasttail = ur'\hline',
lineappend = ur'\hline',
columnformat = ur'|D..{3}|',
cols = [[a.number_str, b.number_str]])
thus results in
In the above example the command '\multicolumn{...}' makes the column heading centered.
When building the data for the table the property .number_str
of the calculation variables was used to get a correctly formatted string
representation of 'a' and 'b'.
- cols: Is a list of the columns of the table.
- lines: Instead of a list of columns the table data may be provided as a list of table
lines.
PEng generates tables in LaTeX by use of the supertabular
environment. For further details on this see the LaTeX
documentation.
Every LaTeX file consists of two parts: first the initial
settings that name the packages and parameters to be used for the
whole document. After this comes the text body. By default PEng uses
the file "Default_Latexheader_Windows.tex" or
"Default_Latexheader_Linux.tex" - depending on the operating
system your are working on - in the directory .
There are two different headers for Linux and Windows because of the
different standard encoding used for unicode characters ("utf-8" in
Linux, "newansi" in Windows).
In case you want to define your own LaTeX -header provide a file
named "LatexHeader.tex" in the directory of the PEng document to be
associated to it. In this way it is possible to influence the
documents layout. The "LatexHeader.tex"-file listed below will
result in project information being printed at the top of each page
of the calculation document.
\documentclass[fleqn]{article}
\usepackage{amssymb}
\usepackage{amsfonts}
\usepackage{amsmath}
\usepackage[ansinew]{inputenc} % now you can include 'äöüß' directly in the text
\usepackage{ae,aecompl}
\usepackage[a4paper, DIVclassic]{typearea}
\usepackage[pdftex]{graphicx}
\usepackage[ngerman]{babel}
\usepackage{fancyhdr}
\usepackage{color}
\definecolor{darkblue}{rgb}{0,0,.5}
\usepackage{hyperref}
\hypersetup{pdftex=true, colorlinks=true, breaklinks=true,
linkcolor=darkblue, menucolor=darkblue, pagecolor=darkblue,
urlcolor=darkblue}
\setlength\mathindent{1pc} %identationlength for formulas
% ---
% here comes the project information:
% ---
\pagestyle{fancy} \setlength\headheight{25pt} \lhead{Projekt: foo\\
No: 00000 } \chead{foo - bar - baz \\
Civil Engineering Company
} \rhead{engineer/phone \\
Someone/00 } \lfoot{ {\tiny \today} }
\renewcommand\headrule{\vspace{-8pt}\dotfill}
Do not let yourself get confused by the above. Instead see the
example in the directory 'Example3' for further help. It shows how
to introduce a chapter structure in documents and generate a table
of contents from it. References, labels, bibliography and citations
are also included. The tex-version of the file you are currently
reading can be found in
the directory 'Documentation'.
One thing you should be aware of is that there are some special
characters in LaTeX one has to escape when using them in text:
these are '&', '%', '#', '_', '$', '{' and '}'. Prefix them
with '\'. The sign '\' has to be expressed by '\textbackslash' followed by a blank.
LaTeX introduces linebreakes by using an internal algorithm. In
case you want to force a linebreak write '\\'. A new paragraph can be started by leaving one line
empty. The first word of the new paragraph will then be somewhat
shifted to the right.
Keywords that make LaTeX do something start with
'\' and have their arguments enclosed in curly brackets. For example:
doc.t(ur"""\textbf{This is boldface text}""")
results in
For further information on LaTeX resort to one of the many
textbooks available or search the internet.
As mentioned in section 'Getting Started' the calculation
variables live in the dictionary provided by the user when
generating the PEng-document. Therefore writing
doc = PEng.Doc(namespace=globals())
makes the variables reside in the global namespace. These variables
are objects of type PEngNum. Besides their value they contain
additional information about the entity like name or format
specifications. As the class PEngNum defines routines for most of
the special methods (see the Python documentation for details) its
objects can be used in the same way as integer or float variables.
Mixing is also possible. See the file 'PEngNum.py' for details
The following is a short explanation of the main structure of PEng.
I made use of the design patterns Parser, Builder and Composite (see Design Patterns)
The main object in PEng is
PEngDoc: It stores references to the parser, the builders, calculation source file and variable namespace.
On initialization PEngDoc creates the parser object of type
PEngParser and configures it with builders. These builders provide
the functionality that PEngParser uses to generate output in
different formats: PEngBuilderNum for calculating results,
PEngBuilderPlainText for text, PEngBuilderLatex for tex-files,
PEngBuilderScreenOutput for text with color-escape sequences. In
order to make it easy to add new builders all building functionality
is provided to PEngParser via the composite builder class
PEngBuilderComposite.
You can download PEng from the sourceforge project page
at http://sourceforge.net/projects/peng/.
The current (23 Aug 2008) version is 0.165a.
If you find any bugs, please send them to cpreisinger at users.sourceforge.net.
In case you have a good idea about how to improve the usability of
PEng or the readability of this documentation please do not hesitate to give me notice.
clemens