python as pen and paper substitute

M

Manuel Graune

Hello everyone,

I am looking for ways to use a python file as a substitute for simple
pen and paper calculations. At the moment I mainly use a combination
of triple-quoted strings, exec and print (Yes, I know it's not exactly
elegant). To clarify, I just start an editor, write a file that
might look something like this:

---------snip-----
code="""
a = 1
b = 2
c = 3
result = a + b
"""
exec(code)
print(code)
print("result =\t", result)
print("result + c =\t", result + c)
---------snip------

and feed this to python.

For what it's worth, this approach achieves what it's supposed to,
which is to get some basic control over the output and
to avoid to much redundant typing.

Now I'm wondering if there is a more elegant method to achieve this which
e. g. does not mess up the syntax-hightlighting, does not use exec()
and avoids the redundant mentioning of the variable that holds the
acutal code. Since I have complete control over the input and the files
are not supposed to be shared, security should not a problem and
simplicity is criterion #1.


So, does anyone have tips?

Regards,

Manuel

P.S.: I know Ipython. In the cases where I use the hack shown above
it just does not fit my workflow
 
J

Johan Grönqvist

Manuel Graune skrev:
To clarify, I just start an editor, write a file that
might look something like this:

---------snip-----
code="""
a = 1
b = 2
c = 3
result = a + b
"""
exec(code)
print(code)
print("result =\t", result)
print("result + c =\t", result + c)
---------snip------

and feed this to python.

I do not understand your use-case, but as one way of performing the same
task as the above code, without sacrificing syntax-highlighting, I would
suggest:

-------------------------
from __future__ import with_statement
import sys

def print_source():
print sys.argv
with open(sys.argv[0]) as file:
for line in file:
print line,

a = 1
b = 2
c = 3
result = a + b

print_source()
print("result =\t", result)
print("result + c =\t", result + c)

------------------------


Does that help towards a solution of your problem?

/ johan
 
M

Manuel Graune

Thanks for your reply.

Johan Grönqvist said:
Manuel Graune skrev:

I do not understand your use-case, but as one way of performing the
same task as the above code, without sacrificing syntax-highlighting,

The use-case is acually fairly simple. The point is to use a python
source-file as subsitute for scrap-paper (with the opportunity to
edit what is already written and without illegible handwriting).
The output should 1) show manually selected python code and comments
(whatever I think is important), 2) show selected results (final and
intermediate) and 3) *not* show python code that for someone only
interested in the calculation and the results (and probably not
knowing python) would just be "noise" (e. g. "import"-statements,
actual "print()"-functions, etc.).
from __future__ import with_statement
import sys

def print_source():
print sys.argv
with open(sys.argv[0]) as file:
for line in file:
print line,

[...]

print_source()
print("result =\t", result)
print("result + c =\t", result + c)


As far as I understand this code, all of this would be printed as well,
which is exactly what I do not want.

Regards,

Manuel
 
M

Manuel Graune

Manuel Graune said:
The use-case is acually fairly simple. The point is to use a python
source-file as subsitute for scrap-paper (with the opportunity to
edit what is already written and without illegible handwriting).
The output should 1) show manually selected python code and comments
(whatever I think is important), 2) show selected results (final and
intermediate) and 3) *not* show python code that for someone only
interested in the calculation and the results (and probably not
knowing python) would just be "noise" (e. g. "import"-statements,
actual "print()"-functions, etc.).

Just as an additional example, let's assume I'd want to add the area of
to circles.

The source-file would look something like this:
------>snip source.py snip<------
#! /usr/bin/python3
from math import pi as PI

code1="""
d1= 3.0
A1= d1**2 * PI / 4.0
"""
exec(code1)
print(code1)
print("Area of Circle 1:\t", A1)

code2="""
d2= 5.0
A2= d1**2 * PI / 4.0
"""
exec(code2)
print(code2)
print("Area of Circle 2:\t", A2)

code3="""
Sum_Of_Areas= A1 + A2
"""
exec(code3)
print(code3)
print("Sum of areas:\t", Sum_Of_Areas)
------->snip<------------------

And the output is:

d1= 3.0
A1= d1**2 * PI / 4.0

Area of Circle 1: 7.06858347058

d2= 5.0
A2= d1**2 * PI / 4.0

Area of Circle 2: 7.06858347058

Sum_Of_Areas= A1 + A2

Sum of areas: 14.1371669412

which can be explained to anyone who knows
basic math and is not at all interested in
python.
 
M

Manuel Graune

Manuel Graune said:
The use-case is acually fairly simple. The point is to use a python
source-file as subsitute for scrap-paper (with the opportunity to
edit what is already written and without illegible handwriting).
The output should 1) show manually selected python code and comments
(whatever I think is important), 2) show selected results (final and
intermediate) and 3) *not* show python code that for someone only
interested in the calculation and the results (and probably not
knowing python) would just be "noise" (e. g. "import"-statements,
actual "print()"-functions, etc.).

Just as an additional example, let's assume I'd want to add the area of
to circles.

The source-file would look something like this:
------>snip source.py snip<------
#! /usr/bin/python3
from math import pi as PI

code1="""
d1= 3.0
A1= d1**2 * PI / 4.0
"""
exec(code1)
print(code1)
print("Area of Circle 1:\t", A1)

code2="""
d2= 5.0
A2= d2**2 * PI / 4.0
"""
exec(code2)
print(code2)
print("Area of Circle 2:\t", A2)

Sum_Of_Areas= A1 + A2
print("Sum of areas:\t", Sum_Of_Areas)
------->snip<------------------

And the output is:

d1= 3.0
A1= d1**2 * PI / 4.0

Area of Circle 1: 7.06858347058

d2= 5.0
A2= d1**2 * PI / 4.0

Area of Circle 2: 19.6349540849

Sum of areas: 26.7035375555

which can be explained to anyone who knows
basic math and is not at all interested in
python.
 
J

Johan Grönqvist

Manuel Graune skrev:
Thanks for your reply.


The output should 1) show manually selected python code and comments
(whatever I think is important), 2) show selected results (final and
intermediate) and 3) *not* show python code that for someone only
interested in the calculation and the results (and probably not
knowing python) would just be "noise" (e. g. "import"-statements,
actual "print()"-functions, etc.).

Here is my second attempt. This version introduces what I might
optimistically call a very simple markup language in the code.
Printing of source can selectively be turned on and off by inserting
lines beginning with "## Ignore" or "## Show" into the source file.


------------------------------
## Ignore
from __future__ import with_statement
import sys

def print_selected_source():
is_printing = True
with open(sys.argv[0]) as file:
for line in file:
if line.startswith("## Ignore"):
is_printing = False
elif line.startswith("## Show"):
is_printing = True
elif is_printing:
print line,


## Show
a = 1
b = 2
c = 3
result = a + b

## Ignore
print_selected_source()
print("result =\t", result)
print("result + c =\t", result + c)
 
J

Johan Grönqvist

Manuel Graune skrev:
Just as an additional example, let's assume I'd want to add the area of
to circles.
[...]
which can be explained to anyone who knows
basic math and is not at all interested in
python.

Third attempt. The markup now includes tagging of different parts of the
code, and printing parts of the source based on a tag.

(Sorry about the mixture of python 2.X and python 3.X print statements,
I use 2.5)

-------------------------
## Ignore
from __future__ import with_statement
import sys

def print_selected_source(tag = ""):
is_printing = True
with open(sys.argv[0]) as file:
for line in file:
if line.startswith("## Ignore"):
is_printing = False
elif line.startswith("## Show") and tag in line:
is_printing = True
elif is_printing:
print line,



from math import pi as PI

## Show Code1
d1= 3.0
A1= d1**2 * PI / 4.0

## Ignore
print_selected_source(tag = "Code1")
print ("Area of Circle 1:\t", A1)

## Show Code2
d2= 5.0
A2= d2**2 * PI / 4.0


## Ignore
print_selected_source(tag = "Code2")
print ("Area of Circle 2:\t", A2)

Sum_Of_Areas= A1 + A2
print ("Sum of areas:\t", Sum_Of_Areas)
 
D

Dave Angel

Johan said:
Manuel Graune skrev:
Thanks for your reply.


The output should 1) show manually selected python code and comments
(whatever I think is important), 2) show selected results (final and
intermediate) and 3) *not* show python code that for someone only
interested in the calculation and the results (and probably not
knowing python) would just be "noise" (e. g. "import"-statements,
actual "print()"-functions, etc.).

Here is my second attempt. This version introduces what I might
optimistically call a very simple markup language in the code.
Printing of source can selectively be turned on and off by inserting
lines beginning with "## Ignore" or "## Show" into the source file.


------------------------------
## Ignore
from __future__ import with_statement
import sys

def print_selected_source():
is_printing = True
with open(sys.argv[0]) as file:
for line in file:
if line.startswith("## Ignore"):
is_printing = False
elif line.startswith("## Show"):
is_printing = True
elif is_printing:
print line,


## Show
a = 1
b = 2
c = 3
result = a + b

## Ignore
print_selected_source()
print("result =\t", result)
print("result + c =\t", result + c)
------------------------------

Is this getting closer?

/ johan
How about simply importing the file with the calculations? Printing the
imported file is quite straightforward, and except for maybe skipping
the import lines that may be at the top (eg. import math), the rest of
the file could be meaningful for the end user.


That has the advantage that it's easy to have multiple "notepads", but
only one set of code that runs them.

DaveA
 
J

James Stroud

Manuel said:
Hello everyone,

I am looking for ways to use a python file as a substitute for simple
pen and paper calculations. At the moment I mainly use a combination
of triple-quoted strings, exec and print (Yes, I know it's not exactly
elegant). To clarify, I just start an editor, write a file that
might look something like this:

I wrote a module called pylave, which is meant to be a
parser-evaluator-solver for scratch paper-like calculations. It has
strict operator precedence, knows a variety of common operations, and
respects parenthetic grouping. It is designed to evaluate ini files,
which can have syntax highlighting depending on your text editor.
Pyparsing is required.


Here is a pylave example:


% cat test.ini
factor = 2
wwww = minor_axis / 2
www = 69.69 + wwww
height = 10
apex = epicenter // height
major_axis = epicenter + 2*radius / sin big
minor_axis = epicenter + (total / 14) % (length-1)
epicenter = 44
radius = ((14 + length)/2 + height)*breadth
length = width + 5
width = 2**2 - factor
total = big*(radius + 14)
big = abs (sin (5e+8))
breadth = 2*length + height
overlap = abs (1 + 1)
nexus = sin (5e-8)
plexus = sin (5e8)


% ./pylave.py test.ini
breadth : 24
www : 93.8350093235
nexus : 5e-08
big : 0.284704073238
major_axis : 3547.35712408
height : 10
radius : 492.0
plexus : -0.284704073238
total : 144.060261058
epicenter : 44
apex : 4
overlap : 2
wwww : 24.1450093235
width : 2
length : 7
factor : 2
minor_axis : 48.290018647


It is not perfect but if it will help, I'll cheeseshop it.

James
 
E

Ethan Furman

How about a decorator that turns your function into an object with the
results? Your code would then look like this:

8<----------------------------------------------
#! /usr/bin/python3
from sp import ScratchPad
from math import pi as PI

@ScratchPad
def code1():
d1= 3.0
A1= d1**2 * PI / 4.0

print("Area of Circle 1:\t", code1.A1)

@ScratchPad
def code2():
d2= 5.0
A2= d2**2 * PI / 4.0

print("Area of Circle 2:\t", code2.A2)

Sum_Of_Areas= code1.A1 + code2.A2
print("Sum of areas:\t", Sum_Of_Areas)

8<----------------------------------------------

and the printout like so:

Python 3.1 (r31:73574, Jun 26 2009, 20:21:35) [MSC v.1500 32 bit
(Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
d1= 3.0
A1= d1**2 * PI / 4.0

Area of Circle 1: 7.06858347058

d2= 5.0
A2= d2**2 * PI / 4.0

Area of Circle 2: 19.6349540849
Sum of areas: 26.7035375555

Here's the code for the decorator:

8<--------------------------------------------------------------
import inspect

class PropertyObj():
"""lookup using . notation"""

def ScratchPad(func):
source = inspect.getsourcelines(func)[0][2:]
lead_space = 0
for char in source[0]:
if char == ' ':
lead_space += 1
else:
break
source = ''.join([line[lead_space:] for line in source])
print('\n' + source)
intermed_result = {}
final_result = PropertyObj()
exec(source, func.__globals__, intermed_result)
for key, value in intermed_result.items():
setattr(final_result, key, value)
return final_result
8<--------------------------------------------------------------

Hope this helps!

~Ethan~
 
M

Manuel Graune

Hello Johan,

thanks to you (and everyone else who answered) for your effort.

Johan Grönqvist said:
Manuel Graune skrev:
Just as an additional example, let's assume I'd want to add the area of
to circles.
[...]
which can be explained to anyone who knows
basic math and is not at all interested in
python.

Third attempt. The markup now includes tagging of different parts of
the code, and printing parts of the source based on a tag.

after playing around for a while, this is what I finally ended up with:

8<--------8<-------- source ---8<--------
#! /usr/bin/python
## Show
# List of all imports:
from __future__ import with_statement, print_function
from math import pi as PI
import sys
##

class Source_Printer(object):
def __init__(self):
self.is_printing= False
with open(sys.argv[0]) as file:
self.lines=(line for line in file.readlines())
for line in self.lines:
if line.startswith("print_source"):
break
elif line == "##\n":
self.is_printing= False
elif line.startswith("## Show"):
print("\n")
self.is_printing= True
elif self.is_printing:
print(line,end="")
def __call__(self):
for line in self.lines:
if line == "##\n" or line.startswith("print_source"):
if self.is_printing:
self.is_printing= False
break
else:
self.is_printing= False
elif line.startswith("## Show"):
print("\n")
self.is_printing= True
elif self.is_printing:
print(line, end="")


print_source= Source_Printer()
## Show
#Calculation of first Area:
d1= 3.0
A1= d1**2 * PI / 4.0
##
print_source()

print ("Area of Circle 1:\t", A1)

## Show
#Calculation of second area:
d2= 5.0
A2= d2**2 * PI / 4.0
##
# This is a comment that won't be printed

print_source()
print ("Area of Circle 2:\t", A2)

# This is another one
Sum_Of_Areas= A1 + A2
print ("Sum of areas:\t", Sum_Of_Areas)

8<--------8<-------- result: ---8<--------

# List of all imports:
from __future__ import with_statement, print_function
from math import pi as PI
import sys


#Calculation of first Area:
d1= 3.0
A1= d1**2 * PI / 4.0
Area of Circle 1: 7.06858347058


#Calculation of second area:
d2= 5.0
A2= d2**2 * PI / 4.0
Area of Circle 2: 19.6349540849
Sum of areas: 26.7035375555

8<--------8<-------- result: ---8<--------

Regards,

Manuel
 
M

Manuel Graune

Hello Johan,

thanks to you (and everyone else who answered) for your effort.

Johan Grönqvist said:
Manuel Graune skrev:
Just as an additional example, let's assume I'd want to add the area of
to circles.
[...]
which can be explained to anyone who knows
basic math and is not at all interested in
python.

Third attempt. The markup now includes tagging of different parts of
the code, and printing parts of the source based on a tag.

after playing around for a while, this is what I finally ended up with:

8<--------8<-------- source ---8<--------
#! /usr/bin/python
## Show
# List of all imports:
from __future__ import with_statement, print_function
from math import pi as PI
import sys
##

class Source_Printer(object):
def __init__(self):
self.is_printing= False
with open(sys.argv[0]) as file:
self.lines= iter(file.readlines())
for line in self.lines:
if line.startswith("print_source"):
break
elif line == "##\n":
self.is_printing= False
elif line.startswith("## Show"):
print("\n")
self.is_printing= True
elif self.is_printing:
print(line,end="")
def __call__(self):
for line in self.lines:
if line == "##\n" or line.startswith("print_source"):
if self.is_printing:
self.is_printing= False
break
else:
self.is_printing= False
elif line.startswith("## Show"):
print("\n")
self.is_printing= True
elif self.is_printing:
print(line, end="")


print_source= Source_Printer()
## Show
#Calculation of first Area:
d1= 3.0
A1= d1**2 * PI / 4.0
##
print_source()

print ("Area of Circle 1:\t", A1)

## Show
#Calculation of second area:
d2= 5.0
A2= d2**2 * PI / 4.0
##
# This is a comment that won't be printed

print_source()
print ("Area of Circle 2:\t", A2)

# This is another one
Sum_Of_Areas= A1 + A2
print ("Sum of areas:\t", Sum_Of_Areas)

8<--------8<-------- result: ---8<--------

# List of all imports:
from __future__ import with_statement, print_function
from math import pi as PI
import sys


#Calculation of first Area:
d1= 3.0
A1= d1**2 * PI / 4.0
Area of Circle 1: 7.06858347058


#Calculation of second area:
d2= 5.0
A2= d2**2 * PI / 4.0
Area of Circle 2: 19.6349540849
Sum of areas: 26.7035375555

8<--------8<-------- result: ---8<--------

Regards,

Manuel
 
M

Michael Torrie

Hello everyone,

I am looking for ways to use a python file as a substitute for simple
pen and paper calculations. At the moment I mainly use a combination
of triple-quoted strings, exec and print (Yes, I know it's not exactly
elegant).

This isn't quite along the lines that this thread is going, but it seems
to me that a program like "reinteract" is about what I want to replace a
pen and paper with a python-based thing. Last time I used it, it was
buggy, but if this concept was developed, it would totally rock:

http://fishsoup.net/software/reinteract/
 
G

Giacomo Boffi

Manuel Graune said:
Hello everyone,

I am looking for ways to use a python file as a substitute for simple
pen and paper calculations.

search("embedded calc mode") if manuel in emacs_fellows_set or sys.exit(1)
 
M

Manuel Graune

Giacomo Boffi said:
search("embedded calc mode") if manuel in emacs_fellows_set or sys.exit(1)

Well, the subject does say python and not elisp, but I'm a vim-user
anyways.

*duckandrun*
 
G

Giacomo Boffi

Manuel Graune said:
Well, the subject does say python

and so i answered in python...

seriously, embedded calc mode is not mathematica's notebooks but is
usable for doing "live maths" in a text buffer
I'm a vim-user anyways.

sorry... otoh, vim is scriptable in python. i know less than nothing
on this subject but i'd be surprised if something akin to your request
were not available
*duckandrun*

tanto ti ripiglio
g
 
M

Michael Torrie

Well, the subject does say python and not elisp, but I'm a vim-user
anyways.

Did you look at the link to Owen Taylor's reinteract program? I think
it's closer to what you want than any other thing mentioned here, with
the exception that it's a standalone GTK (graphical) app.
 
M

Manuel Graune

Michael Torrie said:
Did you look at the link to Owen Taylor's reinteract program? I think
it's closer to what you want than any other thing mentioned here, with
the exception that it's a standalone GTK (graphical) app.

Yes, I did. And I think this program is a great lightweight alernative
to sage, which was mentioned in another post and would probably be
my preferred environment if I had complete freedom to set up my working
environment and would not need to exchange data with others or explain
how someone else is supposed to reuse my code/results in two years time.

Things being as they are, I am looking for a solution which works with
as few additional components as possible, so that a solution based on
a simple copy-and-paste class or decorator is preferable.

Regards,

Manuel
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,043
Latest member
CannalabsCBDReview

Latest Threads

Top