<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>lovholm.net</title>
	<atom:link href="http://www.lovholm.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.lovholm.net</link>
	<description></description>
	<lastBuildDate>Thu, 02 May 2013 22:33:05 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>How to set up an AWS EC2 instance</title>
		<link>http://www.lovholm.net/2013/04/28/setting-up-an-ec2-instance/</link>
		<comments>http://www.lovholm.net/2013/04/28/setting-up-an-ec2-instance/#comments</comments>
		<pubDate>Sun, 28 Apr 2013 17:55:39 +0000</pubDate>
		<dc:creator>Ola Løvholm</dc:creator>
				<category><![CDATA[data]]></category>
		<category><![CDATA[Amazon Web Services]]></category>
		<category><![CDATA[Cloud Computing]]></category>
		<category><![CDATA[EC2]]></category>

		<guid isPermaLink="false">http://www.lovholm.net/?p=1976</guid>
		<description><![CDATA[Amazon Web Service&#8217;s EC2 is the workhorse and general purpose computer in the AWS ecosystem. It is affordable (free or very cheap if you keep it scaled to the minimum...]]></description>
				<content:encoded><![CDATA[<p>Amazon Web Service&#8217;s EC2 is the workhorse and general purpose computer in the AWS ecosystem. It is affordable (free or very cheap if you keep it scaled to the minimum option), it is easy to set up, and it provides you with a computer located in the cloud. This is a good option if you have content you would like to be accessible everywhere, and especially if you develop solutions you want to be accessible through the Internet.</p>
<p>Here are two examples where a cloud computer may come in handy:</p>
<p><strong>1)</strong> If you have ever tried to host services on a local machine through a bread-and-butter Internet Service Provider, you will be delighted to be allocated a persistent IP-address. You can also decide on the ports you want to be accessible or shut bypassing ISP-policy, e.g. blocking outbound port 80 (default HTTP-port).</p>
<p><strong>2) I</strong>f you have ever used a shared host for hosting websites, you may have been met with software that doesn&#8217;t work. This can be because your scripts, plug-ins or other software are using languages not supported by the host. For example many general purpose hosts are not providing support for Python and Ruby. Another problem is libraries and other dependencies. If you want to have access  to more advanced photo-editing through e.g. <a href="http://www.imagemagick.org/script/index.php">Imagemagick</a> then your fate is in the hand of the provider and what stack/software/libraries/dependencies they wish to provide. You are also stuck with using FTP-client as many shared hosting providers do not grant you SSH access to their servers.</p>
<h4>Signing up for AWS access</h4>
<p>Setup is fairly easy. First you need to go to the <a href="http://aws.amazon.com/">AWS website</a> and sign in or sign up with an Amazon account. As part of the registration Amazon will validate your phone number by calling you with an automatic voice service to give you a verification code, so keep your phone with you as you start the registration process. Follow through the web form for registration a Amazon account, then a</p>
<h4>Creating the EC2 Instance</h4>
<div id="attachment_1987" class="wp-caption alignright" style="width: 310px"><a href="http://www.lovholm.net/wp-content/uploads/2013/02/AWS-services.png"><img class="size-medium wp-image-1987" alt="AWS-services" src="http://www.lovholm.net/wp-content/uploads/2013/02/AWS-services-300x187.png" width="300" height="187" /></a><p class="wp-caption-text">AWS has many services, but for this blog post we stick to the EC2. Click on the image to enlarge it.</p></div>
<p>Once registered and validated you should have access to the Management Console. If not you find this by first entering the AWS frontpage, then on the top of the window selecting &#8220;My account/Console&#8221; then &#8220;AWS Management Console&#8221;. This should bring up a new view with all the services that AWS provide (don&#8217;t be dazzled, there is very much information, but luckily one can survive just using a couple of them). Select the EC2 option in the orange section named &#8220;Compute &amp; Networking&#8221;. This should bring up another view. Before continuing, go to the top right corner of the screen (to the right for your name) and select the region that is closest to you. (<a href="http://aws.amazon.com/about-aws/globalinfrastructure/#reglink-na">More on regions</a>)</p>
<div id="attachment_2021" class="wp-caption alignleft" style="width: 310px"><a href="http://www.lovholm.net/wp-content/uploads/2013/03/EC2-view.png"><img class="size-medium wp-image-2021" alt="EC2-view" src="http://www.lovholm.net/wp-content/uploads/2013/03/EC2-view-300x142.png" width="300" height="142" /></a><p class="wp-caption-text">The EC2 view. From here you can create and administer your EC2 instances, and services related to these.</p></div>
<p>In the EC2-view you can easily set up and administer your instances. One thing to be aware of it that once the instance is created some settings persists with it, and these can only be changed by creating a new instance. This can cause you many hours of extra work if you do many changes to your instance, and it could also make it impossible to access the device (if you loose your encryption keys and passwords.)</p>
<p>There are three things we need to pay attention to at this point: what kind of instance do we want, how should we create the authentication, and how do we deal with persistant storage.</p>
<h4>Choosing an AMI</h4>
<p>AMI is the abbreviation for Amazon Machine Image. These are the images with the virtual appliances which are used for instanceiate the EC2 (which is basically a virtual machine). You can choose between free public AMIs, commercial images where you have to pay or you can even create an image yourself (the last is out of scope for this post). For this tutorial we are going to use a commonly used image &#8211; The Amazon Linux AMI.</p>
<p>From the EC2-view click the new instance button, then choose a classical view for selecting an AMI. As you can see there are several options within Linux and Windows. The ones marked with a star got a free tier if used with the micro instance, so no need to worry about the costs yet.</p>
<h4>Creating the keys</h4>
<p>To connect to the EC2 you will need SSH-keys which can identify you. There are two ways of creating these keys, either create the key locally and share the public key with the EC2 instance, or you can let Amazon create the keys and send you the public key for the instance. I recommend creating these locally as you then have both the private and the public keys. There seems to be a limit on downloading the keys from Amazon, and this may cause problems if you loose the key. It is also an advantage to have both keys in case you use two or more computers to communicate with your EC2 instance.</p>
<p>To create an SSH-key open your terminal and enter: <em>ssh-keygen -t rsa -C &#8220;your@email.example&#8221; </em>A tutorial is also provided by GitHub.</p>
<p>Upload this SSH-key when you assign keys in the EC2 setup.</p>
<h4>Getting an IP-address</h4>
<p>When your instance is up and running you get an access point address where you can find and connect to your instance. I would however recommend that you get an IP-address to this point. Not only is it easier and shorter, it also gives you a way of abstract your virtual machine from the address. Amazon provides you with an Elastic IP, and with this you can change which EC2-instance the IP address should point to. This makes it easy to e.g. start up a new and more powerful instance and then quickly change the IP address to this instance instead of letting the user endure the longer time a virtual reboot would take. At some point you would like to map a DNS address to the Elastic IP so e.g. sub.domain.com or domain.com points to your instance, at this point it is nice to just have to configure the elastic IP and not have to change the DNS record when you want to change instances.</p>
<h4>Test your instance</h4>
<p>The instance should now be up and running. Now try to connect to your instance using SSH. The login username may change from AMI to AMI, if your AMI is ubuntu the username is usually <em>ubuntu</em>, if you use the standard Amazon Linux AMI the username is <em>ec2-user. </em></p>
<pre>ssh -v ec2-user@123.123.123.12'</pre>
<h4>Changing the security settings</h4>
<p><img class="size-medium wp-image-2036 alignright" alt="ec2-security" src="http://www.lovholm.net/wp-content/uploads/2013/03/ec2-security-300x92.png" width="300" height="92" /></p>
<p>If you are not able to login it may be that you need to open the firewall to your instance. As you created your instance, you assigned the instance a security settings group.</p>
<p>If you have any problems connecting to a service using a specific port, you should check here to ensure that the traffic is not being blocked at the firewall. For SSH you will need to open port 22.</p>
<h4></h4>
<h4>Creating an alias for easier access</h4>
<p>This is not a part of the setup process, but it&#8217;s a neat little trick for making access easier. Instad of remembering the whole address in the terminal when you use SSH to connect to your instance, make an alias in the .bashrc or .bash_profile.</p>
<p>If you connect writing ssh -i $HOME/keys/aws.pub 1233.4556.7789.1 then put the string below into your .bash_profile and source this.</p>
<pre>alias my_ec2_connect='ssh -v -i $HOME/keys/aws.pub 1233.4556.7789.1'</pre>
<p><em>(Disclaimer to point two: lovholm.net is in fact hosted on a shared host by one.com &#8211; WordPress is very convenient to host at providers such as one, since it&#8217;s built on ubiquitous web-stack PHP+MySQL, and shared hosts are generally affordable and even easier to set-up than dedicated. One does also have a good admin dashboard from which you also can do some simple rerouting &#8211; more on this in a later post)</em></p>
<p><em>The image is from <a href="http://www.flickr.com/photos/ivanwalsh/3649492427/">Flickr</a> and is provided under a CC-licence. The image is associated to cloud computing and IBM, not Amazon. </em></p>
<div name="googleone_share_1" style="position:relative;z-index:5;float: right; margin-left: 10px;"><g:plusone size="medium" count="1" href="http://www.lovholm.net/2013/04/28/setting-up-an-ec2-instance/">{lang: 'en-GB'}</g:plusone></div>]]></content:encoded>
			<wfw:commentRss>http://www.lovholm.net/2013/04/28/setting-up-an-ec2-instance/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Five year anniversary</title>
		<link>http://www.lovholm.net/2013/04/04/five-year-anniversary/</link>
		<comments>http://www.lovholm.net/2013/04/04/five-year-anniversary/#comments</comments>
		<pubDate>Thu, 04 Apr 2013 10:00:24 +0000</pubDate>
		<dc:creator>Ola Løvholm</dc:creator>
				<category><![CDATA[Blogging]]></category>
		<category><![CDATA[about]]></category>
		<category><![CDATA[anniversary]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[lovholm.net]]></category>

		<guid isPermaLink="false">http://www.lovholm.net/?p=2038</guid>
		<description><![CDATA[Five years ago I published the first blog post on this page, and 130 posts later I&#8217;m happy I managed my goal of writing a post now and then. Much...]]></description>
				<content:encoded><![CDATA[<p>Five years ago I published the first blog post on this page, and 130 posts later I&#8217;m happy I managed my goal of writing a post now and then. Much have happened the last five years, and I hope more will happen in the five years to come. Hopefully you will find a similar post on the ten years anniversary 4th April 2017.</p>
<p>Thank you for reading!</p>
<p>Ok, I&#8217;m very enthusiastic about readers, so after a day with many readers in Google Analytics I may be like this, especially with many revisiting users. I hope to see you again:</p>
<p><a href="http://www.lovholm.net/wp-content/uploads/2013/04/entusiastic_gif_celebration.gif"><img class="aligncenter size-full wp-image-2043" alt="entusiastic_gif_celebration" src="http://www.lovholm.net/wp-content/uploads/2013/04/entusiastic_gif_celebration.gif" width="250" height="156" /></a></p>
<div name="googleone_share_1" style="position:relative;z-index:5;float: right; margin-left: 10px;"><g:plusone size="medium" count="1" href="http://www.lovholm.net/2013/04/04/five-year-anniversary/">{lang: 'en-GB'}</g:plusone></div>]]></content:encoded>
			<wfw:commentRss>http://www.lovholm.net/2013/04/04/five-year-anniversary/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Norske illustrasjonskart på fylkes- og kommunenivå med SVG</title>
		<link>http://www.lovholm.net/2013/03/06/norske-illustrasjonskart-pa-fylkes-og-kommuneniva-med-svg/</link>
		<comments>http://www.lovholm.net/2013/03/06/norske-illustrasjonskart-pa-fylkes-og-kommuneniva-med-svg/#comments</comments>
		<pubDate>Wed, 06 Mar 2013 20:24:59 +0000</pubDate>
		<dc:creator>Ola Løvholm</dc:creator>
				<category><![CDATA[data-work]]></category>
		<category><![CDATA[fylke]]></category>
		<category><![CDATA[kart]]></category>
		<category><![CDATA[kommune]]></category>
		<category><![CDATA[pixel]]></category>
		<category><![CDATA[raster]]></category>
		<category><![CDATA[SVG]]></category>
		<category><![CDATA[vector]]></category>

		<guid isPermaLink="false">http://www.lovholm.net/?p=1998</guid>
		<description><![CDATA[Vektor- og rastergrafikk SVG &#8211; Scalable Vector Graphics &#8211; er, som gitt av navnet, et skalerbart vektorbasert grafikk-markup. Vektorgrafikk er bedre egnet til skalering enn raster, da bildet ikke består...]]></description>
				<content:encoded><![CDATA[<h4>Vektor- og rastergrafikk</h4>
<p>SVG &#8211; Scalable Vector Graphics &#8211; er, som gitt av navnet, et skalerbart vektorbasert grafikk-markup. Vektorgrafikk er bedre egnet til skalering enn raster, da bildet ikke består av små bildeelementer (Pixel &#8211; kort for nettopp picture element), men formler for opptegning av grafikken. Nå har det seg riktignok slik at ikke alt fungerer like godt i begge grafikkverdener. Siden vektorer er basert på forskjellige punkter på et lerret og forbindelsen mellom disse, enten igjennom punkter, rette linjer, eller former for interpolerte kurver er vektorer bedre egnet til å representere abstrakte bilder og modeller, mens raster med sine pixelpunkter er godt egnet for å representere sensordata fra for eksempel bildebrikker. Det at fonter i dag representeres som vektorer gjør at disse kan skaleres uten tap i kvalitet (forsøk selv ved å forstørre denne teksten til det 10-dobbelte).</p>
<div id="attachment_2003" class="wp-caption alignleft" style="width: 310px"><a href="http://www.lovholm.net/wp-content/uploads/2013/03/vector_bitmat.gif"><img class=" wp-image-2003 " alt="vector_bitmat" src="http://www.lovholm.net/wp-content/uploads/2013/03/vector_bitmat-300x168.gif" width="300" height="168" /></a><p class="wp-caption-text">Forskjell på vektor og bitmap (raster) font.</p></div>
<p>For å overføre rasterdata til vektordata og motsatt må bildet &#8220;parses&#8221; eller konverteres, dette er ikke alltid like enkelt da bilder med mange detaljer og mye informasjon kan være vanskelig å tolke for programvaren. Har du et bilde av en rett svart strek på hvit bakgrunn er denne enkel å prosessere, men har du derimot et hus er det værre.</p>
<div id="attachment_2004" class="wp-caption alignright" style="width: 310px"><a href="http://www.lovholm.net/wp-content/uploads/2013/03/raster_vector.jpg"><img class=" wp-image-2004 " alt="Et rasterbilde av et hus forsøkt vektorisert, uten hell." src="http://www.lovholm.net/wp-content/uploads/2013/03/raster_vector-300x191.jpg" width="300" height="191" /></a><p class="wp-caption-text">Et rasterbilde av et hus forsøkt vektorisert, uten hell.</p></div>
<p><span style="font-size: 16px; font-weight: bold; line-height: 1.4em;">SVG-formatet</span></p>
<p>En SVG formatert fil kan åpnes i flere forskjellige programmer, med ganske forskjellig visning. Dersom du åpner en SVG-fil i en leser som støtter formatet og prosesserer dette til grafikk vil du få følgende visning av kartet med norske fylker</p>
<p>Dersom du åpner samme fil i en teksteditor (jeg bruker textmate på mac, men du kan benytte <a href="http://www.barebones.com/products/textwrangler/">TextWrangler</a> som er gratis på Mac, og <a href="http://notepad-plus-plus.org/">NotePad++</a> for Windows. Benytter du Linux har du helt sikkert også en favoritteditor) vil du se en struktur som i utganspunktet ser ganske uoversiktelig ut, men som ganske enkelt kan forståes. SVG-standarden har en rekke forskjellige funksjoner, men jeg kommer kun til å nevne noen i denne artikkelen.</p>
<p>I filene du kan benytte for å tegne kommuner og fylker på kartet er det i hovedsak paths eller stier som benyttes. Stien for å tegne Oslo kommune ser slik ut:</p>
<pre class="brush: xml; title: ; notranslate">
  &lt;path
     id=&quot;oslo&quot;
     class=&quot;land oslo county03 ostlandet&quot;
     d=&quot;M 136.54875,466.88777 C 133.12579,463.23916 133.1611,459.6972 136.62044,459.6972 C 138.64571,459.6972 141.17041,464.85896 140.28004,467.17924 C 139.54285,469.10032 138.55185,469.02291 136.54875,466.88777 z&quot;
     style=&quot;fill:#c0c0c0;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-opacity:1&quot;
  /&gt;

</pre>
<p>Verdt å merke seg her er hvordan d-taggen i elementet inneholder en ganske lang liste. Denne listen består av instruksjoner som benyttes når nettleseren, eller andre programmer tolker SVG-filen om til en visuell representasjon. <strong>M </strong>er move to. Her begynner tegneprosessen. <strong>C </strong>er kurve. Hit sendes tre punkter som videre benyttes for å interpolere en kurve. Dette fortsetter fram til formen sluttes med kommandoen <strong>Z</strong>. For å markere et fylke benytter vi fill-argumentet i style-taggen. Som du kan se består denne av en grå fargeverdi nå (elementert kjære Watson, både R &#8211; to første etter hashtag, G &#8211; to i midten &#8211; og B &#8211; to til høyre &#8211; har samme hexadecimale verdi. <a href="http://en.wikipedia.org/wiki/Rgb">RGB</a>)<b><br />
</b></p>
<h4>Norske fylker og kommuner</h4>
<p>Ok, nå har vi noe kunnskap om SVG, men hvordan er det vi får markert enten fylker eller kommuner  med fine farger? Jo, det neste vi trenger er SVG filer med Norgeskart.</p>
<p><a href="http://upload.wikimedia.org/wikipedia/commons/2/21/Norway_municipalities_2012_blank.svg">Wikipedia har en fin SVG-fil over norske kommuner</a>. Høyreklikk på bildet og last ned fila.</p>
<p><a href="https://upload.wikimedia.org/wikipedia/commons/2/2f/Norway_counties_blank.svg">Wikipedia har også en fin SVG-fil over norske fylker.</a> Høyreklikk på bildet og last ned fila.</p>
<p>Finn noen fine farger. Dersom du ikke har noen favoritt RGB-hex fargekoder anbefaler jeg Adobes gode <a href="https://kuler.adobe.com/#themes/rating?time=30">Kuler verktøy</a>.</p>
<h4>Editer SVG-fila</h4>
<p>Filene du nå har lastet ned inneholder path elementer for enten fylker eller kommuner. Ta fila for det politiske nivået du ønsker, åpne denne filen i din favoritteditor, søk deretter på navnet på kommunen eller fylket og skriv inn en annen farge for kommunen eller fylket du ønsker å endre. For eksempel kan du ta utgangspunkt i tekstutsnittet av Oslo kommune fra ovenfor (Oslo er både fylke og kommune, og vil derfor være i begge filene. Merk: Dette er Oslo fra kommunefilen) og legg inn en annen fargekode for fyll.</p>
<pre class="brush: xml; title: ; notranslate">
  &lt;path
     id=&quot;oslo&quot;
     class=&quot;land oslo county03 ostlandet&quot;
     d=&quot;M 136.54875,466.88777 C 133.12579,463.23916 133.1611,459.6972 136.62044,459.6972 C 138.64571,459.6972 141.17041,464.85896 140.28004,467.17924 C 139.54285,469.10032 138.55185,469.02291 136.54875,466.88777 z&quot;
     style=&quot;fill:#FF0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-opacity:1&quot;
  /&gt;

</pre>
<p>Du vil nå ha et rødt Oslo.</p>
<div id="attachment_2005" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.lovholm.net/wp-content/uploads/2013/03/csv_counties.png"><img class=" wp-image-2005 " alt="Et svart Hedmark, grønt Akershus og rødt Finnmark." src="http://www.lovholm.net/wp-content/uploads/2013/03/csv_counties-300x290.png" width="300" height="290" /></a><p class="wp-caption-text">Et svart Hedmark, grønt Akershus og rødt Finnmark.</p></div>
<div id="attachment_2007" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.lovholm.net/wp-content/uploads/2013/03/csv_map01.png"><img class=" wp-image-2007 " alt="Et grønt Rendalen (Norges største kommune utenfor Finnmark) og Hamar." src="http://www.lovholm.net/wp-content/uploads/2013/03/csv_map01-300x158.png" width="300" height="158" /></a><p class="wp-caption-text">Et grønt Rendalen (Norges største kommune utenfor Finnmark) og Hamar.</p></div>
<p><strong>Bilder:</strong></p>
<p>Bilde for å illustrere forskjellen på vektor og raster font, samt bilde av dårlig vektorisert hus er lånt fra.</p>
<p>http://www.1stwebdesigner.com/design/pixel-vector-graphics-difference/</p>
<p>http://giorgioscappaticcio.wordpress.com/category/task-1-image-sourcing/</p>
<div name="googleone_share_1" style="position:relative;z-index:5;float: right; margin-left: 10px;"><g:plusone size="medium" count="1" href="http://www.lovholm.net/2013/03/06/norske-illustrasjonskart-pa-fylkes-og-kommuneniva-med-svg/">{lang: 'en-GB'}</g:plusone></div>]]></content:encoded>
			<wfw:commentRss>http://www.lovholm.net/2013/03/06/norske-illustrasjonskart-pa-fylkes-og-kommuneniva-med-svg/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Enter the Cloud &#8211; Amazon Web Services</title>
		<link>http://www.lovholm.net/2013/02/22/what-is-aws/</link>
		<comments>http://www.lovholm.net/2013/02/22/what-is-aws/#comments</comments>
		<pubDate>Fri, 22 Feb 2013 14:00:01 +0000</pubDate>
		<dc:creator>Ola Løvholm</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[Amazon]]></category>
		<category><![CDATA[Amazon Web Services]]></category>
		<category><![CDATA[Cloud Computing]]></category>
		<category><![CDATA[cloud services]]></category>
		<category><![CDATA[EC2]]></category>
		<category><![CDATA[RDS]]></category>
		<category><![CDATA[S3]]></category>

		<guid isPermaLink="false">http://www.lovholm.net/?p=1936</guid>
		<description><![CDATA[AWS &#8211; Amazon Web Services &#8211; is a great infrastructure cloud service for all IT business from start-ups to full blown corporations. Providing both Infrastructure-as-a-Service (IaaS) through the general purpose...]]></description>
				<content:encoded><![CDATA[<p>AWS &#8211; Amazon Web Services &#8211; is a great infrastructure cloud service for all IT business from start-ups to full blown corporations. Providing both Infrastructure-as-a-Service (IaaS) through the general purpose EC2 and Platform-as-a-service (PaaS) through Beanstalk as well as hybrid solutions such as storage solution S3 and database service RDS.</p>
<p>I have been using these services for about half a year now, and I am convinced these services as well as competing equals (e.g. Microsoft Azure) is a good tool that for everyone who want to experiment with web technology or create web businesses. This is not a new thing, cloud computing have been around for years, and many web services are running on Amazon services today, but through looking into them myself I understood how I can benefit from them in my work with the web and through the Internet, and new experiments</p>
<h3>S3</h3>
<p>Amazon Simple Storage Service provide affordable web space. In this specific market similar services have emerged, which also are easier accessible e.g. Dropbox &#8211; one of the best things since bread came sliced. The good thing about S3 is the tight integration with the other Amazon services, it is also good for hosting static web pages (pages that only needs to be served, without initial computation). Some FTP clients also include S3 support so you can use the S3 service as you would regularly use FTP for storage of files. Another advantage is that you can choose the S3 bucket (the entity in which you place your files on S3) to be distributed to all of Amazons data centres (for an additional cost). This is good if you need to transfer files to end user fast as there are less potential for bottlenecks using a local datacenter (by local here I mean the same continent.)</p>
<h3>EC2</h3>
<p>Amazon Elastic Compute Cloud is the real game changer. While most of the other services are specialised the EC2 is the general purpose machine. An EC2 instance is a virtual computer located in the cloud where you pay for the computing hours you use, a standardised unit being approximately: &#8220;CPU capacity of a 1.0-1.2 GHz 2007 Opteron or 2007 Xeon processor.&#8221; Since the payment is by the hour, and the units are scalable it can be very flexible to your needs. The service enables you to make your hosting scalable both for scaling up, and scaling out.</p>
<p><strong>Scaling up: </strong>The instances comes in several packages. From the modest and almost free micro instance to extra-large distributed platforms. You can change the processor performance and dedicated RAM on your instance, and changing the instance type just require a reboot and you can transfer your persistance storage onto the new virtual machine.</p>
<p><strong>Scaling out:</strong> If you create an image with all your server variables, binaries, libraries and other stuff you need, or a method for loading this from a remote computer, you can in just a couple of minutes initialise new instances with these data, and since you pay by the hour you can e.g. have four computers running at times with high load and one during times with low load. The coolest feature is that you can measure trafic and load new servers as the service is running at lower performance than wanted.</p>
<h4><span style="font-size: 14px; line-height: 1.625;">Elastic-IP: </span></h4>
<p>The URL to the instances are normally quite arcane and difficult to remember. That is why this is quite good. Elastic-IP is just bridge between a IPv4 address that you get allocated, and the instance. Above I described how you could reboot an instance, but the downside to this is that while the instance is restarting your server would be down. To avoid this, you could create a clone of your instance #1 with the higher capacity settings, and when this is loaded, direct the IP to the new instance #2 and then turn off the instance #1. (Well, I guess you would loose the users&#8217; sessions)</p>
<p><a href="http://www.lovholm.net/2013/04/28/setting-up-an-ec2-instance/">Do you want to set up an EC2 instance? (More about how)</a></p>
<h4>RDS</h4>
<p>RDS, or the Relational Database Service. You need this if you want to handle persistent data in a relational manner (and if you&#8217;re not hacking user-data into self-composed formatted files, or using a noSQL solution) and think life is to short to set-up and configure a SQL-database on the general purpose EC2 service.</p>
<div id="attachment_1985" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.lovholm.net/wp-content/uploads/2013/02/RDS-alternatives.png"><img class="size-medium wp-image-1985" alt="When you create a new DB instance you can easily choose type. If you use Oracle you can bring your own licence or rent licence by a hour-licence." src="http://www.lovholm.net/wp-content/uploads/2013/02/RDS-alternatives-300x194.png" width="300" height="194" /></a><p class="wp-caption-text">When you create a new DB instance you can easily choose type. If you use Oracle you can bring your own licence or rent licence by a hour-licence.</p></div>
<p>For the RDS you can choose between (ex-Swedish, now Oracle) MySQL, Microsoft SQL Server or  Oracle (also Oracle *dough* ). The setup is very easy, and you can choose the size of the database, the backup retention period and other variables then start the instance. Check the security settings that the ports are open and that the DB can access traffic from your IP-address. Download <a href="http://www.mysql.com/products/workbench/">SQL Workbench</a> (MySQL) or <a href="http://www.oracle.com/technetwork/developer-tools/sql-developer/overview/index.html">SQL Developer</a> (Oracle) (Sorry, not sure about good tool for MS SQL Server), insert the endpoint URL, username and password and get started.</p>
<h3>Other services</h3>
<div id="attachment_1987" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.lovholm.net/wp-content/uploads/2013/02/AWS-services.png"><img class="size-medium wp-image-1987" alt="AWS-services" src="http://www.lovholm.net/wp-content/uploads/2013/02/AWS-services-300x187.png" width="300" height="187" /></a><p class="wp-caption-text">The AWS selection is huge, but luckily you won&#8217;t need to know every service available to get started. (Click images for full size)</p></div>
<p style="text-align: center;"><a href="http://www.lovholm.net/wp-content/uploads/2013/02/RDS-alternatives.png"><br />
</a> <a href="http://www.lovholm.net/wp-content/uploads/2013/02/DB-options.png"><br />
</a></p>
<p>This picture show the AWS panel from which you administer your services, and as you can see there are several more services to explore. Many of these are specialised to e.g handle MapReduce or deploying specific web-stacks easily, but with the S3, RDS and EC2 it should be easy to get started.</p>
<div name="googleone_share_1" style="position:relative;z-index:5;float: right; margin-left: 10px;"><g:plusone size="medium" count="1" href="http://www.lovholm.net/2013/02/22/what-is-aws/">{lang: 'en-GB'}</g:plusone></div>]]></content:encoded>
			<wfw:commentRss>http://www.lovholm.net/2013/02/22/what-is-aws/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Work programmatically with Google Spreadsheets</title>
		<link>http://www.lovholm.net/2013/02/03/work-programmatically-with-google-spreadsheets/</link>
		<comments>http://www.lovholm.net/2013/02/03/work-programmatically-with-google-spreadsheets/#comments</comments>
		<pubDate>Sun, 03 Feb 2013 20:27:24 +0000</pubDate>
		<dc:creator>Ola Løvholm</dc:creator>
				<category><![CDATA[data-work]]></category>
		<category><![CDATA[Google Docs]]></category>
		<category><![CDATA[gspread]]></category>
		<category><![CDATA[lastFM]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[spreadsheet]]></category>

		<guid isPermaLink="false">http://www.lovholm.net/?p=1940</guid>
		<description><![CDATA[Some time back I authored a script which reads through a CSV formatted list, and based on the artists&#8217; names tried to decide the nationality of the artists by querying...]]></description>
				<content:encoded><![CDATA[<p>Some time back I authored a script which reads through a CSV formatted list, and based on the artists&#8217; names tried to decide the nationality of the artists by querying the last.FM search engine and parsing the XML structured result.</p>
<p>The script worked, and found and returned about 80% of the artists, and around 80% of these again had the conceptually similar artist. What if the alteration could be done in the document itself? For the CSV based script the artists had to be extracted from the database, then parsed and then put into the document. With this attempt we can skip the middle step, and let the script run simultaneous with data being available to view for the users.</p>
<p>If you haven&#8217;t already used Google Docs, you should consider it, as it is a very convenient way of working with documents, especially where there are more users. Through Google Docs you can collaborate on working on documents, and since they are stored in clouds all users will instantly have the latest version. Another advantage is that whey you are working on the document simultaneously each user is editing the same document, so merging different versions is not a problem.</p>
<p>A great tool for combining Google Spreadsheets with the Python programming environment is the <a href="https://github.com/burnash/gspread">gspread</a> module. After installing this package you only need to import the code and then you can with very few lines of code retrieve and update information in the spreadsheet cells.</p>
<p>The specifics for doing this task is pretty much these few lines. Import the package. Login, find correct document and do whatever you need to. (this excerpt won&#8217;t work. Check the whole script under &#8211; NB: mind the indentation. It may not be correct displayed in the browser.)</p>
<pre class="brush: python; title: ; notranslate">
import gspread

G_USERNAME = 'your@gmail.com'
G_PASSWORD = 'yourPassword'
G_IDENTIFIER = 'document_identifier_checkdocument_url_in_your_browser'

# Connecting to the data source
gc = gspread.login(G_USERNAME,G_PASSWORD)
sht1 = gc.open_by_key(G_IDENTIFIER)
worksheet = sht1.get_worksheet(0)

for a in range(2,5124):
try:
name = worksheet.acell(get_val[a]).value
res = getCountry(name)
if res:
print res
country, last_id, name = res
worksheet.update_acell(set_name[a], name)
worksheet.update_acell(set_country[a], country)
except Exception as e:
print e

</pre>
<p>Above is the lines related to connecting Python to the google docs, under you can see the whole script and how the method I mentioned in a <a href="http://www.lovholm.net/find-your-way-around-the-data-automatically-try-to-parse-artist-country-based-on-name/">post earlier </a>is used in this setting.</p>
<pre class="brush: python; title: ; notranslate">
#!/usr/bin/python
# -*- coding:utf-8 -*-

&quot;&quot;&quot;
Clouds &amp;amp; Concerts - 2012
Ola Loevholm

Initialized from the commandline. Runs through The Google doc spreadsheet with topp 5000 artists, and
runs the parsing query against the Last.FM browser then enters the country and search string (for validation)
into the google docs.

&quot;&quot;&quot;

G_USERNAME = 'your@gmail.com'
G_PASSWORD = 'yourPassword'
G_IDENTIFIER = 'document_identifier_checkdocument_url_in_your_browser'

import sys, urllib, string, csv, time
import xml.etree.ElementTree as ET
import gspread

# Loads a dictionary with ISO 3166-1 abbreviations and codes
COUNTRIES = {&quot;AF&quot;:&quot;AFGHANISTAN&quot;,&quot;AX&quot;:&quot;ÅLAND ISLANDS&quot;,&quot;AL&quot;:&quot;ALBANIA&quot;,&quot;DZ&quot;:&quot;ALGERIA&quot;,&quot;AS&quot;:&quot;AMERICAN SAMOA&quot;,&quot;AD&quot;:&quot;ANDORRA&quot;,&quot;AO&quot;:&quot;ANGOLA&quot;,&quot;AI&quot;:&quot;ANGUILLA&quot;,&quot;AQ&quot;:&quot;ANTARCTICA&quot;,&quot;AG&quot;:&quot;ANTIGUA AND BARBUDA&quot;,&quot;AR&quot;:&quot;ARGENTINA&quot;,&quot;AM&quot;:&quot;ARMENIA&quot;,&quot;AW&quot;:&quot;ARUBA&quot;,&quot;AU&quot;:&quot;AUSTRALIA&quot;,&quot;AT&quot;:&quot;AUSTRIA&quot;,&quot;AZ&quot;:&quot;AZERBAIJAN&quot;,&quot;BS&quot;:&quot;BAHAMAS&quot;,&quot;BH&quot;:&quot;BAHRAIN&quot;,&quot;BD&quot;:&quot;BANGLADESH&quot;,&quot;BB&quot;:&quot;BARBADOS&quot;,&quot;BY&quot;:&quot;BELARUS&quot;,&quot;BE&quot;:&quot;BELGIUM&quot;,&quot;BZ&quot;:&quot;BELIZE&quot;,&quot;BJ&quot;:&quot;BENIN&quot;,&quot;BM&quot;:&quot;BERMUDA&quot;,&quot;BT&quot;:&quot;BHUTAN&quot;,&quot;BO&quot;:&quot;BOLIVIA, PLURINATIONAL STATE OF&quot;,&quot;BQ&quot;:&quot;BONAIRE, SINT EUSTATIUS AND SABA&quot;,&quot;BA&quot;:&quot;BOSNIA AND HERZEGOVINA&quot;,&quot;BW&quot;:&quot;BOTSWANA&quot;,&quot;BV&quot;:&quot;BOUVET ISLAND&quot;,&quot;BR&quot;:&quot;BRAZIL&quot;,&quot;IO&quot;:&quot;BRITISH INDIAN OCEAN TERRITORY&quot;,&quot;BN&quot;:&quot;BRUNEI DARUSSALAM&quot;,&quot;BG&quot;:&quot;BULGARIA&quot;,&quot;BF&quot;:&quot;BURKINA FASO&quot;,&quot;BI&quot;:&quot;BURUNDI&quot;,&quot;KH&quot;:&quot;CAMBODIA&quot;,&quot;CM&quot;:&quot;CAMEROON&quot;,&quot;CA&quot;:&quot;CANADA&quot;,&quot;CV&quot;:&quot;CAPE VERDE&quot;,&quot;KY&quot;:&quot;CAYMAN ISLANDS&quot;,&quot;CF&quot;:&quot;CENTRAL AFRICAN REPUBLIC&quot;,&quot;TD&quot;:&quot;CHAD&quot;,&quot;CL&quot;:&quot;CHILE&quot;,&quot;CN&quot;:&quot;CHINA&quot;,&quot;CX&quot;:&quot;CHRISTMAS ISLAND&quot;,
&quot;CC&quot;:&quot;COCOS (KEELING) ISLANDS&quot;,&quot;CO&quot;:&quot;COLOMBIA&quot;,&quot;KM&quot;:&quot;COMOROS&quot;,&quot;CG&quot;:&quot;CONGO&quot;,&quot;CD&quot;:&quot;CONGO, THE DEMOCRATIC REPUBLIC OF THE&quot;,&quot;CK&quot;:&quot;COOK ISLANDS&quot;,&quot;CR&quot;:&quot;COSTA RICA&quot;,&quot;CI&quot;:&quot;CÔTE D'IVOIRE&quot;,&quot;HR&quot;:&quot;CROATIA&quot;,&quot;CU&quot;:&quot;CUBA&quot;,&quot;CW&quot;:&quot;CURAÇAO&quot;,&quot;CY&quot;:&quot;CYPRUS&quot;,&quot;CZ&quot;:&quot;CZECH REPUBLIC&quot;,&quot;DK&quot;:&quot;DENMARK&quot;,&quot;DJ&quot;:&quot;DJIBOUTI&quot;,&quot;DM&quot;:&quot;DOMINICA&quot;,&quot;DO&quot;:&quot;DOMINICAN REPUBLIC&quot;,&quot;EC&quot;:&quot;ECUADOR&quot;,&quot;EG&quot;:&quot;EGYPT&quot;,&quot;SV&quot;:&quot;EL SALVADOR&quot;,&quot;GQ&quot;:&quot;EQUATORIAL GUINEA&quot;,&quot;ER&quot;:&quot;ERITREA&quot;,&quot;EE&quot;:&quot;ESTONIA&quot;,&quot;ET&quot;:&quot;ETHIOPIA&quot;,&quot;FK&quot;:&quot;FALKLAND ISLANDS (MALVINAS)&quot;,&quot;FO&quot;:&quot;FAROE ISLANDS&quot;,&quot;FJ&quot;:&quot;FIJI&quot;,&quot;FI&quot;:&quot;FINLAND&quot;,&quot;FR&quot;:&quot;FRANCE&quot;,&quot;GF&quot;:&quot;FRENCH GUIANA&quot;,&quot;PF&quot;:&quot;FRENCH POLYNESIA&quot;,&quot;TF&quot;:&quot;FRENCH SOUTHERN TERRITORIES&quot;,&quot;GA&quot;:&quot;GABON&quot;,&quot;GM&quot;:&quot;GAMBIA&quot;,&quot;GE&quot;:&quot;GEORGIA&quot;,&quot;DE&quot;:&quot;GERMANY&quot;,&quot;GH&quot;:&quot;GHANA&quot;,&quot;GI&quot;:&quot;GIBRALTAR&quot;,&quot;GR&quot;:&quot;GREECE&quot;,&quot;GL&quot;:&quot;GREENLAND&quot;,&quot;GD&quot;:&quot;GRENADA&quot;,&quot;GP&quot;:&quot;GUADELOUPE&quot;,&quot;GU&quot;:&quot;GUAM&quot;,&quot;GT&quot;:&quot;GUATEMALA&quot;,&quot;GG&quot;:&quot;GUERNSEY&quot;,&quot;GN&quot;:&quot;GUINEA&quot;,&quot;GW&quot;:&quot;GUINEA-BISSAU&quot;,&quot;GY&quot;:&quot;GUYANA&quot;,&quot;HT&quot;:&quot;HAITI&quot;,&quot;HM&quot;:&quot;HEARD ISLAND AND MCDONALD ISLANDS&quot;,
&quot;VA&quot;:&quot;HOLY SEE (VATICAN CITY STATE)&quot;,&quot;HN&quot;:&quot;HONDURAS&quot;,&quot;HK&quot;:&quot;HONG KONG&quot;,&quot;HU&quot;:&quot;HUNGARY&quot;,&quot;IS&quot;:&quot;ICELAND&quot;,&quot;IN&quot;:&quot;INDIA&quot;,&quot;ID&quot;:&quot;INDONESIA&quot;,&quot;IR&quot;:&quot;IRAN, ISLAMIC REPUBLIC OF&quot;,&quot;IQ&quot;:&quot;IRAQ&quot;,&quot;IE&quot;:&quot;IRELAND&quot;,&quot;IM&quot;:&quot;ISLE OF MAN&quot;,&quot;IL&quot;:&quot;ISRAEL&quot;,&quot;IT&quot;:&quot;ITALY&quot;,&quot;JM&quot;:&quot;JAMAICA&quot;,&quot;JP&quot;:&quot;JAPAN&quot;,&quot;JE&quot;:&quot;JERSEY&quot;,&quot;JO&quot;:&quot;JORDAN&quot;,&quot;KZ&quot;:&quot;KAZAKHSTAN&quot;,&quot;KE&quot;:&quot;KENYA&quot;,&quot;KI&quot;:&quot;KIRIBATI&quot;,&quot;KP&quot;:&quot;KOREA, DEMOCRATIC PEOPLE'S REPUBLIC OF&quot;,&quot;KR&quot;:&quot;KOREA, REPUBLIC OF&quot;,&quot;KW&quot;:&quot;KUWAIT&quot;,&quot;KG&quot;:&quot;KYRGYZSTAN&quot;,&quot;LA&quot;:&quot;LAO PEOPLE'S DEMOCRATIC REPUBLIC&quot;,&quot;LV&quot;:&quot;LATVIA&quot;,&quot;LB&quot;:&quot;LEBANON&quot;,&quot;LS&quot;:&quot;LESOTHO&quot;,&quot;LR&quot;:&quot;LIBERIA&quot;,&quot;LY&quot;:&quot;LIBYA&quot;,&quot;LI&quot;:&quot;LIECHTENSTEIN&quot;,&quot;LT&quot;:&quot;LITHUANIA&quot;,&quot;LU&quot;:&quot;LUXEMBOURG&quot;,&quot;MO&quot;:&quot;MACAO&quot;,&quot;MK&quot;:&quot;MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF&quot;,&quot;MG&quot;:&quot;MADAGASCAR&quot;,&quot;MW&quot;:&quot;MALAWI&quot;,&quot;MY&quot;:&quot;MALAYSIA&quot;,&quot;MV&quot;:&quot;MALDIVES&quot;,&quot;ML&quot;:&quot;MALI&quot;,&quot;MT&quot;:&quot;MALTA&quot;,&quot;MH&quot;:&quot;MARSHALL ISLANDS&quot;,&quot;MQ&quot;:&quot;MARTINIQUE&quot;,&quot;MR&quot;:&quot;MAURITANIA&quot;,&quot;MU&quot;:&quot;MAURITIUS&quot;,&quot;YT&quot;:&quot;MAYOTTE&quot;,&quot;MX&quot;:&quot;MEXICO&quot;,&quot;FM&quot;:&quot;MICRONESIA, FEDERATED STATES OF&quot;,
&quot;MD&quot;:&quot;MOLDOVA, REPUBLIC OF&quot;,&quot;MC&quot;:&quot;MONACO&quot;,&quot;MN&quot;:&quot;MONGOLIA&quot;,&quot;ME&quot;:&quot;MONTENEGRO&quot;,&quot;MS&quot;:&quot;MONTSERRAT&quot;,&quot;MA&quot;:&quot;MOROCCO&quot;,&quot;MZ&quot;:&quot;MOZAMBIQUE&quot;,&quot;MM&quot;:&quot;MYANMAR&quot;,&quot;NA&quot;:&quot;NAMIBIA&quot;,&quot;NR&quot;:&quot;NAURU&quot;,&quot;NP&quot;:&quot;NEPAL&quot;,&quot;NL&quot;:&quot;NETHERLANDS&quot;,&quot;NC&quot;:&quot;NEW CALEDONIA&quot;,&quot;NZ&quot;:&quot;NEW ZEALAND&quot;,&quot;NI&quot;:&quot;NICARAGUA&quot;,&quot;NE&quot;:&quot;NIGER&quot;,&quot;NG&quot;:&quot;NIGERIA&quot;,&quot;NU&quot;:&quot;NIUE&quot;,&quot;NF&quot;:&quot;NORFOLK ISLAND&quot;,&quot;MP&quot;:&quot;NORTHERN MARIANA ISLANDS&quot;,&quot;NO&quot;:&quot;NORWAY&quot;,&quot;OM&quot;:&quot;OMAN&quot;,&quot;PK&quot;:&quot;PAKISTAN&quot;,&quot;PW&quot;:&quot;PALAU&quot;,&quot;PS&quot;:&quot;PALESTINIAN TERRITORY, OCCUPIED&quot;,&quot;PA&quot;:&quot;PANAMA&quot;,&quot;PG&quot;:&quot;PAPUA NEW GUINEA&quot;,&quot;PY&quot;:&quot;PARAGUAY&quot;,&quot;PE&quot;:&quot;PERU&quot;,&quot;PH&quot;:&quot;PHILIPPINES&quot;,&quot;PN&quot;:&quot;PITCAIRN&quot;,&quot;PL&quot;:&quot;POLAND&quot;,&quot;PT&quot;:&quot;PORTUGAL&quot;,&quot;PR&quot;:&quot;PUERTO RICO&quot;,&quot;QA&quot;:&quot;QATAR&quot;,&quot;RE&quot;:&quot;RÉUNION&quot;,&quot;RO&quot;:&quot;ROMANIA&quot;,&quot;RU&quot;:&quot;RUSSIAN FEDERATION&quot;,&quot;RW&quot;:&quot;RWANDA&quot;,&quot;BL&quot;:&quot;SAINT BARTHÉLEMY&quot;,&quot;SH&quot;:&quot;SAINT HELENA, ASCENSION AND TRISTAN DA CUNHA&quot;,&quot;KN&quot;:&quot;SAINT KITTS AND NEVIS&quot;,&quot;LC&quot;:&quot;SAINT LUCIA&quot;,&quot;MF&quot;:&quot;SAINT MARTIN (FRENCH PART)&quot;,&quot;PM&quot;:&quot;SAINT PIERRE AND MIQUELON&quot;,&quot;VC&quot;:&quot;SAINT VINCENT AND THE GRENADINES&quot;,
&quot;WS&quot;:&quot;SAMOA&quot;,&quot;SM&quot;:&quot;SAN MARINO&quot;,&quot;ST&quot;:&quot;SAO TOME AND PRINCIPE&quot;,&quot;SA&quot;:&quot;SAUDI ARABIA&quot;,&quot;SN&quot;:&quot;SENEGAL&quot;,&quot;RS&quot;:&quot;SERBIA&quot;,&quot;SC&quot;:&quot;SEYCHELLES&quot;,&quot;SL&quot;:&quot;SIERRA LEONE&quot;,&quot;SG&quot;:&quot;SINGAPORE&quot;,&quot;SX&quot;:&quot;SINT MAARTEN (DUTCH PART)&quot;,&quot;SK&quot;:&quot;SLOVAKIA&quot;,&quot;SI&quot;:&quot;SLOVENIA&quot;,&quot;SB&quot;:&quot;SOLOMON ISLANDS&quot;,&quot;SO&quot;:&quot;SOMALIA&quot;,&quot;ZA&quot;:&quot;SOUTH AFRICA&quot;,&quot;GS&quot;:&quot;SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS&quot;,&quot;SS&quot;:&quot;SOUTH SUDAN&quot;,&quot;ES&quot;:&quot;SPAIN&quot;,&quot;LK&quot;:&quot;SRI LANKA&quot;,&quot;SD&quot;:&quot;SUDAN&quot;,&quot;SR&quot;:&quot;SURINAME&quot;,&quot;SJ&quot;:&quot;SVALBARD AND JAN MAYEN&quot;,&quot;SZ&quot;:&quot;SWAZILAND&quot;,&quot;SE&quot;:&quot;SWEDEN&quot;,&quot;CH&quot;:&quot;SWITZERLAND&quot;,&quot;SY&quot;:&quot;SYRIAN ARAB REPUBLIC&quot;,&quot;TW&quot;:&quot;TAIWAN, PROVINCE OF CHINA&quot;,&quot;TJ&quot;:&quot;TAJIKISTAN&quot;,&quot;TZ&quot;:&quot;TANZANIA, UNITED REPUBLIC OF&quot;,&quot;TH&quot;:&quot;THAILAND&quot;,&quot;TL&quot;:&quot;TIMOR-LESTE&quot;,&quot;TG&quot;:&quot;TOGO&quot;,&quot;TK&quot;:&quot;TOKELAU&quot;,&quot;TO&quot;:&quot;TONGA&quot;,&quot;TT&quot;:&quot;TRINIDAD AND TOBAGO&quot;,&quot;TN&quot;:&quot;TUNISIA&quot;,&quot;TR&quot;:&quot;TURKEY&quot;,&quot;TM&quot;:&quot;TURKMENISTAN&quot;,&quot;TC&quot;:&quot;TURKS AND CAICOS ISLANDS&quot;,&quot;TV&quot;:&quot;TUVALU&quot;,&quot;UG&quot;:&quot;UGANDA&quot;,&quot;UA&quot;:&quot;UKRAINE&quot;,&quot;AE&quot;:&quot;UNITED ARAB EMIRATES&quot;,&quot;GB&quot;:&quot;UNITED KINGDOM&quot;,&quot;US&quot;:&quot;UNITED STATES&quot;,
&quot;UM&quot;:&quot;UNITED STATES MINOR OUTLYING ISLANDS&quot;,&quot;UY&quot;:&quot;URUGUAY&quot;,&quot;UZ&quot;:&quot;UZBEKISTAN&quot;,&quot;VU&quot;:&quot;VANUATU&quot;,&quot;VE&quot;:&quot;VENEZUELA, BOLIVARIAN REPUBLIC OF&quot;,&quot;VN&quot;:&quot;VIET NAM&quot;,&quot;VG&quot;:&quot;VIRGIN ISLANDS, BRITISH&quot;,&quot;VI&quot;:&quot;VIRGIN ISLANDS, U.S.&quot;,&quot;WF&quot;:&quot;WALLIS AND FUTUNA&quot;,&quot;EH&quot;:&quot;WESTERN SAHARA&quot;,&quot;YE&quot;:&quot;YEMEN&quot;,&quot;ZM&quot;:&quot;ZAMBIA&quot;,&quot;ZW&quot;:&quot;ZIMBABWE&quot;}

&amp;nbsp;

# Connecting to the data source
gc = gc = gspread.login(G_USERNAME,G_PASSWORD)
sht1 = gc.open_by_key(G_IDENTIFIER)
worksheet = sht1.get_worksheet(0)
# Iterates through XML-structure and removes the namespace, for easier navigation in getCountry()s ElementTree.findall()
def remove_namespace(doc, namespace):
&quot;&quot;&quot;Remove namespace in the passed document in place.&quot;&quot;&quot;
ns = u'{%s}' % namespace
nsl = len(ns)
for elem in doc.getiterator():
if elem.tag.startswith(ns):
elem.tag = elem.tag[nsl:]
# getCountry - where the magic happens. Encodes string with artistname to url, then query musicbrainz search engine.
# parses the XML-answer and get the name, id and country of the first returned element (with highest weight)
# returns country name i a) artist is found through the search engine b) artist has a country associated to the profile, otherwise returns False
def getCountry(name):
name = urllib.quote_plus(name)
BASE_URL = &quot;http://musicbrainz.org/ws/2/artist/?query=%s&amp;amp;format=xml&amp;amp;method=advanced&quot; % (name)
print &quot;Querying: %s&quot; % (BASE_URL)
try:
search_input = urllib.urlopen(BASE_URL)
# Checks whether HTTP Request Code is 200 - if not goes to sleep for 5 seconds // Inded for 503 Code
http_code = search_input.code
if http_code != 200:
# print &quot;Could not access: %s \t Got HTTP Code: %s. 5 second cool-down&quot; % (name, http_code)
time.sleep(5)
getCountry(name)
except Exception:
print &quot;GETTING_ERROR: Something went wrong while getting HTTP&quot;
return False
#search_xml = search_input.read()
#print search_xml
try:
tree = ET.parse(search_input)
remove_namespace(tree, u'http://musicbrainz.org/ns/mmd-2.0#')
feed = tree.getroot()
elem = feed.findall(&quot;./artist-list/&quot;)
#print elem[0].find('name').text
#print elem[0].get('id')
except Exception:
print &quot;PARSE_ERROR: Something went wrong while parsing HTTP&quot;
return False
try:
if elem[0].find('country') != None:
# print COUNTRIES[elem[0].find('country').text]
try:
country = COUNTRIES[elem[0].find('country').text]
except Exception:
print &quot;Could not find key in countrylist error&quot;
return False
return [country,elem[0].get('id'),elem[0].find('name').text]
else:
print elem[0].find('name').text + &quot; has not any country associated\n&quot;
return False
except IndexError, ValueError:
print &quot;ERROR - COULD NOT GET DATA FROM %s\n&quot; % (name)
return False

#Running through the values
get_val = []
set_name = []
set_country = []
for a in range(2,5124):
v = &quot;B%s&quot; % a
sn = &quot;H%s&quot; % a
sc = &quot;G%s&quot; % a
get_val.append(v)
set_name.append(sn)
set_country.append(sc)

for a in range(2,5124):
try:
name = worksheet.acell(get_val[a]).value
res = getCountry(name)
if res:
print res
country, last_id, name = res
worksheet.update_acell(set_name[a], name)
worksheet.update_acell(set_country[a], country)
except Exception as e:
print e

</pre>
<div name="googleone_share_1" style="position:relative;z-index:5;float: right; margin-left: 10px;"><g:plusone size="medium" count="1" href="http://www.lovholm.net/2013/02/03/work-programmatically-with-google-spreadsheets/">{lang: 'en-GB'}</g:plusone></div>]]></content:encoded>
			<wfw:commentRss>http://www.lovholm.net/2013/02/03/work-programmatically-with-google-spreadsheets/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Facebooksider som RSS</title>
		<link>http://www.lovholm.net/2013/01/30/facebooksider-som-rss/</link>
		<comments>http://www.lovholm.net/2013/01/30/facebooksider-som-rss/#comments</comments>
		<pubDate>Wed, 30 Jan 2013 23:03:31 +0000</pubDate>
		<dc:creator>Ola Løvholm</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Facebook]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[RSS]]></category>
		<category><![CDATA[Social Graph]]></category>
		<category><![CDATA[trick]]></category>

		<guid isPermaLink="false">http://www.lovholm.net/?p=1931</guid>
		<description><![CDATA[RSS er super-praktiskt. Enten om du bruker laptop, tablet eller mobil så er aggregerte kilder gull verdt. Hvor digg er det ikke å kunne samle alt du ønsker å lese...]]></description>
				<content:encoded><![CDATA[<p>RSS er super-praktiskt. Enten om du bruker laptop, tablet eller mobil så er aggregerte kilder gull verdt. Hvor digg er det ikke å kunne samle alt du ønsker å lese i en leser (f.eks Google Reader) eller til og med automatisk oppdatere nettbrettet ditt med de nyeste sakene fra dine favorittkilder?</p>
<p>Her er en liten oppskrift på hvordan du kan gjøre dette på facebook sider du følger. Det er ikke alltid at social feed plukker opp disse, og dessuten er det fint å kunne lagre oppdateringer for ettertiden.</p>
<p>Det første du trenger er denne URL strengen:</p>
<pre><a href="https://www.facebook.com/feeds/page.php?format=atom10&amp;id=241453889260137">https://www.facebook.com/feeds/page.php?format=atom10&amp;id=241453889260137
</a></pre>
<p>Denne ganske ordinære URL strengen som parses som to argumenter av webserveren [:format =&gt;  "atom", :id =&gt; "241453889260137"] (ruby hash syntax), et voila, du får en atom formatert RSS side tilbake. Det du gjør her er å bytte ut id fra URLen ovenfor med iden fra siden du ønsker å følge.</p>
<p>Men hva om det ikke er noe ID i side URLen på Facebook? Som f.eks i bildet under (tatt fra siden til Løvholm Digitale Medier &#8211; mitt forholdsvis nye enkeltmannsforetak).</p>
<p><a href="http://www.lovholm.net/wp-content/uploads/2013/01/Screen-Shot-2013-01-30-at-11.50.14-PM.png"><img class="alignleft size-full wp-image-1950" alt="Screen Shot 2013-01-30 at 11.50.14 PM" src="http://www.lovholm.net/wp-content/uploads/2013/01/Screen-Shot-2013-01-30-at-11.50.14-PM.png" width="551" height="307" /></a></p>
<p>Her blir det litt mer komplisert.Dersom du forsøker å laste inn atom RSS-feeden fra dette navnet vil du kun få en side med en feilmelding.</p>
<p>Vår vei til målet går igjennom fantastiske Open Graph, teknologien Facebook bruker for å organisere sine tjenester og sin verden, og dens API.</p>
<pre>http://graph.facebook.com/lovdigmed</pre>
<p>Her kan du bruke navnet som oppslag og få tilbake en JSON-formatert tekststreng med det du trenger å vite</p>
<p><a href="http://www.lovholm.net/wp-content/uploads/2013/01/Screen-Shot-2013-01-30-at-11.56.36-PM.png"><img class="alignleft size-full wp-image-1951" alt="Screen Shot 2013-01-30 at 11.56.36 PM" src="http://www.lovholm.net/wp-content/uploads/2013/01/Screen-Shot-2013-01-30-at-11.56.36-PM.png" width="717" height="335" /></a></p>
<p>Nå trenger du kun å gå tilbake til den første URLen vi hadde, og benytte IDen til siden (merk: ikke cover_id) for å få tilgang til RSS-feeden.</p>
<p>Nå kan du lese Facebook sideoppdateringer i din yndlingsleser sammen med alt annet interessant du abonnerer på</p>
<p><a href="http://www.lovholm.net/wp-content/uploads/2013/01/Screen-Shot-2013-01-31-at-12.00.10-AM.png"><img class="alignleft size-full wp-image-1953" alt="Screen Shot 2013-01-31 at 12.00.10 AM" src="http://www.lovholm.net/wp-content/uploads/2013/01/Screen-Shot-2013-01-31-at-12.00.10-AM.png" width="953" height="489" /></a></p>
<div name="googleone_share_1" style="position:relative;z-index:5;float: right; margin-left: 10px;"><g:plusone size="medium" count="1" href="http://www.lovholm.net/2013/01/30/facebooksider-som-rss/">{lang: 'en-GB'}</g:plusone></div>]]></content:encoded>
			<wfw:commentRss>http://www.lovholm.net/2013/01/30/facebooksider-som-rss/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New layout for lovholm.net</title>
		<link>http://www.lovholm.net/2013/01/30/new-layout-for-lovholm-net/</link>
		<comments>http://www.lovholm.net/2013/01/30/new-layout-for-lovholm-net/#comments</comments>
		<pubDate>Wed, 30 Jan 2013 22:21:40 +0000</pubDate>
		<dc:creator>Ola Løvholm</dc:creator>
				<category><![CDATA[meta]]></category>
		<category><![CDATA[arras]]></category>
		<category><![CDATA[lovholm.net]]></category>
		<category><![CDATA[theme]]></category>
		<category><![CDATA[web design]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.lovholm.net/?p=1941</guid>
		<description><![CDATA[As the old layout broke with the newer versions of WordPress, and the fact that it was on high time to get a new layout (the last major visual update...]]></description>
				<content:encoded><![CDATA[<p>As the old layout broke with the newer versions of WordPress, and the fact that it was on high time to get a new layout (the last major visual update was back in 2010 &#8211; very long ago in the web world) I have now changed for a beta version of the Arras theme.</p>
<p>As you may see from the current state, not everything is up to date, but I hope you have patience as I will now start to customise the theme (maybe even a post on WP PHP programming will follow).</p>
<p>For future updates, stay tuned <img src='http://www.lovholm.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  &#8211; or subscribe to the RSS feed.</p>
<div name="googleone_share_1" style="position:relative;z-index:5;float: right; margin-left: 10px;"><g:plusone size="medium" count="1" href="http://www.lovholm.net/2013/01/30/new-layout-for-lovholm-net/">{lang: 'en-GB'}</g:plusone></div>]]></content:encoded>
			<wfw:commentRss>http://www.lovholm.net/2013/01/30/new-layout-for-lovholm-net/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Grunnloven av 1814 som ordsky</title>
		<link>http://www.lovholm.net/2012/11/18/grunnloven-av-1814-som-wordcloud/</link>
		<comments>http://www.lovholm.net/2012/11/18/grunnloven-av-1814-som-wordcloud/#comments</comments>
		<pubDate>Sun, 18 Nov 2012 13:47:15 +0000</pubDate>
		<dc:creator>Ola Løvholm</dc:creator>
				<category><![CDATA[data-work]]></category>
		<category><![CDATA[grunnloven]]></category>
		<category><![CDATA[Jonathan Feinberg]]></category>
		<category><![CDATA[Norges grunnlov]]></category>
		<category><![CDATA[Processing]]></category>
		<category><![CDATA[US Consitution]]></category>
		<category><![CDATA[WordCloud]]></category>
		<category><![CDATA[wordle]]></category>

		<guid isPermaLink="false">http://www.lovholm.net/?p=1887</guid>
		<description><![CDATA[WordClouds, eller ordsky på norsk, du har sikkert sett mange av dem. Ideen er å lage en visuell presentasjon av frekvensen av ordene i teksten. Dette er nyttig da det...]]></description>
				<content:encoded><![CDATA[<p>WordClouds, eller ordsky på norsk, du har sikkert sett mange av dem. Ideen er å lage en visuell presentasjon av frekvensen av ordene i teksten. Dette er nyttig da det enkelt kan gi oss en oversikt over hvilke ord som brukes i teksten, og samtidig har den en klar visuell &#8220;dette er kult&#8221;-effekt. For å lage en wordle kan bruke nettsiden som, om ikke introduserte fenomenet, gjorde det populært: <a href="http://www.wordle.net/">Wordle</a>. Vi skal gjøre det på en annen måte, ved hjelp av det visuelle programmeringsmiljøet <a href="http://processing.org/">Processing</a> (<a href="http://www.lovholm.net/2011/08/26/laer-programmering-med-processing-del-0/">kom igang</a>, <a href="http://www.lovholm.net/2011/11/07/visuell-programmering-i-processing/">enkel introduksjon</a>).</p>
<h4>Hvordan fungerer en wordle?</h4>
<p>Ingen er muligens bedre kvalifisert til å svare på dette enn Jonathan Feinberg, skaperen av Wordle, som på den sosiale programmingsspørsmålsiden StackOverflow <a href="http://stackoverflow.com/questions/342687/algorithm-to-implement-a-word-cloud-like-wordle">presenterer framgangsmåten</a>.</p>
<p><a href="http://www.lovholm.net/wp-content/uploads/2012/11/jfwordlestackoverflow.png"><img class="alignleft  wp-image-1903" title="jfwordlestackoverflow" alt="" src="http://www.lovholm.net/wp-content/uploads/2012/11/jfwordlestackoverflow.png" width="582" height="295" /></a></p>
<p>Først telles alle ordene, og sorteres slik at ordene med høyest frekvens kommer først. Deretter fordeles ordene utover lerretet slik at frekvensen gjenspeiles i størrelsen på ordene. De mest gjentatte ordene er de som dukker opp høyest. I løpet av telle-perioden må også ord som av grammatiske (eller andre) grunner ikke skal med fjernes. Ord som &#8216;er&#8217;, &#8216;som&#8217;, &#8216;i&#8217;, &#8216;på&#8217; brukes ofte i norsk, men de har ikke en semantisk mening på enkeltordsnivå som kan reflekteres i en wordle. (ja, det er en distinksjon mellom å være f.eks &#8216;i Drammen&#8217; eller på &#8216;på Drammen&#8217;, men denne reflekteres ikke når alle ord splittes). Når ordene og deres frekvens er bestemt begynner plasseringsjobben, og denne er ganske vanskelig å få til (forsøk  å lage en algoritme for å best organisere alle koffertene for bagasjerommet i en bil, hvor alle koffertene har forskjellige størrelse og fasong).</p>
<h4>Hvordan gjør vi det?</h4>
<p>Vi skal velge en løsning som ligger i mellom Wordle og en hvor vi må utvikle alt helt fra begynnelsen. Biblioteket <a href="http://wordcram.org/">WordCram</a> for Processing gjør jobben ganske enkel. På WordCram sine sider kan du også se et bilde av den amerikanske grunnloven, og dersom du syntes vårt resultat blir likt så stemmer dette, siden det er fra denne visualiseringen inspirasjonen til vår versjon av den norske grunnloven kommer fra.</p>
<div id="attachment_1910" class="wp-caption alignright" style="width: 549px"><a href="http://www.lovholm.net/wp-content/uploads/2012/11/US-consitution.png"><img class=" wp-image-1910  " title="US-consitution" alt="" src="http://www.lovholm.net/wp-content/uploads/2012/11/US-consitution.png" width="539" height="337" /></a><p class="wp-caption-text">US Consitution visualized through WordCram</p></div>
<p>Vi kommer til å låne fire ting fra denne presentasjonen. Den enkleste å kopiere er bakgrunnsfargen som med sin offwhite minner om offisielle papirer (og da snakker vi ikke om 80 g/m² A4 papir). Denne fargen representeres ved RGB-hex fargekoden #F5F1E3.</p>
<p>Vi skal også låne begge fontene som brukes i visualiseringen. Den ene, med håndskriftassosiasjoner heter, typisk nok, Jane Austen og kan lastes ned fra <a href="http://api.viglink.com/api/click?format=go&amp;key=cdee124b11d6baacda6c3e29b12e23dc&amp;loc=http%3A%2F%2Fwordcram.org%2F&amp;v=1&amp;libid=1353243646077&amp;out=http%3A%2F%2Fwww.dafont.com%2Fjane-austen.font&amp;ref=http%3A%2F%2Fwww.google.no%2Furl%3Fsa%3Dt%26rct%3Dj%26q%3D%26esrc%3Ds%26source%3Dweb%26cd%3D2%26ved%3D0CCoQFjAB%26url%3Dhttp%253A%252F%252Fwordcram.org%252F%26ei%3D-duoUP23L-_64QSC_4G4DA%26usg%3DAFQjCNGS2eC62lj10UFCKq_NmfYQQE4J9g%26sig2%3DeUAeL7XQrjdbzS7KyaFcXA&amp;title=WordCram.org%20%7C%20open-source%20word%20clouds%20for%20Processing&amp;txt=Jane%20Austen&amp;jsonp=vglnk_jsonp_13532442625422">dafont.com</a>. Den trykk-inspirerte fonten heter AveriaSerif-Regular. Vi kommer til å bruke Gruesa versjonen av denne. Begge to kan lastes ned fra i pakken med Averia fonter fra <a href="http://api.viglink.com/api/click?format=go&amp;key=cdee124b11d6baacda6c3e29b12e23dc&amp;loc=http%3A%2F%2Fwordcram.org%2F&amp;v=1&amp;libid=1353243646077&amp;out=http%3A%2F%2Fiotic.com%2Faveria%2F&amp;ref=http%3A%2F%2Fwww.google.no%2Furl%3Fsa%3Dt%26rct%3Dj%26q%3D%26esrc%3Ds%26source%3Dweb%26cd%3D2%26ved%3D0CCoQFjAB%26url%3Dhttp%253A%252F%252Fwordcram.org%252F%26ei%3D-duoUP23L-_64QSC_4G4DA%26usg%3DAFQjCNGS2eC62lj10UFCKq_NmfYQQE4J9g%26sig2%3DeUAeL7XQrjdbzS7KyaFcXA&amp;title=WordCram.org%20%7C%20open-source%20word%20clouds%20for%20Processing&amp;txt=AveriaSerif-Regular&amp;jsonp=vglnk_jsonp_13532444633844">IOtic</a>.</p>
<p>Det siste, og kanskje største tingen vi kommer til å låne er framgangsmåten. Koden som brukes ser slik ut:</p>
<pre class="brush: java; title: ; notranslate">
import wordcram.*;
import wordcram.text.*;

void setup() {
size(600,500);
background(#F5F1E3);

PFont averia = loadFont(&quot;Averia-Gruesa-48.vlw&quot;);
PFont janeAusten = loadFont(&quot;JaneAusten-48.vlw&quot;);

new WordCram(this)
.fromTextFile(&quot;grunnloven1814.txt&quot;)
.withFonts(averia, janeAusten)
.withColors(#000000)
.angledAt(0)
.withWordPadding(1)
.drawAll();

}
</pre>
<p>Vi har gjort noen endringer. Spesielt i forhold til font. Istedet for å laste inn systemfonter har jeg gått inn i Processings font verktøy (&#8220;Tools&#8221;-&gt;&#8221;Create font&#8221;) og laget .vlw filer for fontene.</p>
<h4>Grunnloven</h4>
<p>Vi har nå satt opp rammeverket hvor magien skal skje, men vi trenger fortsatt hovedingrediensen, nemlig Grunnloven av 1814. Den finner vi heldigvis på <a href="http://no.wikisource.org/wiki/Kongeriget_Norges_Grundlov_af_17de_Mai_1814">Wikisource</a> (et godt sted for kilder). Kopier teksten, legg den inn i en tekstfil som igjen lagres i mappen data i Processing-sketchen din. Bruk en teksteditor som TextMate eller Notepad, ikke en tekstbehandler som OpenOffice eller Word.</p>
<h4>Et voila</h4>
<div id="attachment_1915" class="wp-caption alignleft" style="width: 608px"><a href="http://www.lovholm.net/wp-content/uploads/2012/11/grunnloven01-svart.png"><img class="size-full wp-image-1915  " title="Grunnloven av 1814 WordCloud" alt="Grunnloven av 1814 WordCloud" src="http://www.lovholm.net/wp-content/uploads/2012/11/grunnloven01-svart.png" width="598" height="475" /></a><p class="wp-caption-text">Ordsky Norges Grunnlov</p></div>
<p>Verdt å merke seg er at det kommer et nytt resultat fra den bakenforliggende algoritmen hver gang den kjøres. Derfor vil resultatet også kunne se slik ut</p>
<div id="attachment_1917" class="wp-caption alignleft" style="width: 606px"><a href="http://www.lovholm.net/wp-content/uploads/2012/11/grunnloven02-svart.png"><img class="size-full wp-image-1917 " title="Grunnloven Wordcloud i svart Jane Austen" alt="Grunnloven Wordcloud " src="http://www.lovholm.net/wp-content/uploads/2012/11/grunnloven02-svart.png" width="596" height="487" /></a><p class="wp-caption-text">Wordle, eller Wordcloud, av Grunnloven 1814 i svart. Denne gangen med Jane Austen-foten mer dominant</p></div>
<h4>In Technicolor</h4>
<p>La oss arbeide videre med utgangspunktet vi allerede har. I visualiseringen av den amerikanske grunnloven brukte de blått og rødt. Dersom vi skal visualisere grunnloven slik at den fremstår &#8220;mer norsk&#8221; er den fargekombinasjonen som vi først tenker på (si gjerne ifra hvis du tenkte på en annen fargekombinasjon): rødt, hvitt og blått, eller som vi også kan kalle de: #EF2B2D, #FFFFFF, #002868.</p>
<p>Igjen fra <a href="http://en.wikipedia.org/wiki/File:Flag_of_Norway.svg">Wikipedia</a>:</p>
<blockquote><p>The flag of <a title="Norway" href="http://commons.wikimedia.org/wiki/Norway">Norway</a> consists of a  dark blue  cross (colour: <a title="en:RGB" href="http://en.wikipedia.org/wiki/RGB">RGB</a> #002868; <a title="en:Pantone" href="http://en.wikipedia.org/wiki/Pantone">Pantone</a> PMS-281U) with white borders on a  bright red  background (RGB #EF2B2D; Pantone PMS-032U). The vertical arm of the cross is shifted towards the flag pole as in the other <a title="w:Nordic Cross Flag" href="http://en.wikipedia.org/wiki/Nordic_Cross_Flag">Scandinavian flags</a>. The overall width−to−height proportions of the flag are 22 to 16, and the individual coloured fields measure 6+1+2+1+12 in width and 6+1+2+1+6 in height.</p>
<p>La oss endre koden fra tidligere til å ta med fargene:</p>
<pre class="brush: java; title: ; notranslate">
import wordcram.*;
import wordcram.text.*;

void setup() {
size(600,500);
background(#F5F1E3);

PFont averia = loadFont(&quot;Averia-Gruesa-48.vlw&quot;);
PFont janeAusten = loadFont(&quot;JaneAusten-48.vlw&quot;);

new WordCram(this)
.fromTextFile(&quot;grunnloven1814.txt&quot;)
.withFonts(averia, janeAusten)
.withColors(#EF2B2D, #FFFFFF, #002868)
.angledAt(0)
.withWordPadding(1)
.drawAll();

}
</pre>
</blockquote>
<p>Resultatet er nå annerledes og i farger (selv om hvitt på off-white blir noe rart. Hvilken farge mener du passer best?)</p>
<p>Nå, to år før grunnlovsjubileet har du en wordcloudversjon av grunnloven.<a href="http://www.lovholm.net/wp-content/uploads/2012/11/grunnloven05-farger.png"><img class="alignleft size-full wp-image-1922" title="grunnloven05-farger" alt="Wordle eller Wordle med Norges grunnlov 1814" src="http://www.lovholm.net/wp-content/uploads/2012/11/grunnloven05-farger.png" width="601" height="440" /></a></p>
<p><a href="http://www.lovholm.net/wp-content/uploads/2012/11/grunnloven03-farger.png"><img class="alignleft size-full wp-image-1920" title="grunnloven03-farger" alt="Grunnloven av 1814 wordle wordcloud" src="http://www.lovholm.net/wp-content/uploads/2012/11/grunnloven03-farger.png" width="597" height="432" /></a></p>
<p><a href="http://www.lovholm.net/wp-content/uploads/2012/11/grunnloven04-farger.png"><img class="alignleft size-full wp-image-1921" title="grunnloven04-farger" alt="" src="http://www.lovholm.net/wp-content/uploads/2012/11/grunnloven04-farger.png" width="598" height="443" /></a></p>
<div name="googleone_share_1" style="position:relative;z-index:5;float: right; margin-left: 10px;"><g:plusone size="medium" count="1" href="http://www.lovholm.net/2012/11/18/grunnloven-av-1814-som-wordcloud/">{lang: 'en-GB'}</g:plusone></div>]]></content:encoded>
			<wfw:commentRss>http://www.lovholm.net/2012/11/18/grunnloven-av-1814-som-wordcloud/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Data-wrangling: find country based on artist name</title>
		<link>http://www.lovholm.net/2012/11/11/find-your-way-around-the-data-automatically-try-to-parse-artist-country-based-on-name/</link>
		<comments>http://www.lovholm.net/2012/11/11/find-your-way-around-the-data-automatically-try-to-parse-artist-country-based-on-name/#comments</comments>
		<pubDate>Sun, 11 Nov 2012 22:19:06 +0000</pubDate>
		<dc:creator>Ola Løvholm</dc:creator>
				<category><![CDATA[data-work]]></category>
		<category><![CDATA[Clouds & Concerts]]></category>
		<category><![CDATA[Musicbrainz]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[screen scraping]]></category>
		<category><![CDATA[Telenor]]></category>
		<category><![CDATA[WiMP]]></category>

		<guid isPermaLink="false">http://www.lovholm.net/?p=1884</guid>
		<description><![CDATA[At the Clouds &#38; Concerts project at the University of Oslo we are working with really interesting topics, based on interesting empirical data. Through our collaboration with the Norwegian streaming...]]></description>
				<content:encoded><![CDATA[<p>At the <a href="http://www.hf.uio.no/imv/english/research/projects/cloudsandconcerts/index.html">Clouds &amp; Concerts</a> project at the <a href="http://www.uio.no/english/">University of Oslo</a> we are working with really interesting topics, based on interesting empirical data. Through our collaboration with the Norwegian streaming service provider <a href="http://wimpmusic.com/wweb/index/">WiMP</a> we are together with <a href="http://telenor.com/">Telenor</a> and WiMP analysing a vast collection of data. More about the project&#8217;s data-part, also the &#8216;Clouds&#8217; part of the project&#8217;s name can be found on the <a href="http://www.hf.uio.no/imv/english/research/projects/cloudsandconcerts/">project&#8217;s web sites.</a></p>
<h4>Artist and Country</h4>
<p>One of the tasks at hand was to find out which country an artist came from, and whether they came from Norway or not. One way of doing this is to manually go through each artist and use preexisting knowledge about music to determine their country of origin, if stuck, use online services (aren&#8217;t we all mostly using Google as initial source of wisdom). Another alternative is to use online services first and then to use human preexisting knowledge to quality assure the final result.</p>
<p>On the Internet, vast amount of sources can be found. However, if you want to get the data without too much fitting, testing, and nitty gritty adaptation for every source, you have an advantage if there is as consistently structured repository you can tap from. Luckily, <a href="http://metabrainz.org/">Metabrainz</a> foundation has a large repository of musical meta-data known as <a href="http://musicbrainz.org/">Musicbrainz</a>.</p>
<p>Below you find a script which should (partially) solve our problem by combining the data from Musicbrainz with data exported from our research data. That being said, this script is more a method than a finished product. It should be very easy adaptable, but it is an advantage if you know Python and handling CSV-files. <a href="http://www.codecademy.com/#!/exercises/0">Codeacademy</a> has a good introduction to Python.</p>
<p>The core idea of the script is to take input with name and number of streams and turn them into output with name from the original datasource, number of streams from the original datasource, as well as country of origin, Musicbrainz-ID, and name parsed by Musicbrainz search engine (for initial quality assurance).</p>
<p>To make things simple there is only one successful output and that is if the name sent to the Musicbrainz search engine return an answer, and if that answer has a country associated with it. Be advised (that is also why I have marked the title with &#8216;try&#8217;), that the search engine may not return a similar result. Of that reason we also print the name of the artist we find so this later can be juxtaposed with the original name in the Excel spreadsheet (you are going to transform the CSV to Excel before reviewing aren&#8217;t you. <a href="http://code.google.com/p/google-refine/">Good tool is Google Refine</a>). Another problem is that popular cultural phenomena, common nouns and tribute bands (probably in that order, descending) have same name. This is why a human is always needed, or semantic absolute URI associated with each phenomena. This leads me on to the last step before the code.</p>
<h4>Other ways this could have been solved (let me know if you solve the problem in any of these ways)</h4>
<h5>The semantic way:</h5>
<p>The data found in the Musicbrainz database is made available through a SPARQL endpoint named <a href="http://wiki.musicbrainz.org/LinkedBrainz">LinkedBrainz</a>.If you know the right ontologies and is comfortable with performing triplestore queries, this is perhaps the most innovative and new-thinking way to solve the problem.</p>
<h5>The Virtual Machine Postgres way:</h5>
<p>Instead of doing a query on the server, you can be a gentleman and download the server onto your own machine. If you have VirtualBox (if you don&#8217;t have it,<a href="https://www.virtualbox.org/"> download it for free</a>) you can run the server locally. An image file with the complete Musicbrainz database can be found on their webpages.</p>
<h4>The code:</h4>
<p>Here is the code used to solve this task. It can also be cloned from the<a href="https://github.com/CloudsAndConcerts/scripts/blob/master/artist_country.py"> Cloud &amp; Concerts GitHub-page</a></p>
<pre class="brush: python; title: ; notranslate">
#!/usr/bin/python
# -*- coding:utf-8 -*-

&quot;&quot;&quot;
Clouds &amp; Concerts - 2012
Ola Loevholm

Called from command line:
The script reads a file named &quot;topp1000_artister.csv&quot; consisting of a list of artists and then tries to find out which country each artist comes from based on the name.
The name is given in the second column of the CSV file.

Called as a module:
The method getCountry() takes an artist name and checks this with musicbrainz seach engine. Returns the country if a) artist is found through the search engine b) artist has a country associated to the profile

&quot;&quot;&quot;

import sys, urllib, string, csv, time
import xml.etree.ElementTree as ET

# Loads a dictionary with ISO 3166-1 abbreviations and countries
COUNTRIES = {&quot;AF&quot;:&quot;AFGHANISTAN&quot;,&quot;AX&quot;:&quot;ÅLAND ISLANDS&quot;,&quot;AL&quot;:&quot;ALBANIA&quot;,&quot;DZ&quot;:&quot;ALGERIA&quot;,&quot;AS&quot;:&quot;AMERICAN SAMOA&quot;,&quot;AD&quot;:&quot;ANDORRA&quot;,&quot;AO&quot;:&quot;ANGOLA&quot;,&quot;AI&quot;:&quot;ANGUILLA&quot;,&quot;AQ&quot;:&quot;ANTARCTICA&quot;,&quot;AG&quot;:&quot;ANTIGUA AND BARBUDA&quot;,&quot;AR&quot;:&quot;ARGENTINA&quot;,&quot;AM&quot;:&quot;ARMENIA&quot;,&quot;AW&quot;:&quot;ARUBA&quot;,&quot;AU&quot;:&quot;AUSTRALIA&quot;,&quot;AT&quot;:&quot;AUSTRIA&quot;,&quot;AZ&quot;:&quot;AZERBAIJAN&quot;,&quot;BS&quot;:&quot;BAHAMAS&quot;,&quot;BH&quot;:&quot;BAHRAIN&quot;,&quot;BD&quot;:&quot;BANGLADESH&quot;,&quot;BB&quot;:&quot;BARBADOS&quot;,&quot;BY&quot;:&quot;BELARUS&quot;,&quot;BE&quot;:&quot;BELGIUM&quot;,&quot;BZ&quot;:&quot;BELIZE&quot;,&quot;BJ&quot;:&quot;BENIN&quot;,&quot;BM&quot;:&quot;BERMUDA&quot;,&quot;BT&quot;:&quot;BHUTAN&quot;,&quot;BO&quot;:&quot;BOLIVIA, PLURINATIONAL STATE OF&quot;,&quot;BQ&quot;:&quot;BONAIRE, SINT EUSTATIUS AND SABA&quot;,&quot;BA&quot;:&quot;BOSNIA AND HERZEGOVINA&quot;,&quot;BW&quot;:&quot;BOTSWANA&quot;,&quot;BV&quot;:&quot;BOUVET ISLAND&quot;,&quot;BR&quot;:&quot;BRAZIL&quot;,&quot;IO&quot;:&quot;BRITISH INDIAN OCEAN TERRITORY&quot;,&quot;BN&quot;:&quot;BRUNEI DARUSSALAM&quot;,&quot;BG&quot;:&quot;BULGARIA&quot;,&quot;BF&quot;:&quot;BURKINA FASO&quot;,&quot;BI&quot;:&quot;BURUNDI&quot;,&quot;KH&quot;:&quot;CAMBODIA&quot;,&quot;CM&quot;:&quot;CAMEROON&quot;,&quot;CA&quot;:&quot;CANADA&quot;,&quot;CV&quot;:&quot;CAPE VERDE&quot;,&quot;KY&quot;:&quot;CAYMAN ISLANDS&quot;,&quot;CF&quot;:&quot;CENTRAL AFRICAN REPUBLIC&quot;,&quot;TD&quot;:&quot;CHAD&quot;,&quot;CL&quot;:&quot;CHILE&quot;,&quot;CN&quot;:&quot;CHINA&quot;,&quot;CX&quot;:&quot;CHRISTMAS ISLAND&quot;,
&quot;CC&quot;:&quot;COCOS (KEELING) ISLANDS&quot;,&quot;CO&quot;:&quot;COLOMBIA&quot;,&quot;KM&quot;:&quot;COMOROS&quot;,&quot;CG&quot;:&quot;CONGO&quot;,&quot;CD&quot;:&quot;CONGO, THE DEMOCRATIC REPUBLIC OF THE&quot;,&quot;CK&quot;:&quot;COOK ISLANDS&quot;,&quot;CR&quot;:&quot;COSTA RICA&quot;,&quot;CI&quot;:&quot;CÔTE D'IVOIRE&quot;,&quot;HR&quot;:&quot;CROATIA&quot;,&quot;CU&quot;:&quot;CUBA&quot;,&quot;CW&quot;:&quot;CURAÇAO&quot;,&quot;CY&quot;:&quot;CYPRUS&quot;,&quot;CZ&quot;:&quot;CZECH REPUBLIC&quot;,&quot;DK&quot;:&quot;DENMARK&quot;,&quot;DJ&quot;:&quot;DJIBOUTI&quot;,&quot;DM&quot;:&quot;DOMINICA&quot;,&quot;DO&quot;:&quot;DOMINICAN REPUBLIC&quot;,&quot;EC&quot;:&quot;ECUADOR&quot;,&quot;EG&quot;:&quot;EGYPT&quot;,&quot;SV&quot;:&quot;EL SALVADOR&quot;,&quot;GQ&quot;:&quot;EQUATORIAL GUINEA&quot;,&quot;ER&quot;:&quot;ERITREA&quot;,&quot;EE&quot;:&quot;ESTONIA&quot;,&quot;ET&quot;:&quot;ETHIOPIA&quot;,&quot;FK&quot;:&quot;FALKLAND ISLANDS (MALVINAS)&quot;,&quot;FO&quot;:&quot;FAROE ISLANDS&quot;,&quot;FJ&quot;:&quot;FIJI&quot;,&quot;FI&quot;:&quot;FINLAND&quot;,&quot;FR&quot;:&quot;FRANCE&quot;,&quot;GF&quot;:&quot;FRENCH GUIANA&quot;,&quot;PF&quot;:&quot;FRENCH POLYNESIA&quot;,&quot;TF&quot;:&quot;FRENCH SOUTHERN TERRITORIES&quot;,&quot;GA&quot;:&quot;GABON&quot;,&quot;GM&quot;:&quot;GAMBIA&quot;,&quot;GE&quot;:&quot;GEORGIA&quot;,&quot;DE&quot;:&quot;GERMANY&quot;,&quot;GH&quot;:&quot;GHANA&quot;,&quot;GI&quot;:&quot;GIBRALTAR&quot;,&quot;GR&quot;:&quot;GREECE&quot;,&quot;GL&quot;:&quot;GREENLAND&quot;,&quot;GD&quot;:&quot;GRENADA&quot;,&quot;GP&quot;:&quot;GUADELOUPE&quot;,&quot;GU&quot;:&quot;GUAM&quot;,&quot;GT&quot;:&quot;GUATEMALA&quot;,&quot;GG&quot;:&quot;GUERNSEY&quot;,&quot;GN&quot;:&quot;GUINEA&quot;,&quot;GW&quot;:&quot;GUINEA-BISSAU&quot;,&quot;GY&quot;:&quot;GUYANA&quot;,&quot;HT&quot;:&quot;HAITI&quot;,&quot;HM&quot;:&quot;HEARD ISLAND AND MCDONALD ISLANDS&quot;,
&quot;VA&quot;:&quot;HOLY SEE (VATICAN CITY STATE)&quot;,&quot;HN&quot;:&quot;HONDURAS&quot;,&quot;HK&quot;:&quot;HONG KONG&quot;,&quot;HU&quot;:&quot;HUNGARY&quot;,&quot;IS&quot;:&quot;ICELAND&quot;,&quot;IN&quot;:&quot;INDIA&quot;,&quot;ID&quot;:&quot;INDONESIA&quot;,&quot;IR&quot;:&quot;IRAN, ISLAMIC REPUBLIC OF&quot;,&quot;IQ&quot;:&quot;IRAQ&quot;,&quot;IE&quot;:&quot;IRELAND&quot;,&quot;IM&quot;:&quot;ISLE OF MAN&quot;,&quot;IL&quot;:&quot;ISRAEL&quot;,&quot;IT&quot;:&quot;ITALY&quot;,&quot;JM&quot;:&quot;JAMAICA&quot;,&quot;JP&quot;:&quot;JAPAN&quot;,&quot;JE&quot;:&quot;JERSEY&quot;,&quot;JO&quot;:&quot;JORDAN&quot;,&quot;KZ&quot;:&quot;KAZAKHSTAN&quot;,&quot;KE&quot;:&quot;KENYA&quot;,&quot;KI&quot;:&quot;KIRIBATI&quot;,&quot;KP&quot;:&quot;KOREA, DEMOCRATIC PEOPLE'S REPUBLIC OF&quot;,&quot;KR&quot;:&quot;KOREA, REPUBLIC OF&quot;,&quot;KW&quot;:&quot;KUWAIT&quot;,&quot;KG&quot;:&quot;KYRGYZSTAN&quot;,&quot;LA&quot;:&quot;LAO PEOPLE'S DEMOCRATIC REPUBLIC&quot;,&quot;LV&quot;:&quot;LATVIA&quot;,&quot;LB&quot;:&quot;LEBANON&quot;,&quot;LS&quot;:&quot;LESOTHO&quot;,&quot;LR&quot;:&quot;LIBERIA&quot;,&quot;LY&quot;:&quot;LIBYA&quot;,&quot;LI&quot;:&quot;LIECHTENSTEIN&quot;,&quot;LT&quot;:&quot;LITHUANIA&quot;,&quot;LU&quot;:&quot;LUXEMBOURG&quot;,&quot;MO&quot;:&quot;MACAO&quot;,&quot;MK&quot;:&quot;MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF&quot;,&quot;MG&quot;:&quot;MADAGASCAR&quot;,&quot;MW&quot;:&quot;MALAWI&quot;,&quot;MY&quot;:&quot;MALAYSIA&quot;,&quot;MV&quot;:&quot;MALDIVES&quot;,&quot;ML&quot;:&quot;MALI&quot;,&quot;MT&quot;:&quot;MALTA&quot;,&quot;MH&quot;:&quot;MARSHALL ISLANDS&quot;,&quot;MQ&quot;:&quot;MARTINIQUE&quot;,&quot;MR&quot;:&quot;MAURITANIA&quot;,&quot;MU&quot;:&quot;MAURITIUS&quot;,&quot;YT&quot;:&quot;MAYOTTE&quot;,&quot;MX&quot;:&quot;MEXICO&quot;,&quot;FM&quot;:&quot;MICRONESIA, FEDERATED STATES OF&quot;,
&quot;MD&quot;:&quot;MOLDOVA, REPUBLIC OF&quot;,&quot;MC&quot;:&quot;MONACO&quot;,&quot;MN&quot;:&quot;MONGOLIA&quot;,&quot;ME&quot;:&quot;MONTENEGRO&quot;,&quot;MS&quot;:&quot;MONTSERRAT&quot;,&quot;MA&quot;:&quot;MOROCCO&quot;,&quot;MZ&quot;:&quot;MOZAMBIQUE&quot;,&quot;MM&quot;:&quot;MYANMAR&quot;,&quot;NA&quot;:&quot;NAMIBIA&quot;,&quot;NR&quot;:&quot;NAURU&quot;,&quot;NP&quot;:&quot;NEPAL&quot;,&quot;NL&quot;:&quot;NETHERLANDS&quot;,&quot;NC&quot;:&quot;NEW CALEDONIA&quot;,&quot;NZ&quot;:&quot;NEW ZEALAND&quot;,&quot;NI&quot;:&quot;NICARAGUA&quot;,&quot;NE&quot;:&quot;NIGER&quot;,&quot;NG&quot;:&quot;NIGERIA&quot;,&quot;NU&quot;:&quot;NIUE&quot;,&quot;NF&quot;:&quot;NORFOLK ISLAND&quot;,&quot;MP&quot;:&quot;NORTHERN MARIANA ISLANDS&quot;,&quot;NO&quot;:&quot;NORWAY&quot;,&quot;OM&quot;:&quot;OMAN&quot;,&quot;PK&quot;:&quot;PAKISTAN&quot;,&quot;PW&quot;:&quot;PALAU&quot;,&quot;PS&quot;:&quot;PALESTINIAN TERRITORY, OCCUPIED&quot;,&quot;PA&quot;:&quot;PANAMA&quot;,&quot;PG&quot;:&quot;PAPUA NEW GUINEA&quot;,&quot;PY&quot;:&quot;PARAGUAY&quot;,&quot;PE&quot;:&quot;PERU&quot;,&quot;PH&quot;:&quot;PHILIPPINES&quot;,&quot;PN&quot;:&quot;PITCAIRN&quot;,&quot;PL&quot;:&quot;POLAND&quot;,&quot;PT&quot;:&quot;PORTUGAL&quot;,&quot;PR&quot;:&quot;PUERTO RICO&quot;,&quot;QA&quot;:&quot;QATAR&quot;,&quot;RE&quot;:&quot;RÉUNION&quot;,&quot;RO&quot;:&quot;ROMANIA&quot;,&quot;RU&quot;:&quot;RUSSIAN FEDERATION&quot;,&quot;RW&quot;:&quot;RWANDA&quot;,&quot;BL&quot;:&quot;SAINT BARTHÉLEMY&quot;,&quot;SH&quot;:&quot;SAINT HELENA, ASCENSION AND TRISTAN DA CUNHA&quot;,&quot;KN&quot;:&quot;SAINT KITTS AND NEVIS&quot;,&quot;LC&quot;:&quot;SAINT LUCIA&quot;,&quot;MF&quot;:&quot;SAINT MARTIN (FRENCH PART)&quot;,&quot;PM&quot;:&quot;SAINT PIERRE AND MIQUELON&quot;,&quot;VC&quot;:&quot;SAINT VINCENT AND THE GRENADINES&quot;,
&quot;WS&quot;:&quot;SAMOA&quot;,&quot;SM&quot;:&quot;SAN MARINO&quot;,&quot;ST&quot;:&quot;SAO TOME AND PRINCIPE&quot;,&quot;SA&quot;:&quot;SAUDI ARABIA&quot;,&quot;SN&quot;:&quot;SENEGAL&quot;,&quot;RS&quot;:&quot;SERBIA&quot;,&quot;SC&quot;:&quot;SEYCHELLES&quot;,&quot;SL&quot;:&quot;SIERRA LEONE&quot;,&quot;SG&quot;:&quot;SINGAPORE&quot;,&quot;SX&quot;:&quot;SINT MAARTEN (DUTCH PART)&quot;,&quot;SK&quot;:&quot;SLOVAKIA&quot;,&quot;SI&quot;:&quot;SLOVENIA&quot;,&quot;SB&quot;:&quot;SOLOMON ISLANDS&quot;,&quot;SO&quot;:&quot;SOMALIA&quot;,&quot;ZA&quot;:&quot;SOUTH AFRICA&quot;,&quot;GS&quot;:&quot;SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS&quot;,&quot;SS&quot;:&quot;SOUTH SUDAN&quot;,&quot;ES&quot;:&quot;SPAIN&quot;,&quot;LK&quot;:&quot;SRI LANKA&quot;,&quot;SD&quot;:&quot;SUDAN&quot;,&quot;SR&quot;:&quot;SURINAME&quot;,&quot;SJ&quot;:&quot;SVALBARD AND JAN MAYEN&quot;,&quot;SZ&quot;:&quot;SWAZILAND&quot;,&quot;SE&quot;:&quot;SWEDEN&quot;,&quot;CH&quot;:&quot;SWITZERLAND&quot;,&quot;SY&quot;:&quot;SYRIAN ARAB REPUBLIC&quot;,&quot;TW&quot;:&quot;TAIWAN, PROVINCE OF CHINA&quot;,&quot;TJ&quot;:&quot;TAJIKISTAN&quot;,&quot;TZ&quot;:&quot;TANZANIA, UNITED REPUBLIC OF&quot;,&quot;TH&quot;:&quot;THAILAND&quot;,&quot;TL&quot;:&quot;TIMOR-LESTE&quot;,&quot;TG&quot;:&quot;TOGO&quot;,&quot;TK&quot;:&quot;TOKELAU&quot;,&quot;TO&quot;:&quot;TONGA&quot;,&quot;TT&quot;:&quot;TRINIDAD AND TOBAGO&quot;,&quot;TN&quot;:&quot;TUNISIA&quot;,&quot;TR&quot;:&quot;TURKEY&quot;,&quot;TM&quot;:&quot;TURKMENISTAN&quot;,&quot;TC&quot;:&quot;TURKS AND CAICOS ISLANDS&quot;,&quot;TV&quot;:&quot;TUVALU&quot;,&quot;UG&quot;:&quot;UGANDA&quot;,&quot;UA&quot;:&quot;UKRAINE&quot;,&quot;AE&quot;:&quot;UNITED ARAB EMIRATES&quot;,&quot;GB&quot;:&quot;UNITED KINGDOM&quot;,&quot;US&quot;:&quot;UNITED STATES&quot;,
&quot;UM&quot;:&quot;UNITED STATES MINOR OUTLYING ISLANDS&quot;,&quot;UY&quot;:&quot;URUGUAY&quot;,&quot;UZ&quot;:&quot;UZBEKISTAN&quot;,&quot;VU&quot;:&quot;VANUATU&quot;,&quot;VE&quot;:&quot;VENEZUELA, BOLIVARIAN REPUBLIC OF&quot;,&quot;VN&quot;:&quot;VIET NAM&quot;,&quot;VG&quot;:&quot;VIRGIN ISLANDS, BRITISH&quot;,&quot;VI&quot;:&quot;VIRGIN ISLANDS, U.S.&quot;,&quot;WF&quot;:&quot;WALLIS AND FUTUNA&quot;,&quot;EH&quot;:&quot;WESTERN SAHARA&quot;,&quot;YE&quot;:&quot;YEMEN&quot;,&quot;ZM&quot;:&quot;ZAMBIA&quot;,&quot;ZW&quot;:&quot;ZIMBABWE&quot;}

# Iterates through XML-structure and removes the namespace, for easier navigation in getCountry()s ElementTree.findall()
def remove_namespace(doc, namespace):
	&quot;&quot;&quot;Remove namespace in the passed document in place.&quot;&quot;&quot;
	ns = u'{%s}' % namespace
	nsl = len(ns)
	for elem in doc.getiterator():
		if elem.tag.startswith(ns):
			elem.tag = elem.tag[nsl:]

# getCountry - where the magic happens. Encodes string with artistname to url, then query musicbrainz search engine.
# parses the XML-answer and get the name, id and country of the first returned element (with highest weight)
# returns country name i a) artist is found through the search engine b) artist has a country associated to the profile, otherwise returns False
def getCountry(name):
	name = urllib.quote_plus(name)
	BASE_URL = &quot;http://musicbrainz.org/ws/2/artist/?query=%s&amp;format=xml&amp;method=advanced&quot; % (name)
	print &quot;Querying: %s&quot; % (BASE_URL)
	try:
		search_input = urllib.urlopen(BASE_URL)
		# Checks whether HTTP Request Code is 200 - if not goes to sleep for 5 seconds // Inded for 503 Code
		http_code = search_input.code
		if http_code != 200:
#			print &quot;Could not access: %s \t Got HTTP Code: %s. 5 second cool-down&quot; % (name, http_code)
			time.sleep(5)
			getCountry(name)
	except Exception:
		print &quot;GETTING_ERROR: Something went wrong while getting HTTP&quot;
		return False
	#search_xml = search_input.read()
	#print search_xml
	try:
		tree = ET.parse(search_input)
		remove_namespace(tree, u'http://musicbrainz.org/ns/mmd-2.0#')
		feed = tree.getroot()
		elem = feed.findall(&quot;./artist-list/&quot;)
		#print elem[0].find('name').text
		#print elem[0].get('id')
	except Exception:
		print &quot;PARSE_ERROR: Something went wrong while parsing HTTP&quot;
		return False
	try:
		if elem[0].find('country') != None:
#			print COUNTRIES[elem[0].find('country').text]
			try:
				country = COUNTRIES[elem[0].find('country').text]
			except Exception:
				print &quot;Could not find key in countrylist error&quot;
				return False
			return [country,elem[0].get('id'),elem[0].find('name').text]
		else:
			print elem[0].find('name').text + &quot; has not any country associated\n&quot;
			return False
	except IndexError, ValueError:
		print &quot;ERROR - COULD NOT GET DATA FROM %s\n&quot; % (name)
		return False

# If method is called from terminal. Iterates through topp1000 artists contained in a CSV-file in same directory.
if __name__ == &quot;__main__&quot;:
	#name = sys.argv[1]
	csvfile = open(&quot;topp1000_artister.csv&quot;)
	outfile = open(&quot;topp1000_output.csv&quot;,&quot;w&quot;)
	artistlist = csv.reader(csvfile, delimiter=',', quotechar='&quot;')
	for line in artistlist:
		result = getCountry(line[1])
		try:
			if result != False:
				result_string = &quot;%s,%s,%s,%s,%s,%s\n&quot; % (line[0],line[1],line[2],result[0],result[1],result[2])
#				print result_string
			else:
				result_string = &quot;%s,%s,%s,%s\n&quot; % (line[0],line[1],line[2],&quot;No Country Found or fail occured&quot;)
#				print result_string
		except IndexError, ValueError:
			print e
			result_string = &quot;Error on element: %s\n&quot; % line[1]
		try:
			outfile.write(result_string)
		except:
			print &quot;Write error happened with %s&quot; % line[1]
</pre>
<p>And as always, I am most greatful for feedback! Hope this may come in handy!</p>
<div name="googleone_share_1" style="position:relative;z-index:5;float: right; margin-left: 10px;"><g:plusone size="medium" count="1" href="http://www.lovholm.net/2012/11/11/find-your-way-around-the-data-automatically-try-to-parse-artist-country-based-on-name/">{lang: 'en-GB'}</g:plusone></div>]]></content:encoded>
			<wfw:commentRss>http://www.lovholm.net/2012/11/11/find-your-way-around-the-data-automatically-try-to-parse-artist-country-based-on-name/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Create Thumbnails Programatically</title>
		<link>http://www.lovholm.net/2012/09/16/create-thumbnails-programatically/</link>
		<comments>http://www.lovholm.net/2012/09/16/create-thumbnails-programatically/#comments</comments>
		<pubDate>Sun, 16 Sep 2012 16:52:42 +0000</pubDate>
		<dc:creator>Ola Løvholm</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[PIL]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Python Image Library]]></category>
		<category><![CDATA[resize]]></category>
		<category><![CDATA[scripting tool]]></category>
		<category><![CDATA[thumbnails]]></category>

		<guid isPermaLink="false">http://www.lovholm.net/?p=1845</guid>
		<description><![CDATA[If you have several images following a certain structure on a web page and want them as thumbnails, it can be useful to programatically create these. The manual way of...]]></description>
				<content:encoded><![CDATA[<p><strong>If you have several images following a certain structure on a web page and want them as thumbnails, it can be useful to programatically create these. The manual way of creating thumbnails (using Photoshop or similar) can often be time consuming while the execution time for a script resizing an image is counted in microseconds. If you already have a script this can also be fitted for other similar situations. With the <a href="http://www.pythonware.com/products/pil/">Python Image Library</a> (PIL) thumbnails can be created in no-time. </strong></p>
<p>In this real word example a Python scripts runs through the folder in which the script is located, resizes each image of the type png and jpg (hopefully the filenames corresponds to the format), when the images have been resized they are put inside a new folder.</p>
<p>Note that PIL ensures a correct aspect ratio and that the size variable just sets the boundary. In the code bellow the important feature is to have images that not exceeds 150px in width (standard convention with width and height). Passing the PIL Image object the size will transform the object into a thumbnail. The method by which the transformation should be performed can be added as an optional parameter. From the <a href="http://www.pythonware.com/library/pil/handbook/image.htm">documentation</a>: &#8220;The filter argument can be one of NEAREST, BILINEAR, BICUBIC, or ANTIALIAS (best quality). If omitted, it defaults to NEAREST.&#8221;</p>
<pre class="brush: python; title: ; notranslate">
#!/usr/bin/python
# -*- coding: utf-8 -*-
import Image
import os
#Imports the Image and os libraries. os is part of standard libraries. Image is part of Python Image Library (PIL)
#PIL can be downloaded from: http://www.pythonware.com/products/pil/

#Creates sets and creates the directory onto where you want your files to be saved
outdir = &quot;150images/&quot;
os.mkdir(&quot;./&quot;+outdir)
#If the directory already exists this will cause an OSError.

size = 150, 400 #Set the size that you want to resize your image to.
#Thumbnail automatically checks for ratio consistency so alter the important variable (height or width)

for files in os.listdir(&quot;.&quot;):
    #Sets the appropriate suffix to your files.
    outfile = os.path.splitext(files)[0] + &quot;_thumbnail.jpg&quot;
    #Transforms JPG formatted files
    if files.endswith(&quot;.jpg&quot;):
        im = Image.open(files)
        try:
            im.thumbnail(size, Image.ANTIALIAS)
            im.save(outdir+outfile, &quot;JPEG&quot;)
            print &quot;Saved the file: %s&quot; % outdir+outfile
        except IOError:
            print &quot;cannot create thumbnail for '%s'&quot; % infile
    #Transforms PNG formatted files
    if files.endswith(&quot;.png&quot;):
        im = Image.open(files)
        try:
            im.thumbnail(size, Image.ANTIALIAS)
            im.save(outdir+outfile, &quot;JPEG&quot;)
            print &quot;Saved the file: %s&quot; % outfile
        except IOError:
            print &quot;cannot create thumbnail for '%s'&quot; % infile

</pre>
<p>The script will execute once, but as you execute twice you will get an OSError, this is due to the folder being created in the beginning of the script. I have chosen to name this folder after the significant size boundary in the script (maximum 150px width). PIL is not a part of the standard library, but can easily be installed through pip or easy_install. Python is available on almost every platform and comes preinstalled on the Mac.</p>
<div name="googleone_share_1" style="position:relative;z-index:5;float: right; margin-left: 10px;"><g:plusone size="medium" count="1" href="http://www.lovholm.net/2012/09/16/create-thumbnails-programatically/">{lang: 'en-GB'}</g:plusone></div>]]></content:encoded>
			<wfw:commentRss>http://www.lovholm.net/2012/09/16/create-thumbnails-programatically/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
