# Read from csv-file, write results in new columns in the same csv-file

Hi,

I am currently trying to achieve the following:

given a csv-file e.g. like

x,y,sinx,siny
30,45,,
60,90,,


Values for x and y are given in degree. What I want to do: take the data from the csv-file, calculate sin(x) and sin(y) for the values given in each row and then print the result in the corresponding cell. If possible, do not round the result, so the output should look something like this:

x,y,sinx,siny
30,45,1/2,sqrt(2)/2
60,90,sqrt(3)/2,1


Taking this one step further, if possible the output should be printed in complete LaTeX-code because the date from the csv-file will be used in a LaTeX-document, so the best possible result would be:

x,y,sinx,siny
30,45,\frac{1}{2},\frac{\sqrt{2}}{2}
60,90,\frac{\sqrt{3}}{2},1


I do know about sageTex which is able to do this, but for other reasons I can't use sageTex for my problem.

I am completely new to sage, so I don't know if there is a standard procedure for this or if it is possible at all. Any input is appreciated!

edit retag close merge delete

Sort by » oldest newest most voted

Here are some inputs:

• To read and loop over the entries of the file, you should have a look at the Python csv module, the web has tons of examples.
• Given a string s representing an integer, you can transform it as a Sage integer as ZZ(s).
• Be careful that angles in Sage are in radians, not degrees, so sin(45) will not give you sqrt(2)/2 but sin(pi/4) will.
• Given a symbolic experssion E, you can get its latex string representation with latex(E).

For example:

sage: latex(sin(pi/4))
\frac{1}{2} \, \sqrt{2}


You should get enough information to reach your goal.

more

Here is a solution for the "same" problem, designed but as i would design the process:

• it is natural to separate the in and out file, thus not write in the same file. (Hard to test, some users will hate this overwriting behavior, if not really attentioned, this is also the best way to loose data when errors in coding occur.)
• the outfile will have & as separator, so that i may try to insert the result in there...
• no csv (reader) import will be done to keep things simple.

Code:

import traceback

SEPARATOR     = ';'          # or ',' or ' & ' or ...
SEPARATOR_IN  = ';'          # or ',' or ' & ' or ...
SEPARATOR_OUT = '\n    &'    # or ',' or ' & ' or ...
END_OUT       = '\\\\\n'     # or simply '\n'

inFileName  = r"/home/dan/temp/in1234.csv"
outFileName = r"/home/dan/temp/out1234.csv"

def f(u):
return latex( sin( u/180 *pi ) )

def printOut( x,y, outStream, sep=SEPARATOR ):
z = x+y
outList = [ r"%s^\circ" % x ,
r"%s^\circ" % y ,
r"%s^\circ" % z ,
f(x) ,
f(y) ,
f(z) , ]

outStream.write( sep.join( [ str(entry) for entry in outList ] ) + END_OUT )

inStream  = open(  inFileName, 'r' )    # open for read
outStream = open( outFileName, 'w' )    # open for write

for line in inStream:
print "... parsing %s" % line
try:
x, y = line.strip().split( SEPARATOR_IN )[:2]
x, y = ZZ(x), ZZ(y)
printOut( x, y, outStream, sep=SEPARATOR_OUT )
except Exception:
traceback.print_exc()

inStream.close()
outStream.close()


Use corresponding separators for the own needs. My input file has the lines:

15;30
12;24
30;45
60;90
72;120
6;18;


and i use the German separator, the semicolon. Redefine the separator(s) for the own needs. The output is like this, rather designed to be inserted into a latex document, inside of an array block:

15^\circ
&30^\circ
&45^\circ
&\frac{1}{4} \, \sqrt{6} - \frac{1}{4} \, \sqrt{2}
&\frac{1}{2}
&\frac{1}{2} \, \sqrt{2}\\
12^\circ
&24^\circ
&36^\circ
&\sin\left(\frac{1}{15} \, \pi\right)
&\sin\left(\frac{2}{15} \, \pi\right)
&\frac{1}{4} \, \sqrt{-2 \, \sqrt{5} + 10}\\
30^\circ
&45^\circ
&75^\circ
&\frac{1}{2}
&\frac{1}{2} \, \sqrt{2}
&\frac{1}{4} \, \sqrt{6} + \frac{1}{4} \, \sqrt{2}\\
60^\circ
&90^\circ
&150^\circ
&\frac{1}{2} \, \sqrt{3}
&1
&\frac{1}{2}\\
72^\circ
&120^\circ
&192^\circ
&\frac{1}{4} \, \sqrt{2 \, \sqrt{5} + 10}
&\frac{1}{2} \, \sqrt{3}
&-\sin\left(\frac{1}{15} \, \pi\right)\\


The columns correspond to $x,y,x+y$ and then we apply the sine on these values one by one. If you insist to give the formulas in the header of the in-File, then you have to parse and eval them.

Note: In order to also get something out of $\sin(\pi/15)$ one may use:

def g(u):

roots = [ r
for r in u.minpoly(X).roots(ring=AA, multiplicities=False )
if abs( r-u.n() ) < 0.0001 ]
if roots:
r = roots
return '?'


when

sage: latex( g( sin( pi/15 ) ) )
\frac{1}{4} \, \sqrt{-\sqrt{5} - 8 \, \sqrt{-\frac{3}{32} \, \sqrt{5} + \frac{15}{32}} + 7}


delivers $$\frac{1}{4} \, \sqrt{-\sqrt{5} - 8 \, \sqrt{-\frac{3}{32} \, \sqrt{5} + \frac{15}{32}} + 7}\ .$$ (Not the best shape for a human, but a result.)

more