Tom Leverstonehttps://blog.leverstone.me/2023-12-15T00:00:00+00:00BlogDeployment tech for the hobbyist, again2023-12-15T00:00:00+00:002023-12-15T00:00:00+00:00Tom Guriontag:blog.leverstone.me,2023-12-15:/deployment-tech-for-the-hobbyist-again.html<p><strong>TL;DR:</strong> Try <a class="reference external" href="https://dokku.com/">Dokku</a> if you want to run multiple toy web apps on a single server and keep the cost at minimum.</p>
<img alt="Dokku logo with name" src="/images/dokku-logo-with-name.png" style="width: 100%;" />
<p>Let's talk, yet again, about deploying toy web apps.
I wrote about this topic many moons ago (see docker-compose in production <a class="reference external" href="/docker-compose-in-production.html">part 1</a> and <a class="reference external" href="/docker-compose-in-production-part-2.html">part 2</a>), but …</p><p><strong>TL;DR:</strong> Try <a class="reference external" href="https://dokku.com/">Dokku</a> if you want to run multiple toy web apps on a single server and keep the cost at minimum.</p>
<img alt="Dokku logo with name" src="/images/dokku-logo-with-name.png" style="width: 100%;" />
<p>Let's talk, yet again, about deploying toy web apps.
I wrote about this topic many moons ago (see docker-compose in production <a class="reference external" href="/docker-compose-in-production.html">part 1</a> and <a class="reference external" href="/docker-compose-in-production-part-2.html">part 2</a>), but things have changed and it's time for an update.</p>
<p>The main thing that changed, really, is having much less time to maintain projects and money to keep the servers up.
In the past I had a single virtual server (a <a class="reference external" href="https://www.digitalocean.com/products/droplets">Digital Ocean droplet</a>) that ran everything.
It had <a class="reference external" href="https://nginx.org/en/">nginx</a> installed manually, and whenever I added a project, I had to reconfigure it to pass traffic to the port the project was running on.
This, again, was done manually.
The deployment itself was done by running a custom script somewhere, either from the local machine or from CI/CD.
That's pretty old-school, isn't it?
And what about SSL?
Forget it; that was too complicated.</p>
<p>Over time projects started to transition to different platforms that automated the process.
I had projects on <a class="reference external" href="https://www.heroku.com/">Heroku</a> for years, using their now-retired free dev offering.
The cheapest option at the moment is $5 a month.
Some projects were deployed to <a class="reference external" href="https://docs.digitalocean.com/products/app-platform/">Digital Ocean's App Platform</a> which also starts at the same cost.
I found both platform very convenient to use, and although not particularly expensive, the cost ramps up quickly when you have a few projects, and that's without considering having a DB and other services to support the web app.
Last year, I invested some time learning AWS (Amazon Web Services), and in the process, deployed a toy project to <a class="reference external" href="https://aws.amazon.com/elasticbeanstalk/">Elastic Beanstalk</a>.
In the first year I was on the AWS free tier, but after that the price got really high.
If memory serves the forecast was >$50 a month for a load balancer, two of the smallest server instances possible, and a relational DB.
Two days after the end of the free tier period the project was shut down due to the cost.</p>
<p>A solution was called for hosting my toy projects.
If you read this far, you can understand the requirements:</p>
<ul class="simple">
<li>It needs to be cheap. Ideally, I don't want to consider cost for adding or removing toy projects. A one-server solution sounds good for this.</li>
<li>It needs to be simple and easy to maintain. <a class="reference external" href="https://docs.aws.amazon.com/lambda/">AWS Lambdas</a> are cheap and, in that sense, might be a good solution for toy projects, but my projects already exist in the form of servers and changing them to Lambda functions is too much effort.</li>
</ul>
<p>I had a look at <a class="reference external" href="https://dokku.com/">Dokku</a> many years ago, and decided to check it again now.
The tagline is 'An open-source PaaS alternative to Heroku', and based on my good experience with <a class="reference external" href="https://www.heroku.com/">Heroku</a> it sounds pretty much up my alley.</p>
<p>As already mentioned, I also have good experience with <a class="reference external" href="https://www.digitalocean.com/">Digital Ocean</a>.
If only I can have <a class="reference external" href="https://dokku.com/">Dokku</a> running in a Digital Ocean droplet 🤔</p>
<img alt="Dokku on Digit Ocean" src="/images/dokku-on-digitalocean.png" />
<p>Yes! A quick search reveals a <a class="reference external" href="https://docs.digitalocean.com/products/marketplace/catalog/dokku/">one click deployment of Dokku on Digital ocean through their marketplace</a>.
I went for a $12 virtual machine with 1 CPU, 2GB RAM, and 50GB of SSD storage, hoping it will be enough for a handful of projects for a while.
Within 20 minutes I was trying to deploy my first abandoned toy project on my new <a class="reference external" href="https://dokku.com/">Dokku</a> instance.
Another 20 minutes in, and the project was up and running.
Three more projects followed in what amounts to 2-3 hours work.
From these 4 project, 3 were previously deployed to <a class="reference external" href="https://www.heroku.com/">Heroku</a> using <a class="reference external" href="https://buildpacks.io/">buildpacks</a> and <a class="reference external" href="https://docs.digitalocean.com/products/app-platform/">Digital Ocean's App Platform</a> using containers (having a <tt class="docutils literal">Dockerfile</tt> at the root of the repo).
Moving these to the new system was a breeze:
adding a git remote locally and pushing, then on the new server configuring environment variables and <a class="reference external" href="https://dokku.com/docs/deployment/application-deployment/#setting-up-ssl">configuring SSL following the deployment tutorial</a>, followed by creating A tags on my DNS provider, and that's it!</p>
<p>The 4th project was previously on <a class="reference external" href="https://aws.amazon.com/elasticbeanstalk/">Elastic Beanstalk</a> and backed by a relational DB.
I had the data from the DB exported into JSON before shutting the project down.
I was worried about transitioning it, but found it extremely easy as well!
Adding a DB to it was very simple following the so-far-excellent docs.
It took me a while to wrap my head around loading the backup, but the following did the trick:</p>
<div class="highlight"><pre><span></span>docker ps <span class="c1"># to find the container ID of my app</span>
docker cp my-backup.json my-app-container-id:/app
dokku enter my-app
<span class="c1"># Now run whatever command within the image to load the data</span>
</pre></div>
<p>One last project is an <a class="reference external" href="https://elixir-lang.org/">Elixir</a>/<a class="reference external" href="https://www.phoenixframework.org/">Phoenix</a> project that was previously deployed on <a class="reference external" href="https://www.gigalixir.com/">Gigalixir</a> with their custom buildpacks.
I had to containerise the project to make it work with the new system, and that took a while.
Nothing to blame the new system for though.
Just the usual modernisation of an old project.</p>
<p>Do I care about having these project highly available? no.
Do I care about no-downtime deployments? also no.
What about data loss (e.g. losing the DB)? That's not the end of the world either.
<a class="reference external" href="https://dokku.com/">Dokku</a> supports cron jobs, so it might be interesting to explore doing regular DB backups.
Or, alternatively, I can accept the $2.40 per month to enable weekly backups of the entire droplet.
If you do care about these then maybe your toy project is not that much of a toy any more 😄.</p>
<p>In summary, all of the deployment stories above are here to say that so far I find <a class="reference external" href="https://dokku.com/">Dokku</a> really easy to work with.
There's no much traffic to any of these projects, so CPU / network / disk usage are low as expected.
Memory usage is constantly around %40-%50.
As long as it doesn't creep up dramatically that's probably fine.
So overall it seems that the transition succeeded.</p>
<div class="section" id="shameless-plug">
<h2>Shameless plug</h2>
<p>Here are the projects that are running on my <a class="reference external" href="https://dokku.com/">Dokku</a> instance at the time of writing this post. Source code for all of them can be found on <a class="reference external" href="https://github.com/nagasaki45/">my GitHub profile</a>.</p>
<div class="section" id="cardigan">
<h3><a class="reference external" href="https://cardigan.leverstone.me/">Cardigan</a></h3>
<p>A "platform" for playing card games online. Created during COVID to play <a class="reference external" href="https://boardgamegeek.com/boardgame/284083/crew-quest-planet-nine">The Crew</a> with friend before it was available on <a class="reference external" href="https://boardgamearena.com/">BGA</a>. It was previously deployed to <a class="reference external" href="https://www.gigalixir.com/">Gigalixir</a>.</p>
</div>
<div class="section" id="proker">
<h3><a class="reference external" href="https://proker.leverstone.me/">Proker</a></h3>
<p>A tool we use at work to vote on the complexity of tickets (bugs, feature enhancements, tech debt, etc.) It was previously deployed to <a class="reference external" href="https://docs.digitalocean.com/products/app-platform/">Digital Ocean's App Platform</a>.</p>
</div>
<div class="section" id="xteams">
<h3><a class="reference external" href="https://xteams.leverstone.me/">Xteams!</a></h3>
<p>An app I made many years ago when I was playing volleyball with a group of 15-20 people who were too polite to make up teams. I know a few people were still using it until 3-4 years ago (including the coach of the Hebrew University of Jerusalem Women Volleyball Team). Have no idea if anyone still does. It was previously deployed to <a class="reference external" href="https://aws.amazon.com/elasticbeanstalk/">Elastic Beanstalk</a>, and before that to <a class="reference external" href="https://www.heroku.com/">Heroku</a> (I think).</p>
</div>
<div class="section" id="grabacoffee">
<h3><a class="reference external" href="https://grab-a-coffee.leverstone.me/">GrabACoffee</a></h3>
<p>A hackathon project made at work to encourage people to take coffee breaks together. It was previously on <a class="reference external" href="https://docs.digitalocean.com/products/app-platform/">Digital Ocean's App Platform</a>.</p>
</div>
<div class="section" id="web-audio">
<h3><a class="reference external" href="https://web-audio.leverstone.me/">web-audio</a></h3>
<p>An attempt to play with the WebAudio API that ended up more like an experiment in ajax / websockets. Made when I just started writing code and had no idea what I'm doing. Happy to see it online mainly for nostalgia. Previously deployed on <a class="reference external" href="https://www.heroku.com/">Heroku</a> but went down when they changed the pricing model because there was no point in paying for it.</p>
</div>
</div>
Remote TidalCycles jamming setup2020-09-18T00:00:00+01:002020-09-18T00:00:00+01:00Tom Guriontag:blog.leverstone.me,2020-09-18:/remote-tidal-cycles-jamming-setup.html<object data="https://upload.wikimedia.org/wikipedia/commons/8/80/TidalCycles_identity.svg" style="width: 100%;" type="image/svg+xml">
TidalCycles logo</object>
<p><a class="reference external" href="https://tidalcycles.org/i">TidalCycles</a> (tidal in short) is a live coding language for music performance / composition.
I don't use it myself but been playing with a live coder, Lizzie, AKA <a class="reference external" href="https://lwlsn.github.io/digitalselves-web/">digital selves</a>, for the last year and a half.
Check her out!
With a COVID 2nd wave around the corner we …</p><object data="https://upload.wikimedia.org/wikipedia/commons/8/80/TidalCycles_identity.svg" style="width: 100%;" type="image/svg+xml">
TidalCycles logo</object>
<p><a class="reference external" href="https://tidalcycles.org/i">TidalCycles</a> (tidal in short) is a live coding language for music performance / composition.
I don't use it myself but been playing with a live coder, Lizzie, AKA <a class="reference external" href="https://lwlsn.github.io/digitalselves-web/">digital selves</a>, for the last year and a half.
Check her out!
With a COVID 2nd wave around the corner we decided to search for a solution for remote jamming together.
This blog post is a summary of what seems to work.
It's written mainly as a documentation for Lizzie and self.
Hopefully others will find it useful as well.</p>
<p>So, what do we want to achieve?
We want Lizzie to run tidal code on her laptop and having the audio generated on my laptop at the other side of town.
The clock to sync my hardware synth will be generated with the audio.
So, audio-wise, both Lizzie's output and my hardware synth will generate locally on my side, fully in sync.
Then, the mix of Lizzie's live coding and my hardware synth will be streamed back to Lizzie, so she could hear it too.</p>
<p>How do we plan to do it?
Tidal uses a client / server architecture with the tidal haskell library as the client and SuperCollider (SC) running the audio as the server.
Communication is done over UDP on port 57120 by default.
Our idea is to route the messages from tidal, through a server, to my machine, which runs the SC server.
With such a solution there won't be any need to change anything around tidal, nor around SC, just set up the network properly.
I will listen to the mix locally on my side and send it to Lizzie over zoom / skype / whatever.</p>
<p>With the overall picture in mind, let's dive in.</p>
<div class="section" id="prerequisits">
<h2>Prerequisits</h2>
<ul class="simple">
<li>You'll need a server with admin previliges.</li>
<li>Both ends (the computer running tidal and the computer running SC) should have <a class="reference external" href="https://linux.die.net/man/1/socat">socat</a> installed.</li>
</ul>
<p>Here's the overall process:</p>
<ul class="simple">
<li><a class="reference internal" href="#prepare-the-server">Prepare the server</a></li>
<li><a class="reference internal" href="#create-an-ssh-reverse-tunnel-from-the-server-to-the-laptop-running-sc">Create an SSH reverse tunnel from the server to the laptop running SC</a></li>
<li><a class="reference internal" href="#convert-tcp-messages-back-to-udp-on-the-laptop-running-sc">Convert TCP messages back to UDP on the laptop running SC</a></li>
<li><a class="reference internal" href="#send-the-udp-messages-from-the-laptop-running-tidal-to-the-server">Send the UDP messages from the laptop running tidal to the server</a></li>
<li><a class="reference internal" href="#start-tidal">Start tidal</a></li>
<li><a class="reference internal" href="#stream-the-audio-back-to-the-tidal-user">Stream the audio back to the tidal user</a></li>
</ul>
</div>
<div class="section" id="prepare-the-server">
<h2>Prepare the server</h2>
<p>For a server we created a droplet on <a class="reference external" href="https://digitalocean.com/">digital ocean</a>.
There's almost no setup for the droplet, so we can create one for jamming and delete it later to keep the cost low.</p>
<p>The only configuration needed on the server is to change the SSH settings on the server to allow forwarded ports to bind to the wildcard address (meaning that the address will be publicly accessible) <a class="footnote-reference" href="#id2" id="id1">[1]</a>.</p>
<p>Edit <tt class="docutils literal">/etc/ssh/sshd_config</tt> and add:</p>
<pre class="code literal-block">
GatewayPorts yes
</pre>
<p>Now reload the SSH settings on the server with</p>
<pre class="code literal-block">
systemctl reload ssh.service
</pre>
<p>Note the IP of your server and use it everywhere that <tt class="docutils literal">SERVER_IP</tt> is mentioned below.</p>
</div>
<div class="section" id="create-an-ssh-reverse-tunnel-from-the-server-to-the-laptop-running-sc">
<h2>Create an SSH reverse tunnel from the server to the laptop running SC</h2>
<p>SSH tunnelling doesn't support UDP, so we'll create a tunnel for TCP and convert the UDP messages sent by tidal to TCP on one machine, and back to UDP on the other machine.</p>
<p>On the machine that runs SC run</p>
<pre class="code literal-block">
ssh -R 12345:localhost:12345 root@SERVER_IP
</pre>
<p>The port doesn't really matter, 12345 is used here for convenience.</p>
</div>
<div class="section" id="convert-tcp-messages-back-to-udp-on-the-laptop-running-sc">
<h2>Convert TCP messages back to UDP on the laptop running SC</h2>
<pre class="code literal-block">
socat TCP-LISTEN:12345,fork UDP4:localhost:57120
</pre>
</div>
<div class="section" id="send-the-udp-messages-from-the-laptop-running-tidal-to-the-server">
<h2>Send the UDP messages from the laptop running tidal to the server</h2>
<pre class="code literal-block">
socat UDP-LISTEN:57120,fork TCP4:SERVER_IP:12345
</pre>
</div>
<div class="section" id="start-tidal">
<h2>Start tidal</h2>
<p>Spin up tidal on one side, SC on the other side, put some patterns in and it should work, almost!
The user on the SC side will probably notice that the timing is not super stable and there are warnings about that in the SC log.
This is a result of the network latency.
To fix that, increase tidal's latency.
If you're using atom go to preferences > open config folder. This brings up the tidal source code. In <tt class="docutils literal">tidalcycles/lib/boot.tidal</tt>, change the <tt class="docutils literal">oLatency</tt> value to 0.4 or so in this line of code:</p>
<div class="highlight"><pre><span></span><span class="nf">tidal</span> <span class="ow"><-</span> <span class="n">startTidal</span> <span class="p">(</span><span class="n">superdirtTarget</span> <span class="p">{</span><span class="n">oLatency</span> <span class="ow">=</span> <span class="mf">0.4</span><span class="p">,</span> <span class="n">oAddress</span> <span class="ow">=</span> <span class="s">"127.0.0.1"</span><span class="p">,</span> <span class="n">oPort</span> <span class="ow">=</span> <span class="mi">57120</span><span class="p">})</span> <span class="p">(</span><span class="n">defaultConfig</span> <span class="p">{</span><span class="n">cFrameTimespan</span> <span class="ow">=</span> <span class="mi">1</span><span class="o">/</span><span class="mi">20</span><span class="p">})</span>
</pre></div>
<p>A value of 0.4 worked for us.
If it's still too low try to increase the value until there's no more jitter and warnings in the log.</p>
</div>
<div class="section" id="stream-the-audio-back-to-the-tidal-user">
<h2>Stream the audio back to the tidal user</h2>
<p>So now the live coder's music is coming from the laptop running SC.
In our case, one audio channel from SC is an analog clock to sync the hardware sync.
The other channels from SC, and the hardware synth, are connected to a mixer and the entire mix can now be heard on the SC end of the system.
But the live coder cannot hear anything yet.
We used a 2nd computer that takes mixer's output and streams it back to the live coder over zoom.</p>
<p>The entire system looks something like this.
The area in blue is for the laptop running tidal and the area in pink is the SC + hardware synth end of the system.</p>
<img alt="TidalCycles logo" src="/images/tidal_remote_diagram.jpg" style="width: 100%;" />
</div>
<div class="section" id="advice-on-testing-things-locally">
<h2>Advice on testing things locally</h2>
<p>If you want to test things on a single computer make sure to change the port SC is listening to.
Otherwise you are trying to use the same port twice: once listening to tidal and sending the messages to the server, and again listening to the messages coming from the server.
To do so, start the SuperDirt synth in SC as follows:</p>
<pre class="code literal-block">
SuperDirt.start(port: 57121)
</pre>
<p>You'll also have to change the port that the TCP stream is converted to, so replace</p>
<pre class="code literal-block">
socat TCP-LISTEN:12345,fork UDP4:localhost:57120
</pre>
<p>with</p>
<pre class="code literal-block">
socat TCP-LISTEN:12345,fork UDP4:localhost:57121
</pre>
<p><strong>Enjoy jamming and keep safe!</strong></p>
</div>
<div class="section" id="footnotes">
<h2>Footnotes</h2>
<table class="docutils footnote" frame="void" id="id2" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id1">[1]</a></td><td>Setting the server this way is not 100% secure. We didn't mind it too much as this is a throwaway server with IP that no one except for us will ever know. If you are worried about security consider creating a forward tunnel from the laptop running tidal to the server instead of exposing the port to the public.</td></tr>
</tbody>
</table>
</div>
bibo, the command line reference manager, is in beta now!2020-05-28T00:00:00+01:002020-05-28T00:00:00+01:00Tom Guriontag:blog.leverstone.me,2020-05-28:/bibo-beta.html<object data="/images/bibo_beta_release_banner.svg" style="width: 100%;" type="image/svg+xml">
bibo beta release banner</object>
<p>bibo is a command line reference manager with a single source of truth: the <tt class="docutils literal">.bib</tt> file. It is inspired by <a class="reference external" href="https://github.com/beetbox/beets">beets</a>. After 3 years in the making I believe it's ready for other people to use.</p>
<p>What are the advantages over mendeley / zotero / etc. you ask …</p><object data="/images/bibo_beta_release_banner.svg" style="width: 100%;" type="image/svg+xml">
bibo beta release banner</object>
<p>bibo is a command line reference manager with a single source of truth: the <tt class="docutils literal">.bib</tt> file. It is inspired by <a class="reference external" href="https://github.com/beetbox/beets">beets</a>. After 3 years in the making I believe it's ready for other people to use.</p>
<p>What are the advantages over mendeley / zotero / etc. you ask?</p>
<ul class="simple">
<li>It gives you control over your files. They are not hidden in some obscure database, hence easy to backup, share, etc.</li>
<li>It's a thin editor of .bib files, so no need to export your bibliography anywhere.</li>
<li>It's extensible with plugins.</li>
<li>It's a command line tool. So if you're a fan of the unix philosophy (small building blocks that are easy to integrate with each other) you might love it.</li>
</ul>
<p><a class="reference external" href="https://bibo.readthedocs.io/en/latest/index.html">Here are the docs</a> with everything you need to learn more about the project and to get started.</p>
<p>This beta release (0.1.0) marks the first release that is fully functional, was tested extensively, and should work for most people. It's not a production ready software yet, so make sure you backup your bibliography (and PDFs) before using it! It is, however, used already by a few people, so give it a spin if you like the idea.</p>
<p>If anything is broken, please reach out! I will be happy to read about <a class="reference external" href="https://github.com/Nagasaki45/bibo/issues">issues on github</a>. Contributions are also super welcome. More about this in the docs.</p>
The Krihelinator reached end-of-life2020-04-09T00:00:00+01:002020-04-09T00:00:00+01:00Tom Guriontag:blog.leverstone.me,2020-04-09:/krihelinator-eol.html<img alt="The Krihelinator RIP" src="/images/krihelinator-eol.png" style="width: 100%;" />
<p>After more than 4 years online, the Krihelinator was shut down today. The idea behind this project was to propose an alternative to github's trading page by highlighting projects with high contribution rate instead of stars. I'm a bit sorry to let this project go, as it was one of …</p><img alt="The Krihelinator RIP" src="/images/krihelinator-eol.png" style="width: 100%;" />
<p>After more than 4 years online, the Krihelinator was shut down today. The idea behind this project was to propose an alternative to github's trading page by highlighting projects with high contribution rate instead of stars. I'm a bit sorry to let this project go, as it was one of my main side projects for many years. The decision came after multiple changes to some github pages that the project was scraping. After the last change the data that the project collected was so broken that it didn't make much sense to keep it online as is. I decided not to fix it, as I have other side projects that I would like to dedicate more time to at the moment.</p>
<p>More information about the project can be found on <a class="reference external" href="https://github.com/nagasaki45/krihelinator">github</a>.</p>
New portfolio site2020-04-03T00:00:00+01:002020-04-03T00:00:00+01:00Tom Guriontag:blog.leverstone.me,2020-04-03:/new-portfolio-site-2020.html<p><a class="reference external" href="https://blog.leverstone.me/my-new-portfolio-site.html">Yet again</a>, I have a new portfolio site. Actually, it's just a redesign. Wanted to simplify the previous over-the-top site. Check it out at <a class="reference external" href="https://leverstone.me">leverstone.me</a>. Here's a reminder for how the old one looked like.</p>
<video controls src="/images/old-portfolio-site.mp4"></video>Intro to git workshop2019-02-21T19:00:00+00:002019-02-21T19:00:00+00:00Tom Guriontag:blog.leverstone.me,2019-02-21:/intro-to-git-workshop.html<p>A 4 hours introduction to git workshop for my PhD fellas.
Based on an old <a class="reference external" href="/git-crash-course">git crash course</a> blog post.</p>
<img alt="git logo" src="/images/git_logo.gif" style="width: 100%;" />
<div class="section" id="why">
<h2>Why?</h2>
<ul class="simple">
<li>Keep your projects organized.</li>
<li>Collaborate with others.</li>
<li>Get involved with open source.</li>
</ul>
</div>
<div class="section" id="command-what">
<h2>Command what?</h2>
<p><a class="reference external" href="https://tutorial.djangogirls.org/en/intro_to_command_line/">Introduction to the command line</a>.
From now on, the rest is done there.</p>
</div>
<div class="section" id="configuring-git-for-the-first-time">
<h2>Configuring git …</h2></div><p>A 4 hours introduction to git workshop for my PhD fellas.
Based on an old <a class="reference external" href="/git-crash-course">git crash course</a> blog post.</p>
<img alt="git logo" src="/images/git_logo.gif" style="width: 100%;" />
<div class="section" id="why">
<h2>Why?</h2>
<ul class="simple">
<li>Keep your projects organized.</li>
<li>Collaborate with others.</li>
<li>Get involved with open source.</li>
</ul>
</div>
<div class="section" id="command-what">
<h2>Command what?</h2>
<p><a class="reference external" href="https://tutorial.djangogirls.org/en/intro_to_command_line/">Introduction to the command line</a>.
From now on, the rest is done there.</p>
</div>
<div class="section" id="configuring-git-for-the-first-time">
<h2>Configuring git for the first time</h2>
<div class="highlight"><pre><span></span>git config --global user.name <span class="s2">"Your name here"</span>
git config --global user.email <span class="s2">"your_email@example.com"</span>
git config --global core.editor nano
</pre></div>
</div>
<div class="section" id="working-locally">
<h2>Working locally</h2>
<p>When git manages a directory on your computer we call this directory a local git repository.</p>
<p>There are two ways to start to work in such a repository:</p>
<ul class="simple">
<li><tt class="docutils literal">git clone <span class="pre">https://github.com/some_user/some_repo.git</span></tt> to download a project into a new directory <tt class="docutils literal">some_repo</tt>.</li>
<li><tt class="docutils literal">git init</tt> to make the current directory a git repository.</li>
</ul>
<div class="section" id="unstaged-staged-committed">
<h3>Unstaged ➜ staged ➜ committed</h3>
<img alt="git local workflow" src="/images/git_staging_commit.png" style="width: 100%;" />
<p><strong>Remember!</strong> you can always see the current state and the staging / unstaging commands with <tt class="docutils literal">git status</tt>, so don't try to memorize them.</p>
<p>When you are satisfied with the changes commit them:</p>
<div class="highlight"><pre><span></span>git commit -m <span class="s2">"an informative message describing your change"</span>
</pre></div>
</div>
<div class="section" id="exercise">
<h3>Exercise</h3>
<ol class="arabic simple">
<li>Create a directory called <tt class="docutils literal">jokes</tt>.</li>
<li>Make it a local git repository.</li>
<li>Create a file called <tt class="docutils literal">jokes.txt</tt> in that directory.</li>
<li>Write some funny stuff.</li>
<li>Add and commit.
Try to have an informative commit message.</li>
<li>Repeat steps 4-5 as many times as you want 🙃.</li>
</ol>
</div>
<div class="section" id="explore-your-repo">
<h3>Explore your repo</h3>
<div class="highlight"><pre><span></span>git log <span class="c1"># see the history</span>
git diff <span class="c1"># see the unstaged changes</span>
git diff --staged <span class="c1"># see the staged changes</span>
git show <COMMIT_HASH> <span class="c1"># see the changes in a commit</span>
</pre></div>
</div>
</div>
<div class="section" id="collaborating-through-github">
<h2>Collaborating through GitHub</h2>
<p>GitHub is a place to share and collaborate on git repositories.
Go head and create an account!</p>
<p>Your local git repository can be "linked" to remote repositories.
To see them run <tt class="docutils literal">git remote</tt> (or with extra info using <tt class="docutils literal">git remote <span class="pre">-v</span></tt>).
If you cloned an existing repository you should see one remote, called <tt class="docutils literal">origin</tt>, in the list.
Otherwise, create a new GitHub repository and add it as a remote with:</p>
<div class="highlight"><pre><span></span>git remote add origin https://github.com/you/your_repo.git
</pre></div>
<p>Naming a remote <tt class="docutils literal">origin</tt> is just a convention. It has no special meaning.</p>
<div class="section" id="pull">
<h3><tt class="docutils literal">pull</tt></h3>
<p>To get the latest changes (commits) from your remote run:</p>
<div class="highlight"><pre><span></span>git pull origin master
</pre></div>
<p>What's master? The name of the default branch.
More on that later.</p>
</div>
<div class="section" id="push">
<h3><tt class="docutils literal">push</tt></h3>
<p>If you have permissions to push code to the remote repository you can update the remote with your changes (commits) by running:</p>
<div class="highlight"><pre><span></span>git push origin master
</pre></div>
<p><strong>Remember!</strong> Always <tt class="docutils literal">pull</tt> before you <tt class="docutils literal">push</tt> to avoid unnecessary conflicts.</p>
<img alt="git Austin Powers meme" src="/images/git_meme.jpg" style="width: 100%;" />
<p>Assuming that you already have a local repository with a remote (called <tt class="docutils literal">origin</tt>) that you can push code to, a simple but complete workflow might look like that:</p>
<div class="highlight"><pre><span></span>git pull origin master <span class="c1"># to get the latest changes</span>
<span class="c1"># work work work...</span>
git status <span class="c1"># to see all of the changes you did</span>
git diff <span class="c1"># optional but handy</span>
git add FILE_WITH_CHANGES <span class="c1"># repeat as necessary</span>
git commit -m <span class="s2">"your message"</span> <span class="c1"># commit the changes to the repository</span>
git push origin master <span class="c1"># to upload your changes</span>
</pre></div>
</div>
<div class="section" id="id1">
<h3>Exercise</h3>
<ol class="arabic simple">
<li>Create a new GitHub repo, called <tt class="docutils literal">jokes</tt>.</li>
<li>Add it as a remote for your local <tt class="docutils literal">jokes</tt> repo.</li>
<li>Push your jokes to GitHub.</li>
</ol>
</div>
<div class="section" id="forks-and-pull-requests">
<h3>Forks and pull requests</h3>
<p>If you don't have permissions to push code to a remote repository.</p>
<ol class="arabic simple">
<li>Fork the repository.
It will copy the remote repository to your account.</li>
</ol>
<img alt="GitHub fork button" src="/images/github_fork.png" style="width: 100%;" />
<ol class="arabic simple" start="2">
<li>Add your fork as a remote.</li>
</ol>
<div class="highlight"><pre><span></span>git remote add mine https://github.com/you/your_repo.git
</pre></div>
<ol class="arabic simple" start="3">
<li>Work on your fork.</li>
<li>Send your commits to the owner(s) of the projects using a pull request.</li>
</ol>
<img alt="GitHub pull request button" src="/images/github_pull_request.png" style="width: 100%;" />
</div>
<div class="section" id="id2">
<h3>Exercise</h3>
<ol class="arabic simple">
<li>Fork <a class="reference external" href="https://github.com/Nagasaki45/mat-trivia">this repository</a>.</li>
<li>Clone your fork so you'll have a local git repository on your computer.</li>
<li>Answer some questions in one of the files in <tt class="docutils literal"><span class="pre">mat-trivia/trivia/</span></tt>.</li>
<li>Stage the changes, commit, and push to your remote repo.</li>
<li>Submit a pull request</li>
</ol>
</div>
</div>
<div class="section" id="where-to-go-next">
<h2>Where to go next?</h2>
<ul class="simple">
<li><em>Branches</em> are an important concept in git.
<a class="reference external" href="http://learngitbranching.js.org/">Learn them here</a>.</li>
<li>Ignore files in the repo with <tt class="docutils literal">.gitignore</tt>.</li>
<li><a class="reference external" href="https://speakerdeck.com/alicebartlett/git-for-humans">Good intro to git in slides format</a>.</li>
<li><a class="reference external" href="https://stackoverflow.com/">Stack overflow</a> for questions, as usual :-)</li>
<li><a class="reference external" href="https://git-scm.com/book/en/v2">Pro Git book</a>: lots of info, sometime too verbose.</li>
</ul>
</div>
Dead of Winter: The Long Night - A DIY box insert2019-02-08T00:00:00+00:002019-02-08T00:00:00+00:00Tom Guriontag:blog.leverstone.me,2019-02-08:/dow-tln-insert.html<p>As if there were not enough different topics mashed together in the blog, here's another one.
I'm into board games, and recently got <a class="reference external" href="https://boardgamegeek.com/boardgame/193037/dead-winter-long-night">Dead of Winter: The Long Night</a>.
This blog post is about the box the game came in, and what I did to make it usable.</p>
<p>Below you …</p><p>As if there were not enough different topics mashed together in the blog, here's another one.
I'm into board games, and recently got <a class="reference external" href="https://boardgamegeek.com/boardgame/193037/dead-winter-long-night">Dead of Winter: The Long Night</a>.
This blog post is about the box the game came in, and what I did to make it usable.</p>
<p>Below you can see the cards, standees, and tokens after a single play.
Yes, that's a complete mess!</p>
<img alt="DoW: TLN box after one play. A total mess." src="/images/dow-mess.jpg" style="width: 100%;" />
<p>Thankfully, I'm not the first to be frustrated about this. A quick google search found <a class="reference external" href="https://www.reddit.com/r/foamcore/comments/51mvio/comfc_dead_of_winter_the_long_night/">nezbokaj's plans</a> for a DIY foamboard insert to keep all of the components organized. I followed his plans and I'm super happy with the results.</p>
<img alt="The box with all of the components organized." src="/images/dow-organized-1.jpg" style="width: 100%;" />
<p>To contribute back to these plans, <a class="reference external" href="/images/dow_tln_insert.svg">here's the cutting pattern</a> I followed to get the most out of a A2 piece of foamboard.
First, <strong>use it as a reference!</strong> Don't try to print it out and cut on top of the lines or anything like that. The lines are too wide for that.
Second, when you cut the foamboard, start by cutting everything into stripes by the measurements on the left side of the cutting patter.
Then, cut the stripes into pieces.
Lastly, in the picture below you can see that the insert pushes the lid a bit up.
Maybe about 5-7mm.
I think that a few millimeters can be taken of the deepest measurement (the 6.3cm).
On the other hand, the result is good enough for me.</p>
<img alt="The lid is lifted by a few millimeters." src="/images/dow-lid.jpg" style="width: 100%;" />
<p>The entire thing costed £6. £2.5 for the foamboard and the rest for some glue and a knife.</p>
<p>Here are some more pictures from the process, including pictures with some of the boards in the box.</p>
<img alt="The foamboard insert, before it got into the box." src="/images/dow-insert.jpg" style="width: 100%;" />
<img alt="Small boards (locations and player aids) in the box." src="/images/dow-organized-2.jpg" style="width: 100%;" />
<img alt="Larger boards in the box." src="/images/dow-organized-3.jpg" style="width: 100%;" />
<p class="bold">TL;DR: Go build <a class="reference external" href="https://www.reddit.com/r/foamcore/comments/51mvio/comfc_dead_of_winter_the_long_night/">nezbokaj's insert for Dead of Winter: The Long Night</a>, possibly using my <a class="reference external" href="/images/dow_tln_insert.svg">cutting pattern</a>.</p>
Getting started with Python for data analysis2017-11-10T00:00:00+00:002017-11-10T00:00:00+00:00Tom Guriontag:blog.leverstone.me,2017-11-10:/getting-started-with-python.html<img alt="Python books covers" src="/images/python_books.png" style="width: 100%;" />
<p>A few days ago another friend asked me to recommend reading materials to get started with python.
Yesterday, I saw this tweet.</p>
<img alt=""When you’ve written the same code 3 times, write a function. When you’ve given the same in-person advice 3 times, write a blog post" - David Robinson" src="/images/write_a_blog_post_tweet.png" style="width: 100%;" />
<p>So here I am, writing this blog post.</p>
<p>A short disclaimer:
I like learning from books, but I know that it doesn't work for everybody.
So my recommendations …</p><img alt="Python books covers" src="/images/python_books.png" style="width: 100%;" />
<p>A few days ago another friend asked me to recommend reading materials to get started with python.
Yesterday, I saw this tweet.</p>
<img alt=""When you’ve written the same code 3 times, write a function. When you’ve given the same in-person advice 3 times, write a blog post" - David Robinson" src="/images/write_a_blog_post_tweet.png" style="width: 100%;" />
<p>So here I am, writing this blog post.</p>
<p>A short disclaimer:
I like learning from books, but I know that it doesn't work for everybody.
So my recommendations are, unsurprisingly, for books.
Don't follow them if you don't like learning by reading.</p>
<p>If you have some coding experience and want to dive straight to doing data analysis with python you can skip this paragraph.
If you are not so confident with your programming skills, and want to take it slowly, <a class="reference external" href="https://www.manning.com/books/the-quick-python-book-third-edition">the Quick Python Book</a>, by Naomi Ceder, is highly recommended.
My first steps with python were with the 2nd edition of the same book, and <a class="reference external" href="/python-readings.html">here are my thoughts on it</a>.
In general, it's a bit wordy but the explanations are very clear and to the point.
In fact, being a bit verbose is probably what you want anyway if coding is new to you.
Note that a new edition is about to come out, and an ebook version is already available.
If you are looking for a shorter and faster introduction to python take a look at <a class="reference external" href="https://learnxinyminutes.com/docs/python3/">Learn X in Y minutes</a>. It is especially good for those who are already familiar with coding but are new to python.</p>
<p>To get familiar with the python scientific stack I can highly recommend going over the first section of the <a class="reference external" href="http://www.scipy-lectures.org/">Scipy Lecture Notes</a>.
Their short intro to the language (chapter 1.2) is also great.
With this resource one can learn <a class="reference external" href="http://www.numpy.org/">numpy</a> and <a class="reference external" href="https://matplotlib.org/">matplotlib</a> relatively fast.
The last crucial building block in the python scientific stack that you must learn is <a class="reference external" href="http://pandas.pydata.org/">pandas</a>.
The canonical book for pandas is <a class="reference external" href="http://shop.oreilly.com/product/0636920023784.do">Python for Data Analysis</a> by Wes McKinney, the creator of the package.
Personally, <a class="reference external" href="/python-readings.html">I didn't like this book so much</a>.
On the other hand, I really like everything coming from Jake Vanderplas, and his book, the <a class="reference external" href="http://shop.oreilly.com/product/0636920034919.do">Python Data Science Handbook</a> contains a chapter about pandas.
I didn't read it, but from my familiarity with his writing and from online comments I saw I think that I can stand behind this recommendation.</p>
<p>After that stop reading, and start to solve some real world problems!</p>
Python vs. elixir for a web-app wrapper for a script2017-08-27T00:00:00+01:002017-08-27T00:00:00+01:00Tom Guriontag:blog.leverstone.me,2017-08-27:/web-script.html<img alt="Python vs. elixir" src="/images/python_vs_elixir.png" style="width: 100%;" />
<p>I'm a facing a project with the following requirements:</p>
<ul class="simple">
<li>An existing script should be wrapped with a web server.</li>
<li>The script takes 10-30 seconds to run, so just let the user wait for it to complete.</li>
<li>Multiple users should be able to call the script concurrently.</li>
<li>Make sure to protect …</li></ul><img alt="Python vs. elixir" src="/images/python_vs_elixir.png" style="width: 100%;" />
<p>I'm a facing a project with the following requirements:</p>
<ul class="simple">
<li>An existing script should be wrapped with a web server.</li>
<li>The script takes 10-30 seconds to run, so just let the user wait for it to complete.</li>
<li>Multiple users should be able to call the script concurrently.</li>
<li>Make sure to protect the server from overloading by limiting the number of concurrent active scripts.</li>
</ul>
<p>I created a repo with two projects, in python and elixir, to see how easy / hard the task will be with each technology.
You can find the repo <a class="reference external" href="https://github.com/Nagasaki45/web-script/">here</a>.
The frontend, and the demo script to run, are the same for both projects.
Getting and validating user input is not demonstrated, as it should be straightforward in both languages.
The idea was to compare the concurrency stuff.</p>
<div class="section" id="python">
<h2>Python</h2>
<p>The implementation is based on <a class="reference external" href="https://aiohttp.readthedocs.io/en/latest/index.html">aiohttp</a>, with no much extras.
There is a global counter to track the number of active scripts.
A new POST request checks the counter.
If it reaches the maximal allowed active scripts a 503 error is returned, indicating that the service is unavailable.
Otherwise, first, the counter is incremented.
Then, <tt class="docutils literal">asyncio.create_subprocess_exec</tt> is used to call the script.
Lastly, the result is returned to the user, and the counter is decremented under <tt class="docutils literal">finally</tt>.</p>
</div>
<div class="section" id="elixir">
<h2>Elixir</h2>
<p>The general idea is very similar.
The server is based on <a class="reference external" href="https://github.com/ninenines/cowboy">cowboy</a> and <a class="reference external" href="https://github.com/elixir-plug/plug">plug</a>.
Instead of a global counter I'm using <a class="reference external" href="https://github.com/devinus/poolboy">poolboy</a> to create a pool of workers for calling the script.
On each POST request, if the pool if full, the 503 error is returned.
Otherwise, the script is called and the result is returned to the user.</p>
</div>
<div class="section" id="conclusions">
<h2>Conclusions</h2>
<p>I'm a complete asyncio newbie, and wasn't sure how complex the implementetion will be.
It always feel a bit restrictive for me.
For example, without the already implemented <tt class="docutils literal">asyncio.subprocess</tt> module, following the requirements would be much more difficult.
I'm also more confident with elixir, as I use it almost exclusively for everything web-based.
With elixir you can use whatever library you want and make use of all of the concurrency feature of the language without any special adapters.
Surprisingly, the python solution ended up much simpler than I thought, and it is much shorter than the elixir solution (mainly due to the way a project is structured in elixir).
So, I ended with two easy to use options, hence the decision between them will be even harder.
Or maybe it's time to properly learn asyncio.</p>
</div>
DIY eurorack case2017-07-16T00:00:00+01:002017-07-16T00:00:00+01:00Tom Guriontag:blog.leverstone.me,2017-07-16:/eurorack-case.html<img alt="Final eurorack case." src="/images/eurorack_case_header.jpg" style="width: 100%;" />
<p>I recently drawn into the rabbit hole of modular synthesis.
This week I finished building my first eurorack case.
It's a 3U 84hp skiff.
Or in humans language, it is a relatively small, beginners sized case, to accommodate my first modules.</p>
<div class="section" id="the-plan">
<h2>The plan</h2>
<p>I have access to a laser cutter …</p></div><img alt="Final eurorack case." src="/images/eurorack_case_header.jpg" style="width: 100%;" />
<p>I recently drawn into the rabbit hole of modular synthesis.
This week I finished building my first eurorack case.
It's a 3U 84hp skiff.
Or in humans language, it is a relatively small, beginners sized case, to accommodate my first modules.</p>
<div class="section" id="the-plan">
<h2>The plan</h2>
<p>I have access to a laser cutter at uni, so I thought that it will be great to use it for the project.
Add to that some <a class="reference external" href="https://www.thingiverse.com/thing:1206004">open source designs for laser cutting eurorack cases</a>, and it looked like an easy path to follow.
But then I started to rethink it too much.
I already bought the <a class="reference external" href="http://www.tiptopaudio.com/zrails.php">Tiptop audio Z-Rails</a> to fit into the case, which is not exactly the same as the one in the design above,
In addition, our laser cutter can cut much thicker wood than the 6mm used in this design.
So maybe I will design my own case...</p>
<p>I decided to do so, and with the help of <a class="reference external" href="https://makeabox.io/">make a box</a> produced my own design files, for a 9mm plywood.
And if I'm already using the laser cutter to cut the wood, why not add a stylistic engraved texture on top of it?
Inspired by <a class="reference external" href="http://archive.eyebeam.org/projects/generative-laser-cuts">Aaron Meyers</a>, I opened processing and started to code a generative texture to engrave over my case.
I was sure that engraving the texture will be the most complicated part in this DIY project, but I was wrong.
Very wrong.</p>
</div>
<div class="section" id="what-didn-t-work">
<h2>What didn't work</h2>
<p>These are the mistakes I made.
All of them could be avoided easily.</p>
<ul class="simple">
<li>Consider the position of the screws that connect the rails to the case. I didn't thought about it, and it ended to be very close to a cut, as you can see in the picture.</li>
</ul>
<img alt="Problematic screw positioning." src="/images/eurorack_case_screw.jpg" style="width: 100%;" />
<ul class="simple">
<li>Make sure that the laser cutter can actually cut the material you got! And if unsure, try on a small piece of material before starting. I checked with the workshop instruction, and was sure that 9mm will be fine. On the first attempt, when I configured the laser cutter to attempt to cut 9mm, it ran so slowly that the material caught fire (you can see the burned area in the upper left corner in the picture above)! Then, I speed it up, but with higher speed it took around 20 iterations until it was cut properly. Two consequences of the issues I gut with the cuttings are the burned cut, and...</li>
<li>The cut ended up way wider than I expected. I thought that the laser will cut the material very precisely, and in minimal width, but the cut ended up to be pretty wide (I will say ~2 millimeters).</li>
<li>Make sure you got the dimensions right! I checked online and saw that modules are 128.5mm high. I added the width of the top edge of the Z-Rails, which is 1.2mm, to each side, and ended up with 131mm as the internal height for the case. THIS IS WRONG! It seems that the correct height should be 133.35mm, but recheck for yourself. I had to use chisel to trim 1mm from the top and the bottom pieces to open some more room for the rails.</li>
</ul>
</div>
<div class="section" id="the-went-well">
<h2>The went well</h2>
<p>The engraving ended up much better than I expected.
I started with one PDF file for the entire engraving job, with an overall length of lines to engrave just over 100 meters.
When I tried to send this file to the printer the driver's preview window didn't show all of the lines in my PDF.
Maybe it's just a presentation issue, but I decided to separate the job into layers.
This was easy for my case, as the lines were generated by <a class="reference external" href="https://processing.org/">processing</a> one by one without any dependencies between them.
In the original PDF there were 30K lines, so I created 6 PDFs with 5K lines each, that when overlaid create the same result.
I really glad I did that for few reasons.</p>
<ul class="simple">
<li>I didn't know if the printer will move like a regular printer (with one axis moving forwards all the time and the other forwards and backwards repeatedly), or that it will do the lines one by one as they were "recorded" in the pdf (random order), or will optimize the movement. Apparently, it optimizes the movement, meaning that it starts from one corner and draws line by line from there towards the other side of the board. If I had send the whole plan, and the process was too slow, I would have been ended up with only half of the board engraved. Fortunately, each layer took "only" 53 minutes, so it wasn't a real problem.</li>
<li>Second, with this layered approach I could see the state of the engraving after each layer and decide if I want to continue to the next layer or not. Eventually, I stopped after the 4th layer as the result was good enough for me.</li>
</ul>
<img alt="The engraved texture before cutting." src="/images/eurorack_case_engraving.jpg" style="width: 100%;" />
<p>I also cut some blank panels on the way, from 3mm plywood.
An easy task for the laser printer.
In addition, the gluing and finishing (with danish oil) were successful and without any issues.
But there is nothing interesting I can tell you about these, so let's move on.</p>
</div>
<div class="section" id="files-and-disclaimer">
<h2>Files and disclaimer</h2>
<p>The design files are <a class="reference external" href="https://github.com/Nagasaki45/eurorack-case">here</a>.
Feel free to use the engraving sketch in <tt class="docutils literal">generative_waves/generative_waves.pde</tt> for whatever you want.
As far as I can tell the blank panels files are also fine.
<strong>BUT PLEASE DON'T USE THE FILES IN THIS REPO TO CUT A EURORACK CASE!</strong></p>
</div>
<div class="section" id="to-summarize">
<h2>To summarize</h2>
<p>It's not the most accurate build, but my new case does the job.
Despite the problems, IMHO the end result looks very good.
And finally I'm starting to play with it, and enjoy every moment!</p>
<img alt="Jamming with my new eurorack case." src="/images/eurorack_case_jam.jpg" style="width: 100%;" />
<p>If you want to see more <a class="reference external" href="https://photos.app.goo.gl/dPukY2PL1LhajZlZ2">here is an album of the entire building process</a>.
Some modular music will come soon.
Stay tuned!</p>
</div>
git crash course2017-01-31T17:00:00+00:002017-01-31T17:00:00+00:00Tom Guriontag:blog.leverstone.me,2017-01-31:/git-crash-course.html<p>A really short introduction to git for my PhD fellas.</p>
<div class="section" id="first-trygit">
<h2>First, <a class="reference external" href="https://try.github.io/">TryGit</a></h2>
</div>
<div class="section" id="clone-something">
<h2>Clone something</h2>
<p>There are two ways to start to work in a git repository.</p>
<ul class="simple">
<li><tt class="docutils literal">git clone <span class="pre">https://github.com/some_user/some_repo.git</span></tt> to download a project into a new directory <cite>some_repo</cite>.</li>
<li><tt class="docutils literal">git init</tt> to make the current directory …</li></ul></div><p>A really short introduction to git for my PhD fellas.</p>
<div class="section" id="first-trygit">
<h2>First, <a class="reference external" href="https://try.github.io/">TryGit</a></h2>
</div>
<div class="section" id="clone-something">
<h2>Clone something</h2>
<p>There are two ways to start to work in a git repository.</p>
<ul class="simple">
<li><tt class="docutils literal">git clone <span class="pre">https://github.com/some_user/some_repo.git</span></tt> to download a project into a new directory <cite>some_repo</cite>.</li>
<li><tt class="docutils literal">git init</tt> to make the current directory a git repository.</li>
</ul>
<p>Go ahead and clone a project of interest.</p>
</div>
<div class="section" id="working-locally">
<h2>Working locally</h2>
<img alt="git local workflow" src="/images/git_staging_commit.png" style="width: 100%;" />
<p><strong>Remember!</strong> you can always see the current state and the staging / unstaging commands with <tt class="docutils literal">git status</tt>, so don't try to memorize them.</p>
<p>When you are satisfied with the changes commit them:</p>
<div class="highlight"><pre><span></span>git commit -m <span class="s2">"an informatice message describing your change"</span>
</pre></div>
</div>
<div class="section" id="explore">
<h2>Explore</h2>
<div class="highlight"><pre><span></span>git log <span class="c1"># see the history</span>
git diff <span class="c1"># see the unstaged changes</span>
git diff --staged <span class="c1"># see the staged changes</span>
git show <COMMIT_HASH> <span class="c1"># see the changes in a commit</span>
</pre></div>
</div>
<div class="section" id="collaborating-through-github">
<h2>Collaborating through GitHub</h2>
<p>GitHub is a place to share and collaborate on git repositories.</p>
<p>Your local git repository can be "linked" to remote repositories.
To see them run <tt class="docutils literal">git remote</tt>.
If you cloned an existing repository you should see one remote, called <tt class="docutils literal">origin</tt>, in the list.
Otherwise, create a new GitHub repository and add it as a remote with:</p>
<div class="highlight"><pre><span></span>git remote add origin https://github.com/you/your_repo.git
</pre></div>
<div class="section" id="pull">
<h3><tt class="docutils literal">pull</tt></h3>
<p>To get the latest changes (commits) from your remote run:</p>
<div class="highlight"><pre><span></span>git pull origin master
</pre></div>
</div>
<div class="section" id="push">
<h3><tt class="docutils literal">push</tt></h3>
<p>To update the remote with your changes (commits) run:</p>
<div class="highlight"><pre><span></span>git push origin master
</pre></div>
<p><strong>Remember!</strong> Always <tt class="docutils literal">pull</tt> before you <tt class="docutils literal">push</tt> to avoid unnecessary conflicts.</p>
<img alt="git Austin Powers meme" src="/images/git_meme.jpg" style="width: 100%;" />
</div>
</div>
<div class="section" id="a-simple-but-complete-workflow">
<h2>A simple but complete workflow</h2>
<p>Assuming that you already have a local repository with a remote (called <tt class="docutils literal">origin</tt>) that you can push code to:</p>
<div class="highlight"><pre><span></span>git pull origin master <span class="c1"># to get the latest changes</span>
<span class="c1"># work work work...</span>
git status <span class="c1"># to see all of the changes you did</span>
git diff <span class="c1"># optional but handy</span>
git add FILE_WITH_CHANGES <span class="c1"># repeat as necessary</span>
git commit -m <span class="s2">"your message"</span> <span class="c1"># commit the changes to the repository</span>
git push origin master <span class="c1"># to upload your changes</span>
</pre></div>
</div>
<div class="section" id="more-info-and-resources">
<h2>More info and resources</h2>
<ul class="simple">
<li><em>Branches</em> are an important concept in git. <a class="reference external" href="http://learngitbranching.js.org/">Learn it</a>!</li>
<li><a class="reference external" href="https://git-scm.com/book/en/v2">Pro Git book</a>: lots of info, sometime too verbose.</li>
</ul>
</div>
Media and arts projects - part 22017-01-10T22:00:00+00:002017-01-10T22:00:00+00:00Tom Guriontag:blog.leverstone.me,2017-01-10:/media-and-arts-projects-part-2.html<img alt="The tapeless cassettes" src="/images/tapeless_cassettes_header.jpg" style="width: 100%;" />
<p>In a <a class="reference external" href="https://blog.leverstone.me/media-and-arts-projects-part-1.html">previous post</a> I wrote about my assignments for the sound recording module I took as part of my PhD.
Here, I will present the projects of the Interactive Digital Multimedia Techniques module.</p>
<div class="section" id="the-tapeless-cassettes">
<h2>The tapeless cassettes</h2>
<p>In the first major project of the module we were required to find …</p></div><img alt="The tapeless cassettes" src="/images/tapeless_cassettes_header.jpg" style="width: 100%;" />
<p>In a <a class="reference external" href="https://blog.leverstone.me/media-and-arts-projects-part-1.html">previous post</a> I wrote about my assignments for the sound recording module I took as part of my PhD.
Here, I will present the projects of the Interactive Digital Multimedia Techniques module.</p>
<div class="section" id="the-tapeless-cassettes">
<h2>The tapeless cassettes</h2>
<p>In the first major project of the module we were required to find some unused object and create an interactive digital "something" out of it.
The title for the projects, and the following event in which they were presented, was "CruftFest".
My project, the tapeless cassettes, uses modified audio cassettes as controllers for an interactive and collaborative musical interface.
It invites users to manually turn the cassettes wheels, with their pinky or a BIC® pen, to control the speed of the music.
The interaction is simple and intuitive - the higher the speed of the wheel, the faster the music.
I assembled multiple cassettes to enable a group of users to play together, letting each one to control different track in the music.
The resulted sounds fluctuate in speed and in pitch, and therefore cannot be synchronized.
The lack of synchronization, which is unusual in familiar music, suggest different type of interactions with the musical materials and between players.</p>
<p>More details can be found in the project page <a class="reference external" href="https://github.com/Nagasaki45/TapelessCassettes">on github</a>.</p>
<div class="youtube youtube-16x9"><iframe src="https://www.youtube.com/embed/JZ3Z4X_d1iQ" allowfullscreen seamless frameBorder="0"></iframe></div><p>Here are a few pictures of the project from the CruftFest event.</p>
<img alt="Playing with the cassettes." src="https://lh3.googleusercontent.com/VssKhoacTmRKKIkZKfqmk_NNoiydcAHpXOgUiH0CVhe-s9riEPPs6MMuyAeuTTQd189YpEDEv9Xd0XeA4eJck6TQGre7ToGeLK3w0fDixOnk7BsGDgQYgjSehc7Enb5gDyyeUC-LsrYhybPM05ZbbFLbWJLeCvdZzMFnezp6se23xrp0AFt8PRynLILP7wq9TER2lOZ_727DYn-LvIrmAxV-ai_VUuyylA-PH0a3qudT0URXRcTUhU5RULUVG_RUX7eypD6eoUpmTUUdnNE4VLQ7JaUj2QUOOemyJQNvsGgy30g25GBXSV_aQM2ZVB0Kyw8_7omZmH51VYN273ijHEVCl3ll_VtaLmKJMORlUVNbYjYWRDkRj7wtiuvUMs4f_abSK2tkUV_FUcIoc9C9i_Q_c-GIzyRJZ4Z2mqkU7YNz1LAwFdJJV6XgxHGN4dh36UEv8QscGAjPDdmCOJpMhn4K76RNs1eVRwOJU09IV1TTtgVQU-qe5utXnMiLUKkLInPIzCSm7FlHUfuFg7mvQF6NMjgFUm4gIRYv6bBYdHs29cXrwn3VLAzpczuKUgnMS3xx_6PN4rPMxLTTRcEBCKJ_NS2v9t2Sk2vTdiRNYqAMS4sCa5f8Jg=w942-h628-no" style="width: 100%;" />
<img alt="Playing with the cassettes." src="https://lh3.googleusercontent.com/VssKhoacTmRKKIkZKfqmk_NNoiydcAHpXOgUiH0CVhe-s9riEPPs6MMuyAeuTTQd189YpEDEv9Xd0XeA4eJck6TQGre7ToGeLK3w0fDixOnk7BsGDgQYgjSehc7Enb5gDyyeUC-LsrYhybPM05ZbbFLbWJLeCvdZzMFnezp6se23xrp0AFt8PRynLILP7wq9TER2lOZ_727DYn-LvIrmAxV-ai_VUuyylA-PH0a3qudT0URXRcTUhU5RULUVG_RUX7eypD6eoUpmTUUdnNE4VLQ7JaUj2QUOOemyJQNvsGgy30g25GBXSV_aQM2ZVB0Kyw8_7omZmH51VYN273ijHEVCl3ll_VtaLmKJMORlUVNbYjYWRDkRj7wtiuvUMs4f_abSK2tkUV_FUcIoc9C9i_Q_c-GIzyRJZ4Z2mqkU7YNz1LAwFdJJV6XgxHGN4dh36UEv8QscGAjPDdmCOJpMhn4K76RNs1eVRwOJU09IV1TTtgVQU-qe5utXnMiLUKkLInPIzCSm7FlHUfuFg7mvQF6NMjgFUm4gIRYv6bBYdHs29cXrwn3VLAzpczuKUgnMS3xx_6PN4rPMxLTTRcEBCKJ_NS2v9t2Sk2vTdiRNYqAMS4sCa5f8Jg=w942-h628-no" style="width: 100%;" />
<img alt="Playing with two cassettes together." src="https://lh3.googleusercontent.com/wtO0fG91UFniA3yWIvGQRtIf_uv4T0IE0FJLFnzOHqjkUz77Be0usqalQE5DRXVj9dT40nyUI1aXg-S-7LLgbXBEngdCb8NWjxD2-9FTEZNf3Fm6FUXZwZFpb3qNdLlMVvNpXLdFVazkJGaBpnn0v47OgAQJpMEX9np6ZvBwXVQ7y96uV-4SoIMP6cTA62DgHBhW72vi9laqmfPZ6kdgX4M8M8sa4VirXi_7JyV1TrVI5DIIiojxENXBxHfvxHPo55wVuw6rCovQD2PdWrD_C4tEUxUrXin_iIiG-kIjhm43hmNoiQzvCNnHp8hyfGFyc6-QKrExdOFCIe0AQwy3HsQeUmJoCaGBeU9zNq5Bsr13eFceBw3Bq7_CaH24feqov1OHuAJPTCYS-MR8um3DZl8xc7qW0MkJMYEDg-BNrg7tmnGYg5eeVPPnjIu7vS9G2A2dFeSQmakk0CgSfBUm0Ne29nME6Iv4coEKZd_aemnstVzNXbaxIIbIQgNwpiAtNzEtZk-3xA8vQRMOOxJkBz2UXwa60k79nt5NfqUOpmNHD2N_IPBglV9W7W02TfJ-PErolVOSTIRTitLPUlLl7N1IkwE3bsRB1aAfqyjb7Bf5b3qZ5txBQA=w942-h628-no" style="width: 100%;" />
<img alt="Presenting the project to Andrew McPherson." src="https://lh3.googleusercontent.com/SnxMdzevYmFSlyUD80fL62Dh_35OeYRJB9CmHgqPw7NzPsnPaGACpreHi4iGgeHVYGCn_4sUqrsLb1TJ-c5WLfE6qVSqJzXEpd4CasDvriRBe3JdU32ro9K02orkv68DOLFcp1c7acE44AU9TqO9nV4STDAMJhKp8-iWldjA2sq2f63Z__PjXw6aHZRXkOKVHej5Roj1dDSEdGgHs2R3HaJgyjgRrUlmRBn4vVlJo0sD2kNZR-ldJhkdrW1jhp-qBSNnnWG6a-6M1VtU6HaboEkgw7hCChpH1E02jZ1sIE2Yb9bml_pbbvRQKpwZhwDAjlplsfjr4vT55z7_p26vP-nHwAWWWibZ9jqFa0fhnsItbSaJ5kaBl4DmZUFPgQfG3EknJmt7hA9kreYAI7lY3Ugwf8oQ1gUkxnpo41Gj1fr7peh7R0xsLn09YNi8IQ1rscrtuw7RBhB7cVZagP7vyM2lU6uLys86EB8o-HvxHmvAlKqc4SN4wvYACrDim28UrR9kmfnESKeifecjD3AYV0yd6HneIe9lCsr48WoRYnQdctYidvriQWJlSEMtdaiKAjYAXvFj6W9n3NFPmYZbL5S8nCWIPdJDNELa1FugMlwrpJaxeQ4pZw=w471-h628-no" style="width: 100%;" />
<img alt="Vanessa and Sebastian playing together." src="https://lh3.googleusercontent.com/Ztw4_E5dijN8uKB2F2EYO94dPO98EB8FhMWzGP-v4miJ_uJaelhWysRqn9Wca09u2C4BuWijIC7-AZEx-ZwvqOJqma4TNVNdqjhT5HjRuiS1lvANC8Uy7qwvwa0TJ_OsJl9yVTsJWwPwKWm2QCCDTdRALPUQjHcuus3rB9R9m45S1rEMtHFdBnx0TFH5Tw8sLQmz53UJP25_ebHQbtqi8RXmoSNE9zluR0D1OOOsAhTZkC-kofEUD8PraOj25FcDPXZWhCV8NLt68H22x2919iZi8JL1NDbw_BK7aSqnk5Q8gS1cpsqDMnuL0kYafsmTCiC9boNqfkirTWMc1K5j209Ktm5_0FWIJ9ysXWX3Sn1xEPJVr0rRn5AKteHr8Y8hlHzOv8C3ngRocog4lA3R0BhwudbdHF7G-xihxDqrbgwEn2l0ZiplItsyY1PGHCgz-N_asM3r3EKBQt4ebVrMjiU63sfc2mE1HHwAjto6gTJBpoG1POi5mUYOlEoMXQiYs2jPjwqtll4cuCsBDK-AFLihKecFWLEPi20RM_VL93rl753WIUffLYOfrJPiTmt1Zbxxnlh78BIyQKgdWNyscnFVEuL0SPxvUV5YeVcMOyGuKRCA6dVGUA=w838-h628-no" style="width: 100%;" />
</div>
<div class="section" id="schleikess-suspenders-in-yiddish">
<h2>Schleikess ("suspenders" in Yiddish)</h2>
<p>As the final project for the module I created the Schleikess - a controller for full-body interactive performances.
It requires force and effort to play with, hopefully facilitating expressiveness.
The interface is composed of two elastic bands that are attached to the performers' belt loops on one side, and a main unit that measures the tension on each elastic band.
The performer holds the other side of each elastic band and stretches them to play.
In the current work, a generative drum machine is used to demonstrate the capabilities of this controller by mapping the tension on the bands to tempo the pitch properties of the drums.</p>
<p>Again, all of the bits and bytes can be found <a class="reference external" href="https://github.com/Nagasaki45/Schleikess">online</a>.</p>
<div class="youtube youtube-16x9"><iframe src="https://www.youtube.com/embed/_BUf_VLCIWQ" allowfullscreen seamless frameBorder="0"></iframe></div><p>And a few more pictures from the presentation event.</p>
<img alt="30 seconds presentation." src="https://lh3.googleusercontent.com/gEDGzxqM9c8ODxE8f3fZZGN9LPa3yW6TCk55tYz3PKmS5LxdagbjhL6Yxh8IqcDsAxUrrIsGCtW4z_gqjq2tZZjL3d92_87GIjrCYW8cfP4YYb31wsAUC9H1ZWh066trLB_EAolViafK0fQ6nCeS2Ol4kGFX7Yxhc6vAgnuksqCNzlqgufGp69Qf1m5hIYOpM9jLs48hAgEy2MJHogD0KeIYK8GR1h6Rz5Y0VNtMSMjjRLsieg2UUCiLE-r63BfD3krlUKU2Pjq-CMaScyw_Obr_y6qvZQIMX26Iq7eWh4SvWwSXxVydsaMGwPtuyhWzbDFR9WqGwnK-J3jZTOMbrkU9Ge8QuQmgtSe4ASi5jC7UgXOIlY7OTH_h-_7Nymx_ujWE3hKnv96cf8coZEMRMPeVdKM5d1X4VAk5iN1Gxbs9hM2QFWK4OwB2WfdOPDTXtVcdIjL77xXypW1n4hjmMzzbvoH438P_hG5CqynxNoLAn-uRbO4XBIbBecsDUgn69QbNJcV8XW9UWJpZttp7AZyuylYmf9GZnIRXshb9InPz6VK1BHu9MH4OKEXdXvMmcvQ9tcVRSqcOiUa5L9oVN9IFJUHWEiX-Pr4Ntux6ZTEjs9fKOxdZZQ=w948-h628-no" style="width: 100%;" />
<img alt="The Schleikess are ready for demonstration." src="https://lh3.googleusercontent.com/9990Q8RappPQwljaT3UAYZDW8KUE9eCjYA41mgcEWFHkqSKyPS_rRRH0vkC_J41pdGEpYq8r9Fy9sfzu1l3UfQWFVPBB_05UnkEY0Eu6ES2i8uUV5yxluZC-0UzkO3gL3nW8N84IfOLUYHfDgFrrp-yFunrd06rWh-RABCvLI1tbzfUJ74b0DNTDpC6vrB5vy-xOI9_4wfxY9WR-_rYqfmdVBazsAaoQlaR4spIwaIFuejSNVcBvXRS3kbWm1ayeLr9JQQivy_Flpw4HCK5VG4VLJQxKCYoDv4zd_iwn4lU_qnosVY8bWqyoZ2gaSzJP4-Sws5RO6M4HyeniZ5ccmsOwkmL1_IQfT3gTErTqt-x_wLE5ezdlel6jFSODtDrsVdvo8qI6iZ5yaZIjKyaujWAezRDRQxkI5VrgNc1O_Nbwajrn9biJTf5rob7PhyTgU_IZ6gDwgc7g6ip04XPAwZoiwvH0R3hwMuPq_aRNcDJi7LqhgsCdzhBdRP5WbUKD5a0tOKBe-3ENVfpy3M5h_CwgC6akwhKNu21SoC0MHNpap4t60hwR9nHMES9761I_hkwwAZV_sfpRrXLeRYcZDafA_zLToSn1gcLY9SA7kKGSxAtJWmvjVQ=w838-h628-no" style="width: 100%;" />
<img alt="Presenting to Andrew McPherson." src="https://lh3.googleusercontent.com/wO_aOOhvQbECirKp_OjTUEUMA9yrs6QsrIOx8f6JKocSuStAQlcnwx2qC2-BzMjA0j6Rb7FlxPLjYRfKXbl0y5HnKwoZ5PBMV6U-OsTxLiGJujSxcPFEP77YtvqYhJFfnUMcdckAMNer11Fdy_oBViPMH30vgzIXaOkNWeOUdpErli_N0Qu1P6pWS4uK65leOLOXBL6JzLY3Xbl3jk78aEr0jRazHQ6FaAnSIq5Mbsz84I9iKXkbJYZfUKiWZbiVAyWu7qmVu4hq6qC5dnqIaefNDQFvx4uDaQbDJrPF6ia2RqNwWaMmf6VXaESUtIw6ifQMHbcoEa8xOc0m4i1bTyqCCHypvP6ZtyuR7Rv2BiecJLBWgzKW69QttYUT-rTXvOF_Pe1qYqueLUW7IVlnijcEfdEKvLEt_vUiQFS4_Q7rbqAZWqxoYwFjDghfsF0Ogmb4XAWy51H-Pf8WOiUfI6wqbSHcu3CJQrxYK5Ve8oPWuK_T6U1kDUwocHH-iq1dTaDFhLimNPwQPVL1HIiGfdhBC4XBZjk8bWX3YTQbGF6yI_uz8W3J2WJHHetEe7UO24aliW8zCi-v006caaWWdD6FmG6xzP-djcG_RKMcLr3RCORQ7lYaFg=w471-h628-no" style="width: 100%;" />
<img alt="Vivek and I." src="https://lh3.googleusercontent.com/IgUo4Wmzh8JZxjqD0F5e6CotqIVTNZl5Ie2hC_GCENueF2DANC1v5-JHC50DuPyzvehmeRM6rXUOz80lsWEiYYSE76-F2oDNFbzqGNQ1CnrdYEgaXdUmcmfK2SC5s-k9aWohYJPe_Biop5696oc2DrXrmTOHEy3_uy3n5EZAEknZFcx9hckLYPjc7OD0I7PVtoKUNVmWDjB_5LdjE-juK32KF0hgsxg-d-ZpWhNBD0V2CJMiK3G_I6BF8v5ws0koOzq-mDw7mYQ5O3B_wfsGyvgtGqAT6j9d5Eq3r0p5tlgu4ytqC21eqndVUTZWl6v0cadG5OSR2i3H29WaEljTzWVOwnjYGjQLj7aw6BGTB_kXcCkIO2AMWnjyuZNTdJ6B47_AEbdMvD_-g8buAr0JRllBC7bdhj1PcL0su6N-_W4ssEBZu_LHSMJalNp-Z0CnNtDIp9BoNkBb--QZupnVTue0Ia_vq_wG7VwQc6fBSVakhjUsOnnSKtJmRLjiC05AHHQ0tJdZu4Po5hTwkxFH4qG0b6et-4lBY0xAIb6LKMUTSsBU-Tv4qCxrU-idhSudkWHTpjN4DfOhwjzSeOIF96YmAJlB5CRqGxIKM_Oxfn9UMSFSco3ZKA=w471-h628-no" style="width: 100%;" />
<img alt="Vivek and II." src="https://lh3.googleusercontent.com/hcTnB_CbGswBJ2nom4zTug8ZPsrWV38VRff6Mb41B8EcoAzvJPxQ2dqhuJUBi-_BDuewhY2k5d1arutsdSq5MuL8dzS8q01cPLg8u1l2aVjHRxxsnc-aKQWTfTzrl4z7W-A_IvU_MZOaor74xCG7vG-ARKT5IET_jrFhoKx4fKYneKreIa5efTOONlLu1oI92BSj-QaDyF3JMGXRzAFVd9Qwq_gkhJzhEO4jKcXj1HmJgsanB5wI435Zq0G4JLM1eRTnGyk9STX9uoM77tsVydEaq1ol9PkGW889RvZUk6yHhA-EAZnAXYUZkJOwcLE5es0EOgLRkRhqkBjJkWhSve5c3p4w8C7CZ7dRvzW8zV4bQm8jyH-CKyGhfNnNQZzMKBWfdD19n1PIE32mUmO3Yrdl9oqSkPY_clwhddrO12Nwmxp3jp9GF-7UJ_Aze-Ildw957kKlNB1iDC9fxEQ3y6Bpaqy0yrwIDuodB9jhnPGvhPa0FkiqGRvbGkNJ1aRQEm8f9ccXATGF8-5mbvENGTzEU3mFclfc36bEcAwnLhVKvQK3bZCLPH9PnFR7URoNx-ehkidwsNtENppWpvDQb51_w2TMbX8_5dYhNo0NpmbXwtTNpfNVfA=w471-h628-no" style="width: 100%;" />
</div>
Media and arts projects - part 12016-12-29T22:00:00+00:002016-12-29T22:00:00+00:00Tom Guriontag:blog.leverstone.me,2016-12-29:/media-and-arts-projects-part-1.html<img alt="Sunset Riders - Bury me with my money" src="/images/bury_me_with_my_money.gif" style="width: 100%;" />
<p>I recently shared some of my <a class="reference external" href="/my-first-assignment-as-a-phd-student.html">first experiences as a PhD student</a> in the <a class="reference external" href="http://www.mat.qmul.ac.uk/">Media and Arts Technology program</a>, Queen Mary University of London.
Now, when the first term is over and the second one is about to begin, it is a good time to show the projects I have …</p><img alt="Sunset Riders - Bury me with my money" src="/images/bury_me_with_my_money.gif" style="width: 100%;" />
<p>I recently shared some of my <a class="reference external" href="/my-first-assignment-as-a-phd-student.html">first experiences as a PhD student</a> in the <a class="reference external" href="http://www.mat.qmul.ac.uk/">Media and Arts Technology program</a>, Queen Mary University of London.
Now, when the first term is over and the second one is about to begin, it is a good time to show the projects I have been working on.
This post is therefore the first in a series of 3 posts.
Here I will present my assignments to the Sound Recording and Production Techniques module.</p>
<div class="section" id="bury-me-with-my-money">
<h2>"Bury me with my money!"</h2>
<iframe width="100%" height="300" scrolling="no" frameborder="no" src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/300118139&auto_play=false&hide_related=false&show_comments=true&show_user=true&show_reposts=false&visual=true"></iframe><p>The first significant project in the module was to produce a short soundscape.
Each student wrote a concept on a piece of paper and the concepts were picked by chance by other students.
Mine was "Bury me with my money!". WTF!?!
After a short research I found the origin of the line, in the 90s arcade game Sunset Riders, and a long list of MEMEs surrounding it.</p>
</div>
<div class="section" id="digital-privacy">
<h2>"Digital privacy"</h2>
<iframe width="100%" height="300" scrolling="no" frameborder="no" src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/300119056&auto_play=false&hide_related=false&show_comments=true&show_user=true&show_reposts=false&visual=true"></iframe><p>The instructions for the final project were similar to the previous one.
We were asked to compose another soundscape, but this time we got more freedom to choose the concept by ourselves, and it was required to be a bit longer.
I decided to seize the opportunity and play with deep neural networks on the way.
The idea was to use similar techniques to those presented by <a class="reference external" href="https://deepmind.com/blog/wavenet-generative-model-raw-audio/">google wavenet</a> earlier this year (if you are not familiar with this research yet, go and take a look, it's fascinating!), to create a model that will be able to listen to audio and then generate new audio with similar characteristics.
I wanted to train the model on sounds of private conversations and sex of my partner and I, recorded in our apartment, and use the trained model to generate new audio material that will be used as the basis for the soundscape.</p>
<p>As a serious PhD student I gave the soundscape the title "Digital privacy" and described it as "mirroring the existing conflicts between art, artificial intelligence, and privacy in the age of ubiquitous surveillance".
The truth is, I really want to delve into deep learning and thought that it might be a good way to start :-).</p>
<p>Although I played with machine learning in the past, I'm completely new to deep learning, and after several attempt this first ambitious idea turned out to be a complete failure.
In the end, I used audio samples that I found on the web that were generated in similar techniques.
However, I documented my attempts, so next time I (or someone else) will succeed. You can find all the information <a class="reference external" href="https://github.com/Nagasaki45/digital-privacy-soundscape/blob/master/report/report.md">here</a>.</p>
</div>
Phoenix, templates, and active navbar items2016-12-22T15:30:00+00:002016-12-22T15:30:00+00:00Tom Guriontag:blog.leverstone.me,2016-12-22:/phoenix-templates-and-active-navbar-items.html<p>We build a web-app, and want the items on the navigation bar to be active when the user visits the corresponding page, like this:</p>
<img alt="An animated example of active navigation bar items." src="/images/navbar_active_items.gif" style="width: 100%;" />
<p>I'm not saying that this is a complicated task in other frameworks, but it often feels "hacky".
Here is a <a class="reference external" href="http://www.phoenixframework.org/">phoenix</a> solution that feels pretty elegant …</p><p>We build a web-app, and want the items on the navigation bar to be active when the user visits the corresponding page, like this:</p>
<img alt="An animated example of active navigation bar items." src="/images/navbar_active_items.gif" style="width: 100%;" />
<p>I'm not saying that this is a complicated task in other frameworks, but it often feels "hacky".
Here is a <a class="reference external" href="http://www.phoenixframework.org/">phoenix</a> solution that feels pretty elegant, and therefore worth sharing.</p>
<p>So, let's start with a simple <a class="reference external" href="https://getbootstrap.com/">twitter-bootstrap</a> navbar example for our web-app, with links to our home, products, and about pages.</p>
<div class="highlight"><pre><span></span><span class="p"><</span><span class="nt">nav</span> <span class="na">class</span><span class="o">=</span><span class="s">"navbar navbar-default"</span><span class="p">></span>
<span class="p"><</span><span class="nt">ul</span> <span class="na">class</span><span class="o">=</span><span class="s">"nav navbar-nav"</span><span class="p">></span>
<span class="p"><</span><span class="nt">li</span><span class="p">><</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">"#"</span><span class="p">></span>Home<span class="p"></</span><span class="nt">a</span><span class="p">></</span><span class="nt">li</span><span class="p">></span>
<span class="p"><</span><span class="nt">li</span><span class="p">><</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">"#"</span><span class="p">></span>Products<span class="p"></</span><span class="nt">a</span><span class="p">></</span><span class="nt">li</span><span class="p">></span>
<span class="p"><</span><span class="nt">li</span><span class="p">><</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">"#"</span><span class="p">></span>About<span class="p"></</span><span class="nt">a</span><span class="p">></</span><span class="nt">li</span><span class="p">></span>
<span class="p"></</span><span class="nt">ul</span><span class="p">></span>
<span class="p"></</span><span class="nt">nav</span><span class="p">></span>
</pre></div>
<p>Right now, none of the links are highlighted.
We need to add a <tt class="docutils literal"><span class="pre">class="active"</span></tt> to the <tt class="docutils literal"><li></tt> item that corresponds to the current page.
The question is, how can we do it dynamically, according to the current visited page?</p>
<p>The <a class="reference external" href="https://hexdocs.pm/plug/readme.html#the-plug-conn"><tt class="docutils literal">Plug.Conn</tt></a> contains all of the information for the current request/response cycle, and is available in our views and template.
Moreover, the <tt class="docutils literal">&Phoenix.Controller.action_name/1</tt> function expects a <tt class="docutils literal">Plug.Conn</tt> and returns the name of the controller function that was used to process the request.
With this information in mind, let's create a template to render navbar <tt class="docutils literal"><li></tt> items.
First, we will have to make the <tt class="docutils literal">action_name</tt> function available in our views.
Edit <tt class="docutils literal">web/web.ex</tt> to import it to all of the views.</p>
<div class="highlight"><pre><span></span> # Import convenience functions from controllers
<span class="gd">- import Phoenix.Controller, only: [get_csrf_token: 0, get_flash: 2, view_module: 1]</span>
<span class="gi">+ import Phoenix.Controller, only: [get_csrf_token: 0, get_flash: 2, view_module: 1, action_name: 1]</span>
</pre></div>
<p>Now we are ready to create the template for the navbar items:</p>
<div class="highlight"><pre><span></span><span class="c"><!-- web/templates/layout/navbar_item.html.eex --></span>
<span class="err"><</span>%= if action_name(@conn) == @action do %>
<span class="p"><</span><span class="nt">li</span> <span class="na">class</span><span class="o">=</span><span class="s">"active"</span><span class="p">></span>
<span class="err"><</span>%= else %>
<span class="p"><</span><span class="nt">li</span><span class="p">></span>
<span class="err"><</span>%= end %>
<span class="err"><</span>%= link @text, to: page_path(@conn, @action) %>
<span class="p"></</span><span class="nt">li</span><span class="p">></span>
</pre></div>
<p>Notice that this template expects the <tt class="docutils literal">conn</tt>, <tt class="docutils literal">action</tt> (as an atom), and <tt class="docutils literal">text</tt> (for the link) as assigns.
It also uses the <tt class="docutils literal">link</tt> function to create the <tt class="docutils literal"><a></tt> tags automatically by finding the path in the routing table for us.
We can already use it by replacing our previous navbar with:</p>
<div class="highlight"><pre><span></span><span class="p"><</span><span class="nt">nav</span> <span class="na">class</span><span class="o">=</span><span class="s">"navbar navbar-default"</span><span class="p">></span>
<span class="p"><</span><span class="nt">ul</span> <span class="na">class</span><span class="o">=</span><span class="s">"nav navbar-nav"</span><span class="p">></span>
<span class="err"><</span>%= render "navbar_item.html", conn: @conn, action: :index, text: "Home" %>
<span class="err"><</span>%= render "navbar_item.html", conn: @conn, action: :products, text: "Products" %>
<span class="err"><</span>%= render "navbar_item.html", conn: @conn, action: :about, text: "About" %>
<span class="p"></</span><span class="nt">ul</span><span class="p">></span>
<span class="p"></</span><span class="nt">nav</span><span class="p">></span>
</pre></div>
<p>However, it is even more elegant and concise to add the following function to the layout view:</p>
<div class="highlight"><pre><span></span><span class="c1"># web/views/layout_view.ex</span>
<span class="kd">def</span> <span class="n">navbar_item</span><span class="p">(</span><span class="n">assigns</span><span class="p">)</span> <span class="k">do</span>
<span class="n">render</span> <span class="s2">"navbar_item.html"</span><span class="p">,</span> <span class="n">assigns</span>
<span class="k">end</span>
</pre></div>
<p>And improve the navbar:</p>
<div class="highlight"><pre><span></span><span class="p"><</span><span class="nt">nav</span> <span class="na">class</span><span class="o">=</span><span class="s">"navbar navbar-default"</span><span class="p">></span>
<span class="p"><</span><span class="nt">ul</span> <span class="na">class</span><span class="o">=</span><span class="s">"nav navbar-nav"</span><span class="p">></span>
<span class="err"><</span>%= navbar_item conn: @conn, action: :index, text: "Home" %>
<span class="err"><</span>%= navbar_item conn: @conn, action: :products, text: "Products" %>
<span class="err"><</span>%= navbar_item conn: @conn, action: :about, text: "About" %>
<span class="p"></</span><span class="nt">ul</span><span class="p">></span>
<span class="p"></</span><span class="nt">nav</span><span class="p">></span>
</pre></div>
<p>In addition to <tt class="docutils literal">action_name</tt>, you might also be interested in <tt class="docutils literal">Phoenix.Controller.controller_module</tt>, as suggested <a class="reference external" href="http://stackoverflow.com/a/36009443/1224456">here</a>.
I hope that this short tutorial helped you.
Good luck with your navbar!</p>
An Even Better Pip Worflow™2016-11-04T23:50:00+00:002016-11-04T23:50:00+00:00Tom Guriontag:blog.leverstone.me,2016-11-04:/an-even-better-pip-workflow.html<p>The 9th major version of <a class="reference external" href="https://pypi.python.org/pypi/pip"><tt class="docutils literal">pip</tt></a>, the recommended tool for installing python packages, was released two days ago. I took a short look on <a class="reference external" href="https://pip.pypa.io/en/stable/news/">the changelog</a> to see what's new. At first, I couldn't notice anything that will change my current workflows. Usually, the important changes are listed first, but …</p><p>The 9th major version of <a class="reference external" href="https://pypi.python.org/pypi/pip"><tt class="docutils literal">pip</tt></a>, the recommended tool for installing python packages, was released two days ago. I took a short look on <a class="reference external" href="https://pip.pypa.io/en/stable/news/">the changelog</a> to see what's new. At first, I couldn't notice anything that will change my current workflows. Usually, the important changes are listed first, but there was nothing groundbreaking there. However, I kept reading, to find this:</p>
<ul class="simple">
<li>Add <em>--not-required</em> option to <tt class="docutils literal">pip list</tt> to list packages that are not dependencies of other packages.</li>
</ul>
<p>In "<a class="reference external" href="http://www.kennethreitz.org/essays/a-better-pip-workflow">A Better Pip Workflow™</a>", Kenneth Reitz describes a problematic aspect of dependencies management in python. Usually, we "freeze" the state of the dependencies of a project with <tt class="docutils literal">pip freeze > requirements.txt</tt> to reproduce the exact environment later with <tt class="docutils literal">pip install <span class="pre">-r</span> requirements.txt</tt>. The problem starts when you want to upgrade these dependencies. Take this <a class="reference external" href="https://github.com/Nagasaki45/blog">blog dependencies</a> for example.</p>
<div class="highlight"><pre><span></span>$ pip list
blinker <span class="o">(</span><span class="m">1</span>.4<span class="o">)</span>
docutils <span class="o">(</span><span class="m">0</span>.12<span class="o">)</span>
feedgenerator <span class="o">(</span><span class="m">1</span>.8<span class="o">)</span>
Jinja2 <span class="o">(</span><span class="m">2</span>.8<span class="o">)</span>
MarkupSafe <span class="o">(</span><span class="m">0</span>.23<span class="o">)</span>
pelican <span class="o">(</span><span class="m">3</span>.6.0<span class="o">)</span>
pelican-readtime <span class="o">(</span><span class="m">0</span>.1.2<span class="o">)</span>
pelican-youtube <span class="o">(</span><span class="m">0</span>.2.0<span class="o">)</span>
pip <span class="o">(</span><span class="m">9</span>.0.0<span class="o">)</span>
Pygments <span class="o">(</span><span class="m">2</span>.1.3<span class="o">)</span>
python-dateutil <span class="o">(</span><span class="m">2</span>.5.3<span class="o">)</span>
pytz <span class="o">(</span><span class="m">2016</span>.4<span class="o">)</span>
setuptools <span class="o">(</span><span class="m">28</span>.8.0<span class="o">)</span>
six <span class="o">(</span><span class="m">1</span>.10.0<span class="o">)</span>
Unidecode <span class="o">(</span><span class="m">0</span>.4.19<span class="o">)</span>
</pre></div>
<p>Ideally, I would like to manage only the packages I call directly from code / command line (let's call them the "top most dependencies" from now on), and let them manage their dependencies for me. Therefore, I would have to read this output carefully to decide what to upgrade: "did I install Pygments? and what about docutils? I know for sure that pelican-youtube was installed manually, so let's <tt class="docutils literal">pip install <span class="pre">--upgrade</span> <span class="pre">pelican-youtube</span></tt>" and so forth...</p>
<p>Kenneth's recommendation to simplify the upgrade process is to keep two requirements files, the 1st includes all of the dependencies with their versions (<tt class="docutils literal">pip freeze > requirements.txt</tt>), and the 2nd, <tt class="docutils literal"><span class="pre">requirements-to-freeze.txt</span></tt> should be <strong>managed manually</strong> to contain the top most dependencies. When it's time for an upgrade, call <tt class="docutils literal">pip install <span class="pre">-r</span> <span class="pre">requirements-to-freeze.txt</span> <span class="pre">--upgrade</span></tt>. Just don't forget to run <tt class="docutils literal">pip freeze > requirements.txt</tt> immediately afterwards!</p>
<p>With the flag introduced in <tt class="docutils literal">pip</tt> 9.0.0, there is no more need for the <tt class="docutils literal"><span class="pre">requirements-to-freeze.txt</span></tt> file. To find out which packages should be upgraded run <tt class="docutils literal">pip list <span class="pre">--not-required</span></tt>. However, there are still some caveats to note:</p>
<ol class="arabic simple">
<li>The <tt class="docutils literal"><span class="pre">--not-required</span></tt> flag is implemented for <tt class="docutils literal">pip list</tt> and not for <tt class="docutils literal">pip freeze</tt>. They have different format. When the later is suitable for requirement files the former is not. Here is a <a class="reference external" href="https://github.com/pypa/pip/issues/4088">github issue</a> to implement the same flag for <tt class="docutils literal">pip freeze</tt>.</li>
<li>Assuming that the previous issue will be solved, I couldn't find a <strong>nice</strong> (read as "no bash scripting") way to pipe the output of <tt class="docutils literal">pip freeze <span class="pre">--not-required</span></tt> to <tt class="docutils literal">pip install <span class="pre">--upgrade</span></tt>. There is still an intermediate phase of creating a temporary <tt class="docutils literal"><span class="pre">requirements-to-freeze.txt</span></tt> file.</li>
<li>Until the first issue will be resolved, we will upgrade <tt class="docutils literal">pip</tt> and <tt class="docutils literal">setuptools</tt> with our top most dependencies. The reason is that they are listed by <tt class="docutils literal">pip list</tt> but not by <tt class="docutils literal">pip freeze</tt>.</li>
<li>We will probably want to strip the version numbers from the output of <tt class="docutils literal">pip list <span class="pre">--not-required</span></tt>. It is meaningless to ask pip to upgrade but state the old versions in the same time.</li>
</ol>
<div class="section" id="demo-time">
<h2>Demo time!</h2>
<p>Let's try things out by updating this blog dependencies! First, let's see the top most dependencies:</p>
<div class="highlight"><pre><span></span>$ pip list --not-required
pelican <span class="o">(</span><span class="m">3</span>.6.0<span class="o">)</span>
pelican-readtime <span class="o">(</span><span class="m">0</span>.1.2<span class="o">)</span>
pelican-youtube <span class="o">(</span><span class="m">0</span>.2.0<span class="o">)</span>
pip <span class="o">(</span><span class="m">9</span>.0.0<span class="o">)</span>
setuptools <span class="o">(</span><span class="m">28</span>.8.0<span class="o">)</span>
</pre></div>
<p>OK. Considering the caveats above, we will need some bash scripting here. First, we want to remove the versions from the output. <tt class="docutils literal">sed</tt> might be our friend here. Let's try to use it to remove the versions completely by taking everything from the space to the end of the line and replacing it by an empty string:</p>
<div class="highlight"><pre><span></span>$ pip list --not-required <span class="p">|</span> sed <span class="s1">'s/ .*//'</span>
pelican
pelican-readtime
pelican-youtube
pip
setuptools
</pre></div>
<p>Great! Let's pass this to <tt class="docutils literal">pip install <span class="pre">--upgrade</span></tt>:</p>
<div class="highlight"><pre><span></span>$ pip install --upgrade <span class="sb">`</span>pip list --not-required <span class="p">|</span> sed <span class="s1">'s/ .*//'</span><span class="sb">`</span>
...
Successfully installed feedgenerator-1.9 pelican-3.6.3 pytz-2016.7
</pre></div>
<p>That's all. The top most dependencies were upgraded.</p>
</div>
My first assignment as a PhD student2016-10-11T00:00:00+01:002016-10-11T00:00:00+01:00Tom Guriontag:blog.leverstone.me,2016-10-11:/my-first-assignment-as-a-phd-student.html<div class="youtube youtube-16x9"><iframe src="https://www.youtube.com/embed/GCLCNuh4-Fs" allowfullscreen seamless frameBorder="0"></iframe></div><p>So, what do you see here? Actually, nothing special. Yes, it is my first
assignment as a PhD student in the <a class="reference external" href="http://www.mat.qmul.ac.uk/">Media and Arts Technology</a> programme at
Queen Mary University of London. And yes, it is a simple <a class="reference external" href="https://www.arduino.cc/">arduino</a> exercise. So
why does it deserve a blog post?</p>
<p>The thing …</p><div class="youtube youtube-16x9"><iframe src="https://www.youtube.com/embed/GCLCNuh4-Fs" allowfullscreen seamless frameBorder="0"></iframe></div><p>So, what do you see here? Actually, nothing special. Yes, it is my first
assignment as a PhD student in the <a class="reference external" href="http://www.mat.qmul.ac.uk/">Media and Arts Technology</a> programme at
Queen Mary University of London. And yes, it is a simple <a class="reference external" href="https://www.arduino.cc/">arduino</a> exercise. So
why does it deserve a blog post?</p>
<p>The thing that make this assignment interesting, for me, is the shift in mindset
that it proposes. In the last two years I've been working as a software
developer. As I see it, software engineering most of the time aims to "solve a
problem". It can be a bug fix or a new feature, but the motivation is similar.
Here, on the other hand, the motivation is completely different - more like "try
something new that might be artistically interesting". Personally, I can find
both approaches motivated, but it about time to start to explore the 2nd one a
bit more.</p>
<p>In addition, I think that this assignment also demonstrate that:</p>
<ul class="simple">
<li>Trying out new things should be fun.</li>
<li>You don't need take yourself too seriously when doing science.</li>
</ul>
<p>I really hope that all of these will continue to resonate throughout my PhD.</p>
docker-compose in production - part 22016-08-05T00:00:00+01:002016-08-05T00:00:00+01:00Tom Guriontag:blog.leverstone.me,2016-08-05:/docker-compose-in-production-part-2.html<p>Few months ago I shared my <a class="reference external" href="/docker-compose-in-production.html">experiences with docker-compose in production</a>.
Recently I faced another deployment and decided to use the same technique. This
time I used it somewhat differently. In this blog post I would like to share the
new experiences.</p>
<p>I started by following the process that went …</p><p>Few months ago I shared my <a class="reference external" href="/docker-compose-in-production.html">experiences with docker-compose in production</a>.
Recently I faced another deployment and decided to use the same technique. This
time I used it somewhat differently. In this blog post I would like to share the
new experiences.</p>
<p>I started by following the process that went so well last time, which summarized
to:</p>
<ul class="simple">
<li>Create a <tt class="docutils literal">Dockerfile</tt> for the app.</li>
<li>Create a <tt class="docutils literal"><span class="pre">docker-compose.yml</span></tt> file with my app and its dependencies (official postgres and redis docker images).</li>
<li><tt class="docutils literal">git clone</tt> the project on the server.</li>
<li>Build the project <strong>on the server</strong>.</li>
<li>Copy the "secrets" file to the server.</li>
<li>Spin everything with <tt class="docutils literal"><span class="pre">docker-compose</span> up</tt>.</li>
</ul>
<p>But guess what? My digital ocean's droplet has only 512MB of RAM, which are not
enough for building the image. The beloved technique couldn't work with my
server!</p>
<div class="section" id="docker-hub-to-the-rescue">
<h2><a class="reference external" href="https://hub.docker.com/">Docker Hub</a> to the rescue</h2>
<p>OK. I can't build the image on the server, but I still want to use docker and
docker-compose for all of their advantages. The solution will be to build the
image somewhere else, upload it to <a class="reference external" href="https://hub.docker.com/">Docker Hub</a>- an open and free repository
for docker images - and fetch it from there directly to the server.</p>
<p>There are two ways to upload a docker image to Docker Hub. The first is to link
it to your github account and instruct it to build an image whenever you push
code to the repository. The second is to build the image locally and push it to
the Hub using the docker command line tool. I wished I could choose the first
option, but due to memory restrictions the build failed on their build servers
similarly to the way it failed on my digital ocean droplet. Therefore, I choose
the 2nd option.</p>
<p>With this revised deployment technique there are only two files on the server,
the <tt class="docutils literal"><span class="pre">docker-compose.yml</span></tt> file and the "secrets" file. In my first blog post
about docker-compose the <tt class="docutils literal"><span class="pre">docker-compose.yml</span></tt> used the current directory as
the <tt class="docutils literal">build</tt> path for the image. Now, the full image name on Docker Hub is
referenced. Here is my <tt class="docutils literal"><span class="pre">docker-compose.yml</span></tt> file:</p>
<div class="highlight"><pre><span></span><span class="nt">web</span><span class="p">:</span>
<span class="nt">image</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">nagasaki45/krihelinator_web</span>
<span class="nt">ports</span><span class="p">:</span>
<span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">80:80</span>
<span class="nt">links</span><span class="p">:</span>
<span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">db</span>
<span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">stash</span>
<span class="nt">env_file</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">./secrets</span>
<span class="nt">restart</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">always</span>
<span class="nt">db</span><span class="p">:</span>
<span class="nt">image</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">postgres</span>
<span class="nt">restart</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">always</span>
<span class="nt">stash</span><span class="p">:</span>
<span class="nt">image</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">redis</span>
<span class="nt">restart</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">always</span>
</pre></div>
</div>
<div class="section" id="summary">
<h2>Summary</h2>
<p>Ideally, a server should only serve the application to the clients, and run the
necessary infrastructure to support it. Building or compiling a project on the
server is possible, but it doesn't have to be that way. With docker and
docker-compose based deployments the build can be done on one machine (be it
your local machine, Docker Hub's dedicated build servers, or some other
continuous integration / delivery server). But it's not only possible, it even
simplifies the process a bit as there is no source code involved, and less
operations run on the server. Give docker-compose a try, you won't regret it.</p>
</div>
Migrating to python32016-06-25T00:00:00+01:002016-06-25T00:00:00+01:00Tom Guriontag:blog.leverstone.me,2016-06-25:/migrating-to-python3.html<p>I was recently asked, by my boss, about the possible benefits of migrating our
code base at work from python 2.6 to python 3. Instead of sending an email back
to my boss with my answer, I decided that it worth a blog post. Why? because the
internet is …</p><p>I was recently asked, by my boss, about the possible benefits of migrating our
code base at work from python 2.6 to python 3. Instead of sending an email back
to my boss with my answer, I decided that it worth a blog post. Why? because the
internet is full with comparisons between python 2 and python 3, but it is hard
to tell what are the real gains from doing the migration. Here, I will try to
explain, in a very subjective manner, the benefits I see from such move.</p>
<p>So let's start with the obvious, <strong>python 3 is clearly a better language than
python 2.6</strong>: <tt class="docutils literal">print</tt> is a function instead of a statement, now with sane
arguments; dict and set comprehensions reduce unnecessary, error prone,
verbosity; real division by default, because that's what you want 99% of the
time anyway; iterators by default (<tt class="docutils literal">range</tt> replaced <tt class="docutils literal">xrange</tt>,
<tt class="docutils literal">dict.items()</tt> replaced <tt class="docutils literal">dict.iteritems()</tt>, etc.); explicit relative
imports... Actually, the list goes on and on. However, I <strong>don't</strong> think that
the features above are good reasons to migrate a large project. Modern python
code, written with python 3 in mind, will benefit from them, that's for sure. But
we do not want to rewrite our code base, we want the transition to be as smooth
as possible.</p>
<p>So what <strong>is</strong> valuable? Here is my list:</p>
<div class="section" id="we-must-leave-python-2-6">
<h2>We must leave python 2.6</h2>
<p>Our server is based on <a class="reference external" href="https://pypi.python.org/pypi/Twisted">twisted</a>, which already dropped support for python 2.6.
Our other main dependency is <a class="reference external" href="http://www.sqlalchemy.org/">SQLAlchemy</a>. I don't think that they are going to
drop support for python 2.6 anytime soon but this day will surely come. In
general, staying with python 2.6 will soon mean that for each dependency upgrade
we will have to upgrade everything at once, which is kind of a nightmare.</p>
<p>So, if we must leave python 2.6 behind and upgrade, I really don't think that
migrating to python 3.5, for example, will be way too complicated than to 2.7.
Moreover, moving to python 2.7 now will require another migration, with similar
effort, in the next 4 years.</p>
</div>
<div class="section" id="what-features-do-worth-the-upgrade">
<h2>What features do worth the upgrade</h2>
<div class="section" id="exception-chaining">
<h3><a class="reference external" href="https://www.python.org/dev/peps/pep-3134/">Exception chaining</a></h3>
<p>In python 3, when an exception is raised from within an <tt class="docutils literal">except</tt> block, it is
concatenated to the former exception, and the traceback of both is available to
whoever catch them. That way, we can always be sure that our top most logging
system will log the entire traceback, even if the latest exception "mask" the
original one.</p>
<p>This feature could solve us several debugging hours. Even more, I'm sure that we
gave up on lots of bugs we couldn't investigate properly, as the original
exception was lost due to a bug in the <tt class="docutils literal">except</tt> block.</p>
</div>
<div class="section" id="unorderable-types">
<h3><a class="reference internal" href="#unorderable-types">Unorderable types</a></h3>
<p>If something is broken, I prefer it to raise exception as soon as possible. In
python 2, the following won't fail!</p>
<div class="highlight"><pre><span></span><span class="o">>>></span> <span class="c1"># python2</span>
<span class="o">>>></span> <span class="s1">'hello'</span> <span class="o"><</span> <span class="mi">1</span>
</pre></div>
<p>WTF?!? Why should anyone allow comparison between a string and an int!?!
Moreover, what is the result, <tt class="docutils literal">True</tt> or <tt class="docutils literal">False</tt>? In python 3 this issue was
solved for good:</p>
<div class="highlight"><pre><span></span><span class="o">>>></span> <span class="c1"># python3</span>
<span class="o">>>></span> <span class="s1">'hello'</span> <span class="o"><</span> <span class="mi">1</span>
<span class="n">Traceback</span> <span class="p">(</span><span class="n">most</span> <span class="n">recent</span> <span class="n">call</span> <span class="n">last</span><span class="p">):</span>
<span class="n">File</span> <span class="s2">"<stdin>"</span><span class="p">,</span> <span class="n">line</span> <span class="mi">1</span><span class="p">,</span> <span class="ow">in</span> <span class="o"><</span><span class="n">module</span><span class="o">></span>
<span class="ne">TypeError</span><span class="p">:</span> <span class="n">unorderable</span> <span class="n">types</span><span class="p">:</span> <span class="nb">str</span><span class="p">()</span> <span class="o"><</span> <span class="nb">int</span><span class="p">()</span>
</pre></div>
<p>Again, we saw such bugs before in our system, and they are hard to spot. Having
the language solve this corner for us will be great.</p>
</div>
<div class="section" id="list-comprehensions-that-doesn-t-leak">
<h3>List comprehensions that doesn't leak</h3>
<p>Again, another source for nasty bugs.</p>
<div class="highlight"><pre><span></span><span class="o">>>></span> <span class="c1"># python2</span>
<span class="o">>>></span> <span class="n">i</span> <span class="o">=</span> <span class="mi">42</span>
<span class="o">>>></span> <span class="n">squares</span> <span class="o">=</span> <span class="p">[</span><span class="n">i</span> <span class="o">**</span> <span class="mi">2</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">xrange</span><span class="p">(</span><span class="mi">10</span><span class="p">)]</span>
<span class="o">>>></span> <span class="nb">print</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
<span class="mi">9</span>
</pre></div>
<div class="highlight"><pre><span></span><span class="o">>>></span> <span class="c1"># python3</span>
<span class="o">>>></span> <span class="n">i</span> <span class="o">=</span> <span class="mi">42</span>
<span class="o">>>></span> <span class="n">squares</span> <span class="o">=</span> <span class="p">[</span><span class="n">i</span> <span class="o">**</span> <span class="mi">2</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">xrange</span><span class="p">(</span><span class="mi">10</span><span class="p">)]</span>
<span class="o">>>></span> <span class="nb">print</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
<span class="mi">42</span>
</pre></div>
</div>
</div>
<div class="section" id="and-much-more">
<h2>And much more</h2>
<p>Apart from new features there are the plethora of packages that we can't use
with python 2.6. External dependencies gradually drop support, while the
standard library continuously improves with new and shiny tools, such as
<tt class="docutils literal">concurrent.futures</tt> and <tt class="docutils literal">asyncio</tt>.</p>
</div>
Continuous integration and delivery with travis-ci and codeship2016-05-30T00:00:00+01:002016-05-30T00:00:00+01:00Tom Guriontag:blog.leverstone.me,2016-05-30:/continuous-integration-and-delivery-with-travis-ci-and-codeship.html<img alt="Travis vs. Codeship" src="/images/travis_codeship.png" style="width: 100%;" />
<p>Generally speaking, continuous integration (CI) is the process of
running your test suite automatically when you push code to your repo.
Continuous delivery / deployment (CD) is the process of deploying the
new code to your server whenever you push to specific branches in your
repo. There is enough information about …</p><img alt="Travis vs. Codeship" src="/images/travis_codeship.png" style="width: 100%;" />
<p>Generally speaking, continuous integration (CI) is the process of
running your test suite automatically when you push code to your repo.
Continuous delivery / deployment (CD) is the process of deploying the
new code to your server whenever you push to specific branches in your
repo. There is enough information about these on the web so I won’t
cover it here. Instead, I would like to talk about travis-ci and
codeship, which are: online services that help you accomplish these
tasks easily; tightly integrated with github; free for open source
projects; very recommended. There are many similar services, of course,
but I won’t mention them as I didn’t use them enough to have an opinion.
So, let’s start with travis.</p>
<div class="section" id="travis-ci">
<h2><a class="reference external" href="https://travis-ci.org/">Travis-CI</a></h2>
<p>AFAIK, travis is the natural CI choice for python developers, and for
good reasons:</p>
<ul class="simple">
<li>It’s the easiest to configure and use.</li>
<li>Configuration is kept in the git repo, using a YAML file. Therefore,
it is version controlled, which is always a good thing.</li>
<li>It will run your tests against a set of python versions, each one in
its own build (AKA a test matrix).</li>
</ul>
<p>There are situations, however, in which travis might not be enough for
you, especially when you want to set up continuous deployment. Enters
codeship.</p>
</div>
<div class="section" id="codeship">
<h2><a class="reference external" href="https://codeship.com/">Codeship</a></h2>
<p>Codeship is clearly inferior:</p>
<ul class="simple">
<li>It is configured using a web interface, using bash scripts to prepare
the environment, run the tests, and deploy (with different script per
branch, which is nice). Yep, you’re expected to type bash scripts into
web forms!</li>
<li>The environment setup is lacking. The <a class="reference external" href="https://codeship.com/documentation/languages/python/">official recommendation for setting
the python version</a>, for example, looks like a hack.</li>
<li>You can’t define a test matrix.</li>
</ul>
<p>It sounds bad, I know, but on the other hand codeship has one feature
that is crucial to my workflow. Each project on codeship have an
ssh-key. Therefore, once you copied the public key to your server
<tt class="docutils literal">authorized_keys</tt> file, codeship can ssh / scp to it without
additional effort, exactly as you do from your development environment.</p>
<p>For example, I have static sites that use a simple script to generate
the site and upload it to the server using <tt class="docutils literal">rsync</tt>. From my
development environment it looks like:</p>
<div class="highlight"><pre><span></span>make rsync_upload
</pre></div>
<p>And guess what? The codeship deployment script do exactly the same when
I push code to the <tt class="docutils literal">master</tt> branch, and nothing more!</p>
<blockquote>
It is important to note that travis do offer <a class="reference external" href="https://docs.travis-ci.com/user/private-dependencies/#User-Key">this feature</a> for
paid plans, and that <a class="reference external" href="https://gist.github.com/lukewpatterson/4242707">hacky alternatives</a> exist.</blockquote>
</div>
<div class="section" id="wrap-up">
<h2>Wrap up</h2>
<p>Personally, for everything "deployable" I stay with codeship at the moment,
as this single feature is more important to me than travis's advantages.
To compensate, I document the different scripts (environment setup, test
running, and deployment) in the project <tt class="docutils literal">README</tt>. In addition, although the
test matrix is a crucial feature when you work on libraries and tools,
web sites and application are usually different. You control the environment
you deploy to, and can set the CI environment to be the same / very similar.</p>
<p>Having said that, for everything else, just go with travis. You won't
regret it.</p>
</div>
<div class="section" id="tl-dr">
<h2>TL;DR</h2>
<ul class="simple">
<li>Prefer <a class="reference external" href="https://travis-ci.org/">travis-ci</a> when developing a library / command line
utility / non “deployable” software.</li>
<li>Use <a class="reference external" href="https://codeship.com/">codeship</a> for continuous deployment of web sites and
applications.</li>
</ul>
</div>
Open your eyes2016-05-14T00:00:00+01:002016-05-14T00:00:00+01:00Tom Guriontag:blog.leverstone.me,2016-05-14:/open-your-eyes.html<div class="youtube youtube-16x9"><iframe src="https://www.youtube.com/embed/SgISW_uyjjU" allowfullscreen seamless frameBorder="0"></iframe></div><p>My band, Malinka, released a new video. It's the first release from our live session at Mooki's Raphsoda, so expect more to come... Meanwhile, you can come and here us live:</p>
<ul class="simple">
<li><strong>This Monday</strong> (16.5) in Hudna bar, Tel-Aviv.</li>
<li><span class="strike">Next month (14.6) in Freddi Lemon bar, Jerusalem.</span></li>
</ul>
Video demo of my Sign-language project2016-03-04T22:50:00+00:002016-03-04T22:50:00+00:00Tom Guriontag:blog.leverstone.me,2016-03-04:/video-demo-of-my-sign-language-project.html<p>This project convert sign-language / gestures to speech. You can read
more about it on
<a class="reference external" href="https://github.com/Nagasaki45/Sign-language">github</a> or in <a class="reference external" href="https://leverstone.me/sign-language.html">my
site</a>. I just uploaded a
video demo of the project. Feel free to comment.</p>
<div class="youtube youtube-16x9"><iframe src="https://www.youtube.com/embed/x6i9gXS5VEQ" allowfullscreen seamless frameBorder="0"></iframe></div>docker-compose in production2016-02-29T00:00:00+00:002016-02-29T00:00:00+00:00Tom Guriontag:blog.leverstone.me,2016-02-29:/docker-compose-in-production.html<p>Deployment sucks! I'm not a dev ops / sys admin type of person, and
every time I'm into deploying a web project I start to rethink the whole
process and get confused. Recently, I decided to restart the work on one
of my older django projects,
<a class="reference external" href="https://github.com/Nagasaki45/Xteams">Xteams</a>, and one of the …</p><p>Deployment sucks! I'm not a dev ops / sys admin type of person, and
every time I'm into deploying a web project I start to rethink the whole
process and get confused. Recently, I decided to restart the work on one
of my older django projects,
<a class="reference external" href="https://github.com/Nagasaki45/Xteams">Xteams</a>, and one of the first
tasks was to migrate it from <a class="reference external" href="https://www.heroku.com/">heroku</a> to my
VPS - a <a class="reference external" href="http://digitalocean.com/">digital ocean</a> droplet. Don't get
me wrong, heroku is great, but I'm already paying 5 bucks per month to
digital ocean, where I host all of my web projects, and the single web
dyno that heroku gives for free is a real limitation.
Before starting to migrate the project, I decided about the following
deployment requirements:</p>
<ol class="arabic simple">
<li>I want a consistent production environment, with the fewest possible
system wide dependencies, mainly due to...</li>
<li>I have several projects already deployed to this VPS, so I need a
production environment which will play nice with them both in term of
dependencies and in hostname routing (resolving foo.com and bar.com
to their respective ports / apps).</li>
<li>Staging and production environments should be as similar as possible,
and I want to be able to run the staging environment on my local
machine.</li>
<li>Moreover, if I can utilize parts of the production configurations for
development - like DB / job queue and workers - it's even better.</li>
<li>Keep deployment scripts to the bare minimum.</li>
<li>Not over-engineer the issue.</li>
</ol>
<div class="section" id="dokku">
<h2><a class="reference external" href="http://dokku.viewdocs.io/dokku/">Dokku</a></h2>
<p>I liked heroku. Deploying is really easy, and if I can accomplish a
task using git alone I will probably do it that way :-) So I checked
dokku. It clearly solves the first requirement easily: apart from dokku
itself there is no system wide configuration and dependencies to worry
about. It also solves issues 5 and 6 really nicely: the deployment is
done by pushing to remote repository and production specific
configurations (or secrets) can be added with environment variables,
which I like. On the other hand, I'm not sure if dokku would play nicely
with my other projects, there is no way to run an environment similar to
production locally, and I can't reuse components for development.</p>
</div>
<div class="section" id="deployment-scripts-like-ansible-fabric">
<h2>Deployment scripts (like <a class="reference external" href="https://www.ansible.com/">ansible</a> / <a class="reference external" href="http://www.fabfile.org/">fabric</a>)</h2>
<p>Almost a year ago I read Harry Percival's great book <a class="reference external" href="http://chimera.labs.oreilly.com/books/1234000000754/">"TDD with
Python"</a>. He
teaches how to automate deployment with ansible. I managed to deploy the
sample app for the book and later I used the same technique to deploy
one more django app of mine. However, I really don't like this approach.
It seems very fragile, touching too many configurations too often,
making me afraid about my other projects on the server. It's a lot of
work too, and work that I can't reuse for development. Overall, I feel
that it only answer requirement 3 and 6. The rest are not even close to
be answered.</p>
</div>
<div class="section" id="finally-docker-and-docker-compose-to-the-rescue">
<h2>Finally: docker and docker-compose to the rescue</h2>
<img alt="Docker compose in production" src="/images/docker_compose_prod.jpg" />
<p>You weren't expected this, didn't you?!?
Let's follow the diagram and I will try to convince you why using
docker-compose in production (and also partly in development) is a good
idea. With docker, you can create an image of an application, together
with all of its dependencies, and run it in an isolated environment,
which is called a docker container. docker-compose lets you take a set
of such images, define the links between containers (in means of network
and volume access) and orchestrate all of the containers together, from
building to running.
In the current example I had a DB container with an official postgres
image. Every time I need to configure postgres on my local machine I
find myself reading throughout half of stackoverflow and the official
docs for information. This time it was really easy: I grabbed the
official postgres image from docker hub and that's it - no more
configuration needed.
Second, there is the web container that runs the django app itself.
This is the main container in my project. I wrote a Dockerfile to
describe how the image should be built. It contains only a few lines:
starting from the official python 3.5 image, pip installing
dependencies, and collect static files. Secrets are written in a special
file which django-compose pass to the container as environment
variables. This file is not source controlled: I created one manually on
my local machine and another one, slightly different, on my server.
Here's the Dockerfile for this image:</p>
<script src="https://gist.github.com/Nagasaki45/58bd4d758c1408d2c4b7.js"></script><p>Above the web container there is the Nginx container, which have
access to a shared volume from the web container that contains all of
the static files, so static files are served by Nginx directly. Here is
the Nginx container configuration file:</p>
<script src="https://gist.github.com/Nagasaki45/1830411bc5e510c096ae.js"></script><p>Outside of the docker orchestration there is one more Nginx instance,
its job is to route each incoming request to the correct app on the
server. Every app is listening on a different port and Nginx only route
traffic based on the hostname in the http header. Here's the
configuration file:</p>
<script src="https://gist.github.com/Nagasaki45/4575b34641bc4e804c09.js"></script><p>Here's how my docker-compose configuration file looks like:</p>
<script src="https://gist.github.com/Nagasaki45/15f22aeb60e49d1c30d3.js"></script><p>Building and running these containers is really simple:</p>
<script src="https://gist.github.com/Nagasaki45/9aed10b837612f385bc7.js"></script><p>So now, let's try to tackle the requirements list again:</p>
<ol class="arabic simple">
<li>The only system wide dependencies are docker and docker-compose.
Apart from that there is the system wide Nginx server, which is
already there for the other apps.</li>
<li>Running the new project side by side with the other projects is just
a matter of adding one more server configuration file to the system
wide Nginx (more info is available in <a class="reference external" href="https://github.com/Nagasaki45/Xteams#more-info">the project
README</a>). This is
no different from any other app on the server, whether it's a django
app or a static website.</li>
<li>There is no difference at all between staging and production.
Spinning a staging environment locally is just a matter of building
and running the docker-compose environment.</li>
<li>I'm not using a system wide postgres instance in development.
Instead, I use the same postgress docker image I run in production.
Moreover, if I will need more building blocks, as a job queue and
workers, I will be able to add their respective images to both
development and production docker-compose configuration files.</li>
<li>I do have a script for deployment, but it doesn't do much except
pulling the latest source from github, building and running. That's
all.</li>
<li>One might argue that I did over-engineered the issue. Compared to
using dokku this solution is definitely more complex. However, I'm
not sure if maintaining this deployment mechanism is harder than
maintaining ansible deployment scripts, especially when there are
several different apps on the same server.</li>
</ol>
</div>
<div class="section" id="cons">
<h2>Cons</h2>
<ul class="simple">
<li>Provisioning, although very simple, is done manually: I create a
folder on the server, clone the project, and add the django "secrets"
file. It can be automated too, of course, but I'm not sure I see a
reason for that now.</li>
<li>I wished I could run functional tests from a special
<a class="reference external" href="http://www.seleniumhq.org/">selenium</a> container against the
staging environment. This is not trivial as it requires a
bidirectional network access between the selenium driver and the web
app. I gave up the idea, because of its complexity, and I'm running
selenium tests only against the development environment, outside of
any docker container.</li>
<li>Sharing a volume between the web container and the Nginx container is
a neat trick. However, I most force-remove the old web container
after any build and before running the new container to "refresh" the
volume with the latest collected static files. It's a hack I don't
like, but I live with it.</li>
</ul>
</div>
<div class="section" id="summary">
<h2>Summary</h2>
<p>I really like docker-compose. At first, it looks like a tool with a
steep learning curve. But don't be too intimidated. Give it a try and
you might find an elegant solution for deployments, which will hopefully
scale well with your requirements.
I'm sure that there are lots of approaches I'm not covering here, and
all of the above only reflects my limited experience in the field.
Therefor, feel free to criticize and share your experience about the
subject!</p>
</div>
My new portfolio site2016-02-04T17:06:00+00:002016-02-04T17:06:00+00:00Tom Guriontag:blog.leverstone.me,2016-02-04:/my-new-portfolio-site.html<p>I have a new site!</p>
<a class="reference external image-reference" href="http://www.leverstone.me"><img alt="My portfolio header" src="/images/portfolio_header.jpg" style="width: 100%;" /></a>
<p>The site was created to present the different projects I'm working on
as a portfolio. I will keep posting ideas and explorations here. But I
feel that a site with a proper home page and unique design (compared to
this blog, at least) will present …</p><p>I have a new site!</p>
<a class="reference external image-reference" href="http://www.leverstone.me"><img alt="My portfolio header" src="/images/portfolio_header.jpg" style="width: 100%;" /></a>
<p>The site was created to present the different projects I'm working on
as a portfolio. I will keep posting ideas and explorations here. But I
feel that a site with a proper home page and unique design (compared to
this blog, at least) will present the projects and my skillset in a
better light.
And for the technical part. This is a static, pelican based site. The
theme was adapted from the <a class="reference external" href="http://themes.gohugo.io/creative/">Hugo Creative
theme</a>, with several
modifications. Feel free to
<a class="reference external" href="https://github.com/Nagasaki45/leverstone.me">fork</a> and change for
your own needs.
As usual, comments are more than welcome!</p>
Poor man's trick to add and remove conda from $PATH2015-10-24T00:00:00+01:002015-10-24T00:00:00+01:00Tom Guriontag:blog.leverstone.me,2015-10-24:/poor-mans-trick-to-add-and-remove-conda-from-path.html<p><a class="reference external" href="http://conda.pydata.org/docs/">Conda</a> is great for managing
dependencies as matplotlib and scipy: try to install these with pip, in
a virtualenv, and you will be convinced that conda is better in that
regard.
But!
Somehow, the folks at continuum analytics decided that using conda
should override the default python environment (the system-wide …</p><p><a class="reference external" href="http://conda.pydata.org/docs/">Conda</a> is great for managing
dependencies as matplotlib and scipy: try to install these with pip, in
a virtualenv, and you will be convinced that conda is better in that
regard.
But!
Somehow, the folks at continuum analytics decided that using conda
should override the default python environment (the system-wide python
installation). There are some
<a class="reference external" href="https://groups.google.com/a/continuum.io/forum/#!topic/anaconda/opMLiGnjymE">recommendations</a>,
but AFAIK there is no official solution for the problem.
Here is my solution to keep the system-wide python installation as my
default environment and start to use conda only when I want to:</p>
<div class="highlight"><pre><span></span>$ cat ~/bin/unconda
<span class="nb">export</span> <span class="nv">PATH</span><span class="o">=</span><span class="sb">`</span><span class="nb">echo</span> <span class="s2">":</span><span class="si">${</span><span class="nv">PATH</span><span class="si">}</span><span class="s2">:"</span> <span class="p">|</span> sed -e <span class="s2">"s:\:</span><span class="nv">$HOME</span><span class="s2">/miniconda3/bin\::\::g"</span> -e <span class="s2">"s/^://"</span> -e <span class="s2">"s/:</span>$<span class="s2">//"</span><span class="sb">`</span>
</pre></div>
<p>Got the trick from
<a class="reference external" href="https://ntk.me/2013/05/04/path-environment-variable/">here</a>. Thanks
Natsuki!</p>
<div class="highlight"><pre><span></span>$ cat ~/bin/reconda
<span class="nb">export</span> <span class="nv">PATH</span><span class="o">=</span><span class="s2">"</span><span class="nv">$HOME</span><span class="s2">/miniconda3/bin:</span><span class="nv">$PATH</span><span class="s2">"</span>
</pre></div>
<p>Now just add <tt class="docutils literal">$HOME/bin</tt> to your path if it's not already there and you
are ready to go.
Don't forget to remove the line in your <tt class="docutils literal">.bashrc</tt> that add miniconda to
the path in the first place.</p>
<div class="youtube youtube-16x9"><iframe src="https://www.youtube.com/embed/UdQgJdnrEDw" allowfullscreen seamless frameBorder="0"></iframe></div>Back to music with Malinka2015-08-27T00:00:00+01:002015-08-27T00:00:00+01:00Tom Guriontag:blog.leverstone.me,2015-08-27:/back-to-music-with-malinka.html<div class="youtube youtube-16x9"><iframe src="https://www.youtube.com/embed/fzQoYdzAFz0" allowfullscreen seamless frameBorder="0"></iframe></div><p>It's been a while, but recently I started playing bass guitar in a
band again. The band,
"<a class="reference external" href="https://www.youtube.com/channel/UCXGJ2u2sw8sB6Jwa-63ATNw">Malinka</a>",
is lead by <a class="reference external" href="http://www.stavgerman.com/">Stav German</a>, and we have our
<a class="reference external" href="https://www.facebook.com/events/1019498851418082/">first live show next
week</a> in Tel-Aviv.
Feel free to hear, comment, and come to the show, it's free.</p>
My Jupyter (tmpnb) server and Thebe2015-08-04T00:00:00+01:002015-08-04T00:00:00+01:00Tom Guriontag:blog.leverstone.me,2015-08-04:/my-jupyter-tmpnb-server-and-thebe.html<p><strong>Notice: code execution in the browser is currently broken</strong></p>
<div class="highlight"><pre><span></span><span class="o">%</span><span class="n">matplotlib</span> <span class="n">inline</span>
<span class="kn">import</span> <span class="nn">matplotlib.pyplot</span> <span class="k">as</span> <span class="nn">plt</span>
<span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>
<span class="kn">from</span> <span class="nn">IPython.html.widgets</span> <span class="kn">import</span> <span class="n">interact</span>
<span class="k">def</span> <span class="nf">plot_sine</span><span class="p">(</span><span class="n">frequency</span><span class="o">=</span><span class="mf">1.0</span><span class="p">,</span> <span class="n">amplitude</span><span class="o">=</span><span class="mf">1.0</span><span class="p">):</span>
<span class="n">plt</span><span class="o">.</span><span class="n">ylim</span><span class="p">(</span><span class="o">-</span><span class="mf">1.0</span><span class="p">,</span> <span class="mf">1.0</span><span class="p">)</span>
<span class="n">x</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">linspace</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">1000</span><span class="p">)</span>
<span class="n">plt</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">amplitude …</span></pre></div><p><strong>Notice: code execution in the browser is currently broken</strong></p>
<div class="highlight"><pre><span></span><span class="o">%</span><span class="n">matplotlib</span> <span class="n">inline</span>
<span class="kn">import</span> <span class="nn">matplotlib.pyplot</span> <span class="k">as</span> <span class="nn">plt</span>
<span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>
<span class="kn">from</span> <span class="nn">IPython.html.widgets</span> <span class="kn">import</span> <span class="n">interact</span>
<span class="k">def</span> <span class="nf">plot_sine</span><span class="p">(</span><span class="n">frequency</span><span class="o">=</span><span class="mf">1.0</span><span class="p">,</span> <span class="n">amplitude</span><span class="o">=</span><span class="mf">1.0</span><span class="p">):</span>
<span class="n">plt</span><span class="o">.</span><span class="n">ylim</span><span class="p">(</span><span class="o">-</span><span class="mf">1.0</span><span class="p">,</span> <span class="mf">1.0</span><span class="p">)</span>
<span class="n">x</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">linspace</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">1000</span><span class="p">)</span>
<span class="n">plt</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">amplitude</span><span class="o">*</span><span class="n">np</span><span class="o">.</span><span class="n">sin</span><span class="p">(</span><span class="n">x</span><span class="o">*</span><span class="n">frequency</span><span class="p">))</span>
<span class="n">interact</span><span class="p">(</span><span class="n">plot_sine</span><span class="p">,</span> <span class="n">frequency</span><span class="o">=</span><span class="p">(</span><span class="mf">0.5</span><span class="p">,</span> <span class="mf">10.0</span><span class="p">),</span> <span class="n">amplitude</span><span class="o">=</span><span class="p">(</span><span class="mf">0.0</span><span class="p">,</span> <span class="mf">1.0</span><span class="p">));</span>
</pre></div>
<p>Isn't that amazing?!?
I've recently installed an
<a class="reference external" href="https://github.com/jupyter/tmpnb">tmpnb</a> sever on my digitalocean
server, you can access it at <tt class="docutils literal">nagasaki45.com:8000</tt>.
So, what's the big deal?
This configuration allow anyone to use python (or one of the other
supported / installed kernels) on the web, using my server. You don't
have to ask for permission; you can just go to the provided address and
start to code without any local installation.
And it goes way beyond:</p>
<ul class="simple">
<li>You can open new terminal, 'git clone' your project, and demonstrate
it to someone else. And you can do it on mobile devices too. Again,
no installation required, everything is running on the server.</li>
<li>You can use <a class="reference external" href="https://github.com/oreillymedia/thebe">thebe</a> to add
code snippets as the one above to any static html page (your blog, as
example). Even interactive widgets will run the computation back and
fourth from the server to the web frontend for presentation.</li>
</ul>
<p>So go ahead, write some code, let me execute it for you ;-)</p>
<div class="section" id="edit-6-5-16">
<h2>Edit 6.5.16:</h2>
<p>Oreilly shut down their tmpnb server too :-(
So this blog post won't execute python code anytime soon.</p>
</div>
<div class="section" id="edit-20-9-15">
<h2>Edit 20.9.15:</h2>
<p>I'm stopping the service on my server due to some number crunching tasks
I'm running on it.</p>
</div>
<div class="section" id="edit-1-9-15">
<h2>Edit 1.9.15:</h2>
<p>My digitalocean VM has "only" 512MB of RAM. I decided to span tmpnb
with 4 docker containers, 50MB RAM each, to keep the server load on
minimum. Apparently, it possessed some issues as 50MB are probably not
enough.
Right now the example above uses the same tmpnb server has the one in
thebe example
(<a class="reference external" href="https://oreillymedia.github.io/thebe/examples/matplotlib.html">here</a>),
namely <a class="reference external" href="https://oreillyorchard.com:8000/">https://oreillyorchard.com:8000/</a>. It works much better now as
there are no kernal failures when running the examples.</p>
</div>
Writing a programming book? Don't compose an utility library!2015-05-23T00:00:00+01:002015-05-23T00:00:00+01:00Tom Guriontag:blog.leverstone.me,2015-05-23:/writing-a-programming-book-dont-compose-an-utility-library.html<p>I came across two books recently, in which the authors decided to
write an utility library. The first book was <a class="reference external" href="http://www.amazon.com/Python-Practice-Concurrency-Libraries-Developers/dp/0321905636/">Python in Practice, by
Mark
Summerfield</a>
(my opinion about the book can be found
<a class="reference external" href="/python-readings">here</a>),
and the second, which I'm still reading, is <a class="reference external" href="http://www.amazon.com/Doing-Bayesian-Data-Analysis-Second/dp/0124058884">Doing Bayesian Data Analysis,
Second Edition, by …</a></p><p>I came across two books recently, in which the authors decided to
write an utility library. The first book was <a class="reference external" href="http://www.amazon.com/Python-Practice-Concurrency-Libraries-Developers/dp/0321905636/">Python in Practice, by
Mark
Summerfield</a>
(my opinion about the book can be found
<a class="reference external" href="/python-readings">here</a>),
and the second, which I'm still reading, is <a class="reference external" href="http://www.amazon.com/Doing-Bayesian-Data-Analysis-Second/dp/0124058884">Doing Bayesian Data Analysis,
Second Edition, by John Kruschke</a>.
A separate review will be added when I will finish reading it.
The books are different in their nature: One is about python
programming, while the other is about statistical methods, and uses the
R programming language for hands-on examples and exercises; the first
book is average quality overall (IMHO) and the second is absolutely
amazing! However, I believe that I may be able criticize the utility
libraries that came with the books in the same manner: Don't do this!
And why?</p>
<p><strong>Installation process breaks conventions</strong></p>
<p>When I need an external tool in a python project I know I have
<a class="reference external" href="https://pypi.python.org/pypi">pypi</a> to rely on for finding packages.
I have <a class="reference external" href="https://pip.pypa.io/en/stable/">pip</a> to easily install the
package and prefer to work with
<a class="reference external" href="https://virtualenv.pypa.io/en/latest/">virtualenv</a> whenever
possible. This set of tools help me in maintaining a sane codebase, and
reduce the effort of managing the dependencies by my own.
There is no chance that I will copy an external module into my project
and source control it unless I'll have to, so why to use this module in
an educational project in the first place?
I really don't know what is the convention in installing R external
packages, but I believe that Kruschke suggestion of sourcing his
supplied scripts is not the proper way to do this (enlighten me if I'm
wrong).</p>
<p><strong>Package maintenance / code quality</strong></p>
<p>Before I'm installing an external package I tend to search
about the package quality. First thing is checking how many stars the
package have on github and how many times it was downloaded from pypi.
And there is a reason behind it: I can rely on packages that are used
often to have better code quality; through gihub I can browse the
package issues / latest commits and make sure that it is still
maintained.
I'm sure that books authors invest a large amount of time in writing
their utility libraries. But code free of bugs doesn't exists, and I
prefer to know that the codebase is maintained before I use it (again,
without distinction between educational and "real" projects).</p>
<p><strong>Not specific enough</strong></p>
<p>If your utility library is a mix of different solutions for different
problems, it might not worth keeping in our toolbox. The above is
probably more relevant to Python in practice than to Doing Bayesian Data
Analysis, but I think it's still worth mentioning.</p>
<p><strong>Documentation</strong></p>
<p>When I choose a tool to work with I want it's documentation
to be top notch! Take
<a class="reference external" href="https://docs.djangoproject.com/en/1.8/">django</a> for example. The
project's documentation is not less than perfect, including a great
tutorial for beginners. I really don't want to look for the book when
I'm interesting in put in use some less obvious function from an utility
library.</p>
<img alt="Doing Bayesian Data Analysis, Second Edition, by John Kruschke" src="https://sites.google.com/site/doingbayesiandataanalysis/_/rsrc/1403617861639/config/customLogo.gif?revision=5" style="width: 100%;" />
<div class="section" id="what-i-m-expecting-from-authors-instead">
<h2>What I'm expecting from authors instead</h2>
<ul class="simple">
<li>If you think that your utility functions worth it pack it and publish
it as any other package.</li>
<li>I really don't mind reading one or two additional pages of code in
your book, if there's something interesting in it. Again, if the code
deserved to be mentioned in your book, it may be also deserved to be
talked about explicitly.</li>
<li>If this functionality exists elsewhere you should reference it, and
advise the user to use it. I've never wrote code in R, but was ready
to learn how to work with its ecosystem. I expected Kruschke to teach
me that, instead of showing me how to source his supplied scripts.</li>
</ul>
</div>
<div class="section" id="late-disclaimer">
<h2>Late disclaimer</h2>
<p>Don't get me wrong, supplying code as part of your book is great! But
there are different ways to do it: David Beazley's Python Cookbook is
full of code snippets, fully commented and explained; In Test-Driven
Development with Python, Harry Percival guides the reader in developing
an webapp with reference code available at github.
Don't get me wrong 2: The above doesn't mean that the books are bad.</p>
</div>
<div class="section" id="edit">
<h2>Edit:</h2>
<p>Don't miss Kruschke's comment below! He lights the above topics from
different angle and supplies great arguments for his decisions.
Maybe, as a programmer, I tend to rely on the language ecosystem mechamisms instead of being satisfied with the easier, and more beginners friendly solution Kruschke proposes.
I definitely agree with him that an easier-to-use software for data science, and bayesian data analysis in particular, is always welcomed.
I would like to seize the opportunity to thank Kruschke again for his great book! I really enjoy reading it and I'm sure that I will continue to use the insights gained from it in the future.</p>
</div>
Python readings2014-11-17T00:00:00+00:002014-11-17T00:00:00+00:00Tom Guriontag:blog.leverstone.me,2014-11-17:/python-readings.html<p>I usually learn anything new by reading books. In fact, I got almost
all of my python knowledge (which is not a lot, I'm just an apprentice
programmer) by reading python books.
A year ago I've started to learn web development from <a class="reference external" href="http://www.10x.org.il/">Udi
Oron</a> in
<a class="reference external" href="https://hackita.hasadna.org.il/">Hackita</a> (my impressions
<a class="reference external" href="/hackita">here</a>), and …</p><p>I usually learn anything new by reading books. In fact, I got almost
all of my python knowledge (which is not a lot, I'm just an apprentice
programmer) by reading python books.
A year ago I've started to learn web development from <a class="reference external" href="http://www.10x.org.il/">Udi
Oron</a> in
<a class="reference external" href="https://hackita.hasadna.org.il/">Hackita</a> (my impressions
<a class="reference external" href="/hackita">here</a>), and
shortly after started to work with him as a python teaching assistant in
his courses. Few months ago I've got a permanent position in one of
those companies we've taught in and the stigma of someone that can
answer everybody's python questions still sticks to me in the company.
Between those questions are how to get started with python and where to
find information regarding specific topics.
Hence, here is my thoughts about the books that helped, and still
helping me learning python.</p>
<div class="section" id="disclaimers">
<h2>Disclaimers</h2>
<ul class="simple">
<li>I'm new to python and the world of programming.</li>
<li>Books won't do the work for everybody.</li>
<li>When I first started to learn python I never thought I will end up
making my leaving out of it, so I've learned python 3 (which is
preferable language IMHO). However, most of the industry still uses
python 2. All of the books below are for python 3. It doesn't mean that
they won't help you learn python 2 also, but you will have to find the
differences by yourself.</li>
</ul>
</div>
<div class="section" id="beginners-books">
<h2>Beginners books</h2>
<div class="section" id="the-quick-python-book-second-edition-naomi-r-ceder">
<h3><a class="reference external" href="http://www.amazon.com/Quick-Python-Book-Second-Edition/dp/193518220X">The Quick Python Book, Second Edition (Naomi R. Ceder)</a></h3>
<p><img alt="image0" src="http://ecx.images-amazon.com/images/I/51afqHmFrML._SX258_BO1,204,203,200_.jpg" style="width: 180px;" /></p>
<p>After trying different books for python (Think Python, Dive
into Python 3 and Head First Python) I've found this one to be the
preferable as a learning book for someone that already saw some code,
but is definitely not an experienced programmer.
Part 1 is a short introduction that may also be used as a quick
reference. Part 2 is very organized tutorial for the language. It
contains most of the essentials and will give you the feeling that you
can continue learning by your own (or with more specialized books /
tutorials). Part 3 is much less cohesive then part 2. It seems that the
chapter about regular expressions could get into part 2 but the rest of
the section is too much esoteric and there are some mistakes through all
of it (for example, it refers you to the appendix for more information
that is not there).
I didn't read part 4 completely. I've only read the information about
working with databases in chapter 24 and it is very well written.
Summary: For part 2 I will give 5 start without hesitations. But part
3, although less significant, doesn't deserve it. After all the book is
very recommended.</p>
</div>
</div>
<div class="section" id="more-advance-intermediate-books">
<h2>More advance / intermediate books</h2>
<div class="section" id="python-in-practice-mark-summerfield">
<h3><a class="reference external" href="http://www.amazon.com/Python-Practice-Concurrency-Libraries-Developers/dp/0321905636/ref=sr_1_1?s=books&ie=UTF8&qid=1416060956&sr=1-1&keywords=python+in+practice">Python in Practice (Mark Summerfield)</a></h3>
<p><img alt="image1" src="http://www.qtrac.eu/pipbookm.png" style="width: 180px;" /></p>
<p>I bought this book primary for its chapters about design
patterns as well as the concurrency and the networking chapters (1 to 3,
4 and 6 accordingly). The book doesn't meant to be read from start to
finish, but as a reference and guide to each topic separately. I think
that from the above chapters I've already read most of the content, as
well as the chapter about GUI with tkinter. I have nothing to say though
about the two remaining chapters (extending python and 3d graphics).
The best chapter of this book is the one about high-level concurrency.
In this chapter Summerfield explain with details the difference between
CPU-bound and I/O-bound concurrency and have a strong suggestions
regarding the tools to use for concurrency with python 3. Namely, the
suggestion is to use the threading, multiprocessing and
concurrent.futures modules and never use locks or other lower level
synchronization primitives explicitly, use queues and futures instead.
The examples are good, although I found the code unnecessarily complex
sometimes.
On the other hand, I found the chapters about design patterns to be
much less fruitful. The author attitude is too object oriented for me
where things could be done much easier using a decorator or two instead.
The code examples too, are complex and non pythonic.
I'm sure that there are much better and approaches to high-level
networking then those described in this book. The author implement
<a class="reference external" href="http://en.wikipedia.org/wiki/Remote_procedure_call">remote procedure
call</a> server and
client. Simple examples can be done in a simpler manner then the
suggested code and advance use cases may prefer higher level 3rd party
libraries and frameworks that removes much of the boilerplate (e.g.
<a class="reference external" href="https://www.djangoproject.com/">Django</a> +
<a class="reference external" href="http://www.django-rest-framework.org/">DRF</a> for REST server +
<a class="reference external" href="http://docs.python-requests.org/en/latest/">requests</a> based client).
Summary:The high-level concurrency chapter is really great and deserve
5 stars, but the rest of the book is ranging between 2 and 3.</p>
</div>
<div class="section" id="the-python-cookbook-3rd-edition-david-beasley">
<h3><a class="reference external" href="http://www.amazon.com/Python-Cookbook-David-Beazley/dp/1449340377/ref=sr_1_1?s=books&ie=UTF8&qid=1416061017&sr=1-1&keywords=the+python+cookbook">The Python Cookbook, 3rd edition (David Beasley)</a></h3>
<p><img alt="image2" src="http://ecx.images-amazon.com/images/I/51zDEWm5kcL._SX258_BO1,204,203,200_.jpg" style="width: 180px;" /></p>
<p>After disappointing from "Python in Practice" I've came across this
book as one with similar scope, namely, a design patterns book,
organized into chapters by topic that you can read in any order. In
addition, this one is also great reference book by the fact that most of
the suggested patterns are described in a short, self-contained manner.
This is a really great book! Beasley's attitude is so pythonic. AKA:
readable, simple,
<a class="reference external" href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself">DRY</a>, less OO
and more functional whenever possible, smart usage of the standard
library / 3rd party high level libraries.
Most of the chapters of the book are really fluent and easy to read.
I've found the meta-programming and the object oriented chapters a bit
more complex, but still great after the 2nd or the 3rd read as the ideas
demonstrated there are a bit too advanced for my background.
Summary: Assuming you already know python (don't read it if you don't)
I think that this book is a must have. 5 stars are barely enough.</p>
</div>
</div>
<div class="section" id="scientific-computing-with-python">
<h2>Scientific computing with python</h2>
<p>As already noted, I've never thought that I will find myslef
programming python in a full time job. Essentially, I've decided to
learn python as a data analysis tool for my <a class="reference external" href="https://leverstone.me/an-audio-only-augmented-reality-system-for-social-interaction.html">MA
research</a>. These
are the main sources I've used to get the necessary knowledge.</p>
<div class="section" id="python-for-data-analysis-wes-mckinney">
<h3><a class="reference external" href="http://www.amazon.com/Python-Data-Analysis-Wrangling-IPython/dp/1449319793">Python for Data Analysis (Wes McKinney)</a></h3>
<p><img alt="image3" src="https://d.gr-assets.com/books/1356132971l/14744694.jpg" style="width: 180px;" /></p>
<p>It's not a bad book but if you are looking for a good book for
scientific computing with python you will probably be disappointed.
The book covers mostly the pandas library. It doesn't give much
information about numpy and matplotlib, and say completely nothing about
scipy, which are all more essential for scientific computing than pandas
as far as I understand that topic.
On the other hand, pandas is your tool to go if you need to work with
spreadsheet oriented data (the <a class="reference external" href="http://pandas.pydata.org/index.html#library-highlights">library highlights
page</a> summarize
its strengths pretty good).
This book was one of the first python books I've read, together with
the quick python book above. It explains pandas in a very introductory
way (pretty slow), which make recommending this book even harder: If you
are a beginner, this book is written in the right level, but on the
wrong content; If you are a more advanced programmer looking to learn a
bit of pandas you may find the tutorials
<a class="reference external" href="http://pandas.pydata.org/pandas-docs/dev/tutorials.html">here</a>
comprehensive enough.
Summary: Pandas is a great tool, use it! But I don't think that this
book is a good your way to learn data analysis with python, whether you
are a beginner or not.</p>
</div>
<div class="section" id="python-scientific-lecture-notes">
<h3><a class="reference external" href="https://scipy-lectures.github.io/">Python Scientific Lecture Notes</a></h3>
<p>I have to admit, I've read only the first section of the "lecture
notes", but if you are looking for an introduction to scientific
computing with python this "book" is definitely worth reading. It covers
the basics of numpy, matplotlib and scipy very concisely, with lots of
short but working code examples.</p>
</div>
</div>
<div class="section" id="web-development-with-python">
<h2>Web development with python</h2>
<div class="section" id="two-scoops-of-django-best-practices-for-django-1-6-daniel-greenfeld-aka-pydanny-and-his-wife-audrey-roy">
<h3><a class="reference external" href="http://www.amazon.com/Two-Scoops-Django-Best-Practices/dp/098146730X">Two Scoops of Django: Best Practices for Django 1.6 (Daniel Greenfeld - AKA pydanny, and his wife Audrey Roy)</a></h3>
<p><img alt="image4" src="http://www.arruda.blog.br/wp-content/uploads/2014/03/IMG_1894.jpg" style="width: 180px;" /></p>
<p>Can't say I've finish reading this book. It more like a
reference you open anytime you need for some extra help on each topic,
with emphasis on best practices.
Be aware that this book is not for beginners! But if you want to
progress with python + django you're going to appreciate the suggestions
found there. For django starters, go through the really good
<a class="reference external" href="https://docs.djangoproject.com/en/dev/intro/tutorial01/">tutorial</a>
and write another django app before reading any of the suggestions in
this book. It won't help you if you don't.
There are two editions for this book, for django versions 1.5 and 1.6.
According to the authors <a class="reference external" href="http://twoscoopspress.com/pages/two-scoops-of-django-1-6-faq#what-if-1.7">there will be no more version of this
book</a>,
so don't attempt to wait to one. Take the latest as it has much more
content.
Behind the general recommendation and the versions stuff I will add
that I don't like the "theme" of the book. The code examples themselves
are great but there are lots of illustrations that doesn't really
helping in explaining the concepts nor in remembering them.
Summary: If you take django development seriously just get yourself a
copy, you won't regret it!</p>
</div>
<div class="section" id="tdd-with-python-harry-j-w-percival">
<h3><a class="reference external" href="http://www.amazon.com/Test-Driven-Development-Python-Harry-Percival/dp/1449364829">TDD with python (Harry J. W. Percival)</a></h3>
<p><img alt="image5" src="http://orm-other.s3.amazonaws.com/tddwithpython/final_cover.jpg" style="width: 180px;" /></p>
<p>I've started to read this book only recently, so I'm still in the
middle of it (somewhere around chapter 17). So my very warm
recommendations are for those I've read.
Percival does a great job in explaining and demonstrating the TDD
discipline, introducing web development with django on the way. Although
I am already familiar with django I found the introductory attitude of
the author more then appropriate, and it let me concentrate more on the
TDD side rather on understanding the framework. On the other hand, there
are lots of developers that prefer a more strait forward attitude, with
less text and more working code snippets, so bear in mind that this is
not the case with this one. Here, lots of code examples are written
iteratively throughout the test cycles and upon several pages. I like
it!
Behind introducing TDD, its the first time I manage to deploy an app
to a real server (I've deployed some apps to
<a class="reference external" href="https://www.heroku.com/">heroku</a> before, but it is different). I
will surely recommend those chapters as stand alone tutorial for
deployment (chapters 8 & 9 + appendix C).
The only downside I can think of is if you are not interested in web
development at all. It will be too much work to translate the concepts
in this book into completely different subject.
Summary: Great introduction to the discipline of TDD for web
development. Very recommended. And you can even read it online for free
<a class="reference external" href="http://chimera.labs.oreilly.com/books/1234000000754/">here</a>.</p>
</div>
</div>
<div class="section" id="ending-words">
<h2>Ending words</h2>
<p>I would really like to hear your thoughts about the recommendations,
whether you agree with me and even more if not :-).
You are also welcome to contact me on any question about these books /
other python resources and I will do my best to answer.</p>
</div>
Participants movement tracking animations from my MA experiment #22014-10-27T19:22:00+00:002014-10-27T19:22:00+00:00Tom Guriontag:blog.leverstone.me,2014-10-27:/participants-movement-tracking-animations-from-my-ma-experiment-2.html<p>The following animated renditions are a byproduct of the video
tracking an analysis of my MA thesis second experiment.</p>
<img alt="Experiment design" src="/images/experiment_design.png" style="width: 100%;" />
<p>The figure above shows a schematic diagram of the experiment design.
The videos are of session 1 to 3 of each of the groups (the last session
wasn't analyzed). They have …</p><p>The following animated renditions are a byproduct of the video
tracking an analysis of my MA thesis second experiment.</p>
<img alt="Experiment design" src="/images/experiment_design.png" style="width: 100%;" />
<p>The figure above shows a schematic diagram of the experiment design.
The videos are of session 1 to 3 of each of the groups (the last session
wasn't analyzed). They have been for great help in gaining insights
about the social interactions between the participants themselves and
between the participants and the system components.</p>
<div class="youtube youtube-16x9"><iframe src="https://www.youtube.com/embed/eMvRYz-3hrk" allowfullscreen seamless frameBorder="0"></iframe></div><div class="youtube youtube-16x9"><iframe src="https://www.youtube.com/embed/ViCy3Q0gQlQ" allowfullscreen seamless frameBorder="0"></iframe></div><div class="youtube youtube-16x9"><iframe src="https://www.youtube.com/embed/y2_1mssBn30" allowfullscreen seamless frameBorder="0"></iframe></div><div class="youtube youtube-16x9"><iframe src="https://www.youtube.com/embed/Ck_CcrJ0CsE" allowfullscreen seamless frameBorder="0"></iframe></div><div class="youtube youtube-16x9"><iframe src="https://www.youtube.com/embed/0u8Mcv3FMmE" allowfullscreen seamless frameBorder="0"></iframe></div><div class="youtube youtube-16x9"><iframe src="https://www.youtube.com/embed/TkRZFkfdY8c" allowfullscreen seamless frameBorder="0"></iframe></div><p>The analysis repository can be found <a class="reference external" href="https://github.com/Nagasaki45/MA-experiment-analysis">at
github</a>.
Additional information about the research can be found
<a class="reference external" href="http://leverstone.me/an-audio-only-augmented-reality-system-for-social-interaction.html">here</a>.</p>
Create teams easily with Xteams!2014-09-19T00:00:00+01:002014-09-19T00:00:00+01:00Tom Guriontag:blog.leverstone.me,2014-09-19:/create-teams-easily-with-xteams.html<img alt="Playing volleyball" src="/images/xteams.jpg" style="width: 100%;" />
<p>I've been playing volleyball recently with a group of
amateur players. In the last two months the size of our group has
increased so much that it became very hard to create teams. And if you
think that size is the only issue I can assure you that there are …</p><img alt="Playing volleyball" src="/images/xteams.jpg" style="width: 100%;" />
<p>I've been playing volleyball recently with a group of
amateur players. In the last two months the size of our group has
increased so much that it became very hard to create teams. And if you
think that size is the only issue I can assure you that there are many
more:
- How can one create teams when Dana doesn't want to play with Haim,
who must play with Jacob but not with Yossi... You've got the idea.
- No one will ever want to help in creating teams as he may end up
insulting a not-so-good player by choosing him last.
- Maybe you have too many players around for one game, but just enough
for a tournament of 4 teams.
In order to solve these inconveniences I've created
<a class="reference external" href="https://xteams.leverstone.me/">Xteams!</a> a web-app with one goal in
mind:</p>
<p><strong>Create teams automatically based on discrete scores of the players</strong></p>
<p>Using Xteams, group managers can give scores to players in the
management panel. Players of the group can't access this panel but can
see the list of players, mark which of them arrived to the game and
create teams easily.
At the time of writing, the algorithm behind the teams' allocation was
pretty simple. It takes all of the available players, and the number of
teams to create, and tries to find teams with equal or close to equal
strength (sum of the players scores) by generating several random
allocations and choosing the best of them.</p>
<div class="section" id="for-devs">
<h2>For devs</h2>
<p>The app is still under development (aren't they all?), and many more
modifications, improvements and features are considered. Any help in the
development process is more than welcome (<a class="reference external" href="https://github.com/Nagasaki45/Xteams">github
repo</a>).</p>
</div>
<div class="section" id="thanks">
<h2>Thanks</h2>
<p>To the players of Nahlaot Veshut volleyball team, who consistently help
with new ideas for features and additional improvements.</p>
</div>
My research proposal2014-04-09T00:00:00+01:002014-04-09T00:00:00+01:00Tom Guriontag:blog.leverstone.me,2014-04-09:/my-research-proposal.html<img alt="Baloon bundles on the dance floor" src="https://leverstone.me/images/portfolio/ma_thesis.jpg" style="width: 100%;" />
<p>I've recently submitted my <a class="reference external" href="https://db.tt/4h5u179a">MA research proposal</a>, titled:
"Audio-Only Augmented Reality System for Social Interaction".
Usually, research proposals aims to present the subject and describe
the intents of the current research. This one is a bit more
comprehensive, presenting a fully operated system I've developed,
preliminary results of the system …</p><img alt="Baloon bundles on the dance floor" src="https://leverstone.me/images/portfolio/ma_thesis.jpg" style="width: 100%;" />
<p>I've recently submitted my <a class="reference external" href="https://db.tt/4h5u179a">MA research proposal</a>, titled:
"Audio-Only Augmented Reality System for Social Interaction".
Usually, research proposals aims to present the subject and describe
the intents of the current research. This one is a bit more
comprehensive, presenting a fully operated system I've developed,
preliminary results of the system evaluation, and the exact design for a
future experiment.
Feedback is always welcome. LaTeX source can be found @
<a class="reference external" href="https://github.com/Nagasaki45/MA">github</a>.</p>
Some experiments with SimpleCV - object detection by color2014-04-06T00:00:00+01:002014-04-06T00:00:00+01:00Tom Guriontag:blog.leverstone.me,2014-04-06:/some-experiments-with-simplecv-object-detection-by-color.html<p>Computer vision is way far from my daily interest. But last weekend I
participated in a semi-hackathon, developing code that aims to detect
and track cards by their color.</p>
<div class="youtube youtube-16x9"><iframe src="https://www.youtube.com/embed/wDAFhOv0tKU" allowfullscreen seamless frameBorder="0"></iframe></div><p>Credits deserve to this
<a class="reference external" href="https://www.youtube.com/watch?v=jihxqg3kr-g">guy</a>. I've used his
code as a reference and a starting point.</p>
<p>It is my first experience …</p><p>Computer vision is way far from my daily interest. But last weekend I
participated in a semi-hackathon, developing code that aims to detect
and track cards by their color.</p>
<div class="youtube youtube-16x9"><iframe src="https://www.youtube.com/embed/wDAFhOv0tKU" allowfullscreen seamless frameBorder="0"></iframe></div><p>Credits deserve to this
<a class="reference external" href="https://www.youtube.com/watch?v=jihxqg3kr-g">guy</a>. I've used his
code as a reference and a starting point.</p>
<p>It is my first experience with SimpleCV. After all the code works pretty
well, I think, despite the awful documentation of SimpleCV and some hard
time working with the library.</p>
<p>As always, the code is written in python and is available
at <a class="reference external" href="https://github.com/Nagasaki45/cards-tracker">github</a>. Any
thoughts about the mini-project, the code and computer vision
alternative libraries are always welcome.</p>
Web Audio API - some thoughts and experiments2014-02-14T00:00:00+00:002014-02-14T00:00:00+00:00Tom Guriontag:blog.leverstone.me,2014-02-14:/web-audio-api-some-thoughts-and-experiments.html<p>For me, being able to use advance audio programming on the web looks
like a dream just a couple of weeks ago, and I'm not the only one for
sure.
Doing audio programming, I've mainly experienced with Max/MSP and Pd
but my interest in shared music creation / consumption and …</p><p>For me, being able to use advance audio programming on the web looks
like a dream just a couple of weeks ago, and I'm not the only one for
sure.
Doing audio programming, I've mainly experienced with Max/MSP and Pd
but my interest in shared music creation / consumption and interactive
systems have long seems to demand the extension of this skill set; as
Udi Oron rightly argued in
"<a class="reference external" href="/hackita">Hackita</a>"
two months ago: you have no chance to convince someone to download your
desktop app (Max or Pd patches for example), give them a web app
instead!
I'm not sure if I've heard of the <a class="reference external" href="http://www.w3.org/TR/webaudio/">Web Audio
API</a> before last week, but even if I
did I probably wouldn't had a clue of how to use it back then (before
learning web development and JavaScript at Hackita). Today I can say
that it looks like a great solution for audio programming, and a good
way to look for if you interesting in designing systems for public wide
usage because of the next reasons:</p>
<ul class="simple">
<li>As claimed before, no one downloads and install desktop application
anymore unless it came from known source and the one that download it
knows for sure that he wants to use it (as opposed to just trying
things out).</li>
<li>It's probably the easiest way to go if you want shared behavior and
interaction between users of the system.</li>
<li>Web standards are here to stay. You can be sure that organizations
like Google, Mozilla, and Microsoft will compete to provide the best
implementation possible.</li>
<li>The API itself looks very promising. I hope that I will be able to
summarize pros and cons soon.</li>
</ul>
<div class="separator" style="clear: both; text-align: center;"><a class="reference external image-reference" href="https://web-audio.leverstone.me/"><img alt="Web-audio experiment screenshot" src="/images/web_audio_screenshot.png" /></a>
</div><p>That's being said, <a class="reference external" href="https://web-audio.leverstone.me/">here</a> are my
experiment with the API. If you are interesting in more information and
tutorials be sure to take a look at the "Useful links" menu (top
navigation bar). And as always, source code can be found at
<a class="reference external" href="https://github.com/Nagasaki45/Web-Audio">github</a>.</p>
"Hackita"2013-12-07T00:00:00+00:002013-12-07T00:00:00+00:00Tom Guriontag:blog.leverstone.me,2013-12-07:/hackita.html<p>In the last few weeks I was participating in the first session of
"<a class="reference external" href="https://hackita.hasadna.org.il/">Hackita</a>", which means "The
classroom" in Hebrew. This project aims to bring people from different
backgrounds to learn and develop open source web applications together.
Furthermore, the project is part of <a class="reference external" href="http://www.hasadna.org.il/en/">The Public Knowledge
Workshop</a>, and as …</p><p>In the last few weeks I was participating in the first session of
"<a class="reference external" href="https://hackita.hasadna.org.il/">Hackita</a>", which means "The
classroom" in Hebrew. This project aims to bring people from different
backgrounds to learn and develop open source web applications together.
Furthermore, the project is part of <a class="reference external" href="http://www.hasadna.org.il/en/">The Public Knowledge
Workshop</a>, and as such one of its main
goals is to guide its participants to complete a project that expose
public knowledge to the public by the end of the 2 month session,
somewhere around late January.
Until now we've learned few technologies that will help us accomplish
this goal and from the next week we will start to work on the final
project.
Meanwhile, here are two of my "homework" exercises:</p>
<ul class="simple">
<li><a class="reference external" href="http://simplecrypt.appspot.com/">SimpleCrypt</a> - Online
cryptographic tool, based on
<a class="reference external" href="http://en.wikipedia.org/wiki/Data_Encryption_Standard">DES</a>.
Source @ <a class="reference external" href="https://github.com/Nagasaki45/SimpleCrypt">github</a>.</li>
<li><a class="reference external" href="http://friends-mapper.herokuapp.com/">Friends-Mapper</a> - Creates a
dynamic map of your friends. Source @
<a class="reference external" href="https://github.com/Nagasaki45/Friends-Mapper">github</a>.</li>
</ul>
<p>Information regarding my final project will come soon...</p>
Compare food prices in Jerusalem - a new mini-web-project2013-11-16T00:00:00+00:002013-11-16T00:00:00+00:00Tom Guriontag:blog.leverstone.me,2013-11-16:/compare-food-prices-in-jerusalem-a-new-mini-web-project.html<div class="separator" style="clear: both; text-align: center;"><a class="reference external image-reference" href="http://nagasaki45.pythonanywhere.com/"><img alt="Project screenshot" src="/images/jerusalem_marketprices.png" /></a>
</div><p>Two things happened recently, I've moved to the holly city and started
to learn Python. Here are the consequences: a mini web app to compare
food prices, written in Django and deployed to pythonanywhere, for my
own purpose and for my students friends.</p>
<div style="text-align: center;"><p><a class="reference external" href="http://nagasaki45.pythonanywhere.com/">Jerusalem MarketPrices</a></p>
</div><p>More features will be added …</p><div class="separator" style="clear: both; text-align: center;"><a class="reference external image-reference" href="http://nagasaki45.pythonanywhere.com/"><img alt="Project screenshot" src="/images/jerusalem_marketprices.png" /></a>
</div><p>Two things happened recently, I've moved to the holly city and started
to learn Python. Here are the consequences: a mini web app to compare
food prices, written in Django and deployed to pythonanywhere, for my
own purpose and for my students friends.</p>
<div style="text-align: center;"><p><a class="reference external" href="http://nagasaki45.pythonanywhere.com/">Jerusalem MarketPrices</a></p>
</div><p>More features will be added soon and on demand :-). If you want to be
able to update markets, products and prices, drop a comment and I will
create an account for you.
And as always, source code can be found at
<a class="reference external" href="https://github.com/Nagasaki45/MarketPrices">github</a>.</p>
MusiGali video demonstration2013-10-19T19:35:00+01:002013-10-19T19:35:00+01:00Tom Guriontag:blog.leverstone.me,2013-10-19:/musigali-video-demonstration.html<div class="youtube youtube-16x9"><iframe src="https://www.youtube.com/embed/aXbvVGCQ5wY" allowfullscreen seamless frameBorder="0"></iframe></div><p>A screen capture of MusiGali <a class="reference external" href="https://www.ableton.com/">Ableton Live</a>
set. All the details are
<a class="reference external" href="/musigali-eeg-controlled-music-for-brain-tech-israel-2013">here</a>.</p>
MusiGali - EEG controlled music for Brain Tech Israel 20132013-10-14T00:00:00+01:002013-10-14T00:00:00+01:00Tom Guriontag:blog.leverstone.me,2013-10-14:/musigali-eeg-controlled-music-for-brain-tech-israel-2013.html<p>A project by Giori Politi, Sharon Duek, Jonathan Abramson and myself
which developed / composed especially for the Brain Tech Israel 2013
conference this week.
In this project we created a musical soundtrack based on mind waves
transmitted from an EEG headset. The generated musical line is
parameterized according to levels …</p><p>A project by Giori Politi, Sharon Duek, Jonathan Abramson and myself
which developed / composed especially for the Brain Tech Israel 2013
conference this week.
In this project we created a musical soundtrack based on mind waves
transmitted from an EEG headset. The generated musical line is
parameterized according to levels of attention and meditation of the
headset wearer, leading the listener to unexpected musical realms which
somewhat correspond to his or her neuro-electric activity. One may try
to attain control over the musical line and advance within it through
deliberate control over levels of relaxation and concentration.
The EEG headset that was used for the project is <a class="reference external" href="http://www.neurosky.com/Products/MindWaveMobile.aspx">NueroSky MindWave
mobile</a>. Music
was composed in <a class="reference external" href="https://www.ableton.com/en/live/">Ableton
Live</a> using Max for Live to read
the data from the headset.
Many thanks to Zvika Markfeld and Saron Paz from <a class="reference external" href="http://forrealteam.com/">ForReal
Team</a>, the exhibition curators.</p>
<img alt="MusiGali project presentation at Brain Tech Israel 2013" src="/images/musigali_presentation1.jpg" style="width: 100%;" />
<img alt="MusiGali project presentation at Brain Tech Israel 2013" src="/images/musigali_presentation2.jpg" style="width: 100%;" />
Find nearby Bluetooth devices with BT-logger2013-08-21T00:00:00+01:002013-08-21T00:00:00+01:00Tom Guriontag:blog.leverstone.me,2013-08-21:/find-nearby-bluetooth-devices-with-bt-logger.html<p>With this new Android app you can get information about nearby
Bluetooth devices. The application collect the name, address, RSSI value
and time of discovery of nearby Bluetooth devices and write them to file
in \BluetoothData directory on the main device storage.
The application primary use is to evaluate my …</p><p>With this new Android app you can get information about nearby
Bluetooth devices. The application collect the name, address, RSSI value
and time of discovery of nearby Bluetooth devices and write them to file
in \BluetoothData directory on the main device storage.
The application primary use is to evaluate my Bluetooth based relative
indoor positioning system that you should already be familiar with.
Otherwise you can find all the necessary information regarding my master
thesis <a class="reference external" href="https://leverstone.me/an-audio-only-augmented-reality-system-for-social-interaction.html">here</a>.
As always, everything is
<a class="reference external" href="https://github.com/Nagasaki45/BT-logger">opensource</a>.</p>
Poster presentation for HCI International 20132013-07-17T00:00:00+01:002013-07-17T00:00:00+01:00Tom Guriontag:blog.leverstone.me,2013-07-17:/poster-presentation-for-hci-international-2013.html<p>Next week I'm going to present my master thesis in <a class="reference external" href="http://hcii2013.org/">HCI International
2013</a> conference in Las Vegas.
The poster is already in printing: 42" x 60" with glossy finish. But
for the most of you <a class="reference external" href="http://db.tt/Rx7FnAxn">here is the original pdf</a>.
Comments are more than welcome.</p>
<img alt="Poster for HCI International 2013" src="/images/hci_poster.jpg" style="width: 100%;" />
Some pictures from ISTAS'132013-07-01T00:00:00+01:002013-07-01T00:00:00+01:00Tom Guriontag:blog.leverstone.me,2013-07-01:/some-pictures-from-istas13.html<p>Here are some pictures from the conference, which was great by the way.</p>
<img alt="Presenting the project" src="/images/istas1.jpg" style="width: 100%;" />
<p>Thanks for Alexander Hayes for the picture</p>
<img alt="My desc in the exhibition hall" src="/images/istas2.jpg" style="width: 100%;" />
<p>Me presenting the system in the exhibition hall</p>
<img alt="Amber case thumbsup!" src="/images/istas3.jpg" style="width: 100%;" />
<p>Looks like <a class="reference external" href="http://caseorganic.com/">Amber Case</a> likes interactive music :-)</p>
Slideshow of my thesis presentation2013-06-28T00:00:00+01:002013-06-28T00:00:00+01:00Tom Guriontag:blog.leverstone.me,2013-06-28:/slideshow-of-my-thesis-presentation.html<div style="text-align: center;">
<iframe src="//www.slideshare.net/slideshow/embed_code/key/4fp4TiFyoBEsrf" width="100%" height="440" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px;" allowfullscreen></iframe>
</div><p>In this slideshow you can taste a little bit of how the system and the
experiment looks like. This slideshow originally made for my
presentation at <a class="reference external" href="http://istas13.org/">ISTAS'13</a> (and it contains much
better animations then what you can see here on the slideshare version
:-) ), but I would be happy to present …</p><div style="text-align: center;">
<iframe src="//www.slideshare.net/slideshow/embed_code/key/4fp4TiFyoBEsrf" width="100%" height="440" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px;" allowfullscreen></iframe>
</div><p>In this slideshow you can taste a little bit of how the system and the
experiment looks like. This slideshow originally made for my
presentation at <a class="reference external" href="http://istas13.org/">ISTAS'13</a> (and it contains much
better animations then what you can see here on the slideshare version
:-) ), but I would be happy to present it again, just contact
me.</p>
ARpArty, the first ScenePlayer Plus Bluetooth aware scene, is here for you2013-06-27T00:00:00+01:002013-06-27T00:00:00+01:00Tom Guriontag:blog.leverstone.me,2013-06-27:/arparty-the-first-sceneplayer-plus-bluetooth-aware-scene-is-here-for-you.html<p>You are welcome to download and install ARpArty scene for
<a class="reference external" href="https://play.google.com/store/apps/details?id=com.nagasaki45.sceneplayerplus">ScenePlayer Plus</a>
from <a class="reference external" href="http://db.tt/Y6cn2APx">here</a>. ARpArty was developed as an
implementation of audio-based augmented reality system for interactive
music consumption in a silent disco context and is the main scene that I
use in my research.
In order to install the …</p><p>You are welcome to download and install ARpArty scene for
<a class="reference external" href="https://play.google.com/store/apps/details?id=com.nagasaki45.sceneplayerplus">ScenePlayer Plus</a>
from <a class="reference external" href="http://db.tt/Y6cn2APx">here</a>. ARpArty was developed as an
implementation of audio-based augmented reality system for interactive
music consumption in a silent disco context and is the main scene that I
use in my research.
In order to install the scene, just copy the extracted directory from
the zip file to the SD card of your device, then launch the the app and
add the new scene.
If you are an artist that want to develop Bluetooth aware scenes for
ScenePlayer Plus taking a look at this scene could be a good starting
point.</p>
ScenePlayer Plus2013-06-24T00:00:00+01:002013-06-24T00:00:00+01:00Tom Guriontag:blog.leverstone.me,2013-06-24:/sceneplayer-plus.html<div class="separator" style="clear: both; text-align: center;"><img alt="ScenePlayer Plus logo" src="/images/sceneplayerplus_logo.png" />
</div><p>ScenePlayer Plus is an enhanced version of
<a class="reference external" href="https://github.com/libpd/pd-for-android/tree/master/ScenePlayer">ScenePlayer</a>
by Peter Brinkmann.
It uses additional capabilities of the Android device that are not
used by RjDj or ScenePlayer apps (Bluetooth is an example) but it is
still fully compatible with standard RjDj scenes.
ScenePlayer Plus can be downloaded from <a class="reference external" href="https://play.google.com/store/apps/details?id=com.nagasaki45.sceneplayerplus">Google
Play …</a></p><div class="separator" style="clear: both; text-align: center;"><img alt="ScenePlayer Plus logo" src="/images/sceneplayerplus_logo.png" />
</div><p>ScenePlayer Plus is an enhanced version of
<a class="reference external" href="https://github.com/libpd/pd-for-android/tree/master/ScenePlayer">ScenePlayer</a>
by Peter Brinkmann.
It uses additional capabilities of the Android device that are not
used by RjDj or ScenePlayer apps (Bluetooth is an example) but it is
still fully compatible with standard RjDj scenes.
ScenePlayer Plus can be downloaded from <a class="reference external" href="https://play.google.com/store/apps/details?id=com.nagasaki45.sceneplayerplus">Google
Play</a>.
Source code can be found at
<a class="reference external" href="https://github.com/Nagasaki45/ScenePlayer-Plus">Github</a> and
instruction for creating scenes for ScenePlayer Plus can be found at the
<a class="reference external" href="https://github.com/Nagasaki45/ScenePlayer-Plus/wiki">project wiki</a>.
ScenePlayer Plus has been developed as part of my master thesis as an
implementation of the <a class="reference external" href="http://leverstone.me/an-audio-only-augmented-reality-system-for-social-interaction.html">proposed
system</a>.
With the abilities of <a class="reference external" href="http://libpd.cc/">libpd</a> and the ease of use
of ScenePlayer I've found that the only component that is necessary for
me to develop is the Bluetooth discovery routine for the relative indoor
positioning.
Developers that interested in improving the Bluetooth awareness
capabilities of the app or in adding more features (GPS / compass /
social media APIs etc.) are welcome to contact me.</p>
Abstract: Audio-only augmented reality system for social interaction2013-06-23T00:00:00+01:002013-06-23T00:00:00+01:00Tom Guriontag:blog.leverstone.me,2013-06-23:/abstract-audio-only-augmented-reality-system-for-social-interaction.html<div class="section" id="tom-gurion">
<h2>Tom Gurion</h2>
<p><em>Bar-Ilan University, Ramat-Gan</em></p>
</div>
<div class="section" id="nori-jacoby">
<h2>Nori Jacoby</h2>
<p><em>Hebrew University, Jeruslam; Bar-Ilan University, Ramat-Gan</em></p>
<p>We explore new possibilities for interactive music consumption by proposing an audio-only augmented reality system for social interaction.
We designed and built an Android application that measures the relative position of the device from specially designed Bluetooth …</p></div><div class="section" id="tom-gurion">
<h2>Tom Gurion</h2>
<p><em>Bar-Ilan University, Ramat-Gan</em></p>
</div>
<div class="section" id="nori-jacoby">
<h2>Nori Jacoby</h2>
<p><em>Hebrew University, Jeruslam; Bar-Ilan University, Ramat-Gan</em></p>
<p>We explore new possibilities for interactive music consumption by proposing an audio-only augmented reality system for social interaction.
We designed and built an Android application that measures the relative position of the device from specially designed Bluetooth beacons.
Participants can freely move the beacons that are installed on physical objects, thereby dynamically changing the structure of the music in the virtual space.
In a controlled experiment, we assessed the interactive component of the system in the context of a silent rave party by comparing the system positioning readings in interactive and non-interactive control segments.
We also directly assessed the user experience using self-reported pre/post surveys.
Our preliminary results show that in the post-party survey, participants self-reported significantly higher levels of movement using the system, compared with their behavior on other parties as reported in the pre-party survey.
We used the relative positioning system in the application to objectively validate that the interactive components of the system facilitate greater participant movement in space, thereby offering more frequent opportunities for social interaction.
Indeed, in the post-party survey participants reported that they danced significantly less with people that they knew ahead of time, compared with their pre-party survey reporting of usual behavior.
Our results displaying the potential of using audio-only augmented reality in future mobile applications.</p>
<p><strong>Keywords:</strong> Augmented reality, Music technology, Social interaction, Relative indoor positioning system</p>
</div>
Publication in the proceedings of HCI International 20132013-06-23T00:00:00+01:002013-06-23T00:00:00+01:00Tom Guriontag:blog.leverstone.me,2013-06-23:/publication-in-the-proceedings-of-hci-international-2013.html<div class="separator" style="clear: both; text-align: center;"><img alt="HCI International 2013 logo" src="http://www.ainci.com/hci-international-2013/HCI%20Lab%20%202013%20-%20HCI%20International%20-%20Las%20Vegas%20-%20USA.jpg" />
</div><p><a class="reference external" href="http://db.tt/zpgwMFKJ">Gurion, Tom, and Nori Jacoby. "Audio-Only Augmented Reality System
for Social Interaction." HCI International 2013-Posters’ Extended
Abstracts. Springer Berlin Heidelberg, 2013.
322-326.</a>
Here's the <a class="reference external" href="http://link.springer.com/content/pdf/10.1007%2F978-3-642-39473-7_65.pdf">paper page at
SpringerLink</a></p>
Thesis project Pure Data patch video demonstration2013-06-23T00:00:00+01:002013-06-23T00:00:00+01:00Tom Guriontag:blog.leverstone.me,2013-06-23:/thesis-project-pure-data-patch-video-demonstration.html<div class="youtube youtube-16x9"><iframe src="https://www.youtube.com/embed/2kJoeD2iWBA" allowfullscreen seamless frameBorder="0"></iframe></div><p>This demo shows how movement of participants in space affects the music
they hear through their own Android device and headphones using the
system in a silent disco party. In addition it demonstrate the influence
of different participants on one another when one virtual participant
takes diverse sound zones with …</p><div class="youtube youtube-16x9"><iframe src="https://www.youtube.com/embed/2kJoeD2iWBA" allowfullscreen seamless frameBorder="0"></iframe></div><p>This demo shows how movement of participants in space affects the music
they hear through their own Android device and headphones using the
system in a silent disco party. In addition it demonstrate the influence
of different participants on one another when one virtual participant
takes diverse sound zones with him during this simulation. The music is
the same as in the original system.</p>