<?xml version='1.0' encoding='UTF-8'?><rss xmlns:atom='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0' version='2.0'><channel><atom:id>tag:blogger.com,1999:blog-3343374414660307054</atom:id><lastBuildDate>Wed, 16 May 2012 08:30:26 +0000</lastBuildDate><category>mobile</category><category>visualization</category><category>programming-competitions</category><category>research</category><category>admin</category><category>profiit</category><category>photography</category><category>movies</category><category>web</category><category>programming</category><category>latex</category><category>tutorial</category><category>instability</category><category>data-mining</category><category>slovak</category><category>algorithms</category><category>Switzerland</category><category>movie</category><category>job</category><category>report</category><category>ibm</category><category>teap</category><category>structural-engineering</category><category>python</category><category>tips</category><category>thoughts</category><category>allplan</category><category>fiit</category><category>scia-engineer</category><category>review</category><category>google</category><category>3D-model</category><title>ManaSupo</title><description></description><link>http://www.manasupo.com/</link><managingEditor>noreply@blogger.com (supo)</managingEditor><generator>Blogger</generator><openSearch:totalResults>29</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3343374414660307054.post-2809606022834137727</guid><pubDate>Tue, 08 May 2012 11:43:00 +0000</pubDate><atom:updated>2012-05-08T13:43:43.205+02:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>report</category><title>Berlin Tegel - hostile for the unprepared</title><description>This is a little story of how the Berlin Tegel airport is awesome. NOT!&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;In Berlin they have this tiny conveyor belts just when you get of the plane and I managed to miss mine and walk to the other "room" from which they would not let me back to the belt. So I spent 15min negotiating with the security after which they decided to send me to a kind of lost&amp;amp;found office which was a NIGHTMARE to find because it is not marked and hidden in a maze of corridors. When I found it, the guy gave me a f*cking map of the airport with a path leading to the other side. The whole airport is a retarded maze of self-repeating hexagonal structures, where the only orientational point is the airport tower, which is about 5 meters tall :-D RIDICULOUS! I had to go outside of the airport to a shady backyard area and find a detached customs office located in a shed with nobody in it. It was an empty room with only a phone on the wall. The guy gave me a number I was supposed to call from this phone, so I did and I heard another man picking it up just behind a wall :-D I explained the situation to him and he was like "Alz rightz mizter Schvonawa, juzt a minute!". So I waited another quarter of an hour and then he appeared with my bag. I thanked him and started heading for the door and he went "Enschuldigung mizter Schvonawa, you havz to go thiz way!" pointing to another door. So I went and this room was darker and there were 2 officers siting behind a table. So I was like "nothing to do here" and I just walked to the exit on the other side. And they went "Ohoho mizter, pleaze comen sie here." They started interrogating me about why I came to Germany and just wouldn't understand what a "business trip for my startup" means. "Was is ze ztartup?" :-D After a while they asked me where I am coming from and they didn't seem to like "Zurich" as the answer.. after I gave them my Slovak passport they were totally confused and started asking about why I went to Zurich. After I told them that I live there they started LITERALLY laughing and pointing at the passport and saying "Rightz rightz.".&lt;br /&gt;After I demonstrated that every millimeter of my backpack indeed only contains clothes, they let me go after which I spent another quarter hour finding my way to the bus stop on the airport.&lt;br /&gt;&lt;br /&gt;Morale of the story: NEVER MISS THE FUCKING LUGGAGE BELT!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3343374414660307054-2809606022834137727?l=www.manasupo.com' alt='' /&gt;&lt;/div&gt;</description><link>http://www.manasupo.com/2012/05/berlin-tegel-hostile-for-unprepared.html</link><author>noreply@blogger.com (supo)</author><thr:total>0</thr:total><georss:featurename>Berlin, Germany</georss:featurename><georss:point>52.519171 13.4060912</georss:point><georss:box>52.209997 12.7743772 52.828345 14.037805200000001</georss:box></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3343374414660307054.post-6333682315287130039</guid><pubDate>Sat, 03 Mar 2012 21:15:00 +0000</pubDate><atom:updated>2012-03-03T22:17:51.427+01:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>tips</category><category domain='http://www.blogger.com/atom/ns#'>python</category><category domain='http://www.blogger.com/atom/ns#'>programming</category><title>Gevent+Psycopg2 = execute cannot be used while an asynchronous query is underway</title><description>I am using a stack composed of, among others, Django + Gevent + Gunicorn + psycopg2 (greened with https://bitbucket.org/dvarrazzo/psycogreen/src).&lt;br /&gt;Until recently, I was occasionally getting the following errors, if I rapidly reloaded our application that generates a couple of ajax calls on the startup:&lt;br /&gt;&lt;pre&gt;ProgrammingError: execute cannot be used while an asynchronous query is underway&lt;br /&gt;DatabaseError: execute cannot be used while an asynchronous query is underway&lt;br /&gt;&lt;/pre&gt;After getting the following versions:&lt;br /&gt;&lt;pre&gt;Django 1.4 b1&lt;br /&gt;Gunicorn 0.14&lt;br /&gt;Gevent 0.13.6&lt;br /&gt;psycopg2 2.4.4&lt;br /&gt;&lt;/pre&gt;And greening psycopg2 pre_fork like this (in the Gunicorn config):&lt;br /&gt;&lt;pre&gt;worker_class = "gevent"&lt;br /&gt;def def_pre_fork(server, worker):&lt;br /&gt;    from psyco_gevent import make_psycopg_green&lt;br /&gt;    make_psycopg_green()&lt;br /&gt;    worker.log.info("Made Psycopg Green")&lt;br /&gt;pre_fork = def_pre_fork&lt;br /&gt;&lt;/pre&gt;And using the gunicorn_django in a virtualenv to run the server from supervisor (instead of the manage.py shortcut):&lt;br /&gt;&lt;pre&gt;[program:photobooks]&lt;br /&gt;command=/path/bin/gunicorn_django -c /path/conf/photobooks_gunicorn.conf.py&lt;br /&gt;directory=/path/src/photobooks&lt;br /&gt;environment=PATH="/path/bin"&lt;br /&gt;&lt;/pre&gt;I was not able to reproduce the problem any more.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3343374414660307054-6333682315287130039?l=www.manasupo.com' alt='' /&gt;&lt;/div&gt;</description><link>http://www.manasupo.com/2012/03/geventpsycopg2-execute-cannot-be-used.html</link><author>noreply@blogger.com (supo)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3343374414660307054.post-487882564285187213</guid><pubDate>Thu, 01 Mar 2012 16:31:00 +0000</pubDate><atom:updated>2012-03-01T17:44:28.545+01:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>tutorial</category><category domain='http://www.blogger.com/atom/ns#'>python</category><category domain='http://www.blogger.com/atom/ns#'>programming</category><category domain='http://www.blogger.com/atom/ns#'>web</category><title>Chord progress in Celery</title><description>On our &lt;a href="http://blog.47pixels.com/post/18377327708/new-server-stack"&gt;company blog&lt;/a&gt; I described the new server stack we use to run &lt;a href="http://47posters.com/"&gt;47posters.com&lt;/a&gt;. One part of this stack is a distributed task queue &lt;a href="http://celeryproject.org/"&gt;Celery&lt;/a&gt;. We use it for 2 reasons:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;hard task throttling&lt;/span&gt;&lt;/b&gt; - we have certain more processing heavy tasks, that if spawned by all  Gunicorn processes at the same time would overwhelm the RAM of the  server. With celery we can start them synchronously and use the  --concurrency flag to control the number of heavy tasks processed in  parallel&lt;br /&gt;&lt;br /&gt;&lt;b&gt;asynchronous tasks&lt;/b&gt; - we have one  task that can take time in the order of minutes. This task is actually a  collection of tasks that can be all done in parallel and then one  synchronization tasks that runs after all the partial tasks are  finished.&lt;br /&gt;This synchronization task is done with &lt;a href="http://ask.github.com/celery/userguide/tasksets.html#chords"&gt;chord&lt;/a&gt; and the collection of parallel tasks is modeled with a &lt;a href="http://ask.github.com/celery/userguide/tasksets.html#task-sets"&gt;TaskSet&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;There is only one tricky part&lt;/b&gt; - chord returns an AsyncResult corresponding to the synchronization  task. If you then query the task_id given by this result, you can check  for the cord completion. What you can't do is to &lt;i&gt;&lt;b&gt;track progress of the taskset completion.&lt;/b&gt;&lt;/i&gt; To do this, we have to create a new chord like this:&lt;br /&gt;&lt;pre&gt;from celery.utils import uuid&lt;br /&gt;from celery.task.chords import Chord&lt;br /&gt;class progress_chord(object):&lt;br /&gt;    Chord = Chord&lt;br /&gt;&lt;br /&gt;    def __init__(self, tasks, **options):&lt;br /&gt;        self.tasks = tasks&lt;br /&gt;        self.options = options&lt;br /&gt;&lt;br /&gt;    def __call__(self, body, **options):&lt;br /&gt;        tid = body.options.setdefault("task_id", uuid())&lt;br /&gt;        &lt;span style="background-color: orange; color: black;"&gt;r = &lt;/span&gt;self.Chord.apply_async((list(self.tasks), body),&lt;br /&gt;                                   self.options,&lt;br /&gt;           &lt;span style="background-color: orange;"&gt;&lt;/span&gt;                        **options)&lt;br /&gt;        return body.type.app.AsyncResult(tid)&lt;span style="background-color: orange; color: black;"&gt;, r&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;(I highlighted the difference against the default celery.task.chord).&lt;br /&gt;Now if you call the chord like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;result_chord, result_set =&lt;br /&gt;    tasks.progress_chord(taskSet)(syncTask.subtask(params))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You will be able to get both the result_chord.task_id and result_set.task_id.&lt;br /&gt;&lt;br /&gt;Then what remains is to create a view that polls for the task status:&lt;br /&gt;&lt;pre&gt;def check_batch_result(request):&lt;br /&gt;  chord_result = AsyncResult(request.GET.get("chord_task_id",""))&lt;br /&gt;  task_set_result = AsyncResult(request.GET.get("set_task_id","")).result&lt;br /&gt;  response = {}&lt;br /&gt;  response["tasks_completed"] = task_set_result.completed_count()&lt;br /&gt;  response["tasks_total"] = len(task_set_result.results) &lt;br /&gt;  &lt;br /&gt;  if chord_result.state == celery.states.PENDING:    &lt;br /&gt;    response["status"] = "pending"&lt;br /&gt;    &lt;br /&gt;  elif chord_result.state == celery.states.STARTED:&lt;br /&gt;    response["status"] = "started"&lt;br /&gt;&lt;br /&gt;  elif chord_result.state == celery.states.RETRY:&lt;br /&gt;    response["status"] = "retry"&lt;br /&gt;&lt;br /&gt;  elif chord_result.state == celery.states.RETRY:&lt;br /&gt;    response["status"] = "failure"&lt;br /&gt;    &lt;br /&gt;  elif chord_result.state == celery.states.SUCCESS:&lt;br /&gt;    response["status"] = "successful"&lt;br /&gt;    response["result"] = chord_result.result&lt;br /&gt;&lt;br /&gt;  return Structure2JsonResponse(response)&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/3343374414660307054-487882564285187213?l=www.manasupo.com' alt='' /&gt;&lt;/div&gt;</description><link>http://www.manasupo.com/2012/03/chord-progress-in-celery.html</link><author>noreply@blogger.com (supo)</author><thr:total>1</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3343374414660307054.post-6111837435873595027</guid><pubDate>Fri, 06 Jan 2012 15:00:00 +0000</pubDate><atom:updated>2012-01-06T16:00:31.053+01:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>latex</category><category domain='http://www.blogger.com/atom/ns#'>tips</category><category domain='http://www.blogger.com/atom/ns#'>tutorial</category><title>pdfx.sty date conversion</title><description>Hi everybody,&lt;br /&gt;&lt;br /&gt;there has been a bazillion changes in my life (finishing the Google internship and working in my startup fulltime) and I want to sum that up in another post. This is just a quick tip for people who want to generate &lt;a href="http://en.wikipedia.org/wiki/PDF/X"&gt;PDF/X&lt;/a&gt; files with LaTeX.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;Some resources:&lt;br /&gt;&lt;a href="http://ctan.org/tex-archive/macros/latex/contrib/pdfx"&gt;http://ctan.org/tex-archive/macros/latex/contrib/pdfx&lt;/a&gt;&lt;br /&gt;&lt;a href="http://support.river-valley.com/wiki/index.php?title=Generating_PDF/A_compliant_PDFs_from_pdftex"&gt;http://support.river-valley.com/wiki/index.php?title=Generating_PDF/A_compliant_PDFs_from_pdftex&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;From there, you want to make sure you handle your color profiles:&lt;br /&gt;&lt;a href="http://www.colormanagement.org/en/isoprofile.htm"&gt;http://www.colormanagement.org/en/isoprofile.htm&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;One issue I run into with pdfx.sty a couple of times is a date conversion function, that in the original looks something like this:&lt;br /&gt;&lt;pre class="brush: as3"&gt;\def\convertDate{\getYear}&lt;br /&gt;{\catcode`\D=12&lt;br /&gt; \gdef\getYear D:#1#2#3#4{\edef\xYear{#1#2#3#4}\getMonth}&lt;br /&gt;}&lt;br /&gt;\def\getMonth#1#2{\edef\xMonth{#1#2}\getDay}&lt;br /&gt;\def\getDay#1#2{\edef\xDay{#1#2}\getHour}&lt;br /&gt;\def\getHour#1#2{\edef\xHour{#1#2}\getMin}&lt;br /&gt;\def\getMin#1#2{\edef\xMin{#1#2}\getSec}&lt;br /&gt;\def\getSec#1#2{\edef\xSec{#1#2}\getTZh}&lt;br /&gt;\def\getTZh +#1#2{\edef\xTZh{#1#2}\getTZm}&lt;br /&gt;\def\getTZm '#1#2'{%&lt;br /&gt;    \edef\xTZm{#1#2}%&lt;br /&gt;    \edef\convDate{\xYear-\xMonth-\xDay&lt;br /&gt;      T\xHour:\xMin:\xSec+\xTZh:\xTZm}}&lt;br /&gt;\expandafter\convertDate\pdfcreationdate&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The problem with this piece of code is that it hard-codes the time format produced by &lt;b&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;\pdfcreationdate&lt;/span&gt;&lt;/b&gt; which seems to be different on different platforms (Miktex,Tex-live etc). This particular code expects the date to look like this:&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;D:20091202141420+05'00'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;However people around the Internets are running into errors if their date has '-' instead of the '+' sign. The fix for that is simple, just substitute the sign in the above snippet. Btw the error looks like this:&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;! Use of \getTZh doesn't match its definition.&lt;br /&gt;&lt;inserted text=""&gt; D:20120106132719Z&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;l.132 \expandafter\convertDate\pdfcreationdate&lt;/inserted&gt;&lt;/blockquote&gt;&lt;br /&gt;The time format that I've got from &lt;b&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;\pdfcreationdate&lt;span style="font-family: inherit;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;was even more off:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;D:20120106135936Z&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;To parse this, I had to rewrite the function entirely:&lt;br /&gt;&lt;pre class="brush: as3"&gt;\def\convertDate{\getYear}&lt;br /&gt;{\catcode`\D=12&lt;br /&gt; \gdef\getYear D:#1#2#3#4{\edef\xYear{#1#2#3#4}\getMonth}&lt;br /&gt;}&lt;br /&gt;\def\getMonth#1#2{\edef\xMonth{#1#2}\getDay}&lt;br /&gt;\def\getDay#1#2{\edef\xDay{#1#2}\getHour}&lt;br /&gt;\def\getHour#1#2{\edef\xHour{#1#2}\getMin}&lt;br /&gt;\def\getMin#1#2{\edef\xMin{#1#2}\getSec}&lt;br /&gt;\def\getSec#1#2#3{&lt;br /&gt;    \edef\xSec{#1#2}&lt;br /&gt;    \edef\convDate{\xYear-\xMonth-\xDay T\xHour:\xMin:\xSec}%&lt;br /&gt;}&lt;br /&gt;\expandafter\convertDate\pdfcreationdate&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I will add to this article after I run the pdf through Distiller to check the PDF/X compliance.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3343374414660307054-6111837435873595027?l=www.manasupo.com' alt='' /&gt;&lt;/div&gt;</description><link>http://www.manasupo.com/2012/01/pdfxsty-date-conversion.html</link><author>noreply@blogger.com (supo)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3343374414660307054.post-7788142757584276999</guid><pubDate>Sun, 11 Sep 2011 15:29:00 +0000</pubDate><atom:updated>2011-09-11T17:29:20.799+02:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>movies</category><category domain='http://www.blogger.com/atom/ns#'>data-mining</category><category domain='http://www.blogger.com/atom/ns#'>web</category><title>opensubtitles.com pretending to be big</title><description>For one of my datamining projects, I decided to spend a weekend trying to find out &lt;b&gt;how many subtitles you can actually get online for free&lt;/b&gt;. It took a bit of parallel python writing to scrape an entire website but I found a surprising discrepancy between the claimed database size and the actual number of subtitles they provide.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;b&gt;Opensubtitles.com&lt;/b&gt;&amp;nbsp;claims to be and is addressed in various blogs as the biggest subtitle database online.&lt;br /&gt;&lt;br /&gt;Claimed statistics:&lt;br /&gt;&lt;b&gt;68912 &lt;/b&gt;- movie count&lt;br /&gt;&lt;b&gt;1394569 &lt;/b&gt;- subtitle count&lt;br /&gt;&lt;br /&gt;Actual statistics:&lt;br /&gt;&lt;b&gt;5486 &lt;/b&gt;- movie count&lt;br /&gt;&lt;b&gt;20003 &lt;/b&gt;- subtitle count&lt;br /&gt;&lt;br /&gt;with top 5 languages being:&lt;br /&gt;4029&amp;nbsp;English&lt;br /&gt;2680&amp;nbsp;Polish&lt;br /&gt;1876&amp;nbsp;Portuguese-BR&lt;br /&gt;1643&amp;nbsp;Romanian&lt;br /&gt;1061&amp;nbsp;Spanish&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;They are hiding the actual deficit in plain sight, check e.g.:&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.opensubtitles.org/en/search/sublanguageid-all/moviename-a/offset-1040"&gt;http://www.opensubtitles.org/en/search/sublanguageid-all/moviename-a/offset-1040&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.opensubtitles.org/en/search/sublanguageid-all/moviename-a/offset-1080"&gt;http://www.opensubtitles.org/en/search/sublanguageid-all/moviename-a/offset-1080&lt;/a&gt;&lt;/div&gt;&lt;div&gt;these are 2 consecutive pages in the list of subtitles they provide. Starting with the page 27 and 28 the rest of the 1438 pages provide identical contents.&lt;br /&gt;&lt;br /&gt;On the other hand, this could be some kind of very strange bug on their part. But it seems very unlikely given the nature of the issue.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3343374414660307054-7788142757584276999?l=www.manasupo.com' alt='' /&gt;&lt;/div&gt;</description><link>http://www.manasupo.com/2011/09/opensubtitlescom-pretending-to-be-big.html</link><author>noreply@blogger.com (supo)</author><thr:total>3</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3343374414660307054.post-784924463757601224</guid><pubDate>Wed, 17 Aug 2011 14:09:00 +0000</pubDate><atom:updated>2011-08-17T17:59:56.578+02:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>tips</category><category domain='http://www.blogger.com/atom/ns#'>tutorial</category><category domain='http://www.blogger.com/atom/ns#'>job</category><category domain='http://www.blogger.com/atom/ns#'>Switzerland</category><title>Looking for a job in Switzerland</title><description>&lt;span style="font-weight: bold;"&gt;My story&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;I came to Switzerland on the 15th of July and I already have a job, but I wouldn't say that it is easy to find a job here. It depends on your field, I'm structural engineer, so I'm writing from my point of view. I sent 22 emails and had 3 interviews until I got a job. I made a spreadsheet so I know where and when I sent an email, what they replied and more details (Danny's idea), very useful. I will write you some tips, which can help you to find a job. &lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Language&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;- if you speak German you have a BIG advantage (or French, Italian, depends on the part of Switzerland) &lt;br /&gt;&lt;br /&gt;- if you don't speak, you have to learn as soon as possible &lt;br /&gt;&lt;br /&gt;- &lt;a href="http://www.radio24.ch/"&gt;http://www.radio24.ch/&lt;/a&gt; radio with Swiss German &lt;br /&gt;&lt;br /&gt;- &lt;a href="http://zattoo.com/"&gt;http://zattoo.com/&lt;/a&gt; online German channels &lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Curriculum Vitae&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;- &lt;a href="https://europass.cedefop.europa.eu/"&gt;https://europass.cedefop.europa.eu/&lt;/a&gt; here you can create a good looking CV &lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Certificates&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;- if you have some certificates don't forget to scan them and attach to your application &lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Job offers&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;- &lt;a href="http://www.jobwinner.ch/"&gt;http://www.jobwinner.ch/&lt;/a&gt; on this website you can have your profile with all information about you and documents, so when you find an offer you like, you just write your cover letter and send an application with all information, which you have in your profile. But I prefer to write email directly to the company. Another advantage of this website is, that you can choose your field and new offers are sent to your email every day, that's really helpful &lt;br /&gt;&lt;br /&gt;- &lt;a href="http://www.jobs.ch/en/"&gt;http://www.jobs.ch/en/&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;- &lt;a href="http://www.ingjobs.ch/de/"&gt;http://www.ingjobs.ch/de/&lt;/a&gt; this is mostly for technical fields &lt;br /&gt;&lt;br /&gt;- &lt;a href="http://www.alpha.ch/"&gt;http://www.alpha.ch/&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;- of course there are more websites &lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Hiring&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;- many companies look for employees through recruiting agencies, which can be good, because they are trying to find a job for you, while they have money from that, but you don't know the company you are applying for &lt;br /&gt;&lt;br /&gt;- better is to find offer of real company and check their website, do some research about their references and then you can make a better impression &lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Luck&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;- this is also very important part of looking for a job, so I wish you good luck ;) &lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/-9LLRDGinl8s/Tkve939-3LI/AAAAAAAAAG8/xN1EsKVzW9o/s1600/Spreadsheet.png"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5641848112788987058" src="http://3.bp.blogspot.com/-9LLRDGinl8s/Tkve939-3LI/AAAAAAAAAG8/xN1EsKVzW9o/s320/Spreadsheet.png" style="cursor: pointer; display: block; height: 151px; margin: 0px auto 10px; text-align: center; width: 320px;" /&gt;&lt;/a&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3343374414660307054-784924463757601224?l=www.manasupo.com' alt='' /&gt;&lt;/div&gt;</description><link>http://www.manasupo.com/2011/08/looking-for-job-in-switzerland.html</link><author>noreply@blogger.com (mana)</author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-9LLRDGinl8s/Tkve939-3LI/AAAAAAAAAG8/xN1EsKVzW9o/s72-c/Spreadsheet.png' height='72' width='72'/><thr:total>1</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3343374414660307054.post-6475595658706079161</guid><pubDate>Fri, 15 Jul 2011 21:47:00 +0000</pubDate><atom:updated>2012-01-06T16:03:55.239+01:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>google</category><category domain='http://www.blogger.com/atom/ns#'>report</category><title>Interning at Google - Week 2</title><description>The whirlpool is starting to spin and I am being pulled in. The infrastructure at our disposal is literally scary in both the scale and complexity of control and processes. Among the highlights of the second week, I had a lecture given by &lt;a href="http://en.wikipedia.org/wiki/Bram_Moolenaar"&gt;Bram Moolenaar&lt;/a&gt;&amp;nbsp;the original author of our daily awesome&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Vim_%28text_editor%29"&gt;Vim&lt;/a&gt;&amp;nbsp;(shook his hand yay!) and the guy (can't remember the name:() who created the OO features in &lt;a href="http://www.php.net/"&gt;PHP&lt;/a&gt;&amp;nbsp;proudly wearing &lt;a href="http://www.flickr.com/photos/caseysoftware/2861098256/"&gt;this&lt;/a&gt; on his laptop.&lt;br /&gt;Holding on :-)&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;Among the things I did during my Week 2 as a Software Engineer at Google are:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;rock the medium difficulty on &lt;b&gt;Battery&lt;/b&gt; by Metallica on drums in XBox Rock band&lt;/li&gt;&lt;li&gt;run a sequence of &lt;a href="http://en.wikipedia.org/wiki/MapReduce"&gt;MapReduce&lt;/a&gt; tasks on 50T of data, using 2000 computing nodes&lt;/li&gt;&lt;li&gt;kick some ass and sometimes get my ass kicked in table tennis&lt;/li&gt;&lt;li&gt;come from work after midnight 3 days out of 5&lt;/li&gt;&lt;li&gt;get LOLs out of TONS of easter eggs hidden in various log/status outputs of various tools, that are stylized after various scify/fantazy franchises - you just hear people laughing in the office while they analyze a log dump from some random server/process/etc :-D&lt;/li&gt;&lt;li&gt;and last but not least, visit more classes than during a normal week at my old Uni.&lt;/li&gt;&lt;/ul&gt;I am starting to recognise some of the code-names people use in meetings and I am starting to see the real shape of what I'll be doing. So, so far so good ;-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3343374414660307054-6475595658706079161?l=www.manasupo.com' alt='' /&gt;&lt;/div&gt;</description><link>http://www.manasupo.com/2011/07/interning-at-google-week-2.html</link><author>noreply@blogger.com (supo)</author><thr:total>5</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3343374414660307054.post-2875422973453592204</guid><pubDate>Sat, 09 Jul 2011 21:52:00 +0000</pubDate><atom:updated>2012-03-02T18:48:43.410+01:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>slovak</category><category domain='http://www.blogger.com/atom/ns#'>thoughts</category><category domain='http://www.blogger.com/atom/ns#'>fiit</category><category domain='http://www.blogger.com/atom/ns#'>review</category><category domain='http://www.blogger.com/atom/ns#'>report</category><title>Fakulta Informatiky a Informačných technológií - FIIT</title><description>Pred pár týždňami som ukončil štúdium FIIT na STU v Bratislave, s titulom Ing. v obore Softvérové Inžinierstvo. Počas tých 5 rokov som stretlol nových ľudí, ktorí ma prekvapili aj v dobrom aj v zlom, starých známich som lepšie spoznal a čo-to nové som sa aj naučil. V tomto článku by som chcel zhrnúť moje pôsobenie na FIIT a zhruba načrtnúť stratégiu, ktorou som sa týchto 5 rokov riadil a na záver si dáme &lt;b&gt;dolovanie v dátach zo sekcie &lt;a href="http://www.fiit.stuba.sk/generate_page.php?page_id=402"&gt;Galéria študentov&lt;/a&gt; na webe fakulty&lt;/b&gt; ;-)&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;V prvom rade treba uviesť dôvody, pre ktoré som si FIIT vybral, po mojom štúdiu na Gymnáziu Jura Hronca (GJH). Jednak ma zaujala súťaž &lt;a href="http://profiit.fiit.stuba.sk/uvod.html"&gt;ProFIIT&lt;/a&gt;, ktorá sľubovala body extra na prímačky za riešenie programátorských úloh. Tiež som sa dozvedel, že na predmete TEAP sa dá dostať Á-čko za dobré umiestnenie na súťažiach &lt;a href="http://www.topcoder.com/tc"&gt;www.topcoder.com/tc&lt;/a&gt;, aj ked pred nástupom na FIIT som mal absolvovaných len zopár súťaží.&amp;nbsp;Otec mi raz povedal príhodu o Matfyzákovi, ktorý u nich vo firme nedokázal prakticky aplikovať svoje vedomosti a presadiť sa. Jasné, vytvoriť si názor na základe jedného človeka nie je správne. Moje rozhodnutie tiež ovplyvnili spolužiaci z GJH, ktorý, aspon čo sa týka našej triedy išli väčšina na FIIT. Aj keď FIIT nie je raj na zemi, teraz už viem, že som si vôbec nevybral zle.&lt;br /&gt;&lt;br /&gt;Prvé dva roky na FIIT som strávil preliezaním povinných predmetov tak nejak aby sa nepovedalo a väčšinu voľného času som investoval do štúdia algoritmov a zadaní z programátorských súťaží. Na &lt;a href="http://spoj.pl/"&gt;http://spoj.pl&lt;/a&gt;&amp;nbsp;a podobných weboch som vyriešil stovky príkladov, na &lt;a href="http://www.topcoder.com/tc?module=MemberProfile&amp;amp;cr=20883846"&gt;TopCoderi&lt;/a&gt;&amp;nbsp;absolvoval stovku súťaží, prečítal desiatky článkov popisujúcich algoritmy zo všetkých možných oblastí informatiky. Prvý rok sa mi s Mišom Lohnickým nepodarilo postúpiť ani do regionálneho kola ACM, v Česko-Slovenskom kole sme skončili na 33 mieste, ako 6ty tím z FIIT. V druhom ročníku sme boli na ČR kole na 3. mieste a prvý z FIIT. Naše umiestnenie na regionálnom kole bolo samozrejme horšie, ale až do konca školi sme zostali prvý tím FIIT a aj prvý tím z tech. univerzít v ČR. Možno by to so súťažami dopadlo inak, keby sme sa tomu venovali celých 5 rokov. Trénovať algoritmy na FIIT nebolo v tej dobe jednoduché, lebo sme na to boli sami, neboli žiadne krúžky ani mentoring. Rovnako nebolo jednoduché presadiť sa medzi Matfyzákmi, ktorí už na strednej škole súťažili na medzinárodných olympiádach zatiaľ čo my sme &lt;a href="http://www.youtube.com/watch?v=DWxUhkXdKgg"&gt;jazdili na bicykli&lt;/a&gt;. V konečnom dôsledku však umiestnenie na súťažiach nie je až tak dôležité, aj keď fakt, že som bol v 2008 v Google Zurich na európskom finále Google Code Jam, vyzerá na CV dobre. Ovela viac som však prosperoval a prosperujem zo skúseností a nadhľadu, ktoré tréning na súťaže vytvoril.&lt;br /&gt;&lt;br /&gt;V treťom ročníku nastal čas riešiť bakalárku a tak sme s Mišom dali dokopy tím s Martinom Labajom a Petrom Líškom a rok v kuse sme riešili študentskú softvérovú súťaž &lt;a href="http://www.imaginecup.com/"&gt;Imagine Cup&lt;/a&gt; organizovanú Microsoftom, v ktorej sme reprezentovali Slovensko na svetovom finále v Káhire. Projekt, ktorý nás posunul najmä v schopnosti predať sa, prezentovať a hovoriť s a pred ľudmi sa dá &lt;a href="http://imaginecup.fiit.stuba.sk/2009/index_en.html"&gt;pozrieť tu&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;V tomto období som už registroval tie dve skupiny ľudí a predmetov, ktoré sú okolo FIIT zformované:&lt;br /&gt;&lt;br /&gt;Skupina &lt;a href="http://wiki.fiit.stuba.sk/research/seminars/pewe/"&gt;PeWe&lt;/a&gt;, za kormidlom ktorej stojí Prof. Bieliková,&amp;nbsp;sa zaoberá personalizovaním webu prostredníctvom výskumu (v NLP, user modelingu, odporúčacích, vizualizačných a vzdelávacích systémoch atp.), ktorý sa následne aplikuje a overuje prostredníctvom realizácie rôznych projektov, ktoré sú nasádzané či už na fakulte alebo mimo napr. v &lt;a href="http://www.sme.sk/cocitat/"&gt;spoluprácii so SME&lt;/a&gt;. Skupina má veľký počet členov a tak podrobnosti hladajte na spomenutom odkaze. Členovia tejto skupiny sa často starajú o predmety Softvérového inžinierstva, procesov tvorby softvéru a pod.&lt;br /&gt;&lt;br /&gt;Skupina na &lt;a href="http://www.fiit.stuba.sk/generate_page.php?page_id=2515"&gt;Ústave aplikovanej informatiky&lt;/a&gt;&amp;nbsp;a príbuzných svoj výskum sústredí na oblasť umelej inteligencie, optimalizácie riešení rôznych NP úplnych problémov, strojového učenia, teórii hier a pod. Počas štúdia som sa viac stotožňoval práve s týmto táborom a snažil som sa pomôcť prípravou súťaže ProFIIT a trocha neskôr predmetu TEAP. Členovia tejto skupiny sa podielajú na predmetoch ako Maticové algoritmy, Tvorba efektívnych algoritmov a programov, Evolučné algoritmy, Umelá inteligencia a pod.&lt;br /&gt;&lt;br /&gt;Počas leta medzi 4 a 5 ročníkom som bol vybratý na stáž Great Minds v IBM Research Zurich, kde som napísal svoj prvý vážnejší článok na medzinárodnú IEEE konferenciu ICDM 2010 a získal kopu zaujímavých skúseností a kontaktov. V poslednom roku som dokončil diplomovú prácu a článok ako výcuc z nej, ktorého prijatie na ICDM 2011 sa dozviem za pár mesiacov. V priebehu posledného ročníka som tiež podstúpil prijímací proces pre stáž v Google Zurich, na ktorú som práve v týchto dňoch nastúpil.&lt;br /&gt;&lt;br /&gt;Nádskok a akýsi "image", ktorý som získal počas prvých 2 rokov školy a schopnosť predať sa, ktorú som vycibril v ročníku treťom mi pomoholi vo viacerých predmetoch a povinnostiach, vďaka čomu som štúdiu na FIIT ako takému nikdy nevenoval viac ako pár týždňov čistého času v rámci jedného semestra. Na väčšine predmetov sa dalo s vyučujúcimi rôzne dohodnúť keď videli, že učivo ovládam. Myslím si, že toto je dobrá stratégia na absolvovanie FIIT a vytvorí priestor aj na &lt;a href="http://www.47posters.com/"&gt;založenie firmy&lt;/a&gt; v neskorších ročníkoch, prípadne asi aj na prácu na full-time.&lt;br /&gt;&lt;br /&gt;Dúfam, že sa mi podarilo ilustrovať jeden zo spôsobov, ako naložiť s 5 rokmi života počas štúdia na FIIT a dospieť k zaujímavému výsledku. Stretol som sa s ľudmi, ktorý si myslia, že takto je to možné len na Matfyze. Som rád, že sa mi podarilo ukázať, že je to hlavne o človeku. Chcel by som tiež poďakovať všetkým, s ktorými som sa na FIIT posunul dopredu.&lt;br /&gt;&lt;br /&gt;Na záver som si dovolil stiahnuť 18 stránok zo sekcie &lt;a href="http://www.fiit.stuba.sk/generate_page.php?page_id=402"&gt;Galéria študentov&lt;/a&gt; na &lt;a href="http://www.fiit.stuba.sk/"&gt;www.fiit.stuba.sk&lt;/a&gt;, okrem pod-stránky s rozhovormi so študentami, pretože tieto rozhovory zväčša nadvezujú na úspech spomenutý v niektorej inej pod-stránke. Jednoduchým python skriptom som potom extrahoval zo surového html mená. V zásade ide o ľudí, ktorý sa nejakým spôsobom aktivizovali na fakulte (či už ako autori alebo supervisori úspešných článkov na IIT.SRC alebo ocenených záverečných prác, alebo ako súťažiaci v rôznych informatických súťažiach, od Cisco Olymp cez ACM SRC až po ACM ICPC). Niektoré veci ešte nie sú vyhodnotené pre tento školský rok a preto je poradie len približné ;-) Číslo v prvom stĺpci značí celkový počet výskytov daného mena.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;16 Mária Bieliková&lt;br /&gt;13 Michal Tvarožek&lt;br /&gt;11 &lt;b&gt;Daniel Švoňava&lt;/b&gt;&lt;br /&gt;9 Michal Dobiš&lt;br /&gt;8 Michal Barla&lt;br /&gt;8 Michal Lohnický&lt;br /&gt;7 Martin Labaj&lt;br /&gt;6 Marek Tomša&lt;br /&gt;6 Martin Adam&lt;br /&gt;6 Richard Veselý&lt;br /&gt;6 Vladimír Michalec&lt;br /&gt;5 Jakub Šimko&lt;br /&gt;5 Karol Rástočný&lt;br /&gt;5 Marián Šimko&lt;br /&gt;5 Michal Kompan&lt;br /&gt;5 Márius Šajgalík&lt;br /&gt;5 Peter Bartalos&amp;nbsp;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3343374414660307054-2875422973453592204?l=www.manasupo.com' alt='' /&gt;&lt;/div&gt;</description><link>http://www.manasupo.com/2011/07/fakulta-informatiky-informacnych.html</link><author>noreply@blogger.com (supo)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3343374414660307054.post-6952019865373314432</guid><pubDate>Tue, 05 Jul 2011 20:43:00 +0000</pubDate><atom:updated>2011-07-05T22:55:58.087+02:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>google</category><category domain='http://www.blogger.com/atom/ns#'>report</category><title>Software Engineering at Google</title><description>For 2011 I wanted to try something new again and when I was approached by Google after the &lt;a href="http://code.google.com/codejam/"&gt;Google Code Jam&lt;/a&gt; 2011 (I just placed in top 500, nothing too special, but I got a t-shirt :-P) I agreed to start the interview process. After 2 technical interviews, I was offered a Software Engineering Intern position at the Google Zurich office, which I joyfully accepted. This is the first post about the experience, since I started just yesterday, on the 4th of July.&lt;br /&gt;&lt;br /&gt;I will not be able to disclose any details of course, and will have to be super careful, because of how sensitive some information can be and how strict Google is about this.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;In the one and half of a working day, I already managed to:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;talk with about 50 people as I was testing the widely encouraged "butting into a conversation" at Google. Everywhere I butted in I was automatically included in the discussion, it really works :-)&lt;/li&gt;&lt;li&gt;taste food in every micro-kitchen (places around the office where you can make a coffee in a professional Italian machine, cornflakes with milk, bread with ham and vegies, find various fruits, sweets, drinks, sushi and other snacking items)&lt;/li&gt;&lt;li&gt;try dining a healthy vegetable salad (at least until a cook started grilling meat on the terrace :-D )&lt;/li&gt;&lt;li&gt;get instructed on how to use a professional coffee machine by two doctors and one professor, with the main speaker being Italian! &lt;/li&gt;&lt;/ul&gt;Sounds like a nice place to work so far? To top the cake, I was equipped by a cutting edge hardware to perform my work duties (PC and laptop that sum to 20GB of RAM, you can guess the rest ;-) ).&lt;br /&gt;&lt;br /&gt;These days, I will be getting accustomed to the environment, play with &lt;a href="http://en.wikipedia.org/wiki/MapReduce"&gt;MapReduce&lt;/a&gt; and brainstorming the final shape of the project I will be working on for the next 5+ months in the &lt;a href="http://googleblog.blogspot.com/2009/09/place-pages-for-google-maps-there-are.html"&gt;Place Page&lt;/a&gt; team within Google Maps.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3343374414660307054-6952019865373314432?l=www.manasupo.com' alt='' /&gt;&lt;/div&gt;</description><link>http://www.manasupo.com/2011/07/software-engineering-at-google.html</link><author>noreply@blogger.com (supo)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3343374414660307054.post-7924467150348884112</guid><pubDate>Tue, 05 Jul 2011 19:43:00 +0000</pubDate><atom:updated>2011-07-05T21:45:18.959+02:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>research</category><category domain='http://www.blogger.com/atom/ns#'>programming</category><category domain='http://www.blogger.com/atom/ns#'>ibm</category><category domain='http://www.blogger.com/atom/ns#'>report</category><title>Great Minds at IBM Research</title><description>For the sumer 2010, I was chosen to join the Great Minds programme for research-oriented computer science students, organized by &lt;a href="http://www.zurich.ibm.com/"&gt;IBM Research Laboratory&lt;/a&gt; in Zurich, Switzerland. This article is a small summary of my observations.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;The environment and the atmosphere in the laboratory is a mixture of 2 seemingly un-compatible things:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;commercial company optimizing all the processes, client cooperation and staff efforts to &lt;b&gt;generate profit&lt;/b&gt;&lt;/li&gt;&lt;li&gt;academic institution seeking to produce cutting edge research results, where scientists work in small focused groups on the topics that or of interest &lt;b&gt;to them&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;From my experience, the working time is divided between the work on a commercial project (either a self standing prototype, or on some "smart" part of a bigger IBM project) and the work on a research idea with possibly different team of people. The ratio of these two activities is of course different for different people, but in general it is ones responsibility to manage the time, to both meet the commercial project deadlines and to progress with researching, paper/patent writing etc.&lt;br /&gt;&lt;br /&gt;I personally joined the group working on a business intelligence tool:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.zurich.ibm.com/mcs/infoanalytics/marketing_sales.html"&gt;http://www.zurich.ibm.com/mcs/infoanalytics/marketing_sales.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;and I teamed up with a colleague from the Analytics group to write a paper about high-dimensional data visualization, that was accepted to &lt;a href="http://datamining.it.uts.edu.au/icdm10/"&gt;ICDM 2010&lt;/a&gt; (sub 20% acc. rate) and I presented it in Sydney in December:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.computer.org/portal/web/csdl/doi/10.1109/ICDM.2010.71"&gt;http://www.computer.org/portal/web/csdl/doi/10.1109/ICDM.2010.71&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;All in all, I enjoyed the combination of having the freedom in choosing and pursuing research ideas while also being confronted with the real clients expecting a working tool and the overall context of commerce.&lt;br /&gt;&lt;br /&gt;Ps:&lt;br /&gt;&lt;br /&gt;I spoke about the experience from the perspective of finishing Master/Ing students at a local Computer Science conference, you can find the slides (albeit for some reason they got damaged by SlideShare and the presentation is in Slovak) &lt;a href="http://slidesha.re/k2zoGR"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3343374414660307054-7924467150348884112?l=www.manasupo.com' alt='' /&gt;&lt;/div&gt;</description><link>http://www.manasupo.com/2011/07/great-minds-at-ibm-research.html</link><author>noreply@blogger.com (supo)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3343374414660307054.post-2842319274505369461</guid><pubDate>Wed, 20 Apr 2011 18:10:00 +0000</pubDate><atom:updated>2011-04-20T20:11:20.658+02:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>algorithms</category><category domain='http://www.blogger.com/atom/ns#'>programming-competitions</category><category domain='http://www.blogger.com/atom/ns#'>teap</category><title>First team to win N games</title><description>This is just a quick post for "my" TEAP students who couldn't solve one problem and I promised to show some code (I normally don't do that ;-).&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Problem&lt;/b&gt;&lt;br /&gt;Two teams (A and B) are competing against each other. They proceed to play games in sequence until one of them wins exactly N times. This team is said to be the winner of the sequence.&lt;br /&gt;We have the probability P of the team A winning a single game. Also there can never be a draw.&lt;br /&gt;Given P and N, calculate the probability of A winning the game.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Solution&lt;/b&gt;&lt;br /&gt;The simplest way to solve this is by recursion. We define a function that calculates the solution after A won &lt;b&gt;a&lt;/b&gt; games and B won &lt;b&gt;b&lt;/b&gt; games. I used Python to get the exact solution. Code:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:python"&gt;def solve(a,b,N,P):&lt;br /&gt;  #left something out here ;-) &lt;br /&gt;  return solve(a+1,b,N,P)*(P/Decimal(100)) + &lt;br /&gt;         solve(a,b+1,N,P)*(Decimal(1)-P/Decimal(100))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;See how cool Python is? I believe that you can manage the rest of the solution on your own ;-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3343374414660307054-2842319274505369461?l=www.manasupo.com' alt='' /&gt;&lt;/div&gt;</description><link>http://www.manasupo.com/2011/04/first-team-to-win-n-games.html</link><author>noreply@blogger.com (supo)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3343374414660307054.post-8183327597269460036</guid><pubDate>Thu, 07 Apr 2011 18:09:00 +0000</pubDate><atom:updated>2011-04-07T20:09:10.280+02:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>thoughts</category><title>Conversational style</title><description>The problem of using conversational style while communicating or publishing on the Internet is that if written down and consumed without the context of the given moment in time and environment, body language and relation to the writer, it often comes through as illiteracy bordering with rudeness.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3343374414660307054-8183327597269460036?l=www.manasupo.com' alt='' /&gt;&lt;/div&gt;</description><link>http://www.manasupo.com/2011/04/conversational-style.html</link><author>noreply@blogger.com (supo)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3343374414660307054.post-2776363035993317748</guid><pubDate>Mon, 04 Apr 2011 13:53:00 +0000</pubDate><atom:updated>2011-04-04T15:54:41.123+02:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>algorithms</category><category domain='http://www.blogger.com/atom/ns#'>tutorial</category><category domain='http://www.blogger.com/atom/ns#'>programming</category><title>Dynamic programming checklist</title><description>There are many articles that talk about this programming technique, but I have never seen complete and generic step by step tutorial on how to deal with Dynamic programming problems. So here I present mine suited to my personal taste, but you may still find it useful.&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;div style="font-weight: bold; text-align: center;"&gt;&lt;div style="text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Analysis&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;span class="Apple-style-span"&gt;Design the solution using a recursive function. Just use the first naive function that solves the problem. For this you should define:&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;ul&gt;&lt;li&gt;arguments of the function, that wholly describe the problem you are trying to solve&lt;/li&gt;&lt;li&gt;recursive relation, that describes how the arguments are changed and fed to the recursive call of the function&lt;/li&gt;&lt;li&gt;trivial case, the set of arguments that represents an instance of your problem, that is trivial to solve (like maximum of single element set, or sum of the empty set of numbers etc.)&lt;/li&gt;&lt;/ul&gt;&lt;div style="text-align: left;"&gt;If the number of different sets of arguments is too big, you have to find a representation of your problem that reduces this number. Here you have to exploit properties of the problem and ask yourself, do I really need X to represent the problem? Are all the bits of X used in the computations that the function does? Try to throw most of the X away and maybe introduce other small 'helper' arguments if that helps. Here are some common ways to reduce the number of different arguments:&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;ul&gt;&lt;li&gt;Isn't it enough to pass X modulo something?&lt;/li&gt;&lt;li&gt;What about only the first and last&amp;nbsp;char/digit/number of X?&lt;/li&gt;&lt;li&gt;Or store the original problem in a global variable and pass only an index into it and maybe some other small argument Y.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;ul&gt;&lt;/ul&gt;&lt;div style="text-align: center;"&gt;&lt;div style="text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;&lt;b&gt;Implementation&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;This simple step turns your ugly exponential recursive function into a neat polynomial one (or at least less ugly exponential one), trading the time for memory.&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;ol&gt;&lt;li&gt;Implement that function as you designed it.&lt;/li&gt;&lt;li&gt;Introduce a global variable DP in which you will map already calculated results to corresponding arguments of the function.&lt;/li&gt;&lt;li&gt;Add a check at the start of your recursive function that searches for current arguments in DP. If the result has been already calculated for them, just return it.&lt;/li&gt;&lt;/ol&gt;This should be it, you are basically done. But there are times, when you are not quite there yet. What follows is:&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;div style="text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;&lt;b&gt;Optimization&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;In some cases, recursion is too &lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;slow. Every call of the recursive function takes some time, the memory on the stack needs to be assigned and so on. In this case, it &lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;may help to transform your recursion into iteration.&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;In other cases, the recursive tree&amp;nbsp;can be too deep, causing your stack to overflow. You can transform &lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;your solution to iteration, or if you are lazy like me, there is one &lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;other thing you can do.&amp;nbsp;Try to find out, for which arguments the recursion tree is deep and for which shallow. Like for example&amp;nbsp;your arguments are numbers up to one million and you find out that&amp;nbsp;for high number inputs the recursion is more shallow than it is when&amp;nbsp;dealing with lower numbers. What do you do? Just iterate from one &lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;million downwards and call the function on the numbers as you go!&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Next, the memory requirements for the global cache variable can be just a little too big. In this case it helps to do a kind of a &lt;a href="http://en.wikipedia.org/wiki/Breadth-first_search"&gt;BFS&lt;/a&gt;&amp;nbsp;instead of the&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Depth-first_search"&gt;DFS&lt;/a&gt;&amp;nbsp;your recursive function uses naturally.&amp;nbsp;&amp;nbsp;It can be done by converting&amp;nbsp;to iteration and then storing only a limited portion of the global variable in the memory. This case applies usually when the recursive&amp;nbsp;function moves '&lt;i&gt;slowly&lt;/i&gt;' in some dimension.&amp;nbsp;For example consider function like this, where &lt;b&gt;y&lt;/b&gt;&amp;nbsp;moves only in jumps of 1 and 2:&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;pre class="brush: cpp"&gt;int f(int x,int y)&lt;br /&gt;{&lt;br /&gt;  if (DP[x][y].is_computed()) return DP[x][y];&lt;br /&gt;  DP[x][y]=f(x+m,y+1)+f(x+n,y+2);&lt;br /&gt;  return DP[x][y];&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In this case, after converting to iteration, just 3 columns of the DP table are enough to be kept in &lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;the memory at the same time, regardless of the values of &lt;b&gt;m&lt;/b&gt; and &lt;b&gt;n&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;Finally, there is one more trick I would like to discuss. In some problems, that are solvable by DP, sometimes one dimension of the state space is ridiculously big (like 10&lt;sup&gt;9&lt;/sup&gt;). This is a dead giveaway of the technique so called Matrix Multiplication Boost (ok, I've just made the name up ;-) ). &lt;b&gt;MMB &lt;/b&gt;is applicable in cases, where the transitions between states of the problem have linear properties. Then, you can embed the whole state space (without the big dimension) in a vector &lt;b&gt;V&lt;/b&gt;.&amp;nbsp;Next, encode the transitions in the form of a matrix &lt;b&gt;M&lt;/b&gt;.&amp;nbsp;If everything works fine, the solution of &lt;b&gt;M * V&lt;/b&gt;&amp;nbsp;is a vector, that describes the same space as &lt;b&gt;V&lt;/b&gt;, except moved one step forward in terms of the big dimension mentioned before.&amp;nbsp;Now, to move &lt;b&gt;K&lt;/b&gt;&amp;nbsp;steps forward, you can just calculate &lt;b&gt;M&lt;sup&gt;K&lt;/sup&gt; * V&lt;/b&gt;.&amp;nbsp;See it? Instead of having to iterate over whole &lt;b&gt;K&lt;/b&gt;, you just rise &lt;b&gt;M &lt;/b&gt;to the &lt;b&gt;K&lt;sup&gt;th&lt;/sup&gt;&lt;/b&gt;&amp;nbsp;power. &lt;a href="http://en.wikipedia.org/wiki/Exponentiation_by_squaring"&gt;Matrix exponentiation&lt;/a&gt; can be calculated in O(&lt;b&gt;M&lt;sup&gt;3&lt;/sup&gt; * &lt;/b&gt;log(&lt;b&gt;N&lt;/b&gt;) ) where &lt;b&gt;N&lt;/b&gt; is the bigger dimension of &lt;b&gt;M&lt;/b&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3343374414660307054-2776363035993317748?l=www.manasupo.com' alt='' /&gt;&lt;/div&gt;</description><link>http://www.manasupo.com/2011/04/dynamic-programming-checklist.html</link><author>noreply@blogger.com (supo)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3343374414660307054.post-5560946214204742524</guid><pubDate>Mon, 04 Apr 2011 01:49:00 +0000</pubDate><atom:updated>2011-09-11T17:47:49.879+02:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>algorithms</category><category domain='http://www.blogger.com/atom/ns#'>visualization</category><category domain='http://www.blogger.com/atom/ns#'>programming</category><title>Gridder - Humongous spatial data visualization</title><description>I designed the Gridder algorithm as a part of my diploma thesis and I've been playing with it for some time now. I am trying to find datasets and use-cases for it, so if you get any ideas just leave a comment ;-)&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/--zPQUjXNrew/TZkADK3jmdI/AAAAAAAAAhU/VKL1QAm1CG0/s1600/just_map2_edges.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="260" src="http://2.bp.blogspot.com/--zPQUjXNrew/TZkADK3jmdI/AAAAAAAAAhU/VKL1QAm1CG0/s400/just_map2_edges.png" width="400" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;102,000 worlds biggest cities, plotted as dots. Applied mild edge glow filter for kicks.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;Without going into any sort of detail, the algorithm basically takes a set of spatial data points (coordinates + other data attributes) and creates a representation that:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;allows visualization of data attributes in the spatial context&lt;/li&gt;&lt;li&gt;provides&amp;nbsp;exploratory&amp;nbsp;navigation&lt;/li&gt;&lt;li&gt;does so very fast ( pre-process:&amp;nbsp;&lt;i&gt;O(N log N),&amp;nbsp;&lt;/i&gt;interaction: &lt;i&gt;O(1)&lt;/i&gt; )&lt;/li&gt;&lt;/ul&gt;That may seem a bit confusing so let me present an example. Imagine you take all the Earths cities with population greater than 1000, which there are about 102,000. For each city, you obtain coordinates, name label and population count. What would you do if you wanted to visualize this dataset?&lt;br /&gt;&lt;br /&gt;Well, if you just took those 102k points and plotted them as small dots to a 2D plane, you would get something like the plot above.&lt;br /&gt;&lt;br /&gt;It might be an interesting picture, but it is clear that you can not visualize the individual cities, let alone their labels this way, at least on this level of abstraction or "zoom". Sure, things would appear cleaner once you zoomed all the way to a particular city. The thing is, how do you know where to zoom? With this example data, you know approximately where to zoom because you know the data. With Gridder, I want to visualize data that you have never seen hence I need to provide a way to explore the data and give the user as much &lt;i&gt;&lt;b&gt;useful &lt;/b&gt;&lt;/i&gt;information as I can, on multiple levels of abstraction or resolution.&lt;br /&gt;&lt;br /&gt;Let's see an example of Gridder output for the above data at the given resolution combined with the satellite data visualization:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-MN5Ffx-MHnY/TZkURPkd5wI/AAAAAAAAAhY/51LZQ5Pij8A/s1600/world_map_16x16.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="261" src="http://2.bp.blogspot.com/-MN5Ffx-MHnY/TZkURPkd5wI/AAAAAAAAAhY/51LZQ5Pij8A/s400/world_map_16x16.png" width="400" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Gridder output with city attributes (see bellow)&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Here we notice a couple of things:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;general spatial characteristics (shape) of the data is preserved, especially for important (big) clusters&lt;/li&gt;&lt;li&gt;points are "normalized" to a relatively small number of rows and columns to reduce clutter and simplify interaction&lt;/li&gt;&lt;li&gt;grid intersections represent clusters of data, where for each cluster we see:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;the name of the representing city (biggest in the cluster population wise)&lt;/li&gt;&lt;li&gt;population of the representing city (green circle)&lt;/li&gt;&lt;li&gt;total number of cities in the cluster (yellow circle)&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;br /&gt;Some more examples on this dataset (different resolutions and grid sizes):&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-ng_7rfhRF2I/TZkc-Z51elI/AAAAAAAAAhc/4Gg5WLaM7T4/s1600/sydney_coast_16x16.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="261" src="http://2.bp.blogspot.com/-ng_7rfhRF2I/TZkc-Z51elI/AAAAAAAAAhc/4Gg5WLaM7T4/s400/sydney_coast_16x16.png" width="400" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;The coast of Australia, New South Wales and Sydney (16x16)&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-JiSdMpn_vhY/TZkdWPTQbSI/AAAAAAAAAhg/Qywc82PQO4c/s1600/china_coast_16x16.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="261" src="http://2.bp.blogspot.com/-JiSdMpn_vhY/TZkdWPTQbSI/AAAAAAAAAhg/Qywc82PQO4c/s400/china_coast_16x16.png" width="400" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Something more complex, lots of big cities&lt;br /&gt;The coast of China and Taiwan (16x16)&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-kVWWYtRk-gA/TZkeeG1E0GI/AAAAAAAAAhk/RTv9gDbM_HI/s1600/world_map_8x8.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="261" src="http://1.bp.blogspot.com/-kVWWYtRk-gA/TZkeeG1E0GI/AAAAAAAAAhk/RTv9gDbM_HI/s400/world_map_8x8.png" width="400" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;World view at 8x8&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;This last example reveals 3 interesting things about the data, that I (due to my general ignorance) never realized:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The cluster of Europe is labeled &lt;b&gt;Istanbul&lt;/b&gt;. I went to wikipedia and realized that in fact Istanbul is the 3rd most populated city in the world and hence takes the place of the representative.&lt;/li&gt;&lt;li&gt;The cluster of US southeast is labeled &lt;b&gt;Havana&lt;/b&gt;. It is actually a tad bigger then Huston and a lot bigger than Atalanta and other big cities in this area.&lt;/li&gt;&lt;li&gt;The European yellow dot is &lt;i&gt;huge, &lt;/i&gt;it actually is the biggest one on the map&lt;i&gt;. &lt;/i&gt;We have a lot more cities per square km than say USA (I am too lazy to confirm with some independent data). Note that my data only contains cities above 1000 inhabitants, if we took even smaller settlements Europe might be even further ahead.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Last plot, with an overlay of the actual data points:&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-Sp5H8-IlyOI/TZkrR5Dok6I/AAAAAAAAAhs/VPoK_jUrOK0/s1600/west_europe_16x16_overlay.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="261" src="http://3.bp.blogspot.com/-Sp5H8-IlyOI/TZkrR5Dok6I/AAAAAAAAAhs/VPoK_jUrOK0/s400/west_europe_16x16_overlay.png" width="400" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;A part of Western Europe&lt;br /&gt;Here the overlay lets you observe the difference&lt;br /&gt;between the actual coordinates and Gridder approximation&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3343374414660307054-5560946214204742524?l=www.manasupo.com' alt='' /&gt;&lt;/div&gt;</description><link>http://www.manasupo.com/2011/04/gridder-humongous-spatial-data.html</link><author>noreply@blogger.com (supo)</author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/--zPQUjXNrew/TZkADK3jmdI/AAAAAAAAAhU/VKL1QAm1CG0/s72-c/just_map2_edges.png' height='72' width='72'/><thr:total>1</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3343374414660307054.post-5791843569188944712</guid><pubDate>Thu, 31 Mar 2011 00:47:00 +0000</pubDate><atom:updated>2011-03-31T02:47:24.786+02:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>admin</category><category domain='http://www.blogger.com/atom/ns#'>tutorial</category><title>MySql job failed to start</title><description>I've got this message from MySQL, after importing some data and building indexes. The DB stopped responding and hitting the &lt;br /&gt;&lt;pre&gt;/etc/init.d/mysql restart&lt;/pre&gt;gave me the aforementioned very non-descriptive error. My problem was that the DB &lt;b&gt;didn't have enough disk space&lt;/b&gt; for some temp files, so increasing that solved the problem.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3343374414660307054-5791843569188944712?l=www.manasupo.com' alt='' /&gt;&lt;/div&gt;</description><link>http://www.manasupo.com/2011/03/mysql-job-failed-to-start.html</link><author>noreply@blogger.com (supo)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3343374414660307054.post-4740851067834062418</guid><pubDate>Sun, 27 Mar 2011 22:03:00 +0000</pubDate><atom:updated>2011-03-28T00:19:56.385+02:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>mobile</category><category domain='http://www.blogger.com/atom/ns#'>report</category><title>Pizza box architecture</title><description>Some pics from a brainstorming for my fathers new project after the jump - notice how we simulated the startup atmosphere by drawing on the pizza box ;-)&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-mrxEOI7eqb8/TY-3Mc_1LTI/AAAAAAAAAhQ/srlUdlW7wVo/s1600/joke.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="238" src="http://4.bp.blogspot.com/-mrxEOI7eqb8/TY-3Mc_1LTI/AAAAAAAAAhQ/srlUdlW7wVo/s400/joke.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-Y2Tcko1kKFQ/TY-zCxqhHFI/AAAAAAAAAhE/a8k4nlj1KzY/s1600/IMAG0236.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="238" src="http://3.bp.blogspot.com/-Y2Tcko1kKFQ/TY-zCxqhHFI/AAAAAAAAAhE/a8k4nlj1KzY/s400/IMAG0236.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/--fQTrwJ4OnQ/TY-zFwLZEfI/AAAAAAAAAhI/n-eFogPWrCM/s1600/IMAG0237.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="640" src="http://3.bp.blogspot.com/--fQTrwJ4OnQ/TY-zFwLZEfI/AAAAAAAAAhI/n-eFogPWrCM/s640/IMAG0237.jpg" width="380" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-J2C_OMT6edE/TY-zJNkBPYI/AAAAAAAAAhM/yzzfn3uhfec/s1600/IMAG0238.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="238" src="http://4.bp.blogspot.com/-J2C_OMT6edE/TY-zJNkBPYI/AAAAAAAAAhM/yzzfn3uhfec/s400/IMAG0238.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3343374414660307054-4740851067834062418?l=www.manasupo.com' alt='' /&gt;&lt;/div&gt;</description><link>http://www.manasupo.com/2011/03/pizza-box-architecture.html</link><author>noreply@blogger.com (supo)</author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-mrxEOI7eqb8/TY-3Mc_1LTI/AAAAAAAAAhQ/srlUdlW7wVo/s72-c/joke.jpg' height='72' width='72'/><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3343374414660307054.post-200655646743213219</guid><pubDate>Mon, 21 Mar 2011 23:40:00 +0000</pubDate><atom:updated>2011-03-22T00:41:42.211+01:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>admin</category><category domain='http://www.blogger.com/atom/ns#'>programming</category><title>SSL-HTTPs fails TortoiseHg</title><description>There is a quick and dirty hack that you can use to be able to access repositories behind self-signed SSL with Mercurial 1.1.7 and beyond. On Windows, edit the file: &lt;pre&gt;PATHTO\TortoiseHg\hgrc.d\Paths.rc&lt;/pre&gt;to make it look like this:&lt;br /&gt;&lt;pre&gt;[web]&lt;br /&gt;cacerts=&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/3343374414660307054-200655646743213219?l=www.manasupo.com' alt='' /&gt;&lt;/div&gt;</description><link>http://www.manasupo.com/2011/03/ssl-https-fails-tortoisehg.html</link><author>noreply@blogger.com (supo)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3343374414660307054.post-7663631251894093064</guid><pubDate>Sat, 19 Mar 2011 08:44:00 +0000</pubDate><atom:updated>2011-03-20T14:26:48.174+01:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>mobile</category><category domain='http://www.blogger.com/atom/ns#'>profiit</category><title>ProFIIT finals under way</title><description>&lt;div&gt;Future FIIT students fighting for the spotlight &amp;amp; problem setters prepping the judge solutions presentation and making sure everything runs smoothly...&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh3.ggpht.com/_nBjMEVqLhVg/TYRsudndYYI/AAAAAAAAAg0/854B7bJxbJs/IMAG0225.png" /&gt;&lt;br /&gt;&lt;img src="http://lh4.ggpht.com/_nBjMEVqLhVg/TYRsx32cB0I/AAAAAAAAAg4/iYcZicn3bl8/IMAG0226.png" /&gt;&lt;br /&gt;&lt;img src="http://lh4.ggpht.com/_nBjMEVqLhVg/TYRs1HTzvcI/AAAAAAAAAg8/a7hX6toRmxs/IMAG0227.png" /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3343374414660307054-7663631251894093064?l=www.manasupo.com' alt='' /&gt;&lt;/div&gt;</description><link>http://www.manasupo.com/2011/03/profiit-finals-under-way.html</link><author>noreply@blogger.com (supo)</author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_nBjMEVqLhVg/TYRsudndYYI/AAAAAAAAAg0/854B7bJxbJs/s72-c/IMAG0225.png' height='72' width='72'/><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3343374414660307054.post-1147186633585308982</guid><pubDate>Thu, 17 Mar 2011 22:20:00 +0000</pubDate><atom:updated>2011-04-06T03:52:20.300+02:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>tutorial</category><category domain='http://www.blogger.com/atom/ns#'>python</category><category domain='http://www.blogger.com/atom/ns#'>programming</category><title>Python multiprocessing utility</title><description>This article talks about a simple python command line utility that lets you run your existing programs in parallel, feeding them input and collecting their output to utilize the power of a multi-core processor. &lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Problem:&lt;/b&gt;&lt;br /&gt;We have an &lt;b&gt;Windows&lt;/b&gt; executable that reads some input (from &lt;i&gt;stdin&lt;/i&gt;), performs a calculation based on this input and prints some output (to &lt;i&gt;stdout&lt;/i&gt;). Since the computation for different inputs is independent, it makes sense to run this executable in multiple processes, each one processing their own input file and then in the end, we append all their results (note that you should include the input data in the output, to be able to reconstruct the "Question to the answer" ;-).&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Solution:&lt;/b&gt;&lt;br /&gt;Here you can find a python script that does the process management in a bit more clever way for you.&lt;br /&gt;It takes 2 command line parameters, the input file and the output file. It then reads the input file line by line, assuming that each line holds single instance of the input parameters you want to feed to your executable (you can easily tweak this input behavior, just check the code and/or ask in comments).&lt;br /&gt;The script is keeping track of the running processes (number of which you can set in the class constructor) and as soon as some process finishes, it takes the next input instance and spawns a new process, that gets the input instance to its &lt;i&gt;stdin&lt;/i&gt;. The &lt;i&gt;stdout&lt;/i&gt; of the process is mapped to a temporary file. The scripts creates the same number of temp. files as there are processes and it circulates the file handles in a way that prevents from 2 processing writing in a single file at a single moment.&lt;br /&gt;Eventually the content of temp. files is collected in the desired output file and the temp. files are deleted.&lt;br /&gt;&lt;br /&gt;What you need to know:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The process spawning is rather slow (couple of milliseconds), so you should make sure the individual computations take at least a couple of seconds to make the spawning time negligible.&lt;/li&gt;&lt;li&gt;Each instance is calculated in a separate process, so memory leaks should not cause a problem (process releases memory to OS once it finishes).&lt;/li&gt;&lt;li&gt;Include the input description in the output of the executable, so that you can map outputs to inputs (in other words, the output file doesn't contain the solutions in the same order as the inputs in the input file).&lt;/li&gt;&lt;/ul&gt;Let me know if you find this useful ;-)&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: py"&gt;import ctypes, subprocess, sys, time, os&lt;br /&gt;&lt;br /&gt;class Manu:&lt;br /&gt;  def __init__(self,app,numwork):&lt;br /&gt;    self.SYNCHRONIZE=0x00100000&lt;br /&gt;    self.INFINITE = -1&lt;br /&gt;    self.numwork = numwork&lt;br /&gt;    self.workers={}&lt;br /&gt;    self.app=app&lt;br /&gt;&lt;br /&gt;#######################################    &lt;br /&gt;############# Timer stuff #############&lt;br /&gt;&lt;br /&gt;  def start_timer(self):&lt;br /&gt;    self.t=time.time()&lt;br /&gt;  def get_time(self):&lt;br /&gt;    return time.time()-self.t&lt;br /&gt;&lt;br /&gt;#######################################    &lt;br /&gt;############# File stuff  #############&lt;br /&gt;  &lt;br /&gt;  def init_files(self,out_file):&lt;br /&gt;    self.out_file=out_file    &lt;br /&gt;    self.free_files=set()&lt;br /&gt;    self.taken_files={}&lt;br /&gt;    for i in range(self.numwork):&lt;br /&gt;      self.free_files.add(open("_proces_file"+str(i)+".tmp","w+"))    &lt;br /&gt;&lt;br /&gt;  def free_file(self,proc_handle):&lt;br /&gt;    self.free_files.add(self.taken_files[proc_handle])&lt;br /&gt;    del self.taken_files[proc_handle]&lt;br /&gt;&lt;br /&gt;  def close_files(self):&lt;br /&gt;    for f in self.free_files:&lt;br /&gt;      f.seek(0)&lt;br /&gt;      s=f.read(1048576)&lt;br /&gt;      while s!="":&lt;br /&gt;        self.out_file.write(s)&lt;br /&gt;        s=f.read(1048576)                &lt;br /&gt;      f.close()&lt;br /&gt;&lt;br /&gt;    self.out_file.close()&lt;br /&gt;    for i in range(self.numwork):&lt;br /&gt;      os.remove("_proces_file"+str(i)+".tmp")    &lt;br /&gt;      &lt;br /&gt;&lt;br /&gt;#######################################    &lt;br /&gt;############# Process stuff ###########&lt;br /&gt;  def print_status(self,solved_items):&lt;br /&gt;    avg_yet=(self.get_time()/solved_items)&lt;br /&gt;    print &amp;gt;&amp;gt; sys.stderr, "Solved item: %3d Time: %5ds End in: %5ds Exp. total: %5ds "%(solved_items,self.get_time(),(len(data)-solved_items)*avg_yet,len(data)*avg_yet)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  def work(self,data,out_file):&lt;br /&gt;    print &amp;gt;&amp;gt; sys.stderr, "Work started for",len(data),"items"&lt;br /&gt;    self.init_files(out_file)&lt;br /&gt;    self.start_timer()&lt;br /&gt;    solved_items=0&lt;br /&gt;&lt;br /&gt;    for i,dat in enumerate(data):&lt;br /&gt;      if len(self.workers) == self.numwork:&lt;br /&gt;        self.get_finished()&lt;br /&gt;        solved_items+=1&lt;br /&gt;        self.print_status(solved_items)&lt;br /&gt;&lt;br /&gt;      self.my_spawn(dat)&lt;br /&gt;      &lt;br /&gt;    while len(self.workers)&amp;gt;0:&lt;br /&gt;      self.get_finished()&lt;br /&gt;      solved_items+=1&lt;br /&gt;      self.print_status(solved_items)&lt;br /&gt;      &lt;br /&gt;    &lt;br /&gt;    print &amp;gt;&amp;gt; sys.stderr, "Finished. Total time:",self.get_time(),"Avg. time:",self.get_time()/len(data)&lt;br /&gt;    self.close_files()&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  def my_spawn(self,data):&lt;br /&gt;    f=self.free_files.pop()&lt;br /&gt;    p = subprocess.Popen([self.app], stdout=f, stdin=subprocess.PIPE, shell=False)    &lt;br /&gt;    h = ctypes.windll.kernel32.OpenProcess(self.SYNCHRONIZE, False, p.pid)      &lt;br /&gt;    p.stdin.write(data+"\n")&lt;br /&gt;&lt;br /&gt;    self.taken_files[h]=f    &lt;br /&gt;    self.workers[h]=p&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  def get_finished(self):&lt;br /&gt;    arrtype = ctypes.c_long * len(self.workers)&lt;br /&gt;    handle_array = arrtype(*self.workers.keys())&lt;br /&gt;    ret = ctypes.windll.kernel32.WaitForMultipleObjects(len(self.workers), handle_array, False, self.INFINITE)&lt;br /&gt;    h = handle_array[ret]&lt;br /&gt;&lt;br /&gt;    ctypes.windll.kernel32.CloseHandle(h)&lt;br /&gt;    self.free_file(h)&lt;br /&gt;    del self.workers[h]&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;#Example usage:&lt;br /&gt;in_file=sys.argv[1]&lt;br /&gt;data=[ x.strip() for x in open(in_file).readlines()]&lt;br /&gt;out_file=sys.argv[2]&lt;br /&gt;a=Manu(r"wrapper.exe",8)&lt;br /&gt;a.work(data,open(out_file,"w"))&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/3343374414660307054-1147186633585308982?l=www.manasupo.com' alt='' /&gt;&lt;/div&gt;</description><link>http://www.manasupo.com/2011/03/python-multiprocessing-utility.html</link><author>noreply@blogger.com (supo)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3343374414660307054.post-3999735889864890177</guid><pubDate>Wed, 16 Mar 2011 18:25:00 +0000</pubDate><atom:updated>2011-03-16T19:25:07.843+01:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>mobile</category><title>Octopus merge</title><description>&lt;div&gt;&lt;p&gt;Code merging session with miso @ my place. I really need 3 screens ;)&lt;/p&gt;&lt;br/&gt;&lt;img src='http://lh5.ggpht.com/_nBjMEVqLhVg/TYEAgnalZJI/AAAAAAAAAgw/SjJ7FdLIpBc/IMAG0216.png' /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3343374414660307054-3999735889864890177?l=www.manasupo.com' alt='' /&gt;&lt;/div&gt;</description><link>http://www.manasupo.com/2011/03/octopus-merge.html</link><author>noreply@blogger.com (supo)</author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_nBjMEVqLhVg/TYEAgnalZJI/AAAAAAAAAgw/SjJ7FdLIpBc/s72-c/IMAG0216.png' height='72' width='72'/><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3343374414660307054.post-1043854975043339311</guid><pubDate>Sun, 13 Mar 2011 19:37:00 +0000</pubDate><atom:updated>2011-03-15T11:49:43.410+01:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>mobile</category><category domain='http://www.blogger.com/atom/ns#'>admin</category><category domain='http://www.blogger.com/atom/ns#'>review</category><title>Monitor your server on the go</title><description>After finishing the VPS setup more or less successfully, I started looking into options of how to monitor what is happening with the machine when I am not at the PC. I downloaded &lt;a href="http://code.google.com/p/connectbot/"&gt;ConnectBot&lt;/a&gt;&amp;nbsp;to my HTC Desire HD and used it to connect to the machine. There I have installed&amp;nbsp;&lt;a href="http://htop.sourceforge.net/"&gt;htop&lt;/a&gt;&amp;nbsp;to display various stats like CPU and RAM utilization and running processes interactively and in the real time. Few tips on how to work &lt;i&gt;htop&lt;/i&gt;&amp;nbsp;without a hardware keyboard on your phone:&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;swipe up/down on the left half of the screen to scroll the process list&lt;/li&gt;&lt;li&gt;swiping on the right side scrolls the whole terminal&lt;/li&gt;&lt;li&gt;swiping left/right switches between active terminals&lt;/li&gt;&lt;li&gt;activate the keyboard by pushing bottom right corner of the screen and type:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;q&lt;/b&gt;&amp;nbsp;to quit (or close the left sidebar)&lt;/li&gt;&lt;li&gt;emulating function keys is a bit harder - press the on-screen &lt;b&gt;ctrl,&amp;nbsp;&lt;/b&gt;then activate the keyboard and press a number key ( for e.g. to change the sorting order, press &lt;b&gt;ctrl&lt;/b&gt; then &lt;b&gt;6&lt;/b&gt;&amp;nbsp;on the keyboard, then use the on-screen arrows to navigate up/down in the sidebar. Selected sorting criterion is confirmed with &lt;b&gt;enter&amp;nbsp;&lt;/b&gt;)&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;For more tips head on to the websites of the software I mentioned (check &lt;a href="http://loadimpact.com/kb/doku.php?id=htop"&gt;this&lt;/a&gt; for more keyboard shortcuts - awesome for the software keyboard), there is some more cool stuff waiting for you ;-) Here is a picture of how this setup looks on my 4.3 inch screen (together with my G9x for the size comparison):&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://lh5.googleusercontent.com/-3vO6lHlWl6U/TX0cBaEe6gI/AAAAAAAAAgk/hj6fZDrgN14/s1600/IMG_6914.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="265" src="https://lh5.googleusercontent.com/-3vO6lHlWl6U/TX0cBaEe6gI/AAAAAAAAAgk/hj6fZDrgN14/s400/IMG_6914.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3343374414660307054-1043854975043339311?l=www.manasupo.com' alt='' /&gt;&lt;/div&gt;</description><link>http://www.manasupo.com/2011/03/monitor-your-server-on-go.html</link><author>noreply@blogger.com (supo)</author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh5.googleusercontent.com/-3vO6lHlWl6U/TX0cBaEe6gI/AAAAAAAAAgk/hj6fZDrgN14/s72-c/IMG_6914.jpg' height='72' width='72'/><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3343374414660307054.post-1667521426070412356</guid><pubDate>Sat, 12 Mar 2011 14:06:00 +0000</pubDate><atom:updated>2011-03-12T15:06:00.666+01:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>review</category><category domain='http://www.blogger.com/atom/ns#'>movie</category><title>Battle: Los Angeles</title><description>I read multiple complaints about the jerkiness of the camera in this one - and yes it was really like the blair-witch project, maybe even worse. But it was consistent with the situation and even though we sat close to the screen, it was watchable. If you have problem, just sit further...&lt;br /&gt;&lt;br /&gt;The plot starts good but then it reaches a plateau in the part where it gets a little repetitive. The biggest bummer is again the poor strategic thinking on the alien part. There is no way a race capable of traveling between stars with an experience of conquering planets (there were hints, like the soldiers had surgically implanted weapons) allows to have a &lt;i&gt;single point of failure&lt;/i&gt; in their strategy - however strong it might be.&lt;br /&gt;&lt;br /&gt;Bottom line, although the plot is very simplistic and long-winded at times, the execution, effects and cast (Michelle Rodriguez baby!) save the day. I only recommend this movie to sci-fi/war movie fans.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3343374414660307054-1667521426070412356?l=www.manasupo.com' alt='' /&gt;&lt;/div&gt;</description><link>http://www.manasupo.com/2011/03/battle-los-angeles.html</link><author>noreply@blogger.com (supo)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3343374414660307054.post-9124279557585607461</guid><pubDate>Thu, 10 Mar 2011 11:43:00 +0000</pubDate><atom:updated>2011-03-10T12:43:29.995+01:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>photography</category><category domain='http://www.blogger.com/atom/ns#'>report</category><title>Photo-walk at Slavín, Bratislava</title><description>Hi all,&lt;br /&gt;&lt;br /&gt;yesterday we managed to escape from all the busy-ness and go to a place where I haven't been before, although it is in my home city. This place is called Slavín and it is memorial to soviet soldiers who died while fighting to free Slovakia from German oppression in April 1945. It is basically a mass grave with 6845 bodies.&lt;br /&gt;&lt;br /&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;Direct link to the gallery:&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;a href="http://photos.manasupo.com/p417317495"&gt;http://photos.manasupo.com/p417317495&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Some notes about the shoot:&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;The setting sun gave us a nice warm look and shadows for some depth in pictures. I just added some more of that warmth in the post to make it even more evident. Also in some pictures, I desaturated the whole picture and then saturated some particular colors, to clean them up a bit (red railing, green trashcan).&lt;br /&gt;&lt;br /&gt;Majority was shot with the Canon 100mm f2.8 macro and some wide angles. Surprisingly, the 4&lt;sup&gt;th&lt;/sup&gt;&amp;nbsp;picture was shot with the Canon 50mm f1.4, which sometimes nails the focus for me, but sometimes starts back-focusing and I need to micro-adjust on the spot. The wide shots are done with my favorite Tokina 11-16mm f2.8.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3343374414660307054-9124279557585607461?l=www.manasupo.com' alt='' /&gt;&lt;/div&gt;</description><link>http://www.manasupo.com/2011/03/photo-walk-at-slavin-bratislava.html</link><author>noreply@blogger.com (supo)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3343374414660307054.post-837582644035834749</guid><pubDate>Wed, 09 Mar 2011 02:07:00 +0000</pubDate><atom:updated>2011-03-11T03:14:04.591+01:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>admin</category><category domain='http://www.blogger.com/atom/ns#'>tutorial</category><category domain='http://www.blogger.com/atom/ns#'>web</category><title>From webhosting to VPS</title><description>Hi all,&lt;br /&gt;&lt;br /&gt;I have started a migration of our startup-ish project from a basic webhosting at &lt;a href="http://www.webfaction.com/"&gt;http://www.webfaction.com&lt;/a&gt; to a linode 512 account over at &lt;a href="http://www.linode.com/"&gt;http://www.linode.com&lt;/a&gt; today, which is a VPS with root access and all the related perks. The project is Django based and uses MySQL as well as some C++.&lt;br /&gt;I was really afraid of the configuration, but so far it is turning out quite easy, although I am a COMPLETE noob. The steps I took so far:&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Use the one click &lt;a href="http://www.linode.com/stackscripts/view/?StackScriptID=131"&gt;StackScript&lt;/a&gt;&amp;nbsp;- this installs essential components of your application stack, which is Apache with mod_wsgi, MySQL (other databases available too) and some other stuff&lt;/li&gt;&lt;li&gt;For database interface install phpmyadmin, which is immediately accessible when you point your browser to IP_of_your_linode&lt;i&gt;/phpmyadmin&lt;/i&gt;&lt;pre&gt;sudo apt-get install phpmyadmin&lt;/pre&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Note here, that the DB itself is configured by the StackScript, so in the install pick the option that doesn't reinstall the database&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Added some helpful aliases to ~/.bash_aliases (this gets automatically loaded on relog, or by typing &lt;i&gt;bash&lt;/i&gt;, also you may need to change paths):&lt;pre class="brush: bash"&gt;alias memhttpd="ps -u $LOGNAME -o pid,rss,command | grep httpd | grep -v -e mpm | awk 'BEGIN {sum=0} {sum=sum+\$2} END {printf(\"%f MB\n\",sum/1024)}'"&lt;br /&gt;alias memtotal="ps -u $LOGNAME h -o rss | grep -e mpm -v | (tr '\n' +; echo 0) | bc"&lt;br /&gt;alias memtot="~/webapps/misc/mem/check_mem_console"&lt;br /&gt;alias memcheck="ps -u $LOGNAME -o pid,etime,rss,command | grep -v -e mpm"&lt;br /&gt;alias memcheckhttpd="ps -u $LOGNAME -o pid,etime,rss,command | grep httpd | grep -v -e mpm"&lt;br /&gt;alias apache_restart="/etc/init.d/apache2 restart"&lt;br /&gt;&lt;/pre&gt;&lt;/li&gt;&lt;ul&gt;&lt;/ul&gt;&lt;li&gt;Configure your virtualhosts. It is generally known that you should not serve static content with Django, so you should pick a directory outside of the Django folder and create a virtualhost record for it in:&lt;pre&gt;/etc/apache2/sites-available/yourwebsitename&lt;/pre&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Check&amp;nbsp;&lt;a href="http://www.unix-girl.com/geeknotes/apache_virtual_host_conf.html"&gt;general&lt;/a&gt;,&amp;nbsp;&lt;a href="http://stackoverflow.com/questions/758351/virtualhost-for-wildcard-subdomain-and-static-subdomain"&gt;subdomains&lt;/a&gt;, ...&lt;/li&gt;&lt;li&gt;Don't forget to restart Apache to see the changes in configuration. You can do so by using the &lt;i&gt;apache_restart &lt;/i&gt;alias we registered one step above&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;I have started adding some more &lt;a href="http://www.linode.com/stackscripts/"&gt;StackScripts&lt;/a&gt;, which allow me to simplify some tasks (like &lt;a href="http://www.linode.com/stackscripts/view/?StackScriptID=127"&gt;starting a django project&lt;/a&gt;). To keep things clean, I created a folder ~/stackscripts, where I just copy them. Then for each, I add a line to the end of my &lt;i&gt;.bashrc&lt;/i&gt;:&lt;pre&gt;. ~/stackscripts/scriptname&lt;/pre&gt;which includes them in. Just type &lt;i&gt;bash&lt;/i&gt; in the command line and enjoy. Especially neat feature is that bash auto-completes functions defined in .bashrc and you can tab over them. Nice!&lt;/li&gt;&lt;li&gt;Now this is no longer chronological, but next tip is that if you install a library like &lt;i&gt;OpenCV&lt;/i&gt;, that you intend to use with python, you will need to put the &lt;i&gt;OpenCV/lib&lt;/i&gt; folder in the python path (sys.path). For this, I found that the easiest thing to do is to put a &lt;i&gt;.pth&lt;/i&gt; file in a folder that already is in the python path and list folders you want to add each on a separate line. Then upon execution of python, these folders get added to &lt;i&gt;sys.path&lt;/i&gt; by &lt;i&gt;site.py&lt;/i&gt;.&lt;/li&gt;&lt;li&gt;... to be continue &lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3343374414660307054-837582644035834749?l=www.manasupo.com' alt='' /&gt;&lt;/div&gt;</description><link>http://www.manasupo.com/2011/03/from-webhosting-to-vps.html</link><author>noreply@blogger.com (supo)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3343374414660307054.post-1428563424142014794</guid><pubDate>Tue, 08 Mar 2011 22:10:00 +0000</pubDate><atom:updated>2011-03-08T23:14:01.282+01:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>slovak</category><category domain='http://www.blogger.com/atom/ns#'>programming-competitions</category><category domain='http://www.blogger.com/atom/ns#'>tutorial</category><title>Programátorské súťaže - návod</title><description>Programátorské súťaže sú v podstate druh športu, v ktorom si ľudia porovnávajú schopnosti s otatnými. Existuje veľa druhov programátorských súťaží, nás momentálne zaujímajú tie zamerané na algoritmy. Vo všeobecnosti v nich ide o to, že súťažiaci v limitovanom čase riešia presne definované a ohraničené problémy a na základe kvality svojho riešenia sú nakoniec zoradení.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Základné elementy programátorskej súťaže:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;zadania &lt;/b&gt;- množina jasne definovaných úloh, ktoré sa počas súťaže programátori snažia vyriešiť&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;vyhodnocovač &lt;/b&gt;- stroj, ktorému súťažiaci posielajú svoje riešenia a on ich vyhodnocuje&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;pravidlá &lt;/b&gt;- definujú, akým spôsobom budú súťažiaci zoraďovaný vo výslednom poradí danej súťaže a čo majú povolené a zakázané na súťaži vyvádzať&lt;/li&gt;&lt;/ul&gt;&lt;b&gt;Zadania&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Základný princíp každej úlohy je vždy rovnaký. Ide o premenu nejakých vstupných dát na výstupné dáta. Každá úloha vždy, spravidla v tomto poradí, definuje: &lt;br /&gt;&lt;br /&gt;&lt;i&gt; &lt;/i&gt;&lt;br /&gt;&lt;i&gt;Špecifikácia úlohy&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Popis charakteru premeny vstupných dát na výstupné. Ak je úloha jednoduchá, nachádza sa tu presný popis čo má váš program so vstupnými dátami urobiť aby vypočítal prislúchajúci výstup. Príkladom takejto úlohy je napr. „Dvojicu čísiel na vstupe ščítajte a vypíšte na výstup“.&lt;br /&gt;&lt;br /&gt;Náročnejšie úlohy môžu trebárs povedať, čo so vstupnými dátami treba urobiť, ale opíšu tento proces tak, že keby sme ho priamo implementovali do programu, mal by ten program nejaký problém. Napríklad by pre vstup daného rozsahu bežal niekoľko rokov, potreboval by 1 TB pamäte a pod. &lt;br /&gt;&lt;br /&gt;Takéto v zásade nesprávne riešenie, ktoré nás napadne hneď po prečítaní riešenia je však často dobrý odrazový bod na ceste za dostatočne efektívnym riešením. Súťažiaci musí v tomto prípade nájsť spôsob, akým dosiahne ekvivalentnú transformáciu efektívnejšie. &lt;br /&gt;&lt;br /&gt;V iných prípadoch je spôsob transformácie vstupu na výstup uplne skrytý a po prečítaní zadania netušíme, čo so vstupom robiť, aby sme dostali požadovaný výstup. Ani vtedy netreba hádzať flintu do žita. V týchto prípadoch odporúčam opätovne prečítať zadanie aspon zo 3 krát, či sme náhodou neprehliadli nejaký fakt, ktorý daný problém zjednodušuje dosť na to aby sme sa vedeli pohnúť dalej.&lt;br /&gt;&lt;br /&gt;Ak sme v zadaní nič nenašli, pozrieme sa na vzorový vstup a skúsime na papier odkrokovať, čo by sa s ním malo diať aby sme dostali správny výsledok. A posledná finta, keď neviem vyriešiť nejaký príklad, uistím sa, že v danej súťaži nie je nejaký iný, lahší príklad. Veľmi často sa stáva, že človek sa zasekne na ťažšom príklade a potom nestihne doriešiť jednoduchšie. Keďže aj v TEAP súťažiach aj v MFF súťažiach rozhoduje v prvom rade počet vyriešených príkladov, takáto chyba vie drasticky ovplyvniť výsledné umiestnenie.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Vstup&lt;/i&gt; &lt;br /&gt;&lt;br /&gt;Dáta v textovom formáte, ktoré budú poskytnuté vášmu programu, keď ho bude vyhodnocovať testovať. Váš program sa k nim dostane cez štandardný vstup, čo je inými slovami to isté, ako keby ste dáta čítali z klávesnice. Napr:&lt;br /&gt;&lt;pre class="brush: c"&gt;cin&amp;gt;&amp;gt;x&lt;br /&gt;scanf("%d",&amp;amp;x)&lt;br /&gt;&lt;/pre&gt;Zadanie presne definuje ako budú dáta na vstupe organizované, aké informácie sa budú nachádzať na jednotlivých riadkoch vstupu a pod. Pokiaľ špecifikácia úlohy nepovie inak, môžete predpokladať, že vstupné dáta, ktoré dostane váš program od testovača budú presne spĺňať špecifikáciu zo zadania.&lt;br /&gt;&lt;br /&gt;Z toho vyplíva, že je zbytočné aby ste kontrolovali, či bolo naozaj zadaných 5 čísiel a nie náhodou 6, alebo či dané čísla sú naozaj len kladné a nie je medzi nimi náhodou aj 0.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Výstup&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Dáta, ktoré váš program musí vrátiť vyhodnocovaču. Predáte mu ich tak, že ich jednoducho vypíšete na štandardný výstup, čo je presne to isté ako keby ste ich vypisovali do konzoly. Napr:&lt;br /&gt;&lt;pre class="brush: cpp"&gt;cout&amp;lt;&amp;lt;x&lt;br /&gt;print("%d",x)&lt;br /&gt;&lt;/pre&gt;Formát výstupných dát je tiež vždy presne daný v zadaní. Na to, aby boli výstupné dáta vášho programu uznané vyhodnocovačom za správne, musia presne kopírovať formát, ktorý je vysvetlený v zadaní. Takže keď budete mať na jednom riadku vypísať číslo X, značiace počet jabĺčok na strome, nebude výstup vášho programu vyzerať nejak nasledovne: &lt;br /&gt;&lt;pre&gt;Jablcok na strome : X&lt;br /&gt;&lt;/pre&gt;ale jednoducho len&lt;br /&gt;&lt;pre&gt;X&lt;br /&gt;&lt;/pre&gt;Je dôležité podotknúť, že nie je nutné, aby váš program načítal VŠETKY dáta, ktoré sa nachádzajú na vstupe a až potom začal písať dáta na výstup. Tieto dve činnosti sú nezávyslé a môžu byť realizované v ľubovolnom vzájomnom poradí. Napr:&lt;br /&gt;&lt;pre class="brush: cpp"&gt;cin&amp;gt;&amp;gt;x&lt;br /&gt;cout&amp;lt;&amp;lt;x+x&lt;br /&gt;cin&amp;gt;&amp;gt;y&lt;br /&gt;cout&amp;lt;&amp;lt;y+y&lt;br /&gt;&lt;/pre&gt;je to isté ako&lt;br /&gt;&lt;pre class="brush: cpp"&gt;cin&amp;gt;&amp;gt;x&lt;br /&gt;cin&amp;gt;&amp;gt;y&lt;br /&gt;cout&amp;lt;&amp;lt;x+x&lt;br /&gt;cout&amp;lt;&amp;lt;y+y&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;Vyhodnocovač&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Ok, program je hotový, čo teraz? Aj MFF aj náš testovač fungujú v podstate rovnako. Prihlásite sa na webstránku, cez ktorú sa dajú vyhodnocovaču riešenia dopraviť, preklikáte sa v menu, vyznačíte zadanie, ktoré váš odovzdávaný program rieší a pripojíte zdrojový kód vášho programu.&lt;br /&gt;&lt;br /&gt;Prvá vec čo sa stane s vaším programom je kontrola použitých knižníc a funkcií. V prípade, že je nájdené niečo, čo je v rozpore s pravidlami súťaže, vyhodnocovač vám vráti hlášku &lt;i&gt;Security exception&lt;/i&gt;, prípadne náš TEAP-ácky dokonca aj niečo konkrétnejšie.&lt;br /&gt;&lt;br /&gt;Ak je všetko v poriadku, vyhodnocovač váš program u seba skompiluje a spustí ho na svoje tajné testovacie vstupy, ku ktorým súťažiaci nemajú z pochopiteľných dôvodov priamy prístup. Ak váš program beží a beží a beží a vyhodnocovač sa rozhodne, že už beží pridlho, zastaví ho a vám sa na webstránke zobrazí odpoveď &lt;i&gt;Time limit exceeded&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;Druhou možnosťou je, že program počas svojho behu spraví nejakú nepovolenú operáciu, napríklad vydelí nulou alebo pristúpi do pamäte, ktorá mu nebola pridelená. Vtedy vyhodnocovač zahlási &lt;i&gt;Runtime exception&lt;/i&gt;. Predpokladajme teda, že váš program sa sám štastne ukončil.&lt;br /&gt;&lt;br /&gt;V takom prípade testovač zoberie výstup, ktorý sa vášmu programu podaril vyprodukovať a overí, či naozaj ide o správne riešenie danej úlohy. Ak sa mu zdá, že nie, dá to vedieť hláškou &lt;i&gt;Wrong answer&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;Ak sa mu zdá, že to je skoro ono, len sú tam navyše medzery, prípadne nejaká čiarka atď, poskytne vám hlášku &lt;i&gt;Presentation error&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;Poslednou možnosťou je hláška &lt;i&gt;Accepted&lt;/i&gt;, po zhliadnutí tejto hlášky sa tešíte, pretože ste zadanie úspešne vyriešili a bol vám pripočítaný bod.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Pravidlá&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Pred tým ako sa dáte do súťaženia, je dôležité si prejsť pravidlá danej súťaže. Okrem zoznamu zakázaných funkcií a knižníc a dĺžky trvania súťaže (v rádoch niekoľkých hodín), by ste v nich hlavne mali nájsť algoritmus zoraďovania súťažiacich.&lt;br /&gt;&lt;br /&gt;U nás aj na MFF je toto rovnaké. Súťažiaci sú počas súťaže radený primárne podľa počtu vyriešených (Accepted) príkladov. Ak majú dvaja súťažiaci rovnaký počet príkladov, rozhoduje súčet časov, ktoré potrebovali na vyriešenie všetkých nimi úspešne vyriešených príkladov. Napríklad, ak som 10 minút od začiatku súťaže úspešne odovzdal príklad A a 50 minút nato príklad B, bude môj celkový čas 10+50=60. Ak Jožo vyriešil A za 20 minút, na B potreboval ďaľších 30 minút a C skúsil odovzdať ale dostal späť Wrong answer, bude v poradí danej súťaže nižšie ako ja, pretože jeho súčet časov je až 20+50=70.  Z toho okrem iného vyplíva, že optimálna stratégia je riešit príklady v poradí od tých najlahších, ktoré budete mať hotové za krátky čas až po tie najťažšie.&lt;br /&gt;&lt;br /&gt;Verím, že po zhliadnutí tohoto riešenia sa všetci prestanú báť a budú veselo súťažiť. :-)&lt;br /&gt;&lt;a href="http://www.blogger.com/goog_1203930813"&gt;&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://ksp.sk/%7Eacm/"&gt;http://ksp.sk/~acm/&lt;/a&gt;&lt;br /&gt;&lt;a href="https://profiit.fiit.stuba.sk/login.php"&gt;https://profiit.fiit.stuba.sk/login.php&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3343374414660307054-1428563424142014794?l=www.manasupo.com' alt='' /&gt;&lt;/div&gt;</description><link>http://www.manasupo.com/2011/03/programatorske-sutaze-navod.html</link><author>noreply@blogger.com (supo)</author><thr:total>0</thr:total></item></channel></rss>
