<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;DUAFRnw-eSp7ImA9WhRUFk4.&quot;"><id>tag:blogger.com,1999:blog-3704048544762396176</id><updated>2012-01-27T05:15:17.251+01:00</updated><category term="images" /><category term="compression" /><category term="Python" /><category term="Windows XP" /><category term="I/O" /><category term="numpy" /><category term="blogger" /><category term="installation" /><category term="admin" /><category term="sound" /><category term="CSS" /><category term="web" /><category term="scipy" /><category term="C" /><category term="domain" /><category term="files" /><category term="Pyrex" /><category term="performance" /><category term="urllib" /><category term="template" /><category term="Tkinter" /><category term="wave" /><category term="Psyco" /><category term="GUI" /><title>Coding Mess</title><subtitle type="html">R.L.'s miscellaneous programming and computing remarks</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://codingmess.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://codingmess.blogspot.com/" /><author><name>R.L.</name><uri>http://www.blogger.com/profile/14598815714075739940</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>18</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/CodingMess" /><feedburner:info uri="codingmess" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;D0QCQH4zcSp7ImA9WxBUEU8.&quot;"><id>tag:blogger.com,1999:blog-3704048544762396176.post-7603140256940177315</id><published>2010-02-25T19:13:00.005+01:00</published><updated>2010-02-25T20:16:01.089+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-02-25T20:16:01.089+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="images" /><category scheme="http://www.blogger.com/atom/ns#" term="Python" /><title>Transforming RGB data to wavelength information</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/heAEVDP1yAQuxLj4IKfAYEwCdq8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/heAEVDP1yAQuxLj4IKfAYEwCdq8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/heAEVDP1yAQuxLj4IKfAYEwCdq8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/heAEVDP1yAQuxLj4IKfAYEwCdq8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Here, I'm presenting a reverse transformation to &lt;a href="http://codingmess.blogspot.com/2009/05/conversion-of-wavelength-in-nanometers.html"&gt;wavelength to RGB&lt;/a&gt;. Right now I have no means of testing its accuracy on some real data. As a first check, I've run it on the mercury lamp image shown in my older post. There are small deviations caused probably by low intensity of light in some places. If used on some real stuff, I would definitely attempt to first fit a line (or some other meaningful function) through the estimated wavelengths. Then of course plot the spectra against fitted values. The domain of this function is limited to 380 - 645 nm. So, here's the algorithm in Python:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;def RGB2lambda(R, G, B):&lt;br /&gt;   """Returns 0 if indeciferable"""&lt;br /&gt;   # selects range by maximum component&lt;br /&gt;   # if max is blue - range is 380 - 489&lt;br /&gt;   # if max is green - range is 490 - 579&lt;br /&gt;   # if max is red - range is 580 - 645&lt;br /&gt;  &lt;br /&gt;   # which colour has highest intensity?&lt;br /&gt;   high = float(R)&lt;br /&gt;   highind = 1&lt;br /&gt;   if G &gt; high:&lt;br /&gt;       high = float(G)&lt;br /&gt;       highind = 2&lt;br /&gt;   if B &gt; high:&lt;br /&gt;       high = float(B)&lt;br /&gt;       highind = 3&lt;br /&gt;      &lt;br /&gt;   # normalize highest to 1.0&lt;br /&gt;   RGBnorm = [R / high, G / high, B / high]&lt;br /&gt;  &lt;br /&gt;   # start decoding&lt;br /&gt;   RGBlambda = 0&lt;br /&gt;   if highind == 1: # red is highest&lt;br /&gt;       if B &gt;= G: # there is more blue than green&lt;br /&gt;           return 0 # max red and more blue than green shouldn't happen&lt;br /&gt;       # wavelength linearly changes from 645 to 580 as green increases&lt;br /&gt;       RGBlambda = 645 - RGBnorm[1] * (645. - 580.)&lt;br /&gt;      &lt;br /&gt;   elif highind == 2: # green is max, range is 510 - 579&lt;br /&gt;       if R &gt; B: # range is 510 - 579&lt;br /&gt;           RGBlambda = 510 + RGBnorm[0] * (580 - 510)&lt;br /&gt;       else: # blue is higher than red, range is 490 - 510&lt;br /&gt;           RGBlambda = 510 - RGBnorm[2] * (510 - 490)&lt;br /&gt;          &lt;br /&gt;   elif highind == 3: # blue is max, range is 380 - 490&lt;br /&gt;       if G &gt; R: # range is 440 - 490&lt;br /&gt;           RGBlambda = RGBnorm[1] * (490 - 440) + 440&lt;br /&gt;       else: # there is more red than green, range is 380 - 440&lt;br /&gt;           RGBlambda = 440 - RGBnorm[0] * (440 - 380)&lt;br /&gt;  &lt;br /&gt;   return RGBlambda&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And here is an accuracy check made on my older image of mercury lamp spectrum:&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_xZEQCsgMsd4/S4bCQTV34XI/AAAAAAAAAA0/-mrE7U8Dtec/s1600-h/RGB2lambda.png"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 400px; height: 353px;" src="http://1.bp.blogspot.com/_xZEQCsgMsd4/S4bCQTV34XI/AAAAAAAAAA0/-mrE7U8Dtec/s400/RGB2lambda.png" alt="" id="BLOGGER_PHOTO_ID_5442250785049534834" border="0" /&gt;Accuracy check (synthetic test)&lt;/a&gt;: x-axis is expected value, y-axis is algorithm output. Circles are the data, the ideal is presented by red line (y = x).&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;Please note that this was NOT produced by using a real photo of a spectrum. As someone who has some spectroscopic background I strongly discourage you from using this algorithm to get wavelength information. This was derived from a simplified version of simple wavelength-to-RGB algorithm. Nevertheless, I intend to make some photos of monochromatic light and test it ;-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3704048544762396176-7603140256940177315?l=codingmess.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingMess/~4/EUvsw7R_tK4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://codingmess.blogspot.com/feeds/7603140256940177315/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3704048544762396176&amp;postID=7603140256940177315" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3704048544762396176/posts/default/7603140256940177315?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3704048544762396176/posts/default/7603140256940177315?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodingMess/~3/EUvsw7R_tK4/transforming-rgb-data-to-wavelength.html" title="Transforming RGB data to wavelength information" /><author><name>R.L.</name><uri>http://www.blogger.com/profile/14598815714075739940</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_xZEQCsgMsd4/S4bCQTV34XI/AAAAAAAAAA0/-mrE7U8Dtec/s72-c/RGB2lambda.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://codingmess.blogspot.com/2010/02/transforming-rgb-data-to-wavelength.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0UGRH87fCp7ImA9WxBVF0s.&quot;"><id>tag:blogger.com,1999:blog-3704048544762396176.post-7791148048303107017</id><published>2010-02-21T17:04:00.003+01:00</published><updated>2010-02-21T17:20:25.104+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-02-21T17:20:25.104+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="sound" /><category scheme="http://www.blogger.com/atom/ns#" term="wave" /><category scheme="http://www.blogger.com/atom/ns#" term="Python" /><category scheme="http://www.blogger.com/atom/ns#" term="numpy" /><title>How to make a .wav file with Python, revisited</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/xriaYFIeUWIInTCIg_3gVptE9e0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/xriaYFIeUWIInTCIg_3gVptE9e0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/xriaYFIeUWIInTCIg_3gVptE9e0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/xriaYFIeUWIInTCIg_3gVptE9e0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;I've noticed that my two-year &lt;a href="http://codingmess.blogspot.com/2008/07/how-to-make-simple-wav-file-with-python.html"&gt;old post about making a .wav file with Python&lt;/a&gt; is being read a lot so I forced myself to modify the code a little. Now it should be nicer to read and modify further according to your needs/wishes. I've also incorporated the comments of helpful readers Mike Axiak and Fingon. Thanks guys ;-)&lt;br /&gt;The link to the source of this idea, code by Andrea Valle, does not work as I'm typing this so I can only thank him by saying his name. My contribution to all this is minor.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;import numpy as N&lt;br /&gt;import wave&lt;br /&gt;&lt;br /&gt;def get_signal_data(frequency=440, duration=1, volume=32768, samplerate=44100):&lt;br /&gt;    """Outputs a numpy array of intensities"""&lt;br /&gt;    samples = duration * samplerate&lt;br /&gt;    period = samplerate / float(frequency)&lt;br /&gt;    omega = N.pi * 2 / period&lt;br /&gt;    t = N.arange(samples, dtype=N.float)&lt;br /&gt;    y = volume * N.sin(t * omega)&lt;br /&gt;    return y&lt;br /&gt;&lt;br /&gt;def numpy2string(y):&lt;br /&gt;    """Expects a numpy vector of numbers, outputs a string"""&lt;br /&gt;    signal = "".join((wave.struct.pack('h', item) for item in y))&lt;br /&gt;    # this formats data for wave library, 'h' means data are formatted&lt;br /&gt;    # as short ints&lt;br /&gt;    return signal&lt;br /&gt;&lt;br /&gt;class SoundFile:&lt;br /&gt;    def  __init__(self, signal, filename, duration=1, samplerate=44100):&lt;br /&gt;        self.file = wave.open(filename, 'wb')&lt;br /&gt;        self.signal = signal&lt;br /&gt;        self.sr = samplerate&lt;br /&gt;        self.duration = duration&lt;br /&gt;  &lt;br /&gt;    def write(self):&lt;br /&gt;        self.file.setparams((1, 2, self.sr, self.sr*self.duration, 'NONE', 'noncompressed'))&lt;br /&gt;        # setparams takes a tuple of:&lt;br /&gt;        # nchannels, sampwidth, framerate, nframes, comptype, compname&lt;br /&gt;        self.file.writeframes(self.signal)&lt;br /&gt;        self.file.close()&lt;br /&gt;&lt;br /&gt;if __name__ == '__main__':&lt;br /&gt;    duration = 2&lt;br /&gt;    myfilename = 'test.wav'&lt;br /&gt;    data = get_signal_data(440, duration)&lt;br /&gt;    signal = numpy2string(data)&lt;br /&gt;    f = SoundFile(signal, myfilename, duration)&lt;br /&gt;    f.write()&lt;br /&gt;    print 'file written'&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3704048544762396176-7791148048303107017?l=codingmess.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingMess/~4/GfISMJQe4UE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://codingmess.blogspot.com/feeds/7791148048303107017/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3704048544762396176&amp;postID=7791148048303107017" title="7 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3704048544762396176/posts/default/7791148048303107017?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3704048544762396176/posts/default/7791148048303107017?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodingMess/~3/GfISMJQe4UE/how-to-make-wav-file-with-python.html" title="How to make a .wav file with Python, revisited" /><author><name>R.L.</name><uri>http://www.blogger.com/profile/14598815714075739940</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>7</thr:total><feedburner:origLink>http://codingmess.blogspot.com/2010/02/how-to-make-wav-file-with-python.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A08GRXs5eyp7ImA9WxJQEEw.&quot;"><id>tag:blogger.com,1999:blog-3704048544762396176.post-630056694172698154</id><published>2009-05-22T19:28:00.022+02:00</published><updated>2009-05-22T21:17:04.523+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-22T21:17:04.523+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="images" /><category scheme="http://www.blogger.com/atom/ns#" term="Python" /><title>Conversion of wavelength in nanometers to RGB in Python</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Znht_nItgPQQXIumfG_iWBbd0Fw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Znht_nItgPQQXIumfG_iWBbd0Fw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Znht_nItgPQQXIumfG_iWBbd0Fw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Znht_nItgPQQXIumfG_iWBbd0Fw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;I've been recently doing some calibration/benchmark/demonstration measurements of spectra on an instrument I'm building and thought that it would be cool to visualize the spectra so that you could actually see them in colour. I've also never been able to memorize what colour which wavelength was, so this could even be a self-education project. In other words, the task was to transform wavelength data in nanometers into RGB data.&lt;br /&gt;&lt;br /&gt;A short Google search turned up some very informative sites and among them was the algorithm for nanometer to RGB conversion. What seems to be the oldest search result is a &lt;a href="http://www.physics.sfasu.edu/astro/color/spectra.html"&gt;conversion algorithm written by Dan Bruton in FORTRAN&lt;/a&gt;. You may also be interested in the &lt;a href="http://www.midnightkite.com/color.html"&gt;Color Science&lt;/a&gt; site from the same author. As I was a bit confused by the FORTRAN code, I also used what appears to be a &lt;a href="http://miguelmoreno.net/sandbox/wavelengthtoRGB/"&gt;translation of this code into C#&lt;/a&gt;. I know C# about as much as FORTRAN but the syntax was more understandable to me. My only contribution was a literal translation of the algorithm into Python.&lt;br /&gt;&lt;br /&gt;The function takes a value in nanometers and returns a list of [R, G, B] values. Although a &lt;a href="http://www.pythonware.com/products/pil/"&gt;PIL&lt;/a&gt; putpixel function requires a tuple, I found a list more flexible in case you want to change the values e.g. according to measured intensity. So, here is the code:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;def wav2RGB(wavelength):&lt;br /&gt;    w = int(wavelength)&lt;br /&gt;&lt;br /&gt;    # colour&lt;br /&gt;    if w &amp;gt;= 380 and w &amp;lt; 440:&lt;br /&gt;        R = -(w - 440.) / (440. - 350.)&lt;br /&gt;        G = 0.0&lt;br /&gt;        B = 1.0&lt;br /&gt;    elif w &amp;gt;= 440 and w &amp;lt; 490:&lt;br /&gt;        R = 0.0&lt;br /&gt;        G = (w - 440.) / (490. - 440.)&lt;br /&gt;        B = 1.0&lt;br /&gt;    elif w &amp;gt;= 490 and w &amp;lt; 510:&lt;br /&gt;        R = 0.0&lt;br /&gt;        G = 1.0&lt;br /&gt;        B = -(w - 510.) / (510. - 490.)&lt;br /&gt;    elif w &amp;gt;= 510 and w &amp;lt; 580:&lt;br /&gt;        R = (w - 510.) / (580. - 510.)&lt;br /&gt;        G = 1.0&lt;br /&gt;        B = 0.0&lt;br /&gt;    elif w &amp;gt;= 580 and w &amp;lt; 645:&lt;br /&gt;        R = 1.0&lt;br /&gt;        G = -(w - 645.) / (645. - 580.)&lt;br /&gt;        B = 0.0&lt;br /&gt;    elif w &amp;gt;= 645 and w &amp;lt;= 780:&lt;br /&gt;        R = 1.0&lt;br /&gt;        G = 0.0&lt;br /&gt;        B = 0.0&lt;br /&gt;    else:&lt;br /&gt;        R = 0.0&lt;br /&gt;        G = 0.0&lt;br /&gt;        B = 0.0&lt;br /&gt;&lt;br /&gt;    # intensity correction&lt;br /&gt;    if w &amp;gt;= 380 and w &amp;lt; 420:&lt;br /&gt;        SSS = 0.3 + 0.7*(w - 350) / (420 - 350)&lt;br /&gt;    elif w &amp;gt;= 420 and w &amp;lt;= 700:&lt;br /&gt;        SSS = 1.0&lt;br /&gt;    elif w &amp;gt; 700 and w &amp;lt;= 780:&lt;br /&gt;        SSS = 0.3 + 0.7*(780 - w) / (780 - 700)&lt;br /&gt;    else:&lt;br /&gt;        SSS = 0.0&lt;br /&gt;    SSS *= 255&lt;br /&gt;&lt;br /&gt;    return [int(SSS*R), int(SSS*G), int(SSS*B)]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The output value's range is 0 -- 255. The code could use some streamlining, but even in this form it is fast enough for an occasional image.&lt;br /&gt;&lt;br /&gt;Here is whole visible spectrum as made by this function:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_xZEQCsgMsd4/Shb2bBwqUuI/AAAAAAAAAAk/wgdS2A_djGE/s1600-h/white_spectrum_web.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 650px; height: 100px;" src="http://3.bp.blogspot.com/_xZEQCsgMsd4/Shb2bBwqUuI/AAAAAAAAAAk/wgdS2A_djGE/s400/white_spectrum_web.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5338725352483738338" /&gt;&lt;/a&gt;&lt;br /&gt;... and a line spectrum of our decades-old mercury vapour lamp:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_xZEQCsgMsd4/Shb2FJMWF-I/AAAAAAAAAAc/oJMCwX32imw/s1600-h/Hg_line_spectrum_web.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 650px; height: 100px;" src="http://3.bp.blogspot.com/_xZEQCsgMsd4/Shb2FJMWF-I/AAAAAAAAAAc/oJMCwX32imw/s400/Hg_line_spectrum_web.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5338724976521779170" /&gt;&lt;/a&gt;&lt;br /&gt;Finally, in case you want to read more about computer colour science:&lt;br /&gt;&lt;a href="http://mintaka.sdsu.edu/GF/explain/optics/rendering.html"&gt;Rendering spectra&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.fourmilab.ch/documents/specrend/"&gt;Colour Rendering of Spectra&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3704048544762396176-630056694172698154?l=codingmess.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingMess/~4/L2zeAqQhDLk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://codingmess.blogspot.com/feeds/630056694172698154/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3704048544762396176&amp;postID=630056694172698154" title="20 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3704048544762396176/posts/default/630056694172698154?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3704048544762396176/posts/default/630056694172698154?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodingMess/~3/L2zeAqQhDLk/conversion-of-wavelength-in-nanometers.html" title="Conversion of wavelength in nanometers to RGB in Python" /><author><name>R.L.</name><uri>http://www.blogger.com/profile/14598815714075739940</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_xZEQCsgMsd4/Shb2bBwqUuI/AAAAAAAAAAk/wgdS2A_djGE/s72-c/white_spectrum_web.png" height="72" width="72" /><thr:total>20</thr:total><feedburner:origLink>http://codingmess.blogspot.com/2009/05/conversion-of-wavelength-in-nanometers.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0IHSHc_eSp7ImA9WxRbEk8.&quot;"><id>tag:blogger.com,1999:blog-3704048544762396176.post-5151246139719021579</id><published>2008-12-02T14:03:00.005+01:00</published><updated>2008-12-02T14:45:39.941+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-12-02T14:45:39.941+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="performance" /><category scheme="http://www.blogger.com/atom/ns#" term="C" /><category scheme="http://www.blogger.com/atom/ns#" term="Pyrex" /><category scheme="http://www.blogger.com/atom/ns#" term="Python" /><category scheme="http://www.blogger.com/atom/ns#" term="numpy" /><title>Creating NumPy arrays in Pyrex</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/AlA7MC8nOpdua_Ua6WJjgbFBg8Q/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/AlA7MC8nOpdua_Ua6WJjgbFBg8Q/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/AlA7MC8nOpdua_Ua6WJjgbFBg8Q/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/AlA7MC8nOpdua_Ua6WJjgbFBg8Q/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;In a previous post I have described &lt;a href="http://codingmess.blogspot.com/2008/11/pyrex-for-dummies.html"&gt;basic usage of the Pyrex language&lt;/a&gt; which may be used to interface C code into Python or to speed up your Python code by adding C-like declarations. At the time I did not knew how to use numpy C-API to create new numpy arrays. I have mentioned it in the post and luckily for me a very helpful comment by &lt;a href="http://diffusingthoughts.blogspot.com/"&gt;diffusing thoughts&lt;/a&gt; showed me how to do this. It also got me started so that I could decipher how to use other C-API calls.&lt;br /&gt;I currently do not have any production code in which the array creation is a bottleneck. Nevertheless I was curious if these C-API calls are actually faster than using the Python calls to NumPy. Here I present a howto describing what I learned together with some benchmarking results. I'm certain that I will forget how to use these C-API calls and hopefully this post will one day save me some time.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Prerequisites&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;numpy and pyrex have to be installed&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;c_numpy.pxd file from the numpy installation must be accessible (I just put it into my current working directory)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;I use the following header of the pyrex (*.pyx) file:&lt;pre&gt;import numpy&lt;br /&gt;cimport c_numpy&lt;br /&gt;cdef extern from "C:\Python25\Lib\site-packages\numpy\core\include\numpy\arrayobject.h":&lt;br /&gt;    cdef object PyArray_SimpleNewFromData(int nd,&lt;br /&gt;                                          c_numpy.npy_intp *dims,&lt;br /&gt;                                          int typenum,&lt;br /&gt;                                          void *data)&lt;br /&gt;    cdef object PyArray_ZEROS(int nd,&lt;br /&gt;                              c_numpy.npy_intp *dims,&lt;br /&gt;                              int typenum,&lt;br /&gt;                              int fortran)&lt;br /&gt;    cdef object PyArray_SimpleNew(int nd,&lt;br /&gt;                                  c_numpy.npy_intp *dims,&lt;br /&gt;                                  int typenum)&lt;br /&gt;    cdef object PyArray_Arange(double start,&lt;br /&gt;                               double stop,&lt;br /&gt;                               double step,&lt;br /&gt;                               int typenum)&lt;br /&gt;&lt;br /&gt;c_numpy.import_array()&lt;/pre&gt;&lt;br /&gt;The documentation for C-API of numpy is available for download on the &lt;a href="http://numpy.scipy.org/"&gt;numpy homepage&lt;/a&gt; in the form of "Guide to NumPy" pdf file (numpybook).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;numpy.zeros vs. PyArray_ZEROS&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;example:&lt;pre&gt;cdef int length&lt;br /&gt;cdef c_numpy.ndarray newarr&lt;br /&gt;length = 10&lt;br /&gt;newarr = PyArray_ZEROS(1, &amp;amp;length, c_numpy.NPY_DOUBLE, 0)&lt;/pre&gt;notes:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;for multidimensional arrays the first two variables within PyArray_ZEROS have to be changed accordingly, see numpybook (I have not tested this)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;the type may also be changed if desirable (I however only need doubles)&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;equivalent numpy code:&lt;br /&gt;&lt;pre&gt;newarr = numpy.zeros(length)&lt;/pre&gt;Benchmarking these two ways shows that they have the same speed for creating arrays larger than ~ 100 000 values. The C-API is faster on arrays smaller than ~ 50 000 values and about 50% faster on arrays of length 1 000.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;numpy.arange vs. PyArray_Arange&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;example:&lt;pre&gt;cdef double start, stop, step&lt;br /&gt;cdef c_numpy.ndarray newarr&lt;br /&gt;start = 0&lt;br /&gt;stop = 10&lt;br /&gt;step = 1&lt;br /&gt;newarr = PyArray_Arange(start, stop, step, c_numpy.NPY_DOUBLE)&lt;/pre&gt;equivalent numpy code:&lt;br /&gt;&lt;pre&gt;newarr = numpy.arange(start, stop, step)&lt;/pre&gt;Here the C-API is only faster on small arrays (length less than 1 000).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;numpy.empty vs. PyArray_SimpleNew&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;example:&lt;pre&gt;cdef int length&lt;br /&gt;cdef c_numpy.ndarray newarr&lt;br /&gt;length = 10&lt;br /&gt;newarr = PyArray_SimpleNew(1, &amp;amp;length, c_numpy.NPY_DOUBLE)&lt;/pre&gt;equivalent numpy code:&lt;pre&gt;newarr = numpy.empty(length)&lt;/pre&gt;This is the only case where using C-API is always faster than the numpy way. PyArray_SimpleNew is about 65% faster on arrays of length less than 50 000. It is ~20% faster on arrays of length 500 000. It is still somewhat faster in creating arrays of length 50 000 000.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;PyArray_SimpleNewFromData&lt;/span&gt;&lt;br /&gt;This call creates a new numpy array from malloc-ed C array.&lt;br /&gt;&lt;br /&gt;example:&lt;pre&gt;cdef extern from "stdlib.h":&lt;br /&gt;    ctypedef int size_t&lt;br /&gt;    void *malloc(size_t)&lt;br /&gt;&lt;br /&gt;cdef c_numpy.npy_intp size&lt;br /&gt;cdef c_numpy.ndarray newarr&lt;br /&gt;cdef double *arrsource&lt;br /&gt;&lt;br /&gt;size = 10&lt;br /&gt;arrsource = &amp;lt;double *&amp;gt;malloc(sizeof(double) * size)&lt;br /&gt;newarr = PyArray_SimpleNewFromData(1, &amp;amp;size, c_numpy.NPY_DOUBLE, &amp;lt;void *&amp;gt;arrsource)&lt;br /&gt;newarr.flags = newarr.flags|(c_numpy.NPY_OWNDATA) # sets the ownership bit&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Notes&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;I have seen some discussion posts which discourage from doing this. See e.g. &lt;a href="http://lists.copyleft.no/pipermail/pyrex/2006-May/001793.html"&gt;here&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;It may also be helpful to read &lt;a href="http://blog.enthought.com/?p=62"&gt;this post by Travis Oliphant&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Technical notes&lt;/span&gt;&lt;br /&gt;The benchmarking was done by repeated allocation of a lot of arrays from within Pyrex code. The length of the arrays was also varied to assess whether there is some dependency on the amount of memory being allocated. The largest arrays tested were the largest which didn't caused MemoryError in Python. The number of allocations was selected to assure that the benchmark run at least several seconds (generally thousands of calls or more). I have also tested that it is safe to read and write values into the created arrays.&lt;br /&gt;The benchmarking was done on a PC with Windows XP, Python 2.5.2, Pyrex 0.9.8.2, MinGW 5.1.4 and NumPy 1.2.0.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3704048544762396176-5151246139719021579?l=codingmess.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingMess/~4/iN09DRZOfUY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://codingmess.blogspot.com/feeds/5151246139719021579/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3704048544762396176&amp;postID=5151246139719021579" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3704048544762396176/posts/default/5151246139719021579?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3704048544762396176/posts/default/5151246139719021579?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodingMess/~3/iN09DRZOfUY/creating-numpy-arrays-in-pyrex.html" title="Creating NumPy arrays in Pyrex" /><author><name>R.L.</name><uri>http://www.blogger.com/profile/14598815714075739940</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://codingmess.blogspot.com/2008/12/creating-numpy-arrays-in-pyrex.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEMFQn8_fyp7ImA9WxRUFkw.&quot;"><id>tag:blogger.com,1999:blog-3704048544762396176.post-2102179784098134949</id><published>2008-11-24T19:15:00.025+01:00</published><updated>2008-11-25T12:26:53.147+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-11-25T12:26:53.147+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="performance" /><category scheme="http://www.blogger.com/atom/ns#" term="C" /><category scheme="http://www.blogger.com/atom/ns#" term="Pyrex" /><category scheme="http://www.blogger.com/atom/ns#" term="Python" /><category scheme="http://www.blogger.com/atom/ns#" term="numpy" /><title>Pyrex for dummies</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/p2toOV2GNrWm976r6ik9rV6mgKo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/p2toOV2GNrWm976r6ik9rV6mgKo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/p2toOV2GNrWm976r6ik9rV6mgKo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/p2toOV2GNrWm976r6ik9rV6mgKo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;a href="http://codingmess.blogspot.com/2008/11/pyrex-mixing-c-and-python-code.html"&gt;Pyrex&lt;/a&gt; is a very powerful tool if you need to speed up some Python code or connect it with some C code. My main motivation to use it was the ability to distribute only the compiled files and not also a C compiler etc.&lt;br /&gt;&lt;br /&gt;Unfortunately, the learning curve is a bit steep if you want to do anything non-trivial (if you are not a skilled programmer, that is). I find it very difficult to read and understand just about anything about Python C API and related topics. So any attempt to learn new tricks means spending hours with Google and trying to find an example of usage which is simple enough for me to understand.&lt;br /&gt;&lt;br /&gt;What follows is a few steps which I generally follow when rewriting Python into Pyrex code.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Profile your code. Start with rewriting the slowest parts of your code (unless you want to know how fast you can make everything).&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Try to compile unchanged Python code with Pyrex. This way you will start with a working code and if something goes wrong you probably broke it with later changes.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Declare loop control variables as C types: &lt;pre&gt;cdef int i&lt;/pre&gt; and change Python for loops into Pyrex for loops &lt;pre&gt;for i from 0 &amp;lt;= i &amp;lt; 10:&lt;/pre&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Numpy array data should be accessed directly. It's fairly easy to do now, that I finally know how to do this (see further).&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Additional speedup may be achieved by eliminating or minimising Python function calls and/or replacing them with C function calls.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;To help understanding your functions, add at least one line to the docstring such as: &lt;pre&gt;"""myfunc( N, array x) -&gt; array y"""&lt;/pre&gt;Pyrex (or C) function parameters are not accessible as in Python functions by using help(myfunc) therefore you must explicitly write it to the docstring.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;These steps have so far done the trick for my purposes. I essentially only need fast maths code so I have no idea about other areas. What I may have to learn later is some string stuff but so far I had neither guts nor reason to try it. This means I'm using pure Python strings in my Pyrex modules.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Now some selected details as promised:&lt;/span&gt;&lt;br /&gt;To use some standard C function you have to declare it before use. So, if I e.g. need asin() from the math.h library I put this at the beginning of the Pyrex module:&lt;br /&gt;&lt;pre&gt;cdef extern from "math.h":&lt;br /&gt;   double asin(double)&lt;/pre&gt;&lt;br /&gt;Using Numpy C API to access array data directly was tough to learn, this is my current way:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;put to the beginning of the script:&lt;pre&gt;cimport c_numpy&lt;/pre&gt;for this to work you have to copy 'c_numpy.pxd' file from 'Python\Lib\site-packages\numpy\doc\pyrex' into the directory with your script (there is a warning about future removal, I hope the same-named file in '\doc\cython' will work as well).&lt;/li&gt;&lt;br /&gt;&lt;li&gt;initialize numpy by :&lt;pre&gt;c_numpy.import_array()&lt;/pre&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;declare new numpy array:&lt;pre&gt;cdef c_numpy.ndarray x&lt;/pre&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;create numpy array:&lt;pre&gt;x = numpy.zeros(10)&lt;/pre&gt;There is another (possibly faster) way of creating new arrays but this is what i use now (I also do not know the other way, should have made a note...).&lt;/li&gt;&lt;br /&gt;&lt;li&gt;declare pointer to store the adress of the numpy array data:&lt;pre&gt;cdef double *xdata&lt;/pre&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;copy data adress to your pointer:&lt;pre&gt;xdata = &amp;lt;double *&amp;gt;x.data&lt;/pre&gt;The x.data is a char poiter to the first number in your array. I have no idea what this means (why char?).&lt;/li&gt;&lt;br /&gt;&lt;li&gt;you may now index xdata to get desired element value:&lt;pre&gt;xdata[6] = 12.54&lt;/pre&gt; or &lt;pre&gt;tempvar = xdata[1]&lt;/pre&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;you may declare the numpy array in the same way during function declaration:&lt;pre&gt;def myfunc(double step, c_numpy.ndarray x):&lt;br /&gt;...&lt;/pre&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Using the Numpy C API is more cumbersome than just indexing numpy arrays but the code speedup is often significant.&lt;br /&gt;Looking through my Pyrex modules this should in essence be all that is needed to get started with Pyrex.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3704048544762396176-2102179784098134949?l=codingmess.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingMess/~4/vkO5qr2HSXo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://codingmess.blogspot.com/feeds/2102179784098134949/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3704048544762396176&amp;postID=2102179784098134949" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3704048544762396176/posts/default/2102179784098134949?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3704048544762396176/posts/default/2102179784098134949?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodingMess/~3/vkO5qr2HSXo/pyrex-for-dummies.html" title="Pyrex for dummies" /><author><name>R.L.</name><uri>http://www.blogger.com/profile/14598815714075739940</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>4</thr:total><feedburner:origLink>http://codingmess.blogspot.com/2008/11/pyrex-for-dummies.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0IHQnc5eCp7ImA9WxRUEko.&quot;"><id>tag:blogger.com,1999:blog-3704048544762396176.post-4405642432568744856</id><published>2008-11-21T11:16:00.009+01:00</published><updated>2008-11-21T13:45:33.920+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-11-21T13:45:33.920+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="performance" /><category scheme="http://www.blogger.com/atom/ns#" term="C" /><category scheme="http://www.blogger.com/atom/ns#" term="Pyrex" /><category scheme="http://www.blogger.com/atom/ns#" term="installation" /><category scheme="http://www.blogger.com/atom/ns#" term="Python" /><title>Pyrex - mixing C and Python code</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/tvGn3HOCUixYzoWZJCGcNyIP_qc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/tvGn3HOCUixYzoWZJCGcNyIP_qc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/tvGn3HOCUixYzoWZJCGcNyIP_qc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/tvGn3HOCUixYzoWZJCGcNyIP_qc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;I have had a little optimization mania recently. After realizing that &lt;a href="http://codingmess.blogspot.com/2008/08/scipyweave-doesnt-work-compiler.html"&gt;scipy.weave is ill suited for deployment&lt;/a&gt; on the computers of my non-programming colleagues I was looking for other options and tried the &lt;a href="http://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/"&gt;Pyrex&lt;/a&gt; extension. I recommend reading the &lt;a href="http://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/"&gt;Pyrex home page&lt;/a&gt; for details of what exactly Pyrex is. A title sentence of its home page explains it nicely: &lt;blockquote&gt;Pyrex lets you write code that mixes Python and C data types any way you want, and compiles it into a C extension for Python. &lt;/blockquote&gt;This has the (for me) significant advantage that there is no need to install scipy and gcc on any computer that you want your code to run on (as compared to the scipy.weave model). Distributing the compiled extension file is enough.&lt;br /&gt;To make Pyrex work on Windows follow &lt;a href="http://wiki.python.org/moin/PyrexOnWindows"&gt;these instructions&lt;/a&gt; (&lt;a href="http://www.velocityreviews.com/forums/t356785-pyrex-installation-on-windows-xp-stepbystep-guide.html"&gt;here&lt;/a&gt; seems to be a copy). As usual you have to change something a bit to make it work with gcc. The key step of these instructions is creation (or edit) of distutils.cfg and adding these lines into it:&lt;br /&gt;&lt;pre&gt;[build]&lt;br /&gt;compiler = mingw32&lt;/pre&gt;Aside from this I also use a modified python setup command:&lt;br /&gt;&lt;pre&gt;python setup.py build-ext --inplace&lt;/pre&gt;It suits me better to have the compiled extension in the working directory and not in Python dir as happens with the 'install' command.&lt;br /&gt;I am aware of the &lt;a href="http://cython.org/"&gt;Cython&lt;/a&gt; language which has developed from Pyrex but I have not tried it. I guess I don't need to fix what ain't broken ;-) Pyrex works great for me right now.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3704048544762396176-4405642432568744856?l=codingmess.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingMess/~4/4MjA3kEJOlo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://codingmess.blogspot.com/feeds/4405642432568744856/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3704048544762396176&amp;postID=4405642432568744856" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3704048544762396176/posts/default/4405642432568744856?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3704048544762396176/posts/default/4405642432568744856?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodingMess/~3/4MjA3kEJOlo/pyrex-mixing-c-and-python-code.html" title="Pyrex - mixing C and Python code" /><author><name>R.L.</name><uri>http://www.blogger.com/profile/14598815714075739940</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://codingmess.blogspot.com/2008/11/pyrex-mixing-c-and-python-code.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEABSXkyeSp7ImA9WxRUFkw.&quot;"><id>tag:blogger.com,1999:blog-3704048544762396176.post-7018546398572087997</id><published>2008-08-26T17:14:00.008+02:00</published><updated>2008-11-25T12:32:38.791+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-11-25T12:32:38.791+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="performance" /><category scheme="http://www.blogger.com/atom/ns#" term="Psyco" /><category scheme="http://www.blogger.com/atom/ns#" term="Python" /><title>Speeding up Python code with Psyco</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/PQvzIGFBufuXXrl_adh_u5_FBgI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/PQvzIGFBufuXXrl_adh_u5_FBgI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/PQvzIGFBufuXXrl_adh_u5_FBgI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/PQvzIGFBufuXXrl_adh_u5_FBgI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt;&lt;span style=";font-family:times new roman;font-size:130%;"  &gt;Possibly the easiest way of speeding up Python code is to use &lt;/span&gt;&lt;span style="font-size:130%;"&gt;&lt;a style="font-family: times new roman;" href="http://psyco.sourceforge.net/introduction.html"&gt;Psyco&lt;/a&gt;&lt;/span&gt;&lt;span style=";font-family:times new roman;font-size:130%;"  &gt;. Psyco is extremely easy to use and it is at least worth a try before delving into C/C++ mess either directly or with the help of scipy.weave.&lt;/span&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:times new roman;font-size:130%;"  &gt;The usage is simple, just &lt;/span&gt;&lt;span style="font-size:130%;"&gt;&lt;a style="font-family: times new roman;" href="http://sourceforge.net/project/showfiles.php?group_id=41036"&gt;download Psyco&lt;/a&gt;&lt;/span&gt;&lt;span style=";font-family:times new roman;font-size:130%;"  &gt;, install it and add following to your code:&lt;/span&gt;&lt;/div&gt;&lt;pre&gt;import psyco&lt;br /&gt;psyco.full()&lt;br /&gt;&lt;/pre&gt;&lt;div style="text-align: justify;"&gt;&lt;span style=";font-family:times new roman;font-size:130%;"  &gt;The full() directive tells Psyco to optimize everything. I usually put these two lines to the beginning of the code, just after other imports. Psyco website states that possible speedups can be between 2x-100x. I have seen every number between 10% faster to 50x faster code execution.&lt;/span&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:times new roman;font-size:130%;"  &gt;The following is an example of very high acceleration of very simple code:&lt;/span&gt;&lt;/div&gt;&lt;pre&gt;def test(N, M):&lt;br /&gt;    res = []&lt;br /&gt;    for i in range(N):&lt;br /&gt;        for j in range(M):&lt;br /&gt;            if j == 0:&lt;br /&gt;                x = i*i*i&lt;br /&gt;                res.append(x)&lt;br /&gt;    return res&lt;br /&gt;&lt;/pre&gt;&lt;div style="text-align: justify;"&gt;&lt;span style=";font-family:times new roman;font-size:130%;"  &gt;Running this function with N = 10000 and M = 100000 takes ~60 seconds on Intel E8200 processor. After importing and running Psyco the very same code takes ~1.2 seconds. The speedup is then ~50x.&lt;/span&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:times new roman;font-size:130%;"  &gt;Psyco works &lt;/span&gt;&lt;span style=";font-family:times new roman;font-size:130%;"  &gt;best &lt;/span&gt;&lt;span style=";font-family:times new roman;font-size:130%;"  &gt;on functions which run at least couple of seconds per each call and are similar to the presented test function. Psyco only optimizes code within functions and &lt;del&gt;scripts&lt;/del&gt; classes but this isn't really a problem.&lt;br /&gt;To only optimize one function use&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;pre&gt;psyco.bind(yourfunctionname)&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3704048544762396176-7018546398572087997?l=codingmess.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingMess/~4/ScxYUtHbQ2I" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://codingmess.blogspot.com/feeds/7018546398572087997/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3704048544762396176&amp;postID=7018546398572087997" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3704048544762396176/posts/default/7018546398572087997?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3704048544762396176/posts/default/7018546398572087997?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodingMess/~3/ScxYUtHbQ2I/speeding-up-python-code-with-psyco.html" title="Speeding up Python code with Psyco" /><author><name>R.L.</name><uri>http://www.blogger.com/profile/14598815714075739940</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://codingmess.blogspot.com/2008/08/speeding-up-python-code-with-psyco.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUEERnc9eip7ImA9WxdaF0s.&quot;"><id>tag:blogger.com,1999:blog-3704048544762396176.post-3808816806660458197</id><published>2008-08-23T16:19:00.004+02:00</published><updated>2008-08-26T17:13:27.962+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-08-26T17:13:27.962+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="blogger" /><category scheme="http://www.blogger.com/atom/ns#" term="template" /><category scheme="http://www.blogger.com/atom/ns#" term="CSS" /><title>Improving blogger template style - Sand Dollar</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Cg_pZzXZaqRmzDdi7NkhAgiyuSU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Cg_pZzXZaqRmzDdi7NkhAgiyuSU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Cg_pZzXZaqRmzDdi7NkhAgiyuSU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Cg_pZzXZaqRmzDdi7NkhAgiyuSU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:times new roman;"&gt;There is something what I don't like on my currently selected blogger template style - the Sand Dollar. It spans all available screen real estate from left to right. I would like to make it fixed-width and centered.&lt;/span&gt; &lt;span style="font-family:times new roman;"&gt;To achieve this, I've changed the '#outer-wrapper' part of the template by adding 'width: 980px;'. This makes the rendered web page stay only 980 pixels wide which should be enough even on 1024 pixel wide common displays.&lt;br /&gt;To center web page contents, just add 'margin: 0 auto;' to the same section. This means in english: top and bottom margins are zero, left and right margins are set by browser (which means content will be centered). You can find the specifications of the margin command &lt;a href="http://www.w3schools.com/CSS/pr_margin.asp"&gt;here&lt;/a&gt;.&lt;/span&gt; &lt;span style="font-family:times new roman;"&gt;&lt;br /&gt;The entire outer-wrapper section now looks like this:&lt;/span&gt;&lt;/span&gt;&lt;pre&gt;&lt;br /&gt;#outer-wrapper {&lt;br /&gt;font:$bodyfont;&lt;br /&gt;width: 980px;&lt;br /&gt;margin: 0 auto;&lt;br /&gt;}&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3704048544762396176-3808816806660458197?l=codingmess.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingMess/~4/ehe3X1jhnUI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://codingmess.blogspot.com/feeds/3808816806660458197/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3704048544762396176&amp;postID=3808816806660458197" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3704048544762396176/posts/default/3808816806660458197?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3704048544762396176/posts/default/3808816806660458197?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodingMess/~3/ehe3X1jhnUI/improving-blogger-template-style-sand.html" title="Improving blogger template style - Sand Dollar" /><author><name>R.L.</name><uri>http://www.blogger.com/profile/14598815714075739940</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://codingmess.blogspot.com/2008/08/improving-blogger-template-style-sand.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU4FRH8yeip7ImA9WxRXFko.&quot;"><id>tag:blogger.com,1999:blog-3704048544762396176.post-701770455744009608</id><published>2008-08-21T18:39:00.011+02:00</published><updated>2008-10-22T14:18:35.192+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-10-22T14:18:35.192+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="installation" /><category scheme="http://www.blogger.com/atom/ns#" term="scipy" /><category scheme="http://www.blogger.com/atom/ns#" term="Python" /><category scheme="http://www.blogger.com/atom/ns#" term="Windows XP" /><title>scipy.weave doesn't work - compiler troubles</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/gGecQavTtXt34luc7KhUqtLL0PY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gGecQavTtXt34luc7KhUqtLL0PY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/gGecQavTtXt34luc7KhUqtLL0PY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gGecQavTtXt34luc7KhUqtLL0PY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:times new roman;"&gt;The &lt;a href="http://www.scipy.org/"&gt;scientific python package SciPy&lt;/a&gt; contains a very powerful library called weave. Weave enables one to relatively easily embed C/C++ code into Python code. Thus, if you happen to have a computationally intensive code you can gain a lot of speed by rewriting it in C/C++. There are a lot of ways of how to accomplish this but weave makes this feat relatively easy even for an amateur like me.&lt;br /&gt;There is however one caveate for Windows users. I commonly install all software into the 'C:\Program files\' directory. If you do this with Python and a weave requirement, &lt;a href="http://www.mingw.org/"&gt;MinGW&lt;/a&gt; compiler, weave will not work. The trouble is the space within directory name. Weave scripts and possibly also gcc are not written to deal with spaces within paths and will not find required files like gcc.exe. You will end up with error messages like:&lt;/span&gt;&lt;/span&gt;&lt;pre&gt;error: command 'gcc' failed: No such file or directory&lt;br /&gt;ValueError: The 'mingw32' compiler was not found.&lt;/pre&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:times new roman;"&gt;At first I have made a hack in the first affected script, the 'platform_info.py', but this only resulted in another error:&lt;/span&gt;&lt;/span&gt;&lt;pre&gt;Could not locate executable g++&lt;br /&gt;Executable g++ does not exist&lt;br /&gt;Traceback (most recent call last):&lt;br /&gt; File "G:\Temp\tmpfgm8bn\_ev-uq.py", line 8, in &lt;module&gt;&lt;br /&gt;   s,o = exec_command(cmd, _with_python=0, **{})&lt;br /&gt; File "C:\Program Files\Python25\lib\site-packages\numpy\distutils\exec_command.py", line 253, in exec_command&lt;br /&gt;   use_tee=use_tee,**env)&lt;br /&gt; File "C:\Program Files\Python25\lib\site-packages\numpy\distutils\exec_command.py", line 402, in _exec_command&lt;br /&gt;   so_dup = os.dup(so_fileno)&lt;br /&gt;OSError: [Errno 9] Bad file descriptor&lt;br /&gt;&lt;/module&gt;&lt;/pre&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:times new roman;"&gt;So, to make things short, just install Python and MinGW into C:\. This will save you from a lot of trouble.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;UPDATE 08/10/22:&lt;/span&gt; It turned out today that your user name also may not have a space within it. I've just spent an hour trying to get weave working on a colleague's computer where the username is actually a "user name". No, renaming the user does not do the trick. I 'solved' it by creating a new user with 'valid' username.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3704048544762396176-701770455744009608?l=codingmess.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingMess/~4/sDUUdX0bFQ4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://codingmess.blogspot.com/feeds/701770455744009608/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3704048544762396176&amp;postID=701770455744009608" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3704048544762396176/posts/default/701770455744009608?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3704048544762396176/posts/default/701770455744009608?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodingMess/~3/sDUUdX0bFQ4/scipyweave-doesnt-work-compiler.html" title="scipy.weave doesn't work - compiler troubles" /><author><name>R.L.</name><uri>http://www.blogger.com/profile/14598815714075739940</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total><feedburner:origLink>http://codingmess.blogspot.com/2008/08/scipyweave-doesnt-work-compiler.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEMGQH4-fyp7ImA9WxdaEUk.&quot;"><id>tag:blogger.com,1999:blog-3704048544762396176.post-7937082094238112611</id><published>2008-08-19T13:47:00.000+02:00</published><updated>2008-08-19T13:47:01.057+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-08-19T13:47:01.057+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Windows XP" /><title>Strange scipy.weave import error</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Rn_fK2OJdSuRSXM5rvMyUOCucSQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Rn_fK2OJdSuRSXM5rvMyUOCucSQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Rn_fK2OJdSuRSXM5rvMyUOCucSQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Rn_fK2OJdSuRSXM5rvMyUOCucSQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: times new roman;"&gt;Today, I've booted my PC and tried to run a script which uses scipy.weave package. What I got was a rather unusual error:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;EOFError: EOF read where object expected&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: times new roman;"&gt;I've tried to type&lt;/span&gt;&lt;/span&gt; &lt;pre&gt;import scipy.weave&lt;/pre&gt; &lt;span style="font-size:130%;"&gt;&lt;span style="font-family: times new roman;"&gt;which just reproduced the error. After some thinking I got an idea that some files were broken. A scipy reinstall however warned that some files are broken and cannot be (re)written. So I run the scandisk/chkdsk/whatever its name currently is. It did find some errors within files mentioned in the error message. Nonetheless the import still didn't work, this time replying with another error:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;ValueError: bad marshal data&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: times new roman;"&gt;After this I tried repairing both scipy and Python installations to no success. No warnings this time though.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: times new roman;"&gt;Finally, I uninstalled Python alltogether and deleted all files and directories within C:\Python25\. After installing everything back everything seems to fine allright. I think it is the first such error since I've started using NTFS as my filesystem some five or six years ago.&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3704048544762396176-7937082094238112611?l=codingmess.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingMess/~4/YOi1v-YmUDU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://codingmess.blogspot.com/feeds/7937082094238112611/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3704048544762396176&amp;postID=7937082094238112611" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3704048544762396176/posts/default/7937082094238112611?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3704048544762396176/posts/default/7937082094238112611?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodingMess/~3/YOi1v-YmUDU/strange-scipyweave-import-error.html" title="Strange scipy.weave import error" /><author><name>R.L.</name><uri>http://www.blogger.com/profile/14598815714075739940</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://codingmess.blogspot.com/2008/08/strange-scipyweave-import-error.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A04MQnw9cSp7ImA9WxdaEEg.&quot;"><id>tag:blogger.com,1999:blog-3704048544762396176.post-874130549888994233</id><published>2008-08-18T09:25:00.003+02:00</published><updated>2008-08-18T13:46:23.269+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-08-18T13:46:23.269+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Tkinter" /><category scheme="http://www.blogger.com/atom/ns#" term="Python" /><category scheme="http://www.blogger.com/atom/ns#" term="GUI" /><title>Text box with scrollbar</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/jfzGjonL1QeAhjQ2TtrPaSPTEGM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/jfzGjonL1QeAhjQ2TtrPaSPTEGM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/jfzGjonL1QeAhjQ2TtrPaSPTEGM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/jfzGjonL1QeAhjQ2TtrPaSPTEGM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;span style=";font-family:times new roman;font-size:130%;"  &gt;A very nice example can be found &lt;a href="http://www.java2s.com/Code/Python/GUI-Tk/TextwithScrollBar.htm"&gt;here&lt;/a&gt;.&lt;br /&gt;I you want to move focus so that the last entry in the text box will be visible, you may modify the code as follows:&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;import Tkinter&lt;br /&gt;&lt;br /&gt;root = Tkinter.Tk()&lt;br /&gt;s = Tkinter.Scrollbar(root)&lt;br /&gt;T = Tkinter.Text(root)&lt;br /&gt;&lt;br /&gt;T.focus_set()&lt;br /&gt;s.pack(side=Tkinter.RIGHT, fill=Tkinter.Y)&lt;br /&gt;T.pack(side=Tkinter.LEFT, fill=Tkinter.Y)&lt;br /&gt;s.config(command=T.yview)&lt;br /&gt;T.config(yscrollcommand=s.set)&lt;br /&gt;&lt;br /&gt;for i in range(40):&lt;br /&gt;   T.insert(Tkinter.END, "This is line %d\n" % i)&lt;br /&gt;   T.yview(Tkinter.MOVETO, 1.0)&lt;br /&gt;&lt;br /&gt;Tkinter.mainloop()&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:times new roman;"&gt;The 1.0 parameter of .yview means the end of the Text widget contents.&lt;br /&gt;I'm usually using the Grid geometry manager and aligning the scrollbar with it requires some more work than with pack. Nothing out of ordinary though.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3704048544762396176-874130549888994233?l=codingmess.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingMess/~4/YwUoIe7MvoI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://codingmess.blogspot.com/feeds/874130549888994233/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3704048544762396176&amp;postID=874130549888994233" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3704048544762396176/posts/default/874130549888994233?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3704048544762396176/posts/default/874130549888994233?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodingMess/~3/YwUoIe7MvoI/text-box-with-scrollbar.html" title="Text box with scrollbar" /><author><name>R.L.</name><uri>http://www.blogger.com/profile/14598815714075739940</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://codingmess.blogspot.com/2008/08/text-box-with-scrollbar.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUQDRHg8cSp7ImA9WxdbEUQ.&quot;"><id>tag:blogger.com,1999:blog-3704048544762396176.post-8250303465691837252</id><published>2008-08-08T11:15:00.002+02:00</published><updated>2008-08-08T13:02:55.679+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-08-08T13:02:55.679+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="files" /><category scheme="http://www.blogger.com/atom/ns#" term="I/O" /><category scheme="http://www.blogger.com/atom/ns#" term="Python" /><category scheme="http://www.blogger.com/atom/ns#" term="compression" /><title>Filenames, paths, .zip files and such in Python</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/oltGZu51V8Ac7EsgoAfHlNgp7Lg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/oltGZu51V8Ac7EsgoAfHlNgp7Lg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/oltGZu51V8Ac7EsgoAfHlNgp7Lg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/oltGZu51V8Ac7EsgoAfHlNgp7Lg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:times new roman;"&gt;It may be hard to believe but I've had troubles looking for a way how to split a path to a file into filename and the path to it. So here it is. Let's have a path such as this:&lt;/span&gt;&lt;/span&gt; &lt;pre&gt;'C:/Python25/python.exe'&lt;/pre&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:times new roman;"&gt;we want to separate a file name 'python.exe' from the path to it 'C:/Python25/'. With the help of a standard Python module os.path it is an easy task to do:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;import os.path&lt;br /&gt;mypath = 'C:/Python25/python.exe'&lt;br /&gt;separated = os.path.split(mypath)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style=";font-family:times new roman;font-size:130%;"  &gt;where 'separated' is a tuple with two items. First is the path, second is the filename.&lt;br /&gt;Do you also want to separate file name from its extension (e.g. '.exe' in our case)? It's easy:&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;name,extension = os.path.splitext(separated[1])&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family: times new roman;"&gt;Do you also want to reverse this process? Just call the os.path.join() function:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;completefilename = os.path.join(separated[0],separated[1])&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:times new roman;"&gt;Finally, I also wanted to compress some files to save disk space. There is a standard Python library called zipfile which supports creating .zip files (it also requires another library called zlib for compression of the .zip archives). Usage is simple:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;import zipfile&lt;br /&gt;f = zipfile.ZipFile( 'myfile.zip', 'w', compression = zipfile.ZIP_DEFLATED)&lt;br /&gt;f.write('mydata.txt')&lt;br /&gt;f.close()&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:times new roman;"&gt;The 'ZIP_DEFLATED' option tells the ZipFile class to compress the data, otherwise no compression is done.&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3704048544762396176-8250303465691837252?l=codingmess.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingMess/~4/7mVjCtx_64g" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://codingmess.blogspot.com/feeds/8250303465691837252/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3704048544762396176&amp;postID=8250303465691837252" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3704048544762396176/posts/default/8250303465691837252?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3704048544762396176/posts/default/8250303465691837252?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodingMess/~3/7mVjCtx_64g/filenames-paths-zip-files-and-such-in.html" title="Filenames, paths, .zip files and such in Python" /><author><name>R.L.</name><uri>http://www.blogger.com/profile/14598815714075739940</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://codingmess.blogspot.com/2008/08/filenames-paths-zip-files-and-such-in.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DE8NRX04fSp7ImA9WxdbEUU.&quot;"><id>tag:blogger.com,1999:blog-3704048544762396176.post-7097414110222432891</id><published>2008-07-28T09:19:00.007+02:00</published><updated>2008-08-08T11:14:54.335+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-08-08T11:14:54.335+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="domain" /><category scheme="http://www.blogger.com/atom/ns#" term="installation" /><category scheme="http://www.blogger.com/atom/ns#" term="Windows XP" /><title>Windows XP Home won't allow login after installation, domain error</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/knzhXLS7Qzueiz9HH0QuH2qnV3g/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/knzhXLS7Qzueiz9HH0QuH2qnV3g/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/knzhXLS7Qzueiz9HH0QuH2qnV3g/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/knzhXLS7Qzueiz9HH0QuH2qnV3g/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div  style="text-align: justify;font-family:times new roman;"&gt;&lt;span style="font-size:130%;"&gt;I've recently installed Windows XP Home to a computer which was previously equipped with Win XP Professional. There was a minor glitch during the installation when the installer refused to delete the C: partition because there were some installation files present. This was possibly caused by inserting the install CD into running computer, the installer then copied some files into C: and expected to put Windows on a D: or E: partition. After reset a new installation started and run OK. Unfortunately, I couldn't log in into the machine although I haven't set any password for the only user account set up during installation. The message was "Domain does not Exist" with "smart" advice to contact system administrator. I've found several questions posted on the web regarding the same problem but no real answer to the problem. The trouble is, I have not set up any domain and Win XP Home officially does not even support domains!&lt;br /&gt;My conclusion was that the installer somehow picked up some remnants of the previous Win XP Pro system (which does support domains but on this PC was not using them) and malfunctioned.&lt;br /&gt;&lt;br /&gt;So I've done a reinstall with following steps:&lt;br /&gt;1) format not only C: but also D: partitions;&lt;br /&gt;2) full format on C: to NTFS before system installation begins (i.e. not the fast formatting option); it takes about 12 minutes on a 50 GB partition;&lt;br /&gt;3) different user name from the previous (XP Pro) system.&lt;br /&gt;&lt;br /&gt;I'm not sure whether these steps are all necessary or which one did the trick but after second installation everything works as it should.&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3704048544762396176-7097414110222432891?l=codingmess.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingMess/~4/8gOn6rIeIVg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://codingmess.blogspot.com/feeds/7097414110222432891/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3704048544762396176&amp;postID=7097414110222432891" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3704048544762396176/posts/default/7097414110222432891?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3704048544762396176/posts/default/7097414110222432891?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodingMess/~3/8gOn6rIeIVg/windows-xp-home-wont-allow-login-after.html" title="Windows XP Home won't allow login after installation, domain error" /><author><name>R.L.</name><uri>http://www.blogger.com/profile/14598815714075739940</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://codingmess.blogspot.com/2008/07/windows-xp-home-wont-allow-login-after.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D04EQXo-fyp7ImA9WxdWF00.&quot;"><id>tag:blogger.com,1999:blog-3704048544762396176.post-6898149289075693452</id><published>2008-07-10T18:05:00.001+02:00</published><updated>2008-07-10T18:05:00.457+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-07-10T18:05:00.457+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="images" /><category scheme="http://www.blogger.com/atom/ns#" term="Tkinter" /><category scheme="http://www.blogger.com/atom/ns#" term="Python" /><category scheme="http://www.blogger.com/atom/ns#" term="GUI" /><title>Showing a webcam image in the desktop window using Python. Part 3: self-refreshing app</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/xqYdnqm_zmqol7epdEEf7EmF0JE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/xqYdnqm_zmqol7epdEEf7EmF0JE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/xqYdnqm_zmqol7epdEEf7EmF0JE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/xqYdnqm_zmqol7epdEEf7EmF0JE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:times new roman;"&gt;This is the last part of a three-part series. In the first part, I've described &lt;/span&gt;&lt;a style="font-family: times new roman;" href="http://codingmess.blogspot.com/2008/07/showing-webcam-image-in-desktop-window.html"&gt;how to read image from the web&lt;/a&gt;&lt;span style="font-family:times new roman;"&gt;. The second part was dedicated to &lt;a href="http://codingmess.blogspot.com/2008/07/showing-webcam-image-in-desktop-window_08.html"&gt;showing images in a window on the desktop&lt;/a&gt;. This last part will deal with auto-refreshing of the displayed image. This is particularly useful when you want to display a webcam image which is regularly updated.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:times new roman;"&gt;To handle autorefresh we will use a Tkinter method after() which will call a defined function after some given delay.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:times new roman;"&gt;To the previous code, we will add the following function:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;def timingloop(start=0):&lt;br /&gt;  now = time.clock()&lt;br /&gt;  if start == 1:&lt;br /&gt;      getimagefromweb(myurl)&lt;br /&gt;  if now &gt; container.start + container.refresh:&lt;br /&gt;      getimagefromweb(myurl)&lt;br /&gt;      container.start = now&lt;br /&gt;  else:&lt;br /&gt;      remains = str(int(container.refresh - now + container.start))&lt;br /&gt;      message = 'Next update in '+remains+' seconds.'&lt;br /&gt;      container.statusbarVar.set(message)&lt;br /&gt;      container.statusbar.update()&lt;br /&gt;  container.main.after(200, timingloop)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:times new roman;"&gt;This function controls downloading new images by calling getimagefromweb() and checks when to do it by comparing saved times with current time. Finally, the function calls itself after 200 miliseconds.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:times new roman;"&gt;For the program to work you also have to add some other stuff into the code. To the beginning add "&lt;span style="font-size:100%;"&gt;&lt;span style="font-family:courier new;"&gt;import time&lt;/span&gt;&lt;/span&gt;" to import time library. The last part of the script has to be slightly modified as follows:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;# the script&lt;br /&gt;myurl = 'http://siemens.mesto-zatec.cz/obrazek.jpg'&lt;br /&gt;container = Container()&lt;br /&gt;container.width = 800&lt;br /&gt;container.height = 602&lt;br /&gt;&lt;br /&gt;container.start = time.clock()&lt;br /&gt;container.refresh = 20 # window refresh rate in seconds&lt;br /&gt;&lt;br /&gt;drawwindow()&lt;br /&gt;timingloop(1)&lt;br /&gt;&lt;br /&gt;mainloop()&lt;br /&gt;print 'end OK'&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:times new roman;"&gt;We have added two new variables with timestamp and a refresh rate in seconds after which the image will be re-loaded. Finally, the getimagefromweb() function has been replaced by the timingloop() with parameter "1" which tells it that it is the start of the program and that it should load the image immediately. After the first timingloop() there is enough time to call mainloop() without which the program hangs (and I'm not sure why). As you can see using after() is a bit unintuitive because you can call other functions after "after()" was called and is still running in the background.&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3704048544762396176-6898149289075693452?l=codingmess.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingMess/~4/825S-iKDy7A" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://codingmess.blogspot.com/feeds/6898149289075693452/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3704048544762396176&amp;postID=6898149289075693452" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3704048544762396176/posts/default/6898149289075693452?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3704048544762396176/posts/default/6898149289075693452?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodingMess/~3/825S-iKDy7A/showing-webcam-image-in-desktop-window_10.html" title="Showing a webcam image in the desktop window using Python. Part 3: self-refreshing app" /><author><name>R.L.</name><uri>http://www.blogger.com/profile/14598815714075739940</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://codingmess.blogspot.com/2008/07/showing-webcam-image-in-desktop-window_10.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUUHRXYyeip7ImA9WxdWFU0.&quot;"><id>tag:blogger.com,1999:blog-3704048544762396176.post-2364661964546076815</id><published>2008-07-08T06:14:00.002+02:00</published><updated>2008-07-08T10:53:54.892+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-07-08T10:53:54.892+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="images" /><category scheme="http://www.blogger.com/atom/ns#" term="Tkinter" /><category scheme="http://www.blogger.com/atom/ns#" term="Python" /><category scheme="http://www.blogger.com/atom/ns#" term="GUI" /><title>Showing a webcam image in the desktop window using Python. Part 2: displaying images in windows</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/rUjSfYmRSxAXqKNjMRD2x5pfvlM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/rUjSfYmRSxAXqKNjMRD2x5pfvlM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/rUjSfYmRSxAXqKNjMRD2x5pfvlM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/rUjSfYmRSxAXqKNjMRD2x5pfvlM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:times new roman;"&gt;In the previous post I have shown how to &lt;/span&gt;&lt;a style="font-family: times new roman;" href="http://codingmess.blogspot.com/2008/07/showing-webcam-image-in-desktop-window.html"&gt;download an image from web with the use of Python&lt;/a&gt;&lt;span style="font-family:times new roman;"&gt;. Today I will show code which takes this image and draws it in a standalone window.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:times new roman;"&gt;Before we start it is necessary to be prepared somewhat. You need a specialised library to make windows. I 'm using Tkinter which comes with Python as default. There are more options like &lt;/span&gt;&lt;a style="font-family: times new roman;" href="http://www.wxpython.org/download.php"&gt;wxwidgets&lt;/a&gt;&lt;span style="font-family:times new roman;"&gt; but I've started with Tkinter and so far it has covered all my needs. It seemed quite tricky to learn so I have found a good tutorial on Tkinter and learned it that way. Unfortunately, it is only in czech and currently seems offline so I cannot link to it anyway :-(.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:times new roman;"&gt;To deal with images I'm using the &lt;/span&gt;&lt;a style="font-family: times new roman;" href="http://www.pythonware.com/products/pil/"&gt;PIL or Python Imaging Library&lt;/a&gt;&lt;span style="font-family:times new roman;"&gt;. This you will need to download and install in order to use following code. Good news is that it's free :-)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:times new roman;"&gt;Programming windowed applications is a lot more complicated than simple beginner stuff and in today's code there are commands which I don't know why they are there...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:times new roman;"&gt;The code:&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;pre&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;from Tkinter import *&lt;br /&gt;import urllib&lt;br /&gt;from PIL import Image, ImageTk&lt;br /&gt;&lt;br /&gt;class Container:&lt;br /&gt;    pass&lt;br /&gt;&lt;br /&gt;def drawwindow():&lt;br /&gt;    main = Tk()&lt;br /&gt;    main.title('Zatec webcam')      # window title&lt;br /&gt;    main.resizable(width=False, height=False)&lt;br /&gt;    container.main = main&lt;br /&gt;    container.canvas = Canvas(main, width=container.width, height=container.height)&lt;br /&gt;    container.canvas.pack(expand=1, fill=BOTH)&lt;br /&gt;    container.statusbarVar = StringVar()&lt;br /&gt;    container.statusbar = Label(main, textvariable=container.statusbarVar)&lt;br /&gt;    container.statusbar.pack()&lt;br /&gt;    container.statusbarVar.set('Ready.')&lt;br /&gt;    container.statusbar.update()&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;def showimage(image):&lt;br /&gt;    '''Loads given image and puts it into the window'''&lt;br /&gt;    img = Image.open(image)&lt;br /&gt;    photo = ImageTk.PhotoImage(img)&lt;br /&gt;    container.canvas.create_image(container.width/2+2, container.height/2, image=photo)&lt;br /&gt;    container.obr = photo # why is this line necessary?&lt;br /&gt;&lt;br /&gt;def getimagefromweb(url):&lt;br /&gt;    '''Downloads content from given url and saves it as image.'''&lt;br /&gt;    container.statusbarVar.set('Reading new image from web...')&lt;br /&gt;    container.statusbar.update()&lt;br /&gt;    try:&lt;br /&gt;      u = urllib.urlopen(url) # open url&lt;br /&gt;      container.statusbarVar.set('Url opened...')&lt;br /&gt;      container.statusbar.update()&lt;br /&gt;&lt;br /&gt;      content = u.read()      # read the opened url&lt;br /&gt;      container.statusbarVar.set('Url read...')&lt;br /&gt;      container.statusbar.update()&lt;br /&gt;&lt;br /&gt;      u.close()               # url was closed&lt;br /&gt;      container.statusbarVar.set('Url closed...')&lt;br /&gt;      container.statusbar.update()&lt;br /&gt;&lt;br /&gt;    except IOError:&lt;br /&gt;      print('IOError')&lt;br /&gt;      pass&lt;br /&gt;    except:&lt;br /&gt;      print('Unknown url error')&lt;br /&gt;&lt;br /&gt;    # saving what was downloaded&lt;br /&gt;    f = open('img.jpg','wb')&lt;br /&gt;    f.write(content)&lt;br /&gt;    f.close()   # file was closed&lt;br /&gt;    &lt;br /&gt;    # showing the image&lt;br /&gt;    showimage('img.jpg')&lt;br /&gt;    container.statusbarVar.set('Ready.')&lt;br /&gt;    container.statusbar.update()&lt;br /&gt;&lt;br /&gt;# the script&lt;br /&gt;myurl = 'http://siemens.mesto-zatec.cz/obrazek.jpg'&lt;br /&gt;container = Container()&lt;br /&gt;container.width = 800&lt;br /&gt;container.height = 602&lt;br /&gt;&lt;br /&gt;drawwindow()&lt;br /&gt;getimagefromweb(myurl)&lt;br /&gt;&lt;br /&gt;mainloop()&lt;br /&gt;print 'end OK'&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:times new roman;"&gt;The class Container is used to store information which is passed between functions. The code could be rewritten to form a single class but it works this way too :-).&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:times new roman;"&gt;There are three functions. Drawwindow is used to create window with desired elements in it (Canvas and Label). To provide some info on download status there is a text in the Label. This is done with the help of StringVar() which is from Tkinter library. If we used only a string, it would be immutable later on. After the Label is changed, an .update() function must be called to change it on the display too.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:times new roman;"&gt;The showimage() function gets an image file from disk and puts it into the Canvas. There is some magic in it, sorry about that.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:times new roman;"&gt;The third function, getimagefromweb(), is adopted from previous post by adding info into the Label and after the image saved it calls the showimage() function.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:times new roman;"&gt;In the script, we first draw the window elements with drawwindow() and then download an image and paste it into the Canvas with  getimagefromweb().&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:times new roman;"&gt;The last command, mainloop(), tells Tkinter that we are ready and draws everything on the display. Without this command nothing will be shown (though it will be ready). Also, after mainloop is called, the focus is changed from your script to the GUI which is driven by user action. After you close the window the focus is returned to your python script.&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3704048544762396176-2364661964546076815?l=codingmess.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingMess/~4/UsSKJUlE0nI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://codingmess.blogspot.com/feeds/2364661964546076815/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3704048544762396176&amp;postID=2364661964546076815" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3704048544762396176/posts/default/2364661964546076815?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3704048544762396176/posts/default/2364661964546076815?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodingMess/~3/UsSKJUlE0nI/showing-webcam-image-in-desktop-window_08.html" title="Showing a webcam image in the desktop window using Python. Part 2: displaying images in windows" /><author><name>R.L.</name><uri>http://www.blogger.com/profile/14598815714075739940</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://codingmess.blogspot.com/2008/07/showing-webcam-image-in-desktop-window_08.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0cBSHkzfCp7ImA9WxdWE0g.&quot;"><id>tag:blogger.com,1999:blog-3704048544762396176.post-6882976794688945204</id><published>2008-07-06T10:23:00.018+02:00</published><updated>2008-07-06T15:30:59.784+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-07-06T15:30:59.784+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="urllib" /><category scheme="http://www.blogger.com/atom/ns#" term="images" /><category scheme="http://www.blogger.com/atom/ns#" term="web" /><category scheme="http://www.blogger.com/atom/ns#" term="Python" /><title>Showing a webcam image in the desktop window using Python. Part 1: reading image from web</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/cNUo_KzZgn4fGnosCYcTWQ044Ww/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/cNUo_KzZgn4fGnosCYcTWQ044Ww/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/cNUo_KzZgn4fGnosCYcTWQ044Ww/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/cNUo_KzZgn4fGnosCYcTWQ044Ww/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:times new roman;"&gt;I will describe everything that is necessary to show a window with a webcam (or any other) image in it. I'm using similar app to display a stock price chart (downloaded from a website) which is regularly updated. I will divide the text into three parts because I think this will be easier to grasp than one large article. This part will deal with downloading web content, in the second one the content will be displayed and in the third, final, one I will cover the self-refreshing which was the most difficult to figure out.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:times new roman;"&gt;Again, I believe there is more than one way to do it. What follows is how I solved it.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:times new roman;"&gt;There is a nice built-in library in Python called urllib which we will use to download the image in question.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:times new roman;"&gt;The code is simple:&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;pre&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;import urllib&lt;br /&gt;&lt;br /&gt;def getimagefromweb(url):&lt;br /&gt;   '''Downloads content from given url and saves it as image.'''&lt;br /&gt;   try:&lt;br /&gt;       u = urllib.urlopen(url) # open url&lt;br /&gt;       content = u.read()      # read the openned url&lt;br /&gt;       u.close()               # url was closed&lt;br /&gt;&lt;br /&gt;   except IOError:&lt;br /&gt;       print('IOError')&lt;br /&gt;   except:&lt;br /&gt;       print('Unknown url error')&lt;br /&gt;&lt;br /&gt;   # saving what was downloaded&lt;br /&gt;   f = open('img.jpg','wb')&lt;br /&gt;   f.write(content)&lt;br /&gt;   f.close()   # file was closed&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;myurl = 'http://siemens.mesto-zatec.cz/obrazek.jpg'&lt;br /&gt;getimagefromweb(myurl)&lt;br /&gt;print 'all OK'&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;&lt;span style="font-family:times new roman;"&gt;The (only) function "getimagefromweb" receives a url with content to be downloaded and then reads from this adress in the same way that is used when reading/writing files. When dealing with web it is very advisable to use error-catching code like this one. It is common that the website will not respond in time and without error catching your application would crash.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:times new roman;"&gt;As a final task the function saves image to harddisk so that it can be later re-read and shown on the desktop. This is a workaroud because I could not figure out a way how to display it directly.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:times new roman;"&gt;The url leads to the &lt;/span&gt;&lt;a style="font-family: times new roman;" href="http://siemens.mesto-zatec.cz/webcam.html"&gt;webcam of the main square&lt;/a&gt;&lt;span style="font-family:times new roman;"&gt; of the &lt;/span&gt;&lt;a style="font-family: times new roman;" href="http://english.mesto-zatec.cz/"&gt;Zatec city&lt;/a&gt;&lt;span style="font-family:times new roman;"&gt; where I was born and have grown up. It has quite interesting medieval centre so its nice to have it shown on desktop :-)&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3704048544762396176-6882976794688945204?l=codingmess.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingMess/~4/VhFwXBaU95E" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://codingmess.blogspot.com/feeds/6882976794688945204/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3704048544762396176&amp;postID=6882976794688945204" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3704048544762396176/posts/default/6882976794688945204?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3704048544762396176/posts/default/6882976794688945204?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodingMess/~3/VhFwXBaU95E/showing-webcam-image-in-desktop-window.html" title="Showing a webcam image in the desktop window using Python. Part 1: reading image from web" /><author><name>R.L.</name><uri>http://www.blogger.com/profile/14598815714075739940</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://codingmess.blogspot.com/2008/07/showing-webcam-image-in-desktop-window.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A08FRnwzeyp7ImA9WxBVF0s.&quot;"><id>tag:blogger.com,1999:blog-3704048544762396176.post-6004702944325417805</id><published>2008-07-04T06:15:00.007+02:00</published><updated>2010-02-21T17:30:17.283+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-02-21T17:30:17.283+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="sound" /><category scheme="http://www.blogger.com/atom/ns#" term="wave" /><category scheme="http://www.blogger.com/atom/ns#" term="Python" /><category scheme="http://www.blogger.com/atom/ns#" term="numpy" /><title>How to make a simple .wav file with Python</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/HdbKcSSrlNSwkZN-0wO3i8IMHSs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/HdbKcSSrlNSwkZN-0wO3i8IMHSs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/HdbKcSSrlNSwkZN-0wO3i8IMHSs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/HdbKcSSrlNSwkZN-0wO3i8IMHSs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;span style=";font-family:times new roman;font-size:130%;"  &gt;&lt;span style="font-weight: bold;"&gt;EDIT: I've edited this code a little and incorporated reader's comments, &lt;/span&gt;&lt;a style="font-weight: bold;" href="http://codingmess.blogspot.com/2010/02/how-to-make-wav-file-with-python.html"&gt;here's the new version&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I've recently had an idea to test some vibration-resonance problems by playing a set of sounds and detecting the vibrations in question. The glitch is, how to create a sound of desired frequency? I believe there is a lot of ways to solve this but having only a hammer (read Python) as my tool it looked like a nail ;-)&lt;/span&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:times new roman;font-size:130%;"  &gt;The idea is then to create a simple sine wave and play it back with a computer. My first try was with &lt;/span&gt;&lt;span style="font-size:130%;"&gt;&lt;a style="font-family: times new roman;" href="http://www.pygame.org/wiki/about"&gt;pygame&lt;/a&gt;&lt;/span&gt;&lt;span style=";font-family:times new roman;font-size:130%;"  &gt; module but the sound quality was poor and unsatisfactory.&lt;/span&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:times new roman;font-size:130%;"  &gt;If not playing sound directly one can write the wave to the file and then play the file with whatever means are suitable. This turned out to be the better way after all.&lt;/span&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:times new roman;font-size:130%;"  &gt;A search of the internet turned up this discussion of &lt;/span&gt;&lt;span style="font-size:130%;"&gt;&lt;a style="font-family: times new roman;" href="http://mail.python.org/pipermail/python-list/2004-September/284204.html"&gt;creating .wav files with Python&lt;/a&gt;&lt;/span&gt;&lt;span style=";font-family:times new roman;font-size:130%;"  &gt;. I've adopted the "minimal example" from there (written by Andrea Valle&lt;/span&gt;&lt;span style=";font-family:times new roman;font-size:130%;"  &gt;) to be usable with modern modules (it used obsolete Numeric and RandomArray modules).&lt;/span&gt;&lt;span style="font-size:130%;"&gt; &lt;/span&gt;&lt;span style=";font-family:times new roman;font-size:130%;"  &gt;The code is not neat but it works well.&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;import numpy as N&lt;br /&gt;import wave&lt;br /&gt;&lt;br /&gt;class SoundFile:&lt;br /&gt;   def  __init__(self, signal):&lt;br /&gt;       self.file = wave.open('test.wav', 'wb')&lt;br /&gt;       self.signal = signal&lt;br /&gt;       self.sr = 44100&lt;br /&gt;&lt;br /&gt;   def write(self):&lt;br /&gt;       self.file.setparams((1, 2, self.sr, 44100*4, 'NONE', 'noncompressed'))&lt;br /&gt;       self.file.writeframes(self.signal)&lt;br /&gt;       self.file.close()&lt;br /&gt;&lt;br /&gt;# let's prepare signal&lt;br /&gt;duration = 4 # seconds&lt;br /&gt;samplerate = 44100 # Hz&lt;br /&gt;samples = duration*samplerate&lt;br /&gt;frequency = 440 # Hz&lt;br /&gt;period = samplerate / float(frequency) # in sample points&lt;br /&gt;omega = N.pi * 2 / period&lt;br /&gt;&lt;br /&gt;xaxis = N.arange(int(period),dtype = N.float) * omega&lt;br /&gt;ydata = 16384 * N.sin(xaxis)&lt;br /&gt;&lt;br /&gt;signal = N.resize(ydata, (samples,))&lt;br /&gt;&lt;br /&gt;ssignal = ''&lt;br /&gt;for i in range(len(signal)):&lt;br /&gt;   ssignal += wave.struct.pack('h',signal[i]) # transform to binary&lt;br /&gt;&lt;br /&gt;f = SoundFile(ssignal)&lt;br /&gt;f.write()&lt;br /&gt;print 'file written'&lt;br /&gt;&lt;/pre&gt;&lt;span style=";font-family:times new roman;font-size:130%;"  &gt;This code should work as intended and produce .wav files of given length and frequency. A few comments:&lt;/span&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:times new roman;font-size:130%;"  &gt;a) if you need different sampling frequencies, just replace all &lt;span style="font-family:courier new;"&gt;44100&lt;/span&gt; numbers with desired sampling frequency;&lt;/span&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:times new roman;font-size:130%;"  &gt;b) the &lt;span style="font-family:courier new;"&gt;setparams&lt;/span&gt; command is relatively well described in &lt;span style="font-family:courier new;"&gt;wave&lt;/span&gt; doc in Python help, its fourth parameter (&lt;span style="font-family:courier new;"&gt;nframes&lt;/span&gt;) may probably be whatever number you want, the procedure is designed to write all data you sent to it;&lt;/span&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:times new roman;font-size:130%;"  &gt;c) the &lt;span style="font-family:courier new;"&gt;16384&lt;/span&gt; number seems to be a volume setting for .wav file, this value is near the maximum so only lowering the volume is possible from here;&lt;/span&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:times new roman;font-size:130%;"  &gt;d) &lt;span style="font-family:courier new;"&gt;wave.struct.pack('h', #) &lt;/span&gt;- this was tough to find but without this command the resulting file will not be correct (at least on Windows machines)&lt;/span&gt;&lt;span style="font-size:130%;"&gt;,&lt;/span&gt;&lt;span style=";font-family:times new roman;font-size:130%;"  &gt; I do not yet understand what it does...&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3704048544762396176-6004702944325417805?l=codingmess.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingMess/~4/xKVZUx0iEnU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://codingmess.blogspot.com/feeds/6004702944325417805/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3704048544762396176&amp;postID=6004702944325417805" title="14 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3704048544762396176/posts/default/6004702944325417805?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3704048544762396176/posts/default/6004702944325417805?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodingMess/~3/xKVZUx0iEnU/how-to-make-simple-wav-file-with-python.html" title="How to make a simple .wav file with Python" /><author><name>R.L.</name><uri>http://www.blogger.com/profile/14598815714075739940</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>14</thr:total><feedburner:origLink>http://codingmess.blogspot.com/2008/07/how-to-make-simple-wav-file-with-python.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkMCQ3gzeyp7ImA9WxdWEEo.&quot;"><id>tag:blogger.com,1999:blog-3704048544762396176.post-2918048661312965663</id><published>2008-07-03T09:54:00.006+02:00</published><updated>2008-07-03T10:41:02.683+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-07-03T10:41:02.683+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="admin" /><title>Introductory and testing first post</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/SWNDNR-g9-RjB6NghLwfWxZFT9k/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/SWNDNR-g9-RjB6NghLwfWxZFT9k/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/SWNDNR-g9-RjB6NghLwfWxZFT9k/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/SWNDNR-g9-RjB6NghLwfWxZFT9k/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div  style="text-align: justify;font-family:times new roman;"&gt;&lt;span style="font-size:130%;"&gt;Hello there, whoever reads this!&lt;br /&gt;I've started this blog to collect my dilluted and unorganized programming and general computer knowledge. I'm not a full time programmer and all of my coding skills were self-taught. There are long periods of time when I'm not coding and having bad memory this causes me to forget anything I've ever known. After a year without programming I usually even forget the basic language commands and syntax.&lt;br /&gt;This site is dedicated to preserving some of my present knowledge for future reference by anybody who may be interested in it.&lt;br /&gt;I've a long history of programming languages including &lt;a href="http://en.wikipedia.org/wiki/BASIC_programming_language"&gt;Basic&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Pascal_%28programming_language%29"&gt;Pascal&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/C_%28programming_language%29"&gt;C/C++&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Matlab"&gt;Matlab&lt;/a&gt; and, more recently, &lt;a href="http://en.wikipedia.org/wiki/Python_%28programming_language%29"&gt;Python&lt;/a&gt;.&lt;br /&gt;I'm currently a scientist-in-training and I've found Matlab to be a very fine and powerful tool. Unfortunately the price is quite prohibitive for occasionally used software and for random playing. I believe Python is a very good replacement of Matlab (at least for most of my purposes) and recommend it to anyone who might appreciate simple syntax, fast development and high portability. In connection with some add-on modules like &lt;a href="http://www.scipy.org/"&gt;SciPy&lt;/a&gt; I believe it can compete with Matlab on even grounds.&lt;br /&gt;As a sideline I also intend to use this blog to learn some web-creating skills.&lt;br /&gt;That'll be all for now.&lt;br /&gt;R.L.&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3704048544762396176-2918048661312965663?l=codingmess.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodingMess/~4/EXmrLsBKBg0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://codingmess.blogspot.com/feeds/2918048661312965663/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3704048544762396176&amp;postID=2918048661312965663" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3704048544762396176/posts/default/2918048661312965663?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3704048544762396176/posts/default/2918048661312965663?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodingMess/~3/EXmrLsBKBg0/introductory-and-testing-first-post.html" title="Introductory and testing first post" /><author><name>R.L.</name><uri>http://www.blogger.com/profile/14598815714075739940</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://codingmess.blogspot.com/2008/07/introductory-and-testing-first-post.html</feedburner:origLink></entry></feed>

