tag:blogger.com,1999:blog-31179429033388412502024-02-18T17:44:42.009-08:00taixzo's blogtaixzohttp://www.blogger.com/profile/14616222527114166282noreply@blogger.comBlogger6125tag:blogger.com,1999:blog-3117942903338841250.post-23735331945779147672015-05-25T20:03:00.000-07:002015-05-25T20:03:09.470-07:00Dynamically creating dictionaries for Julius with eSpeakIn working to port <a href="http://talk.maemo.org/showthread.php?t=84753" target="_blank">Saera</a> to the Jolla, I wanted to add a feature that is quite useful for a voice control program: the ability to play a song by name. The issue with this is that song names tend to use many words which are not in the VoxForge dictionaries, and certainly too many to create into a grammar by hand. But there is a piece of software that I am using already, which creates pronunciations for arbitrary words: <a href="http://espeak.sourceforge.net/" target="_blank">eSpeak</a>! It turns out that when given the -x flag, eSpeak outputs the phonemes that it creates. For example:<br />
<blockquote class="tr_bq">
<span style="font-family: "Courier New",Courier,monospace;">$ espeak -x america</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> a#m'ErIk@</span><br />
<span style="font-family: "Courier New",Courier,monospace;">$</span></blockquote>
But there is a problem here: those are eSpeak phonemes, not Julius phonemes. Julius would define the pronunciation of "america" as:<br />
<blockquote class="tr_bq">
<span style="font-family: "Courier New",Courier,monospace;">ax m eh r ax k ax</span></blockquote>
I couldn't find a straightforward mapping from one to the other, so I created one:<br />
<br />
<table style="font-family: "Courier New",Courier,monospace;"><tbody>
<tr><td>eSpeak</td> <td>Julius</td></tr>
<tr><td>O@r-'</td> <td>er</td></tr>
<tr><td>aI@</td> <td>ay ax</td></tr>
<tr><td>aU@</td> <td>aw er</td></tr>
<tr><td>O@r</td> <td>ao r</td></tr>
<tr><td>nkI</td> <td>ng k iy</td></tr>
<tr><td>tS</td> <td>ch</td></tr>
<tr><td>dZ</td> <td>jh</td></tr>
<tr><td>@L</td> <td>ax l</td></tr>
<tr><td>@2</td> <td>ax</td></tr>
<tr><td>@5</td> <td>uw</td></tr>
<tr><td>@r</td> <td>er</td></tr>
<tr><td>3:</td> <td>er</td></tr>
<tr><td>3r</td> <td>er</td></tr>
<tr><td>aa</td> <td>ae</td></tr>
<tr><td>a#</td> <td>ax</td></tr>
<tr><td>A:</td> <td>aa</td></tr>
<tr><td>A@</td> <td>aa r</td></tr>
<tr><td>e@</td> <td>eh r</td></tr>
<tr><td>I2</td> <td>ix</td></tr>
<tr><td>i:</td> <td>iy</td></tr>
<tr><td>i@</td> <td>ih</td></tr>
<tr><td>u:</td> <td>uw</td></tr>
<tr><td>U@</td> <td>uh r</td></tr>
<tr><td>O:</td> <td>ao</td></tr>
<tr><td>O@</td> <td>ao r</td></tr>
<tr><td>o@</td> <td>ao r</td></tr>
<tr><td>aI</td> <td>ay</td></tr>
<tr><td>eI</td> <td>ey</td></tr>
<tr><td>OI</td> <td>oy</td></tr>
<tr><td>aU</td> <td>aw</td></tr>
<tr><td>oU</td> <td>ow</td></tr>
<tr><td>tt</td> <td>t</td></tr>
<tr><td>b</td> <td>b</td></tr>
<tr><td>d</td> <td>d</td></tr>
<tr><td>f</td> <td>f</td></tr>
<tr><td>g</td> <td>g</td></tr>
<tr><td>h</td> <td>hh</td></tr>
<tr><td>k</td> <td>k</td></tr>
<tr><td>l</td> <td>l</td></tr>
<tr><td>m</td> <td>m</td></tr>
<tr><td>n</td> <td>n</td></tr>
<tr><td>N</td> <td>ng</td></tr>
<tr><td>p</td> <td>p</td></tr>
<tr><td>r</td> <td>r</td></tr>
<tr><td>s</td> <td>s</td></tr>
<tr><td>S</td> <td>sh</td></tr>
<tr><td>Z</td> <td>zh</td></tr>
<tr><td>t</td> <td>t</td></tr>
<tr><td>T</td> <td>th</td></tr>
<tr><td>D</td> <td>dh</td></tr>
<tr><td>v</td> <td>v</td></tr>
<tr><td>j</td> <td>y</td></tr>
<tr><td>w</td> <td>w</td></tr>
<tr><td>z</td> <td>z</td></tr>
<tr><td>@</td> <td>ax</td></tr>
<tr><td>3</td> <td>er</td></tr>
<tr><td>a</td> <td>ae</td></tr>
<tr><td>E</td> <td>eh</td></tr>
<tr><td>I</td> <td>ih</td></tr>
<tr><td>i</td> <td>iy</td></tr>
<tr><td>0</td> <td>aa</td></tr>
<tr><td>V</td> <td>ah</td></tr>
<tr><td>U</td> <td>uh</td></tr>
<tr><td>'</td>
</tr>
<tr><td>,</td>
</tr>
<tr><td>;</td>
</tr>
<tr><td>:</td>
</tr>
<tr><td>-</td>
</tr>
<tr><td>!</td>
</tr>
<tr><td>_
</td></tr>
</tbody></table>
<br />
<br />
<br />
Now the only thing left was to create a Julius grammar out of the generated phonemes.
taixzohttp://www.blogger.com/profile/14616222527114166282noreply@blogger.com0tag:blogger.com,1999:blog-3117942903338841250.post-75885105227046837842012-12-18T17:40:00.000-08:002012-12-18T18:14:42.285-08:00Python in Qt CreatorI've been recently working to port <a href="http://talk.maemo.org/showthread.php?t=84753" target="_blank">Saera</a> to the N9, which means I have to use Qt. After a few dead ends, I decided to try building a few of the Qt sample apps to get a feel for how it was supposed to work. I learned how to use Qt Creator, how to pair with a device, and how to write a simple QML app. I decided to move on to the project itself - and ran into a large hurdle to clear: Qt Creator doesn't support Python.<br />
Or rather, it does, but only as a filetype; there isn't a way to tell Qt Creator to use a Python file as the main executable rather than the C++ file it automatically generates. I didn't really want to have to port Saera to C, so I went searching for a workaround. It turns out there is <a href="http://code.google.com/p/qt-creator-python/" target="_blank">a fork of Qt Creator with Python support</a>; however, I couldn't get it to compile properly on my system. And Google wasn't much help; most of the results I found were basically saying "If you want to use Python, you can't have the convenience of Qt Creator, but rather you have to do the whole thing manually."<br />
However, I found a workaround: Leave the C++ in there, but rather than having it load and run the QML, have it load the Python file itself, and just run that. For those who are interested, here's my code:<br />
<br />
C++:<br />
<blockquote class="tr_bq">
<pre><!--StartFragment--><span style="color: navy;">#include</span><span style="color: silver;"> </span><span style="color: green;"><QtGui/QApplication></span></pre>
<pre><span style="color: navy;">#include</span><span style="color: silver;"> </span><span style="color: green;">"qmlapplicationviewer.h"</span></pre>
<pre><span style="color: navy;">#include</span><span style="color: silver;"> </span><span style="color: green;"><libgen.h></span></pre>
<pre></pre>
<pre><span style="color: purple;">Q_DECL_EXPORT</span><span style="color: silver;"> </span><span style="color: olive;">int</span><span style="color: silver;"> </span>main(<span style="color: olive;">int</span><span style="color: silver;"> </span>argc,<span style="color: silver;"> </span><span style="color: olive;">char</span><span style="color: silver;"> </span>*argv[])</pre>
<pre>{</pre>
<pre></pre>
<pre></pre>
<pre><span style="color: silver;"> </span><span style="color: olive;">enum</span><span style="color: silver;"> </span>{<span style="color: silver;"> </span><span style="color: purple;">BUFFERSIZE</span><span style="color: silver;"> </span>=<span style="color: silver;"> </span><span style="color: navy;">1024</span><span style="color: silver;"> </span>};</pre>
<pre><span style="color: silver;"> </span><span style="color: olive;">char</span><span style="color: silver;"> </span>buf[BUFFERSIZE];</pre>
<pre><span style="color: silver;"> </span><span style="color: purple;">ssize_t</span><span style="color: silver;"> </span>len<span style="color: silver;"> </span>=<span style="color: silver;"> </span>readlink(<span style="color: green;">"/proc/self/exe"</span>,<span style="color: silver;"> </span>buf,<span style="color: silver;"> </span><span style="color: olive;">sizeof</span>(buf)-<span style="color: navy;">1</span>);</pre>
<pre></pre>
<pre><span style="color: silver;"> </span><span style="color: olive;">if</span><span style="color: silver;"> </span>(len<span style="color: silver;"> </span>!=<span style="color: silver;"> </span>-<span style="color: navy;">1</span>)<span style="color: silver;"> </span>{</pre>
<pre><span style="color: silver;"> </span>buf[len]<span style="color: silver;"> </span>=<span style="color: silver;"> </span><span style="color: green;">'\0'</span>;</pre>
<pre><span style="color: silver;"> </span>}</pre>
<pre><span style="color: silver;"> </span><span style="color: olive;">else</span><span style="color: silver;"> </span>{</pre>
<pre><span style="color: silver;"> </span><span style="color: olive;">return</span><span style="color: silver;"> </span><span style="color: navy;">2</span>;</pre>
<pre><span style="color: silver;"> </span>}</pre>
<pre></pre>
<pre><span style="color: silver;"> </span><span style="color: olive;">char</span><span style="color: silver;"> </span>*dirc<span style="color: silver;"> </span>=<span style="color: silver;"> </span>strdup(buf);</pre>
<pre><span style="color: silver;"> </span><span style="color: olive;">char</span><span style="color: silver;"> </span>*dname<span style="color: silver;"> </span>=<span style="color: silver;"> </span>dirname(dirc);</pre>
<pre><span style="color: silver;"> </span>strcat(dname,<span style="color: silver;"> </span><span style="color: green;">"/../qml/saera/main.py"</span>);</pre>
<pre></pre>
<pre><span style="color: silver;"> </span><span style="color: olive;">char</span><span style="color: silver;"> </span>*arr[]<span style="color: silver;"> </span>=<span style="color: silver;"> </span>{<span style="color: green;">"python"</span>,<span style="color: silver;"> </span>dname,<span style="color: silver;"> </span>NULL};</pre>
<pre><span style="color: silver;"> </span>execvp(<span style="color: green;">"python"</span>,<span style="color: silver;"> </span>arr);</pre>
<pre>}</pre>
</blockquote>
Python code (main.py):<br />
<blockquote class="tr_bq">
<span style="color: green;"><span style="font-family: inherit;">#!/usr/bin/python</span></span> </blockquote>
<blockquote class="tr_bq">
<span style="color: green; font-family: inherit;">#</span><span style="color: silver; font-family: inherit;"> </span><span style="color: green; font-family: inherit;">-*-</span><span style="color: silver; font-family: inherit;"> </span><span style="color: green; font-family: inherit;">coding:</span><span style="color: silver; font-family: inherit;"> </span><span style="color: green; font-family: inherit;">utf-8</span><span style="color: silver; font-family: inherit;"> </span><span style="color: green; font-family: inherit;">-*-</span> </blockquote>
<blockquote class="tr_bq">
<span style="color: green; font-family: inherit;">import</span><span style="color: silver; font-family: inherit;"> </span><span style="font-family: inherit;">sys, os</span></blockquote>
<blockquote class="tr_bq">
<span style="color: green; font-family: inherit;">from</span><span style="color: silver; font-family: inherit;"> </span><span style="font-family: inherit;">PySide</span><span style="color: silver; font-family: inherit;"> </span><span style="color: green; font-family: inherit;">import</span><span style="color: silver; font-family: inherit;"> </span><span style="font-family: inherit;">QtCore</span></blockquote>
<blockquote class="tr_bq">
<span style="color: green; font-family: inherit;">from</span><span style="color: silver; font-family: inherit;"> </span><span style="font-family: inherit;">PySide.QtCore</span><span style="color: silver; font-family: inherit;"> </span><span style="color: green; font-family: inherit;">import</span><span style="color: silver; font-family: inherit;"> </span><span style="font-family: inherit;">*</span></blockquote>
<blockquote class="tr_bq">
<span style="color: green; font-family: inherit;">from</span><span style="color: silver; font-family: inherit;"> </span><span style="font-family: inherit;">PySide.QtGui</span><span style="color: silver; font-family: inherit;"> </span><span style="color: green; font-family: inherit;">import</span><span style="color: silver; font-family: inherit;"> </span><span style="font-family: inherit;">*</span></blockquote>
<blockquote>
<span style="font-family: inherit;"><span style="color: green;">from</span><span style="color: silver;"> </span>PySide.QtDeclarative<span style="color: silver;"> </span><span style="color: green;">import</span><span style="color: silver;"> </span>*</span></blockquote>
<blockquote>
<span style="font-family: inherit;">os.chdir(os.path.dirname(os.path.abspath(__file__)))</span></blockquote>
<blockquote>
<span style="font-family: inherit;">size<span style="color: silver;"> </span>=<span style="color: silver;"> </span>(<span style="color: navy;">800</span>,<span style="color: silver;"> </span><span style="color: navy;">480</span>)</span></blockquote>
<blockquote>
<span style="font-family: inherit;">app<span style="color: silver;"> </span>=<span style="color: silver;"> </span>QApplication(sys.argv)</span></blockquote>
<blockquote>
<span style="font-family: inherit;">view<span style="color: silver;"> </span>=<span style="color: silver;"> </span>QDeclarativeView()</span></blockquote>
<blockquote>
<span style="font-family: inherit;">window<span style="color: silver;"> </span>=<span style="color: silver;"> </span>QMainWindow()</span></blockquote>
<blockquote>
<span style="font-family: inherit;">window.resize(*size)</span></blockquote>
<blockquote>
<span style="font-family: inherit;">window.setCentralWidget(view)</span></blockquote>
<blockquote>
<span style="font-family: inherit;">view.setResizeMode(QDeclarativeView.SizeRootObjectToView)</span></blockquote>
<blockquote>
<span style="font-family: inherit;">view.setSource(<span style="color: green;">"main.qml"</span>)</span></blockquote>
<blockquote>
<span style="font-family: inherit;">window.show()</span></blockquote>
<blockquote>
<span style="font-family: inherit;">app.exec_()</span></blockquote>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
taixzohttp://www.blogger.com/profile/14616222527114166282noreply@blogger.com0tag:blogger.com,1999:blog-3117942903338841250.post-56649102298877011092012-08-15T14:51:00.000-07:002012-08-15T14:52:21.386-07:00Cyclic Physics MappingIn computer games, the performance of a complex physical object, such as a car, is generally represented by a few numbers: in the case of a car, numbers representing acceleration, tire grip, center of gravity, drag, etc. These numbers are "tweaked" to get performance that matches the real thing, if there is a real thing being modeled. This works fine for making the perfect replica of an existing vehicle, but what about if you want to make something new? You can't just plug in numbers, because you have no numbers to plug in. So, you could guess, or you could physically model the workings of the car.<br />
The latter would seem like a great way to get a good model. After all, if designers use CAD to predict the performance of a part in real life, why not just predict the performance of all the parts and build a virtual car? The problem is speed. Let's look at the engine itself. Inside the cylinders, a mixture of gasoline and air explodes, pushing the cylinder down. Explosions aren't cheap to simulate; and as even an idling engine produces more than <a href="http://en.wikipedia.org/wiki/Idle_speed" target="_blank">25 explosions per second</a>, it seems impossible that one could simulate an entire running engine, much less a whole car.<br />
Or is it? There's a great way to reduce physics computing overhead, which is known in the Bullet physics library as "sleeping". This happens when:<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<ol>
<li>the forces acting on an object are in equilibrium, </li>
<li>that object has been static for a period of time (a second or so), and</li>
<li>there is no active object within the reaction boundaries.</li>
</ol>
<div>
To illustrate:</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFAjW3A2QCd0Zb-PhyE9OHvIaaviqgETTJfT471c4bN4rv8YrRuF2ge9nBYO4DPBejWTMLZE0Z1JjJYNnrIkB18MiaO5AZjm1t3Xn3_W3tTNOhZUSa8JKDsENvyxGqrAnGXMYR5r2qwQQ/s1600/Screen+shot+2012-08-14+at+5.56.22+PM.png" style="margin-left: auto; margin-right: auto;" /></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Two falling blocks in Blender; the white outline indicates they are active.</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmzLKy3ugCLiE6d9n0EeHVgzk8Yps_C7ncvNxZ9bPjBgYvOZeybUn4mmJsq8jYCsBtQr3RwldlH-nW6pWDAfoXQheitvC0exeV3fWb5YJEKpXPdh8iRGjlN3BRnlAbh5A4AMhUJPT7qL4/s1600/Screen+shot+2012-08-14+at+5.56.51+PM.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmzLKy3ugCLiE6d9n0EeHVgzk8Yps_C7ncvNxZ9bPjBgYvOZeybUn4mmJsq8jYCsBtQr3RwldlH-nW6pWDAfoXQheitvC0exeV3fWb5YJEKpXPdh8iRGjlN3BRnlAbh5A4AMhUJPT7qL4/s1600/Screen+shot+2012-08-14+at+5.56.51+PM.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The blocks after coming to rest. The green indicates that they are now "sleeping" and no longer being calculated.</td></tr>
</tbody></table>
<div style="text-align: left;">
The problem with this is that it only works on objects which are completely at rest. How do we deal with an active object? The solution is lumping things together. For example, instead of doing a laborious fluid dynamics calculation for the explosion, we can lump the combustion chamber into a system with five variables: the amount of gas entering the chamber, the amount of air entering the chamber, the momentum of the piston, the force the piston exerts on the gas, and the speed of the piston. We can calculate the amount of gas that actually burns now, and from that deduce the temperature change (and volume change) in the gas - and therefore the force on the piston.</div>
<div style="text-align: left;">
This is great, but it still won't come anywhere close to simulating a vehicle in real time. The solution is in seeing that most things come in some form of cycles - in this case, the piston repeats itself every two revolutions of the crankshaft. So, we can simulate this cycle <i>once</i> and then just repeat it until one of the variables changes.</div>
<div style="text-align: left;">
But why re-simulate each time a variable changes? The output it creates is continuous within reasonable parameters - so why not just simulate the cycle several times, for different data points in each of the variables, and use splines to interpolate the performance in real time? Furthermore, now that we have a system with a few variable inputs and outputs, it can be lumped into a larger system. Now we can treat the engine as a whole as a system, which has a few variables: fuel input, air input, crankshaft speed, and power output. At lower revs, the crankshaft speed won't be constant, because it slows down in between each explosion, but at higher revs it would be nearly constant.</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgY7XSJ0RTXvln0VubUeWIH6BJ7Dmxv5rT5rk5fRnWQGWgFmoEMW-8GJneSKetM3Nq2aQpKPjaVJMBDuV35IIjp5ayUadv5aDRJewpK39S6vWLlrcOfsXs6KYnSvy-MKCba7kSBBtq5EVI/s1600/engspeed.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="282" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgY7XSJ0RTXvln0VubUeWIH6BJ7Dmxv5rT5rk5fRnWQGWgFmoEMW-8GJneSKetM3Nq2aQpKPjaVJMBDuV35IIjp5ayUadv5aDRJewpK39S6vWLlrcOfsXs6KYnSvy-MKCba7kSBBtq5EVI/s400/engspeed.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The discontinuity is the point where the engine stalls; beyond this point a cyclic simulation is pointless.</td></tr>
</tbody></table>
<div style="text-align: left;">
So, now we've lumped the engine into a single "black box" as seen by our physics engine, but this can continue. This lumping method, which I will call "Cyclic Physics Mapping" because we are mapping physical properties into parameterised cycles, allows us to make progressively larger "black boxes" out of components, until we have basically what was mentioned at the beginning of this post - a car whose performance is represented by a few variables - except that now we have a physical model of the entire car. Which has certain consequences: for example, it is relatively easy to redo the CPM for a different fuel, to simulate, say, nitrous injection, or a switch from gasoline to hydrogen. Also - suppose you drive over a parking bumper at high speed and bend your transmission. That's going to create more drag; the mapping down to the transmission level will have to be redone, but the engine simulation is not affected - you will now be driving a car that now behaves realistically as a damaged car would. There's not really an easy way to do that with purely numbers-based systems.</div>
<div style="text-align: left;">
This isn't just applicable to cars; you could do the same thing for anything complex and physical in a virtual world - boats, planes, even the guns in an FPS could have a physical basis in the same way. And even noncomplex objects, like the boxes shown before, would be handled like this - once the boxes come to rest relative to the platform they are on, they and the platform can now be treated as a group. Any system that interacts minimally with other systems can be considered a black box under these circumstances.</div>
<div style="text-align: left;">
<br /></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />taixzohttp://www.blogger.com/profile/14616222527114166282noreply@blogger.com0tag:blogger.com,1999:blog-3117942903338841250.post-12578483089162603512012-04-28T17:15:00.000-07:002012-08-15T14:53:20.085-07:00Hidden methods in PythonHow would one access variables programmatically in Python? Well, there are two dictionaries, one returned by globals() which contains all global variables, and one returned by locals() which contains all local variables. To demonstrate:<br />
<div>
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">>>> a = 4</span></div>
<div>
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">>>> locals()[<span class="Apple-style-span" style="color: blue;">'a'</span>]</span></div>
<div>
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">4</span></div>
<div>
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">>>> locals()[<span class="Apple-style-span" style="background-color: white;"><span class="Apple-style-span" style="color: blue;">'b'</span></span>] = <span class="Apple-style-span" style="color: blue;">'spam'</span></span></div>
<div>
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">>>> b</span></div>
<div>
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">'spam'</span></div>
<div>
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">>>></span></div>
<div>
Declaring a variable is the same thing as accessing its name in the locals() dictionary (or the globals() dictionary if the variable is declared global).<br />
But what if we do this:<br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="color: magenta;">class</span> a:</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> b = 4</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">locals()[<span class="Apple-style-span" style="background-color: white;"><span class="Apple-style-span" style="color: blue;">'a.b'</span></span>] = <span class="Apple-style-span" style="color: blue;">'spam'</span></span><br />
What will be the value of a.b?<br />
<br />
<a name='more'></a><br />
<br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">>>> a.b</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">4</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">>>></span><br />
The reason behind this is that the dot is not part of the variable name; you can't access a.b through <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">locals()[<span class="Apple-style-span" style="color: blue;">'a.b'</span>]</span>. You'd have to do <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">locals()[<span class="Apple-style-span" style="color: blue;">'a'</span>].b</span>. But what about the value of 'spam' that we stored in there? It's still there:<br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">>>> locals()[<span class="Apple-style-span" style="color: blue;">'a.b'</span>]</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="color: blue;">'spam'</span></span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">>>></span><br />
But we can't access it by just calling a.b. We couldn't even if there was no variable to begin with:<br />
<br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">>>> del a</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">>>> a.b</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">Traceback (most recent call last):</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> File <span class="Apple-style-span" style="color: blue;">"<stdin>"</span>, line 1, <span class="Apple-style-span" style="color: red;">in</span> <module></span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="color: magenta;">NameError</span>: name <span class="Apple-style-span" style="color: blue;">'a'</span> <span class="Apple-style-span" style="color: red;">is</span> <span class="Apple-style-span" style="color: red;">not</span> defined</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">>>> </span><br />
What happened here? It's simple: variable names with a dot in them are not permitted. So even though we have a variable called <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="color: blue;">'a.b'</span></span> in <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">locals()</span>, it isn't accessible through the local namespace. The reason we were allowed to put it in <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">locals()</span>, though, is because <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">locals()</span> behaves like a regular Python dictionary. Dictionaries allow any string to be used as a key; we could even put a variable in there called <span class="Apple-style-span" style="color: blue;"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">'class if ([{;\n@'</span></span> and it would still accept it, it just wouldn't be accessible. Dictionaries actually allow <i>any</i> value to be used as a key, not just strings; we could say something like <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">locals()[<span class="Apple-style-span" style="color: lime;">len</span>] = <span class="Apple-style-span" style="color: blue;">'spam'</span></span> and it would work, because <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="color: lime;">len</span></span> is a built-in function which is a perfectly valid key.<br />
<br />
Is there any use for hiding variables this way? Not really, because they're still accessible through <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">locals()</span>. But it offers an interesting look at the internals of Python variables.</div>
taixzohttp://www.blogger.com/profile/14616222527114166282noreply@blogger.com0tag:blogger.com,1999:blog-3117942903338841250.post-67439357896915089252012-03-28T10:08:00.002-07:002012-08-15T14:54:26.302-07:00Learning PythonI was cleaning out a flash drive and found the log I made two years ago when learning Python. I thought I'd post the first day here. Bear in mind that the only languages I knew beforehand were ActionScript and JavaScript.<br />
<br />
2010/05/08 10:20: Started the Python tutorial. It's nice that you don't need to install anything extra. Hello world is simple but there are no parentheses. Interesting.<br />
<a name='more'></a><br />
2010/05/08 11:00: And no braces either. <i>Everything</i> is whitespace. It's easy to do the examples from the book, but once I try to do something myself it goes wrong.<br />
2010/05/08 12:00: Strings don't have a length property! Well, I'll write a function to get the length. That should be fairly basic.<br />
2010/05/08 13:00: Loops are confusing in Python, since you can only loop through a sequence. But it seems strings are sequences. My length() function works!<br />
[note: function was:<br />
<div style="font-family: "Courier New",Courier,monospace;">
def length(string):</div>
<div style="font-family: "Courier New",Courier,monospace;">
a = 0;</div>
<div style="font-family: "Courier New",Courier,monospace;">
for i in string:</div>
<div style="font-family: "Courier New",Courier,monospace;">
a = a + 1;</div>
<span style="font-family: "Courier New",Courier,monospace;"> return a;</span>]<br />
2010/05/08 13:15: I miswrote it as len(a) instead of length(a) and it still worked! Does Python automatically correct things?<br />
2010/05/08 13:20: Damn. len() is a built-in function, which does the same thing as mine does. I didn't need to write that after all.<br />
2010/05/08 17:00: Wrote a simple calculator which can handle big numbers (more than 14 digits).<br />
2010/05/08 17:30: And it seems that Python's math can do this too. Much faster than mine. I asked it for 2**1,000,000 and it calculated it in about ten seconds! I've got to google things before I do them in Python, chances are it's there already.<br />
2010/05/08 18:00: That's it! I'll write a Python program that googles something!<br />
2010/05/08 19:00: Why can't I add a number to a string?<br />
2010/05/08 19:30: Sooo...Python is an interpreted language but it's picky about type.<br />
2010/05/08 20:00: urllib2 is surprisingly easy to parse. The HTML page that Google returns, however, is not. Something about '</scr'+'ipt>' in the JavaScript. I'll give this one another try tomorrow.taixzohttp://www.blogger.com/profile/14616222527114166282noreply@blogger.com0tag:blogger.com,1999:blog-3117942903338841250.post-77933507227472535042012-03-23T10:46:00.003-07:002012-03-23T10:47:57.064-07:00C/C++ loop surprisesA basic element of almost any program is a loop. Loops are a simple concept to grasp, but they can have pitfalls in some languages; here I will present one I learned about yesterday in C.<br />
The basic for loop in C is of this form:<br />
<span style="font-family: 'Courier New', Courier, monospace;">int n;</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">unsigned int i;</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">for (i=0; i<n; i++) {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> //do something</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">}</span><br />
Which is pretty foolproof as long as you leave i alone inside the loop. But another type of loop is the decrementing loop. Here is a simple program that prints the numbers from 5 down to 1:<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;">#include <stdio.h></span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace;">int main (int argc, char **argv) {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>int n = 5;</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>unsigned int i;</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>for (i=n; i>=1; i--) {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>printf("%u\n", i);</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">}</span><br />
And the output:<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;">5</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">4</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">3</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">2</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">1</span><br />
<a name='more'></a><br />
<div>
Ok. Now what if we want to count down to 0? The obvious thing to do would be to change line 5 to:</div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>for (i=n; i>=0; i--) {</span></div>
<div>
But when this is compiled and run, it doesn't stop:</div>
<div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">5</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">4</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">3</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">2</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">1</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">0</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">4294967295</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">4294967294</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">4294967293</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">4294967292</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">4294967291</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">4294967290</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">4294967289</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">4294967288</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">4294967287</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">4294967286</span></div>
</div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">...</span></div>
<div>
What happened? Well, the way a loop works is this: in each iteration, the condition is tested, then (if true) the loop body is executed, then the iterator is executed. So at what should be the last cycle, i is compared to see if it is greater or equal to zero (it is), then the body (printf) is executed, then i is decremented - and because i is an unsigned int, it wraps around to its maximum value! The next time around, it is compared against 0 (it is still greater), and the cycle continues indefinitely.</div>
<div>
So, how do we make a loop that counts down to 0? The simplest way is to replace</div>
<div>
<span class="Apple-tab-span" style="font-family: 'Courier New', Courier, monospace; white-space: pre;"> </span><span style="font-family: 'Courier New', Courier, monospace;">unsigned </span><span style="font-family: 'Courier New', Courier, monospace;">int i;</span></div>
<div>
with</div>
<div>
<span class="Apple-tab-span" style="font-family: 'Courier New', Courier, monospace; white-space: pre;"> </span><span style="font-family: 'Courier New', Courier, monospace;">int i;</span></div>
<div>
This removes the sign, and after passing 0 i will go negative for the loop's termination.</div>
<div>
But this brings two disadvantages: one, that although it will still compile, in some loops using a signed int for the loop variable will generate a compiler warning; and two, that we are creating a loop that should only use positive numbers anyway, so making it signed for a sign that is never used within the loop is a bit superfluous.</div>
<div>
One potential solution is to move the decrement to the top of the loop, and test its value before being decremented:</div>
<div>
<span class="Apple-tab-span" style="font-family: 'Courier New', Courier, monospace; white-space: pre;"> </span><span style="font-family: 'Courier New', Courier, monospace;">for (i=n; i-->0; ) {</span></div>
<div>
Here, we are taking advantage of the fact that the decrement operator returns the value pre-decrement. We then leave the iterator field empty. This prints:</div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">4</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">3</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">2</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">1</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">0</span></div>
<div>
But wait! It started at 4! This is because it gets decremented in every cycle - including the first. So what we actually have to do is to add one in the first loop, giving us the somewhat ugly, but working:</div>
<div>
<span class="Apple-tab-span" style="font-family: 'Courier New', Courier, monospace; white-space: pre;"> </span><span style="font-family: 'Courier New', Courier, monospace;">for (i=n+1; i-->0; ) {</span></div>
<div>
Another solution is to check that i+1 is greater than 0. This seems like it would get confused when i wraps around to UINT_MAX, but that wrap actually helps, because UINT_MAX+1 is 0.</div>
<div>
<span class="Apple-tab-span" style="font-family: 'Courier New', Courier, monospace; white-space: pre;"> </span><span style="font-family: 'Courier New', Courier, monospace;">for (i=n; i+1>0; i--) {</span></div>
<div>
Finally, there's one more option, which is to not use a for loop. Using while loops is generally regarded as bad practice because they can lead to infinite loops, however as we have seen this particular test may be infinite under a for loop anyway. A while loops gives us the flexibility to put the test and the iterator where we choose, so we can put the test after the body but the iterator after the test. Here's a solution as a while-break loop:</div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">#include <stdio.h></span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace;">int main (int argc, char **argv) {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>int n = 5;</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>unsigned int i=n;</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>while (1) {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>printf("%u\n", i);</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;"> </span>if (i==0) {</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;"> </span>break;</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><span class="Apple-tab-span" style="white-space: pre;"> </span>i--;</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">}</span></div>
<br />taixzohttp://www.blogger.com/profile/14616222527114166282noreply@blogger.com0