Caught in the Net (Posts about buridan donkey)francescomecca.euenContents © 2024 <a href="mailto:francescomecca.eu">Francesco Mecca</a> Wed, 28 Feb 2024 09:29:25 GMTNikola (getnikola.com)http://blogs.law.harvard.edu/tech/rssThe Buridan's donkey in pythonfrancescomecca.eu/blog/2016/4/2/buridan_donkey/Francesco Mecca<p>During the final weeks of my exam session I started reading a bit about python 3 using an excellent book: <a href="http://www.diveintopython.net/">Dive into Python</a>. When I noted that python uses the <a href="https://en.wikipedia.org/wiki/Mersenne_Twister">Mersenne Twister PRNG</a> as well I decided to write another version of my <a href="http://francescomecca.eu/index.php/archives/207">Buridan's donkey program</a>.</p> <p>.. code:: python</p> <div class="code"><pre class="code literal-block"> <span class="kn">import</span> <span class="nn">random</span><span class="o">,</span> <span class="nn">sys</span> <span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">'__main__'</span><span class="p">:</span> <span class="n">args</span> <span class="o">=</span> <span class="nb">list</span><span class="p">()</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">sys</span><span class="o">.</span><span class="n">stdin</span><span class="o">.</span><span class="n">isatty</span><span class="p">():</span> <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">sys</span><span class="o">.</span><span class="n">stdin</span><span class="p">:</span> <span class="k">if</span> <span class="n">line</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="ow">is</span> <span class="s1">'</span><span class="se">\n</span><span class="s1">'</span><span class="p">:</span> <span class="n">line</span> <span class="o">=</span> <span class="n">line</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">line</span><span class="p">)</span> <span class="k">else</span><span class="p">:</span> <span class="n">args</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span> <span class="n">argRange</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">argRange</span><span class="p">):</span> <span class="nb">print</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span> <span class="o">+</span> <span class="s1">'.'</span><span class="p">,</span> <span class="n">args</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="n">random</span><span class="o">.</span><span class="n">randrange</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">))))</span> </pre></div> <p>This script works in a different way than the one in c++. Rather than shuffling a list made by the entries in the arguments, it pops randomly one entry from the list till the list is empty.</p> <p>Not satisfied enough, I wrote also a telegram bot using the <a href="https://github.com/eternnoir/pyTelegramBotAPI">telebot library</a> that works as the script above but inside the telegram app. The bot can be added to your contact list by simply searching for <a href="http://telegram.me/duridan_donkey_bot">@duridan_donkey_bot</a> (yes, a typo!)</p> <p>All the code is opensource and can be found on my github page.</p> <p>Francesco Mecca</p>buridan donkeymersenne twisterPesceWandapythonrandomfrancescomecca.eu/blog/2016/4/2/buridan_donkey/Sat, 02 Apr 2016 00:00:00 GMTThe Buridan&#8217;s donkey paradoxfrancescomecca.eu/blog/2015/9/20/the-buridans-donkey-paradox/Francesco Mecca<p style="text-align: left;"> The Buridan’s donkey is an illustration of a paradox regarding the philosophy of moral determinism and free will. </p> <p style="text-align: left;"> The paradox shows an hypothetical situation in which a donkey searching for food is caught in the middle of two equally appealing stacks of hay located at the same distance from the donkey. Because the donkey has no real reason to choose one over the other he dies of starvation. </p> <p><a href="https://en.wikipedia.org/wiki/Buridan's_ass"><img class="aligncenter size-full wp-image-209" src="http://francescomecca.eu/wp-content/uploads/2015/09/Deliberations_of_Congress.jpg" alt="Deliberations_of_Congress" width="431" height="425" srcset="http://francescomecca.eu/wp-content/uploads/2015/09/Deliberations_of_Congress-300x296.jpg 300w, http://francescomecca.eu/wp-content/uploads/2015/09/Deliberations_of_Congress.jpg 431w" sizes="(max-width: 431px) 100vw, 431px"></a>I have decided to write a cli program that chooses for me when I can’t make up my mind.</p> <p>The program is written in C++ and when invoked along with two or more arguments it puts them in a vector and then changes the order randomly.</p> <p>.. code:: c</p> <div class="code"><pre class="code literal-block"><span class="n">#include</span><span class="w"> </span><span class="o">&lt;</span><span class="n">iostream</span><span class="o">&gt;</span> <span class="n">#include</span><span class="w"> </span><span class="o">&lt;</span><span class="n">vector</span><span class="o">&gt;</span> <span class="n">#include</span><span class="w"> </span><span class="o">&lt;</span><span class="n">algorithm</span><span class="o">&gt;</span> <span class="n">#include</span><span class="w"> </span><span class="o">&lt;</span><span class="n">random</span><span class="o">&gt;</span> <span class="n">#include</span><span class="w"> </span><span class="o">&lt;</span><span class="n">string</span><span class="o">&gt;</span> <span class="n">#include</span><span class="w"> </span><span class="o">&lt;</span><span class="n">sys</span><span class="o">/</span><span class="n">poll</span><span class="p">.</span><span class="n">h</span><span class="o">&gt;</span> <span class="k">using</span><span class="w"> </span><span class="n">namespace</span><span class="w"> </span><span class="n">std</span><span class="p">;</span> <span class="n">struct</span><span class="w"> </span><span class="n">pollfd</span><span class="w"> </span><span class="n">stdin_poll</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="err">{</span> <span class="w"> </span><span class="p">.</span><span class="n">fd</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">fileno</span><span class="w"> </span><span class="p">(</span><span class="n">stdin</span><span class="p">),</span><span class="w"> </span><span class="p">.</span><span class="n">events</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">POLLIN</span> <span class="err">}</span><span class="p">;</span> <span class="n">void</span><span class="w"> </span><span class="n">read_from_piped_input</span><span class="w"> </span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">string</span><span class="o">&gt;&amp;</span><span class="w"> </span><span class="n">lst</span><span class="p">)</span> <span class="err">{</span> <span class="w"> </span><span class="n">string</span><span class="w"> </span><span class="n">x</span><span class="p">;</span> <span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="n">getline</span><span class="w"> </span><span class="p">(</span><span class="n">cin</span><span class="p">,</span><span class="w"> </span><span class="n">x</span><span class="p">))</span><span class="w"> </span><span class="err">{</span> <span class="w"> </span><span class="n">lst</span><span class="p">.</span><span class="n">push_back</span><span class="w"> </span><span class="p">(</span><span class="n">x</span><span class="p">);</span> <span class="w"> </span><span class="err">}</span> <span class="err">}</span> <span class="n">void</span><span class="w"> </span><span class="n">read_from_arguments</span><span class="w"> </span><span class="p">(</span><span class="n">const</span><span class="w"> </span><span class="nc">int</span><span class="o">&amp;</span><span class="w"> </span><span class="n">argc</span><span class="p">,</span><span class="w"> </span><span class="nc">char</span><span class="o">*</span><span class="w"> </span><span class="n">argv</span><span class="err">[]</span><span class="p">,</span><span class="w"> </span><span class="n">vector</span><span class="o">&lt;</span><span class="n">string</span><span class="o">&gt;&amp;</span><span class="w"> </span><span class="n">lst</span><span class="p">)</span> <span class="err">{</span> <span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">argc</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="err">{</span> <span class="w"> </span><span class="n">cout</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="ss">"Usage: asino [string] [string] ..."</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="n">endl</span><span class="p">;</span> <span class="w"> </span><span class="k">exit</span><span class="p">;</span> <span class="w"> </span><span class="err">}</span> <span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">string</span><span class="o">&gt;::</span><span class="n">size_type</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">argc</span><span class="p">;</span><span class="w"> </span><span class="o">++</span><span class="n">i</span><span class="p">)</span><span class="w"> </span><span class="err">{</span> <span class="w"> </span><span class="n">lst</span><span class="p">.</span><span class="n">push_back</span><span class="w"> </span><span class="p">(</span><span class="n">argv</span><span class="o">[</span><span class="n">i</span><span class="o">]</span><span class="p">);</span> <span class="w"> </span><span class="err">}</span> <span class="err">}</span> <span class="nc">int</span><span class="w"> </span><span class="n">main</span><span class="w"> </span><span class="p">(</span><span class="nc">int</span><span class="w"> </span><span class="n">argc</span><span class="p">,</span><span class="w"> </span><span class="nc">char</span><span class="o">*</span><span class="w"> </span><span class="n">argv</span><span class="err">[]</span><span class="p">)</span> <span class="err">{</span> <span class="w"> </span><span class="n">vector</span><span class="o">&lt;</span><span class="n">string</span><span class="o">&gt;</span><span class="w"> </span><span class="n">lst</span><span class="p">;</span> <span class="w"> </span><span class="nc">int</span><span class="w"> </span><span class="n">poll_ret</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">poll</span><span class="w"> </span><span class="p">(</span><span class="o">&amp;</span><span class="n">stdin_poll</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">);</span> <span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">poll_ret</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="err">{</span> <span class="w"> </span><span class="n">read_from_piped_input</span><span class="w"> </span><span class="p">(</span><span class="n">lst</span><span class="p">);</span> <span class="w"> </span><span class="err">}</span> <span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="err">{</span> <span class="w"> </span><span class="n">read_from_arguments</span><span class="w"> </span><span class="p">(</span><span class="n">argc</span><span class="p">,</span><span class="w"> </span><span class="n">argv</span><span class="p">,</span><span class="w"> </span><span class="n">lst</span><span class="p">);</span> <span class="w"> </span><span class="err">}</span> <span class="w"> </span><span class="n">random_device</span><span class="w"> </span><span class="n">rd</span><span class="p">;</span> <span class="w"> </span><span class="n">mt19937</span><span class="w"> </span><span class="n">m</span><span class="p">(</span><span class="n">rd</span><span class="p">());</span> <span class="w"> </span><span class="n">shuffle</span><span class="w"> </span><span class="p">(</span><span class="n">lst</span><span class="p">.</span><span class="k">begin</span><span class="w"> </span><span class="p">(),</span><span class="w"> </span><span class="n">lst</span><span class="p">.</span><span class="k">end</span><span class="w"> </span><span class="p">(),</span><span class="w"> </span><span class="n">m</span><span class="p">);</span> <span class="w"> </span><span class="nc">int</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span> <span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">string</span><span class="o">&gt;::</span><span class="n">iterator</span><span class="w"> </span><span class="n">it</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">lst</span><span class="p">.</span><span class="k">begin</span><span class="w"> </span><span class="p">();</span><span class="w"> </span><span class="n">it</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="n">lst</span><span class="p">.</span><span class="k">end</span><span class="w"> </span><span class="p">();</span><span class="w"> </span><span class="o">++</span><span class="n">it</span><span class="p">)</span><span class="w"> </span><span class="err">{</span> <span class="w"> </span><span class="n">cout</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="n">i</span><span class="o">++</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="ss">". "</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="o">*</span><span class="n">it</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="n">endl</span><span class="p">;</span> <span class="w"> </span><span class="err">}</span> <span class="err">}</span> </pre></div> <p>I have used the <a href="http://en.cppreference.com/w/cpp/numeric/random/mersenne_twister_engine" target="_blank">Mersenne Twister PRNG</a> just to give it a try.</p> <p style="text-align: left;"> One of the challenges was to read from stdin instead of arguments when the program is piped after another program in the shell: </p> <p>.. code:: sh</p> <div class="code"><pre class="code literal-block">ls /media/my_movies/ | buridan </pre></div> <p>So I have used poll() that checks for a specified amount of time if the selected device (/dev/stdin in my case) can perform I/O operations; in my code:</p> <p>.. code:: bash</p> <div class="code"><pre class="code literal-block">poll (&amp;stdin_poll, 1, 0) </pre></div> <p>I selected the POLLIN as event so poll() only checks if there is data to read, 1 as the number of items in the fds array, 0 milliseconds of timeout because when the program is invoked /dev/stdin may already contain input.</p> <p>The program should be compiled this way:</p> <p>.. code:: bash</p> <div class="code"><pre class="code literal-block">g++ -std=c++11 ./program.cpp -o output </pre></div> <p>You are free to reuse this little piece of code as you wish.</p> <p>EDIT: 02-04-2016 The original idea for the Buridan's donkey came from my mentor <a href="https://twitter.com/bassosimone">Simone Basso</a> who wrote the original one in haskell.</p> <p style="text-align: right;"> Francesco Mecca </p>buridanburidan c++buridan donkeyburidan'assc++11PesceWandapoll()poll.hfrancescomecca.eu/blog/2015/9/20/the-buridans-donkey-paradox/Sun, 20 Sep 2015 10:34:36 GMT