<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4078805449160415851</id><updated>2024-10-05T11:32:03.010+09:00</updated><category term="arduino"/><category term="java"/><category term="jython"/><category term="python"/><category term="C"/><category term="chrome"/><category term="emacs"/><category term="ipod touch"/><category term="scala"/><category term="applescript"/><category term="perl"/><category term="android"/><category term="google"/><category term="growl"/><category term="html5"/><category term="mac"/><category term="hadoop"/><category term="haskell"/><category term="kafka"/><category term="notifo"/><category term="protocol buffers"/><category term="terminal"/><category term="vim"/><category term="web"/><category term="xml"/><category term="555"/><category term="C++"/><category term="R"/><category term="avr"/><category term="bc"/><category term="camera"/><category term="dlna"/><category term="druid"/><category term="file system"/><category term="git"/><category term="igraph"/><category term="inotify"/><category term="javascript"/><category term="kindle"/><category term="mercurial"/><category term="notifyosd"/><category term="omake"/><category term="paver"/><category term="pdf"/><category term="radio"/><category term="security"/><category term="sqlite"/><category term="tex"/><category term="text editor"/><category term="tv"/><category term="xcode"/><category term="xmpp"/><title type='text'>EngineeringException</title><subtitle type='html'>SAEKI Yoshiyasu&#39;s weblog</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://laclefyoshi.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://laclefyoshi.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/09934531596280495750</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>84</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4078805449160415851.post-6029480752196745817</id><published>2014-12-31T17:49:00.000+09:00</published><updated>2014-12-31T17:49:23.648+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="druid"/><category scheme="http://www.blogger.com/atom/ns#" term="kafka"/><title type='text'>Interactive time series data analysis using Apache Kafka and Druid</title><content type='html'>&lt;br /&gt;
Japanese version is &lt;a href=&quot;http://d.hatena.ne.jp/LaclefYoshi/20141221/1419164493&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;Abstract&lt;/h4&gt;&lt;br /&gt;
&lt;a href=&quot;http://druid.io/&quot;&gt;Druid&lt;/a&gt; is a database system. This is composed of a component for collecting time series data in realtime and a component for analyzing the datasets with queries from users.&lt;br /&gt;
&lt;br /&gt;
Druid says that itself is based on Dremel (VLDB2010) and PowerDrill (VLDB2012). In other words, Druid is like Cloudera Impala. But Druid doesn&#39;t ask for high-performance machines. According to &lt;a href=&quot;http://druid.io/docs/0.6.160/Production-Cluster-Configuration.html&quot;&gt;Druid Production Cluster Configuration&lt;/a&gt;, it seems to require some huge RAM especially.&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;References&lt;/h4&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://github.com/druid-io/druid&quot;&gt;druid-io/druid&lt;/a&gt;&lt;/li&gt;
&lt;ul&gt;&lt;li&gt;Main repository for Druid. This contains source codes of servers and examples for extensions.&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;&lt;a href=&quot;https://github.com/druid-io/druid-api&quot;&gt;druid-io/druid-api&lt;/a&gt;&lt;/li&gt;
&lt;ul&gt;&lt;li&gt;A repository for APF of Druid. This provides some information for creating extensions for parsing data, interpreting query and so on.&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;&lt;a href=&quot;https://github.com/metamx/java-util&quot;&gt;metamx/java-util&lt;/a&gt;&lt;/li&gt;
&lt;ul&gt;&lt;li&gt;A library repository for Druid. There is an interface for parser for some reason.&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;&lt;a href=&quot;http://dl.acm.org/citation.cfm?id=2588555.2595631&quot;&gt;Druid&lt;/a&gt;&lt;/li&gt;
&lt;ul&gt;&lt;li&gt;SIGMOD2014 Parper&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;&lt;a href=&quot;http://www.oscon.com/oscon2014/public/schedule/detail/34075&quot;&gt;Druid: Interactive Queries Meet Real-time Data: Open Source Convention - O&#39;Reilly OSCON, July 20 - 24, 2014 in Portland, OR&lt;/a&gt;&lt;/li&gt;
&lt;ul&gt;&lt;li&gt;OSCON2014 Slide&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/results?search_query=druid+real-time&quot;&gt;https://www.youtube.com/results?search_query=druid+real-time&lt;/a&gt;&lt;/li&gt;
&lt;ul&gt;&lt;li&gt;There are some presentation about Druid.&lt;/li&gt;
&lt;/ul&gt;&lt;/ul&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;Collecting time series data&lt;/h4&gt;&lt;br /&gt;
Currently, the stable version of Druid is 0.6.160. I use this version. For understanding the details, I refer &lt;a href=&quot;https://github.com/druid-io/druid/tree/druid-0.6.160&quot;&gt;druid-io/druid at druid-0.6.160&lt;/a&gt; and &lt;a href=&quot;https://github.com/druid-io/druid-api/tree/druid-api-0.2.14.1&quot;&gt;druid-io/druid-api at druid-api-0.2.14.1&lt;/a&gt;. The Druid codes is unstable as we know from commit history. Therefore, for increasing the life of my works I have shied away from writing codes for just Druid. I equip external systems for inability of default of Druid in place of creating extensions for Druid.&lt;br /&gt;
&lt;br /&gt;
For building my system, I use &lt;a href=&quot;https://www.vagrantup.com/&quot;&gt;Vagrant&lt;/a&gt; and &lt;a href=&quot;https://www.docker.com/&quot;&gt;Docker&lt;/a&gt;. I got a Vagrantfile from &lt;a href=&quot;https://github.com/coreos/coreos-vagrant&quot;&gt;coreos/coreos-vagrant&lt;/a&gt; and modified it for setting aside 4GB memory. &lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;diff --git a/Vagrantfile b/Vagrantfile
index 2a1572e..c877612 100644
--- a/Vagrantfile
+++ b/Vagrantfile
@@ -13,7 +13,7 @@ $num_instances = 1
 $update_channel = &quot;alpha&quot;
 $enable_serial_logging = false
 $vb_gui = false
-$vb_memory = 1024
+$vb_memory = 4096
 $vb_cpus = 1

 # Attempt to apply the deprecated environment variable NUM_INSTANCES to
&lt;/pre&gt;&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ vagrant up  # starting VM
$ vagrant ssh  # entering VM
CoreOS (alpha)
core@core-01 ~ $ mkdir zookeeper kafka druid clients
core@core-01 ~ $ which docker
/usr/bin/docker
&lt;/pre&gt;&lt;br /&gt;
The following of consoles are in VM.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h5&gt;Building dependent system&lt;/h5&gt;&lt;br /&gt;
&lt;br /&gt;
Druid is a distributed system composed of some machines. For their coordination, &lt;a href=&quot;http://druid.io/docs/0.6.160/ZooKeeper.html:title=Zookeeper&quot;&gt;Zookeeper&lt;/a&gt; is used. Dockerfile for launching Zookeeper is &lt;a href=&quot;https://github.com/laclefyoshi/druid_test/blob/master/zookeeper&quot;&gt;https://github.com/laclefyoshi/druid_test/blob/master/zookeeper&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ cd zookeeper
$ docker build -t laclefyoshi/zookeeper:1.0 .
$ docker run -d -p 2181:2181 --name zookeeper laclefyoshi/zookeeper:1.0
&lt;/pre&gt;&lt;br /&gt;
Druid caches time series data from &lt;a href=&quot;http://druid.io/docs/0.6.160/Firehose.html&quot;&gt;Firehose&lt;/a&gt;. We have some choices with extensions for Firehose. For example, Storm Trident State is used as Firehose in a book: &lt;a href=&quot;https://www.packtpub.com/big-data-and-business-intelligence/storm-blueprints-patterns-distributed-real-time-computation&quot;&gt;Storm Blueprints: Patterns for Distributed Real-time Computation&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
I use &lt;a href=&quot;http://kafka.apache.org/&quot;&gt;Apache Kafka&lt;/a&gt; (Version 0.8) as Firehose. I use foregoing Zookeeper for Kafka and Druid as shared system. Dockerfile for launching Kafka is &lt;a href=&quot;https://github.com/laclefyoshi/druid_test/tree/master/kafka&quot;&gt;https://github.com/laclefyoshi/druid_test/tree/master/kafka&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ cd kafka
$ docker build -t laclefyoshi/kafka:1.0 .
$ docker run -d -p 9092:9092 --link zookeeper:zookeeper --name kafka laclefyoshi/kafka:1.0
&lt;/pre&gt;&lt;br /&gt;
&lt;h5&gt;Building Druid&lt;/h5&gt;&lt;br /&gt;
More than one Druid service run on a Druid system. A Druid system defines the name, Firehose as a source of time series data, structure of the data and so on.&lt;br /&gt;
&lt;br /&gt;
There are two modes for building Druid system: standalone mode and cluster mode. In standalone mode, Druid system runs on one machine and runs one Druid service. In cluster mode, it runs on a number of machines assigned roles and runs multiple Druid services. I introduce the simple standalone mode. Dockerfile for launching a Druid system and service is &lt;a href=&quot;https://github.com/laclefyoshi/druid_test/tree/master/druid&quot;&gt;https://github.com/laclefyoshi/druid_test/tree/master/druid&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ cd druid
$ docker build -t laclefyoshi/druid:1.0 .
$ docker run -d -p 8083:8083 --link zookeeper:zookeeper --link kafka:kafka --name druid laclefyoshi/druid:1.0
&lt;/pre&gt;&lt;br /&gt;
Finally, I set up a container for sending time series data to Kafka. This is called Kafka Producer and sends the following data.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;{&quot;timestamp&quot;: &quot;2014-12-21T10:17:00&quot;, &quot;number&quot;: 7, &quot;word&quot;: &quot;fox&quot;}
&lt;/pre&gt;&lt;br /&gt;
&lt;code&gt;timestamp&lt;/code&gt; is a time and date of the data. &lt;code&gt;number&lt;/code&gt; is a random number. &lt;code&gt;word&lt;/code&gt; is an English word. Dockerfile for launching Kafka Producer is &lt;a href=&quot;https://github.com/laclefyoshi/druid_test/tree/master/clients&quot;&gt;https://github.com/laclefyoshi/druid_test/tree/master/clients&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ cd clients
$ docker build -t laclefyoshi/clients:1.0 .
$ docker run -d --link zookeeper:zookeeper --link kafka:kafka --name clients laclefyoshi/clients:1.0
&lt;/pre&gt;&lt;br /&gt;
Now, I have finished to building containers for using Druid.  &lt;code&gt;clients&lt;/code&gt; container send time series data to &lt;code&gt;kafka&lt;/code&gt; container. And &lt;code&gt;druid&lt;/code&gt; container catches and collects the data from &lt;code&gt;kafka&lt;/code&gt; container. &lt;code&gt;zookeeper&lt;/code&gt; container follows them.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ docker ps
CONTAINER ID        IMAGE                       COMMAND                CREATED              STATUS              PORTS                    NAMES
4021acc277c7        laclefyoshi/clients:1.0     &quot;bash send_data.sh&quot;    About a minute ago   Up About a minute                            clients
9280e328e97d        laclefyoshi/druid:1.0       &quot;bash ./start_druid_   9 minutes ago        Up 9 minutes        0.0.0.0:8083-&gt;8083/tcp   druid
9e17bab05cc2        laclefyoshi/kafka:1.0       &quot;bash ./kafka_create   11 minutes ago       Up 11 minutes       0.0.0.0:9092-&gt;9092/tcp   kafka
c0614de5dce0        laclefyoshi/zookeeper:1.0   &quot;./bin/zkServer.sh s   25 minutes ago       Up 25 minutes       0.0.0.0:2181-&gt;2181/tcp   zookeeper
&lt;/pre&gt;&lt;br /&gt;
&lt;h4&gt;Analyzing time series data using Druid&lt;/h4&gt;&lt;br /&gt;
After some minutes of building system, I post the following query to Druid with HTTP POST.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ cat query.json
{
  &quot;queryType&quot;:&quot;timeBoundary&quot;,
  &quot;dataSource&quot;:&quot;druid_test&quot;,
  &quot;intervals&quot;:[&quot;2014-12-01/2014-12-31&quot;]
}
$ curl -X &#39;POST&#39; -H &#39;Content-Type:application/json&#39; -d @query.json http://localhost:8083/druid/v2/?pretty
&lt;/pre&gt;&lt;br /&gt;
Then Druid replies the following response.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;[ {
  &quot;timestamp&quot; : &quot;2014-12-21T10:17:00.000Z&quot;,
  &quot;result&quot; : {
    &quot;minTime&quot; : &quot;2014-12-21T10:17:00.000Z&quot;,
    &quot;maxTime&quot; : &quot;2014-12-21T10:51:00.000Z&quot;
  }
} ]
&lt;/pre&gt;&lt;br /&gt;
This query is for identifying the time range of data for analysis on a Druid service: &lt;code&gt;druid_test&lt;/code&gt;. This name of the service is defined in &lt;a href=&quot;https://github.com/laclefyoshi/druid_test/blob/master/druid/runtime.properties#L8&quot;&gt;&lt;code&gt;druid.service&lt;/code&gt; in runtime.properties&lt;/a&gt; and the designation for timestamp field is defined in &lt;a href=&quot;https://github.com/laclefyoshi/druid_test/blob/master/druid/realtime.spec#L9&quot;&gt;the parser configuration in realtime.spec&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Next, I post a query for counting words in each 15 minutes in 30 minutes, so I get 2 results by 1 query. In addition, I get the sorting result in descending order of counts.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ cat query.json
{
  &quot;queryType&quot;: &quot;groupBy&quot;,
  &quot;dataSource&quot;: &quot;druid_test&quot;,
  &quot;granularity&quot;: &quot;fifteen_minute&quot;,
  &quot;dimensions&quot;: [&quot;word&quot;],
  &quot;limitSpec&quot;: {
     &quot;type&quot;: &quot;default&quot;,
     &quot;columns&quot;: [
       {&quot;dimension&quot;: &quot;count_word&quot;, &quot;direction&quot;: &quot;DESCENDING&quot;}
      ],
     &quot;limit&quot;: 10
  },
  &quot;aggregations&quot;: [
    {&quot;type&quot;: &quot;count&quot;, &quot;name&quot;: &quot;count_word&quot;}
  ],
  &quot;intervals&quot;: [&quot;2014-12-21T10:20/2014-12-21T10:50&quot;]
} 

$ time curl -X &#39;POST&#39; -H &#39;Content-Type:application/json&#39; -d @query.json http://localhost:8083/druid/v2/?pretty
[ {
  &quot;version&quot; : &quot;v1&quot;,
  &quot;timestamp&quot; : &quot;2014-12-21T10:15:00.000Z&quot;,
  &quot;event&quot; : {
    &quot;count_word&quot; : 4,
    &quot;word&quot; : &quot;lazy&quot;
  }
}, {
  &quot;version&quot; : &quot;v1&quot;,
  &quot;timestamp&quot; : &quot;2014-12-21T10:15:00.000Z&quot;,
  &quot;event&quot; : {
    &quot;count_word&quot; : 4,
    &quot;word&quot; : &quot;the&quot;
  }
}, {
  &quot;version&quot; : &quot;v1&quot;,
  &quot;timestamp&quot; : &quot;2014-12-21T10:15:00.000Z&quot;,
  &quot;event&quot; : {
    &quot;count_word&quot; : 3,
    &quot;word&quot; : &quot;over&quot;
  }
}, {
  &quot;version&quot; : &quot;v1&quot;,
  &quot;timestamp&quot; : &quot;2014-12-21T10:15:00.000Z&quot;,
  &quot;event&quot; : {
    &quot;count_word&quot; : 3,
    &quot;word&quot; : &quot;quick&quot;
  }
}, {
  &quot;version&quot; : &quot;v1&quot;,
  &quot;timestamp&quot; : &quot;2014-12-21T10:15:00.000Z&quot;,
  &quot;event&quot; : {
    &quot;count_word&quot; : 2,
    &quot;word&quot; : &quot;dog&quot;
  }
}, {
  &quot;version&quot; : &quot;v1&quot;,
  &quot;timestamp&quot; : &quot;2014-12-21T10:15:00.000Z&quot;,
  &quot;event&quot; : {
    &quot;count_word&quot; : 2,
    &quot;word&quot; : &quot;jumps&quot;
  }
}, {
  &quot;version&quot; : &quot;v1&quot;,
  &quot;timestamp&quot; : &quot;2014-12-21T10:15:00.000Z&quot;,
  &quot;event&quot; : {
    &quot;count_word&quot; : 1,
    &quot;word&quot; : &quot;fox&quot;
  }
}, {
  &quot;version&quot; : &quot;v1&quot;,
  &quot;timestamp&quot; : &quot;2014-12-21T10:30:00.000Z&quot;,
  &quot;event&quot; : {
    &quot;count_word&quot; : 6,
    &quot;word&quot; : &quot;brown&quot;
  }
}, {
  &quot;version&quot; : &quot;v1&quot;,
  &quot;timestamp&quot; : &quot;2014-12-21T10:30:00.000Z&quot;,
  &quot;event&quot; : {
    &quot;count_word&quot; : 6,
    &quot;word&quot; : &quot;quick&quot;
  }
}, {
  &quot;version&quot; : &quot;v1&quot;,
  &quot;timestamp&quot; : &quot;2014-12-21T10:30:00.000Z&quot;,
  &quot;event&quot; : {
    &quot;count_word&quot; : 4,
    &quot;word&quot; : &quot;fox&quot;
  }
} ]
real    0m0.035s
user    0m0.003s
sys     0m0.001s
&lt;/pre&gt;&lt;br /&gt;
The processing the query spends about 0.03 seconds in Druid. According to the results, &lt;code&gt;clients&lt;/code&gt; sends one or two data in a minute. Between 10:15 and 10:30, &quot;lazy&quot; and &quot;fox&quot; appear 4 times. Between 10:30 and 10:45, &quot;brown&quot; appears 6 times.&lt;br /&gt;
&lt;br /&gt;
This analysis is very simple counting data but suitable for practical use. For example, if the data is of Web servers, I can get the summary of logs based on IP addresses or User-Agents. For another example, if the data is of SSH servers, I can detect unauthorized invasion by counting the authentication failure.&lt;br /&gt;
&lt;br /&gt;
For more practical use, Druid can interpreting other query other than &lt;code&gt;groupBy&lt;/code&gt;. For example, there are &lt;code&gt;sum&lt;/code&gt; for getting sum of values of specific fields, &lt;code&gt;topN&lt;/code&gt; for getting ranking of counting, &lt;code&gt;filter&lt;/code&gt; for filtering the data based on values of specific fields and so on.&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;Footnote&lt;/h4&gt;&lt;br /&gt;
All system which I want to use as Firehose of Druid don&#39;t provide suitable formatted data for Druid. Therefore, in many cases, a system, for example &lt;a href=&quot;https://storm.apache.org/&quot;&gt;Apache Storm&lt;/a&gt;, is needed for reprocessing time series data between the sources of data and Firehose.&lt;br /&gt;
</content><link rel='replies' type='application/atom+xml' href='http://laclefyoshi.blogspot.com/feeds/6029480752196745817/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://laclefyoshi.blogspot.com/2014/12/interactive-time-series-data-analysis.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/6029480752196745817'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/6029480752196745817'/><link rel='alternate' type='text/html' href='http://laclefyoshi.blogspot.com/2014/12/interactive-time-series-data-analysis.html' title='Interactive time series data analysis using Apache Kafka and Druid'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/09934531596280495750</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4078805449160415851.post-90590849144670886</id><published>2014-01-26T15:21:00.001+09:00</published><updated>2014-01-26T15:24:27.273+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="chrome"/><title type='text'>text to speech in Google Chrome</title><content type='html'>&lt;br /&gt;
Google Chrome 33 beta provides &lt;a href=&quot;https://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html&quot;&gt;Web Speech API&lt;/a&gt;. I tried to use it on JavaScript console of Google Chrome.&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/laclefyoshi/8627514.js&quot;&gt;&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
Some voices are provided by Google Chrome and others are provided by the platform (in my case, Mac provides the voices).&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/laclefyoshi/8627542.js&quot;&gt;&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
The message is needed to bind a text, a voice and the language.&lt;br /&gt;
&lt;br /&gt;
An American speaks English.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;&gt; msg.text = &quot;JavaScript (JS) is a dynamic computer programming language.&quot;
&gt; msg.voice = voices[0]
&gt; msg.lang = voices[0].lang  # &quot;en-US&quot;

&gt; window.speechSynthesis.speak(msg)
&lt;/pre&gt;&lt;br /&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;//www.youtube.com/embed/HSogoqBsAEY&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;br /&gt;
A Japanese speaks English.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;&gt; msg.text = &quot;JavaScript (JS) is a dynamic computer programming language.&quot;
&gt; msg.voice = voices[7]
&gt; msg.lang = voices[7].lang  # &quot;ja-JP&quot;
&lt;/pre&gt;&lt;br /&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;//www.youtube.com/embed/CqoR-27ygyU&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;br /&gt;
A Chinese speaks English.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;&gt; msg.text = &quot;JavaScript (JS) is a dynamic computer programming language.&quot;
&gt; msg.voice = voices[9]
&gt; msg.lang = voices[9].lang  # &quot;zh-CN&quot;
&lt;/pre&gt;&lt;br /&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;//www.youtube.com/embed/Y4GTkC-whFI&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;br /&gt;
In this case, the text interpreted as Chinese &lt;a href=&quot;http://en.wikipedia.org/wiki/Pinyin&quot;&gt;pinyin&lt;/a&gt;. Maybe &lt;code&gt;lang&lt;/code&gt; attribute specifies how to interpret the text. But when &quot;en-US&quot; is specified as the &lt;code&gt;lang&lt;/code&gt;, the voice changes to an American&#39;s voice.&lt;br /&gt;
&lt;br /&gt;
A Japanese speaks Japanese.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;&gt; msg.text = &quot;JavaScript（ジャヴァスクリプト）とは、プログラミング言語のひとつである。&quot;
&gt; msg.voice = voices[7]
&gt; msg.lang = voices[7].lang
&lt;/pre&gt;&lt;br /&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;//www.youtube.com/embed/JdfCTx0y_ZY&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;br /&gt;
This case is failure, too. This speaks an &lt;b&gt;escaped&lt;/b&gt; Japanese text.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;&gt; escape(&quot;JavaScript（ジャヴァスクリプト）とは、プログラミング言語のひとつである。&quot;)
&quot;JavaScript%uFF08%u30B8%u30E3%u30F4%u30A1%u30B9%u30AF%u30EA%u30D7%u30C8%uFF09%u3068%u306F%u3001%u30D7%u30ED%u30B0%u30E9%u30DF%u30F3%u30B0%u8A00%u8A9E%u306E%u3072%u3068%u3064%u3067%u3042%u308B%u3002&quot;
&lt;/pre&gt;&lt;br /&gt;
There are some problems for practical use, but this API will be used for pushing information from Web to people&#39;s ears. I think that the Web increasingly resembles TV.&lt;br /&gt;
&lt;br /&gt;
Thanks.</content><link rel='replies' type='application/atom+xml' href='http://laclefyoshi.blogspot.com/feeds/90590849144670886/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://laclefyoshi.blogspot.com/2014/01/text-to-speech-in-google-chrome.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/90590849144670886'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/90590849144670886'/><link rel='alternate' type='text/html' href='http://laclefyoshi.blogspot.com/2014/01/text-to-speech-in-google-chrome.html' title='text to speech in Google Chrome'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/09934531596280495750</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4078805449160415851.post-1440931417904567061</id><published>2013-12-28T15:34:00.000+09:00</published><updated>2013-12-28T20:09:43.427+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="radio"/><title type='text'>software-defined radio with Gqrx on Mac</title><content type='html'>&lt;br /&gt;
&lt;a href=&quot;http://en.wikipedia.org/wiki/Software-defined_radio&quot;&gt;Software-defined radio (SDR)&lt;/a&gt; is an inexpensive hobby for people who are interested in radio intercept.&lt;br /&gt;
&lt;br /&gt;
I went to Akihabara last week and bought &lt;b&gt;DVB-T+DAB+FM RTL2832U+R820T&lt;/b&gt;. This device is normally a receiver for one-segment broadcasting but is known internationally as a SDR device. I wasted little time in receiving radio.&lt;br /&gt;
&lt;br /&gt;
I used &lt;a href=&quot;http://gqrx.dk/&quot;&gt;Gqrx&lt;/a&gt; for controlling my SDR device. I thought it was painful to build &lt;a href=&quot;http://sdr.osmocom.org/trac/wiki/rtl-sdr&quot;&gt;rtl-sdr&lt;/a&gt; and &lt;a href=&quot;http://gnuradio.org/redmine/projects/gnuradio/wiki&quot;&gt;GNU Radio&lt;/a&gt; and so on from scratch. Gqrx lacks documents, but I could smoothly understand how to use it. Simply stated, I just started the application, specified a frequency and adjusted the volume.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEir8i4jSS-0_wBBqkJ7jVUp0IeUitqZJCK0kPqRmEu38Z3SaxljazAdaPKa5Fb4EdlKxQzCfqaBHfVSPylPJoayKSLJgNsecij1fAzeEWhKLCXDkjZlwN42CN_U6J6sBeYvYsihx7e9Fo-f/s1600/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88+2013-12-28+14.49.11.png&quot; imageanchor=&quot;1&quot; &gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEir8i4jSS-0_wBBqkJ7jVUp0IeUitqZJCK0kPqRmEu38Z3SaxljazAdaPKa5Fb4EdlKxQzCfqaBHfVSPylPJoayKSLJgNsecij1fAzeEWhKLCXDkjZlwN42CN_U6J6sBeYvYsihx7e9Fo-f/s320/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88+2013-12-28+14.49.11.png&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
I&#39;m listening to fire radio for Tokyo. It appears that incidents large and small occur every 30 seconds.&lt;br /&gt;
&lt;br /&gt;
Thanks.</content><link rel='replies' type='application/atom+xml' href='http://laclefyoshi.blogspot.com/feeds/1440931417904567061/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://laclefyoshi.blogspot.com/2013/12/software-defined-radio-with-gqrx-on-mac.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/1440931417904567061'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/1440931417904567061'/><link rel='alternate' type='text/html' href='http://laclefyoshi.blogspot.com/2013/12/software-defined-radio-with-gqrx-on-mac.html' title='software-defined radio with Gqrx on Mac'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/09934531596280495750</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEir8i4jSS-0_wBBqkJ7jVUp0IeUitqZJCK0kPqRmEu38Z3SaxljazAdaPKa5Fb4EdlKxQzCfqaBHfVSPylPJoayKSLJgNsecij1fAzeEWhKLCXDkjZlwN42CN_U6J6sBeYvYsihx7e9Fo-f/s72-c/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88+2013-12-28+14.49.11.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4078805449160415851.post-9122150097969207867</id><published>2013-11-10T20:41:00.000+09:00</published><updated>2013-11-10T20:42:14.980+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="mac"/><title type='text'>updating SSD firmware version in Mac mini with USB flash drive</title><content type='html'>&lt;br /&gt;
&lt;br /&gt;
I bestirred myself and updated SSD firmware in my Mac.&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Mac: Mac mini (Mid 2011)&lt;/li&gt;
&lt;li&gt;OS: OS X Mavericks (10.9)&lt;/li&gt;
&lt;li&gt;SSD: PLEXTOR PX-128M5P&lt;/li&gt;
&lt;ul&gt;&lt;li&gt;Current Firmware version: 1.01&lt;/li&gt;
&lt;li&gt;New Firmware version: 1.05 (released 2013-05-09)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.plextoramericas.com/index.php/download?task=viewcategory&amp;catid=164&quot;&gt;URL&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/ul&gt;&lt;br /&gt;
The instructions for updating firmware is written based on using CD/DVD drive, but as you may know, Mac mini doesn&#39;t have a CD/DVD drive. I found the method for updating firmware with an USB flash drive.&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://discussions.apple.com/message/15917897#15917897&quot;&gt;Will new Crucial SSD work if i dont...: Apple Support Communities&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
I downloaded &lt;code&gt;PX-128M5Pro 1.05.iso&lt;/code&gt; from the official page and &lt;code&gt;rEFIt-Syslinux.dmg&lt;/code&gt; from above URL.&lt;br /&gt;
&lt;br /&gt;
I used the he following process.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ hdiutil attach rEFIt-Syslinux.dmg
/dev/disk4              FDisk_partition_scheme
/dev/disk4s1            DOS_FAT_32                      /Volumes/SYSLINUX
/dev/disk4s2            Apple_HFS                       /Volumes/rEFIt

$ diskutil list
/dev/disk0
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *128.0 GB   disk0
   1:                        EFI EFI                     209.7 MB   disk0s1
   2:                  Apple_HFS Macintosh SSD           127.2 GB   disk0s2
   3:                 Apple_Boot Recovery HD             650.0 MB   disk0s3
/dev/disk1
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *500.1 GB   disk1
   1:                        EFI EFI                     209.7 MB   disk1s1
   2:                  Apple_HFS Macintosh HD            499.2 GB   disk1s2
   3:                 Apple_Boot Recovery HD             650.0 MB   disk1s3
/dev/disk2
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *640.1 GB   disk2
   1:                        EFI EFI                     209.7 MB   disk2s1
   2:                  Apple_HFS HD-PCTU2                639.8 GB   disk2s2
/dev/disk3
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:                            NO NAME                  *2.1 GB     disk3
/dev/disk4
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *32.6 MB    disk4
   1:                 DOS_FAT_32 SYSLINUX                8.2 MB     disk4s1
   2:                  Apple_HFS rEFIt                   23.2 MB    disk4s2

$ diskutil unmountDisk /dev/disk3  # usb flash drive
Unmount of all volumes on disk3 was successful
$ diskutil unmountDisk /dev/disk4  # rEFIt-Syslinux.dmg
Unmount of all volumes on disk3 was successful

$ sudo dd if=/dev/disk4 of=/dev/disk3 bs=1m
31+1 records in
31+1 records out
32636928 bytes transferred in 13.280089 secs (2457584 bytes/sec)

$ diskutil eject /dev/disk3
$ diskutil eject /dev/disk4


## unplug and plug USB flash drive for remounting it
## /Volumes/SYSLINUX and /Volumes/rEFIt appear


$ hdiutil mount PX-128M5Pro\ 1.05.iso
/dev/disk3                                              /Volumes/SSD FLASH_

$ ls -l /Volumes/SSD\ FLASH_/isolinux/
total 5848
-r-xr-xr-x  1 yoshiyasu  staff   139B 11 20  2010 BOOTMSG.TXT*
-r-xr-xr-x  1 yoshiyasu  staff   2.8M  5  6  2013 BTDSK.IMG*
-r-xr-xr-x  1 yoshiyasu  staff   576B  2 23  2003 F1_HELP.TXT*
-r-xr-xr-x  1 yoshiyasu  staff   506B  8 21  2003 F2_LICEN.TXT*
-r-xr-xr-x  1 yoshiyasu  staff   1.4K  5 10  2003 F_ABOUT.TXT*
-r-xr-xr-x  1 yoshiyasu  staff   591B  6 12  2004 ISOLINUX.CFG*
-r-xr-xr-x  1 yoshiyasu  staff    14K 12 21  2008 isolinux.bin*
-r-xr-xr-x  1 yoshiyasu  staff    20K  9 25  2008 memdisk*

$ cd /Volumes/SYSLINUX
$ ls -l
total 3224
-rwxrwxrwx  1 yoshiyasu  staff    65K  5  3  2007 COMMAND.COM*
-rwxrwxrwx  1 yoshiyasu  staff    15K  3  3  2011 ldlinux.sys*
-rwxrwxrwx  1 yoshiyasu  staff    54K  3  3  2011 menu.c32*
-rwxrwxrwx@ 1 yoshiyasu  staff   237B  4  4  2011 syslinux.cfg*
-rwxrwxrwx  1 yoshiyasu  staff   1.4M  3  3  2011 ubninit*
-rwxrwxrwx  1 yoshiyasu  staff    25K  3  3  2011 ubnkern*
$ rm syslinux.cfg
$ cp /Volumes/SSD\ FLASH_/isolinux/* .
$ mv ISOLINUX.CFG syslinux.cfg


## don&#39;t eject USB flash drive but eject other external drives
## push the option key and reboot

## select the boot drive &quot;rEFIt&quot; -&gt; &quot;Boot Legacy OS from SYSLINUX&quot;
&lt;/pre&gt;&lt;br /&gt;
I followed instructions, and the updating was finished in a few minutes.&lt;br /&gt;
&lt;br /&gt;
I&#39;m not sure the effect but certainly the SSD firmware revision shows 1.05 on the System Profiler.&lt;br /&gt;
&lt;br /&gt;
Thanks.&lt;br /&gt;
</content><link rel='replies' type='application/atom+xml' href='http://laclefyoshi.blogspot.com/feeds/9122150097969207867/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://laclefyoshi.blogspot.com/2013/11/updating-ssd-firmware-version-in-mac.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/9122150097969207867'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/9122150097969207867'/><link rel='alternate' type='text/html' href='http://laclefyoshi.blogspot.com/2013/11/updating-ssd-firmware-version-in-mac.html' title='updating SSD firmware version in Mac mini with USB flash drive'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/09934531596280495750</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4078805449160415851.post-4805803290220260998</id><published>2013-10-05T15:59:00.001+09:00</published><updated>2013-10-05T15:59:23.134+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="emacs"/><category scheme="http://www.blogger.com/atom/ns#" term="scala"/><title type='text'>flymake and scalastyle</title><content type='html'>&lt;br /&gt;
I&#39;ve used &lt;a href=&quot;http://checkstyle.sourceforge.net/&quot;&gt;checkstyle&lt;/a&gt; when coding Java. Because I have a greater opportunity to write Scala recently, I found &lt;a href=&quot;http://www.scalastyle.org/&quot;&gt;scalastyle&lt;/a&gt;: checkstyle for Scala.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://laclefyoshi.blogspot.jp/2012/04/flymake-and-checkstyle.html&quot;&gt;Checkstyle collaborates easily with emacs because the outputs are suitable for flymake&lt;/a&gt;, but scalastyle doesn&#39;t.&lt;br /&gt;
&lt;br /&gt;
The following is an example of default outputs of scalastyle. If flymake gets this outputs, nothing happens.&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/laclefyoshi/6837484.js&quot;&gt;&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyFq1dOTOe17k-E41eWUv6zeIX_KJeoc5B7-h8pNUke8AjBdPO3x_dPqFAtoQSwUHZLxms80FpzXNRKUfUCqfxgp1V79yFS8NMCsimKn-sZ0TCv1u_UI6ca3r_RzKZd4BmAlf19w_gSE2A/s1600/URLHandle.scala_-_emacs_SAEKI-no-Mac-mini.local.png&quot; imageanchor=&quot;1&quot; &gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyFq1dOTOe17k-E41eWUv6zeIX_KJeoc5B7-h8pNUke8AjBdPO3x_dPqFAtoQSwUHZLxms80FpzXNRKUfUCqfxgp1V79yFS8NMCsimKn-sZ0TCv1u_UI6ca3r_RzKZd4BmAlf19w_gSE2A/s320/URLHandle.scala_-_emacs_SAEKI-no-Mac-mini.local.png&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
That&#39;s why I wrote a script for converting outputs of scalastyle into a flymake-friendly format. I want to use the script on Linux and Mac, so I used &lt;code&gt;python&lt;/code&gt; instead of &lt;code&gt;sed&lt;/code&gt; (I know that &lt;code&gt;sed&lt;/code&gt; on Mac is not the same as it on Linux)&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/laclefyoshi/6837545.js&quot;&gt;&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
The following is an example of reformed outputs of &lt;code&gt;scalastyle.sh&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/laclefyoshi/6837610.js&quot;&gt;&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
I stored the script into &lt;code&gt;~/.local/bin/scalastyle.sh&lt;/code&gt; and edited &lt;code&gt;.emacs&lt;/code&gt; as follows.&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/laclefyoshi/6837562.js&quot;&gt;&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMeIDMG2UvZbl3yORdSNfnj7LtTFy_-_7uCgQBL3ALo5nBcJ4N2cVuhvXaXS21a0-USA5482s0UeKCwtSVrJewYR2pEXL_W-UtjOpch0IlHZtS3v7fn8H3OF8f-CoUXCPjlBwMh3guG9iJ/s1600/URLHandle.scala_-_emacs_SAEKI-no-Mac-mini.local+2.png&quot; imageanchor=&quot;1&quot; &gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMeIDMG2UvZbl3yORdSNfnj7LtTFy_-_7uCgQBL3ALo5nBcJ4N2cVuhvXaXS21a0-USA5482s0UeKCwtSVrJewYR2pEXL_W-UtjOpch0IlHZtS3v7fn8H3OF8f-CoUXCPjlBwMh3guG9iJ/s320/URLHandle.scala_-_emacs_SAEKI-no-Mac-mini.local+2.png&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
That&#39;s a good time to migrate from emacs to IDE (the candidate is IntelliJ for now).&lt;br /&gt;
&lt;br /&gt;
Thanks.&lt;br /&gt;
</content><link rel='replies' type='application/atom+xml' href='http://laclefyoshi.blogspot.com/feeds/4805803290220260998/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://laclefyoshi.blogspot.com/2013/10/flymake-and-scalastyle.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/4805803290220260998'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/4805803290220260998'/><link rel='alternate' type='text/html' href='http://laclefyoshi.blogspot.com/2013/10/flymake-and-scalastyle.html' title='flymake and scalastyle'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/09934531596280495750</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyFq1dOTOe17k-E41eWUv6zeIX_KJeoc5B7-h8pNUke8AjBdPO3x_dPqFAtoQSwUHZLxms80FpzXNRKUfUCqfxgp1V79yFS8NMCsimKn-sZ0TCv1u_UI6ca3r_RzKZd4BmAlf19w_gSE2A/s72-c/URLHandle.scala_-_emacs_SAEKI-no-Mac-mini.local.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4078805449160415851.post-7701049380684042506</id><published>2013-09-22T14:29:00.000+09:00</published><updated>2013-09-22T14:29:44.924+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="hadoop"/><category scheme="http://www.blogger.com/atom/ns#" term="scala"/><title type='text'>scalding with Oozie</title><content type='html'>&lt;br /&gt;
&lt;a href=&quot;https://github.com/twitter/scalding&quot;&gt;scalding&lt;/a&gt; is a great library for Hadoop. Previously, I wrote many UDFs for &lt;a href=&quot;http://pig.apache.org/&quot;&gt;Pig&lt;/a&gt;, but it seemed like such a drag to write Java codes because those UDFs were almost halfway. I could write codes for data processing easy thanks to scalding and Scala.&lt;br /&gt;
&lt;br /&gt;
And now, I use &lt;a href=&quot;http://oozie.apache.org/&quot;&gt;Oozie&lt;/a&gt; for scheduling Hadoop applications. For using scalding applications in Oozie, I need to use &lt;a href=&quot;http://archive.cloudera.com/cdh4/cdh/4/oozie/WorkflowFunctionalSpec.html#a3.2.7_Java_Action&quot;&gt;Java Action&lt;/a&gt;. The configuration for Java Action of Oozie is not complicated. I share a practical templates of workflow.xml and configuration.xml.&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/laclefyoshi/6656860.js&quot;&gt;&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
The following is the directory structure for this workflow.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;.
├── lib
│   └── app.jar
└── workflow.xml
&lt;/pre&gt;&lt;br /&gt;
A note of caution is &lt;code&gt;file&lt;/code&gt; element in workflow.xml. The first part of value delimited &quot;#&quot; specifies a hdfs path for a jar file and the second part decides a alias name.  The alias name is used in values of &lt;code&gt;arg&lt;code&gt; and so on.&lt;br /&gt;
&lt;br /&gt;
Scalding provides the matrix library. I&#39;m not unable to use it effectively, but the library really seems to useful because it can cover some tasks with &lt;a href=&quot;http://www.numpy.org/&quot;&gt;numpy&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Thanks.&lt;br /&gt;
</content><link rel='replies' type='application/atom+xml' href='http://laclefyoshi.blogspot.com/feeds/7701049380684042506/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://laclefyoshi.blogspot.com/2013/09/scalding-with-oozie.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/7701049380684042506'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/7701049380684042506'/><link rel='alternate' type='text/html' href='http://laclefyoshi.blogspot.com/2013/09/scalding-with-oozie.html' title='scalding with Oozie'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/09934531596280495750</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4078805449160415851.post-4493495782691283353</id><published>2013-09-16T15:47:00.000+09:00</published><updated>2013-09-16T15:47:00.242+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="hadoop"/><title type='text'>installing CDH into secured servers with Cloudera Manager</title><content type='html'>&lt;br /&gt;
I needed to install CDH4 (Cloudera&#39;s Distribution Including Apache Hadoop) into secured (closed) servers which can access only the internal network and a gateway server but can&#39;t access the external networks as well as the Internet.&lt;br /&gt;
&lt;br /&gt;
Because I wanted to choose the most comfortable way to install and manage CDH, I decided to use Cloudera Manager (Standard Version). Therefore I could follow &lt;a href=&quot;http://www.cloudera.com/content/cloudera-content/cloudera-docs/CM4Ent/latest/Cloudera-Manager-Installation-Guide/cmig_install_path_A.html&quot;&gt;the Cloudera&#39;s guide / Installation Path A - Automated Installation by Cloudera Manager&lt;/a&gt; but I needed to do some works for using Cloudera Manager in the local network.&lt;br /&gt;
&lt;br /&gt;
There are 4 servers in the secured network. Each server runs CentOS 6.4 (64bit). In what follows &lt;code&gt;gateway01&lt;/code&gt; is a gateway server which can access the Internet and the secured network and &lt;code&gt;secured001&lt;/code&gt; is a server in the secured network.&lt;br /&gt;
&lt;br /&gt;
Firstly, I needed to build a local repository for yum (&lt;a href=&quot;http://www.cloudera.com/content/cloudera-content/cloudera-docs/CM4Ent/latest/Cloudera-Manager-Installation-Guide/cmig_create_local_repo.html&quot;&gt;the Cloudera&#39;s guide&lt;/a&gt;).&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;(gateway01)$ mkdir cloudera
(gateway01)$ ls cloudera
cloudera-manager-installer.bin  # need to register for getting it: https://www.cloudera.com/content/support/en/downloads.html
(gateway01)$ mkdir cloudera/repo
(gateway01)$ mkdir cloudera/parcel
(gateway01)$ cd cloudera/repo
(gateway01)$ wget http://archive.cloudera.com/cm4/redhat/6/x86_64/cm/4/RPMS/x86_64/cloudera-manager-agent-4.7.1-1.cm471.p0.125.el6.x86_64.rpm
(gateway01)$ wget http://archive.cloudera.com/cm4/redhat/6/x86_64/cm/4/RPMS/x86_64/cloudera-manager-daemons-4.7.1-1.cm471.p0.125.el6.x86_64.rpm
(gateway01)$ wget http://archive.cloudera.com/cm4/redhat/6/x86_64/cm/4/RPMS/x86_64/cloudera-manager-server-4.7.1-1.cm471.p0.125.el6.x86_64.rpm
(gateway01)$ wget http://archive.cloudera.com/cm4/redhat/6/x86_64/cm/4/RPMS/x86_64/cloudera-manager-server-db-4.7.1-1.cm471.p0.125.el6.x86_64.rpm
(gateway01)$ wget http://archive.cloudera.com/cm4/redhat/6/x86_64/cm/4/RPMS/x86_64/enterprise-debuginfo-4.7.1-1.cm471.p0.125.el6.x86_64.rpm
(gateway01)$ wget http://archive.cloudera.com/cm4/redhat/6/x86_64/cm/4/RPMS/x86_64/jdk-6u31-linux-amd64.rpm
(gateway01)$ cd ../parcel
(gateway01)$ wget http://archive.cloudera.com/cdh4/parcels/latest/CDH-4.4.0-1.cdh4.4.0.p0.39-el6.parcel
(gateway01)$ wget http://archive.cloudera.com/cdh4/parcels/latest/manifest.json
(gateway01)$ cd ../../
(gateway01)$ scp -r cloudera secured001:./
(gateway01)$ ssh secured001

(secured001)$ cd ~/cloudera/repo/
(secured001)$ createrepo .
(secured001)$ cd ~/
(secured001)$ sudo cat &amp;lt;&amp;lt;EOF &amp;gt; /etc/yum.repos.d/local.repo
[myrepo]
name=myrepo
baseurl=http://secured001:8081/cloudera/repo
enabled=1
gpgcheck=0
(secured001)$ python -m SimpleHTTPServer 8081 &amp;
(secured001)$ sudo ./cloudera/cloudera-manager-installer.bin --skip_repo_package=1
&lt;/pre&gt;&lt;br /&gt;
&lt;code&gt;--skip_repo_package=1&lt;/code&gt; in the last line means that Cloudera Manager don&#39;t access the Cloudera repository on the Internet (archive.cloudera.com) and access only the local repository.&lt;br /&gt;
&lt;br /&gt;
Secondly, I accessed &lt;code&gt;http://secured001:7180/&lt;/code&gt; after finishing the installation process of Cloudera Manager and followed the guide. It&#39;s not hard to install the components of CDH through the web browser as long as I keep in mind that I need to indicate the local Parcel repository (&lt;code&gt;http://secured001:8081/cloudera/parcel&lt;/code&gt;) here.&lt;br /&gt;
&lt;br /&gt;
Just for the record, I failed to install &lt;a href=&quot;http://www.cloudera.com/content/cloudera/en/products/cdh/impala.html&quot;&gt;Impala&lt;/a&gt; because of missing &lt;code&gt;&quot;impala&quot;&lt;/code&gt; user. So I installed it separately.&lt;br /&gt;
&lt;br /&gt;
Thanks.&lt;br /&gt;
</content><link rel='replies' type='application/atom+xml' href='http://laclefyoshi.blogspot.com/feeds/4493495782691283353/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://laclefyoshi.blogspot.com/2013/09/installing-cdh-into-secured-servers.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/4493495782691283353'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/4493495782691283353'/><link rel='alternate' type='text/html' href='http://laclefyoshi.blogspot.com/2013/09/installing-cdh-into-secured-servers.html' title='installing CDH into secured servers with Cloudera Manager'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/09934531596280495750</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4078805449160415851.post-7060638436090539844</id><published>2013-05-25T16:34:00.002+09:00</published><updated>2014-12-31T17:49:50.308+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="java"/><category scheme="http://www.blogger.com/atom/ns#" term="kafka"/><category scheme="http://www.blogger.com/atom/ns#" term="scala"/><title type='text'>Hosebird and Kafka: Scala version conflict</title><content type='html'>&lt;br /&gt;
I tried to integrate &lt;a href=&quot;https://github.com/twitter/hbc&quot;&gt;Hosebird (an official client library for Twitter Firehose)&lt;/a&gt; (version 1.4.0) and &lt;a href=&quot;http://kafka.apache.org/&quot;&gt;Kafka (A message queuing server)&lt;/a&gt; (0.7.0), but got the below error at runtime.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ mvn clean package
$ java -cp target/hosebird_kafka-1.0-SNAPSHOT.jar hosebird_kafka.App a b c d
Exception in thread &quot;hosebird-client-io-thread-0&quot; java.lang.NoSuchMethodError: scala.runtime.RichInt.until(I)Lscala/collection/immutable/Range;
        at com.twitter.joauth.UrlEncoder$.apply(UrlEncoder.scala:42)
        at com.twitter.joauth.UrlEncoder.apply(UrlEncoder.scala)
        at com.twitter.hbc.core.endpoint.BaseEndpoint.addQueryParameter(BaseEndpoint.java:98)
        at com.twitter.hbc.core.endpoint.DefaultStreamingEndpoint.addDefaultParams(DefaultStreamingEndpoint.java:48)
        at com.twitter.hbc.core.endpoint.BaseEndpoint.getURI(BaseEndpoint.java:57)
        at com.twitter.hbc.core.HttpConstants.constructRequest(HttpConstants.java:71)
        at com.twitter.hbc.httpclient.ClientBase.run(ClientBase.java:134)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
        at java.lang.Thread.run(Thread.java:680)
&lt;/pre&gt;&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/laclefyoshi/5648266.js&quot;&gt;&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/laclefyoshi/5648271.js&quot;&gt;&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
The reason for the &lt;code&gt;NoSuchMethodError&lt;/code&gt; is version conflicts of Scala.&lt;br /&gt;
&lt;br /&gt;
Hosebird (&lt;code&gt;hbc-core-1.4.0&lt;/code&gt;) depends on &lt;a href=&quot;https://github.com/twitter/joauth&quot;&gt;joauth-3.2.3&lt;/a&gt;, &lt;code&gt;joauth-3.2.3&lt;/code&gt; depends on  and Kafka (&lt;code&gt;kafka-0.7.0-incubating&lt;/code&gt;) depends on &lt;code&gt;scala-library-2.8.0&lt;code&gt;.&lt;br /&gt;
&lt;br /&gt;
Because maven adopts the smaller version when multiple libraries depends on a same library with different versions, this time &lt;code&gt;scala-library-2.8.0&lt;code&gt; is adopted as this project dependency. In the result, &lt;code&gt;joauth-3.2.3&lt;/code&gt; can&#39;t use a method of &lt;code&gt;scala-library-2.9.2&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
All versions of &lt;code&gt;joauth&lt;/code&gt; in &lt;a href=&quot;http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.twitter%22%20AND%20a%3A%22joauth%22&quot;&gt;Maven Central Repository&lt;/a&gt; depend on &lt;code&gt;scala-library-2.9.2&lt;/code&gt;. But I found old &lt;code&gt;joauth&lt;/code&gt; in &lt;a href=&quot;http://typesafe.artifactoryonline.com/typesafe/repo/com/twitter/joauth/&quot;&gt;here directory&lt;/a&gt;. Apparently &lt;a href=&quot;http://typesafe.artifactoryonline.com/typesafe/repo/com/twitter/joauth/2.0.1/&quot;&gt;joauth-2.0.1&lt;/a&gt; depends on &lt;code&gt;scala-library-2.8.1&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
After I installed &lt;code&gt;joauth-2.0.1&lt;/code&gt; in local repository, I added the dependency. I could create and run jar normally.&lt;br /&gt;
&lt;br /&gt;
Thanks.&lt;br /&gt;
</content><link rel='replies' type='application/atom+xml' href='http://laclefyoshi.blogspot.com/feeds/7060638436090539844/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://laclefyoshi.blogspot.com/2013/05/hosebird-and-kafka-scala-version.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/7060638436090539844'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/7060638436090539844'/><link rel='alternate' type='text/html' href='http://laclefyoshi.blogspot.com/2013/05/hosebird-and-kafka-scala-version.html' title='Hosebird and Kafka: Scala version conflict'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/09934531596280495750</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4078805449160415851.post-3278396967496422060</id><published>2013-03-31T15:18:00.000+09:00</published><updated>2013-04-01T21:24:44.247+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="arduino"/><category scheme="http://www.blogger.com/atom/ns#" term="avr"/><title type='text'>serjtag patches for avrdude-5.11.1</title><content type='html'>&lt;br /&gt;
I needed to update firmware of &lt;a href=&quot;http://www.aitendo.com/product/3174&quot;&gt;AVR-USBasp-B&lt;/a&gt; (&lt;a href=&quot;http://www.fischl.de/usbasp/&quot;&gt;original USBasp&#39;s page&lt;/a&gt;) which I bought at Akihabara&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;avrdude: Warning: Found USB device &quot;USBasp&quot; with old VID/PID! Please update firmware of USBasp!
avrdude: warning: cannot set sck period. please check for usbasp firmware update.
&lt;/pre&gt;&lt;br /&gt;
But I don&#39;t have another writer (Arduino runs in another project, so I don&#39;t use &lt;a href=&quot;http://laclefyoshi.blogspot.com/2011/01/note-of-caution-for-arduino-isp.html&quot;&gt;Arduino-ISP&lt;/a&gt;). I tried to use FTDI BitBang AVR-Writer with FT232R.&lt;br /&gt;
&lt;br /&gt;
I needed to apply patches to &lt;a href=&quot;http://www.nongnu.org/avrdude/&quot;&gt;avrdude&lt;/a&gt; for using FTDI BitBang AVR-Writer but &lt;a href=&quot;http://suz-avr.sblo.jp/category/780472-1.html&quot;&gt;the original avrdude-serjtag patches&lt;/a&gt; don&#39;t support avrdude-5.11.1 (latest version). So I edited the patches and created github repository: &lt;a href=&quot;https://github.com/laclefyoshi/avrdude-serjtag&quot;&gt;laclefyoshi/avrdude-serjtag · GitHub&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
After building and installing avrdude (read README.md), I succeeded to update  firmware of AVR-USBasp-B.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlJXXarZ2SwASmOflLst65A_FB5b6bp-Xl8uPKcB-rsJ7mXL9Uir7j65ut23cdaX6AqF96GPoz7__nadUH6EcCzOItN1RJqHvC3UMm3__8-2IKJGKY6q2AZpa_aYXn4gL6sDyqgQVTopgU/s1600/IMG_0173.JPG&quot; imageanchor=&quot;1&quot; &gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlJXXarZ2SwASmOflLst65A_FB5b6bp-Xl8uPKcB-rsJ7mXL9Uir7j65ut23cdaX6AqF96GPoz7__nadUH6EcCzOItN1RJqHvC3UMm3__8-2IKJGKY6q2AZpa_aYXn4gL6sDyqgQVTopgU/s320/IMG_0173.JPG&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ sudo kextunload /System/Library/Extensions/FTDIUSBSerialDriver.kext


$ avrdude -C /opt/usr/avrdude/etc/avrdude.conf -c diecimila -P ft0 -p m8 -v

avrdude: Version 5.11.1, compiled on Mar 30 2013 at 17:18:59
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2009 Joerg Wunsch

         System wide configuration file is &quot;/opt/usr/avrdude/etc/avrdude.conf&quot;
         User configuration file is &quot;/Volumes/Macintosh HD/Users/yoshiyasu/.avrduderc&quot;
         User configuration file does not exist or is not a regular file, skipping

         Using Port                    : ft0
         Using Programmer              : diecimila
avrdude: BitBang OK
avrdude: pin assign miso 3 sck 5 mosi 6 reset 7
avrdude: drain OK
         AVR Part                      : ATMEGA8
         Chip Erase delay              : 10000 us
         PAGEL                         : PD7
         BS2                           : PC2
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom         4    20   128    0 no        512    4      0  9000  9000 0xff 0xff
           flash         33    10    64    0 yes      8192   64    128  4500  4500 0xff 0x00
           lfuse          0     0     0    0 no          1    0      0  2000  2000 0x00 0x00
           hfuse          0     0     0    0 no          1    0      0  2000  2000 0x00 0x00
           lock           0     0     0    0 no          1    0      0  2000  2000 0x00 0x00
           calibration    0     0     0    0 no          4    0      0     0     0 0x00 0x00
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

         Programmer Type : ft245r
         Description     : FT232R Synchronous BitBang

 ft245r:  bitclk 230400 -&gt; ft baud 115200
avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9307
avrdude: safemode: lfuse reads as EF
avrdude: safemode: hfuse reads as D9

avrdude: safemode: lfuse reads as EF
avrdude: safemode: hfuse reads as D9
avrdude: safemode: Fuses OK

avrdude done.  Thank you.


$ avrdude -C /opt/usr/avrdude/etc/avrdude.conf -c diecimila -P ft0 -p m8 -U flash:w:usbasp.atmega8.2011-05-28.hex:i
avrdude: BitBang OK
avrdude: pin assign miso 3 sck 5 mosi 6 reset 7
avrdude: drain OK

 ft245r:  bitclk 230400 -&gt; ft baud 115200
avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9307
avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed
         To disable this feature, specify the -D option.
avrdude: erasing chip
 ft245r:  bitclk 230400 -&gt; ft baud 115200
avrdude: reading input file &quot;usbasp.atmega8.2011-05-28.hex&quot;
avrdude: writing flash (4700 bytes):

Writing | ################################################## | 100% 2.25s



avrdude: 4700 bytes of flash written
avrdude: verifying flash memory against usbasp.atmega8.2011-05-28.hex:
avrdude: load data flash data from input file usbasp.atmega8.2011-05-28.hex:
avrdude: input file usbasp.atmega8.2011-05-28.hex contains 4700 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 1.29s



avrdude: verifying ...
avrdude: 4700 bytes of flash verified

avrdude: safemode: Fuses OK

avrdude done.  Thank you.

$ avrdude -C /opt/usr/avrdude/etc/avrdude.conf -c diecimila -P ft0 -p m8 -U hfuse:w:0xC9:m  # read http://www.fischl.de/usbasp/Readme.txt

$ sudo kextload /System/Library/Extensions/FTDIUSBSerialDriver.kext
&lt;/pre&gt;&lt;br /&gt;
I read Atmega8 with USBasp.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ avrdude -C /opt/usr/avrdude/etc/avrdude.conf -c usbasp -P ft0 -p m8  -v

avrdude: Version 5.11.1, compiled on Mar 30 2013 at 17:18:59
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2009 Joerg Wunsch

         System wide configuration file is &quot;/opt/usr/avrdude/etc/avrdude.conf&quot;
         User configuration file is &quot;/Volumes/Macintosh HD/Users/yoshiyasu/.avrduderc&quot;
         User configuration file does not exist or is not a regular file, skipping

         Using Port                    : ft0
         Using Programmer              : usbasp
         AVR Part                      : ATMEGA8
         Chip Erase delay              : 10000 us
         PAGEL                         : PD7
         BS2                           : PC2
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom         4    20   128    0 no        512    4      0  9000  9000 0xff 0xff
           flash         33    10    64    0 yes      8192   64    128  4500  4500 0xff 0x00
           lfuse          0     0     0    0 no          1    0      0  2000  2000 0x00 0x00
           hfuse          0     0     0    0 no          1    0      0  2000  2000 0x00 0x00
           lock           0     0     0    0 no          1    0      0  2000  2000 0x00 0x00
           calibration    0     0     0    0 no          4    0      0     0     0 0x00 0x00
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

         Programmer Type : usbasp
         Description     : USBasp, http://www.fischl.de/usbasp/

avrdude: auto set sck period (because given equals null)
avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9307
avrdude: safemode: lfuse reads as DF
avrdude: safemode: hfuse reads as CA

avrdude: safemode: lfuse reads as DF
avrdude: safemode: hfuse reads as CA
avrdude: safemode: Fuses OK

avrdude done.  Thank you.
&lt;/pre&gt;&lt;br /&gt;
USBasp is small and good programmer. Recently, sometimes, I want to take time away from Arduino and use  AVR microcontrollers.&lt;br /&gt;
&lt;br /&gt;
Thanks.</content><link rel='replies' type='application/atom+xml' href='http://laclefyoshi.blogspot.com/feeds/3278396967496422060/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://laclefyoshi.blogspot.com/2013/03/serjtag-patches-for-avrdude-5111.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/3278396967496422060'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/3278396967496422060'/><link rel='alternate' type='text/html' href='http://laclefyoshi.blogspot.com/2013/03/serjtag-patches-for-avrdude-5111.html' title='serjtag patches for avrdude-5.11.1'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/09934531596280495750</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlJXXarZ2SwASmOflLst65A_FB5b6bp-Xl8uPKcB-rsJ7mXL9Uir7j65ut23cdaX6AqF96GPoz7__nadUH6EcCzOItN1RJqHvC3UMm3__8-2IKJGKY6q2AZpa_aYXn4gL6sDyqgQVTopgU/s72-c/IMG_0173.JPG" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4078805449160415851.post-9166033628940275466</id><published>2013-02-09T22:56:00.003+09:00</published><updated>2013-02-09T22:57:44.833+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="arduino"/><category scheme="http://www.blogger.com/atom/ns#" term="camera"/><title type='text'>controlling digital camera with Arduino and light</title><content type='html'>&lt;br /&gt;
I bought a digital camera: &lt;a href=&quot;http://en.wikipedia.org/wiki/Canon_EOS_650D&quot;&gt;EOS Kiss X6i&lt;/a&gt; last year.&lt;br /&gt;
&lt;br /&gt;
This camera has an interface for remote controller. On examination, I knew this plug is 2.5mm stereo mini plug and has very simple mechanism. So I connected the camera and Arduino.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://www.doc-diy.net/photo/eos_wired_remote/&quot;&gt;This page&lt;/a&gt; provides me with useful information.&lt;br /&gt;
&lt;br /&gt;
Arduino read Analog-Pin 1 (connecting with a light sensor input). If the value of Analog-Pin 1 exceeds a certain value, Arduino outputs Digital-Pin 2 (focus) and 3 (shutter).&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTVNtC3zYou_FVIXmNO1yc16f8Zzgs_EWXCGGmM60mb1iJ4FU8PsFcPwiTHwVhWBLI3_Q9gU6aZ2SmKH0Fah8kG-rm67Qkmjm77KNj2j7OeXmuD-768AbhwPH8JZpTeXLVyWm62SyDGm9g/s1600/camera_with_arduino.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left:1em; margin-right:1em&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;400&quot; width=&quot;380&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTVNtC3zYou_FVIXmNO1yc16f8Zzgs_EWXCGGmM60mb1iJ4FU8PsFcPwiTHwVhWBLI3_Q9gU6aZ2SmKH0Fah8kG-rm67Qkmjm77KNj2j7OeXmuD-768AbhwPH8JZpTeXLVyWm62SyDGm9g/s400/camera_with_arduino.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/laclefyoshi/4745322.js&quot;&gt;&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
I think that taking pictures continuously is to place excessive strain on camera, so I set 30 seconds of delay.&lt;br /&gt;
&lt;br /&gt;
&lt;iframe width=&quot;420&quot; height=&quot;315&quot; src=&quot;http://www.youtube.com/embed/UJOT296v9TM&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;br /&gt;
The light sensor can replace other sensors or triggers. For example, Ethernet shield can be connected. I enjoy the extension of my camera&#39;s release.&lt;br /&gt;
&lt;br /&gt;
Thanks.&lt;br /&gt;
</content><link rel='replies' type='application/atom+xml' href='http://laclefyoshi.blogspot.com/feeds/9166033628940275466/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://laclefyoshi.blogspot.com/2013/02/controlling-digital-camera-with-arduino.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/9166033628940275466'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/9166033628940275466'/><link rel='alternate' type='text/html' href='http://laclefyoshi.blogspot.com/2013/02/controlling-digital-camera-with-arduino.html' title='controlling digital camera with Arduino and light'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/09934531596280495750</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTVNtC3zYou_FVIXmNO1yc16f8Zzgs_EWXCGGmM60mb1iJ4FU8PsFcPwiTHwVhWBLI3_Q9gU6aZ2SmKH0Fah8kG-rm67Qkmjm77KNj2j7OeXmuD-768AbhwPH8JZpTeXLVyWm62SyDGm9g/s72-c/camera_with_arduino.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4078805449160415851.post-6700877722808487182</id><published>2012-10-21T09:06:00.002+09:00</published><updated>2012-10-21T09:06:23.318+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="emacs"/><title type='text'>using Source Code Pro in emacs</title><content type='html'>&lt;br /&gt;
I used &lt;a href=&quot;http://www.ms-studio.com/FontSales/anonymouspro.html&quot;&gt;Anonymous Pro&lt;/a&gt; in emacs previously. But I saw &lt;a href=&quot;http://blogs.adobe.com/typblography/2012/09/source-code-pro.html&quot;&gt;Adobe&#39;s blog&lt;/a&gt; and I was interested in this new font.&lt;br /&gt;
&lt;br /&gt;
Hiragino Kaku Gothic Pro is a font included Mac OS X for Japanese.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJaFWPZu3gs_HsnjpLkRH5RKSMFI8om-1HGhBKUB9iBallW-bsAP-Z_mRCxYEjlS9r4h9S5Y_FYFt1FVTvE4uLp5PYXYo3qBF4dbH9Q8CZr58zE-GQ_ukcUwCs8Ny95QtHwxXmFiAz9zEo/s1600/pep8.py+-+emacs%2540saeki-no-Mac-mini.local-1.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left:1em; margin-right:1em&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;375&quot; width=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJaFWPZu3gs_HsnjpLkRH5RKSMFI8om-1HGhBKUB9iBallW-bsAP-Z_mRCxYEjlS9r4h9S5Y_FYFt1FVTvE4uLp5PYXYo3qBF4dbH9Q8CZr58zE-GQ_ukcUwCs8Ny95QtHwxXmFiAz9zEo/s400/pep8.py+-+emacs%2540saeki-no-Mac-mini.local-1.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/3925286.js&quot;&gt; &lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
There is a very well-recognized distinction between &quot;0&quot;, &quot;O&quot;, &quot;1&quot;, &quot;I&quot; and &quot;l&quot; certainly.&lt;br /&gt;
&lt;br /&gt;
Thanks.&lt;br /&gt;
</content><link rel='replies' type='application/atom+xml' href='http://laclefyoshi.blogspot.com/feeds/6700877722808487182/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://laclefyoshi.blogspot.com/2012/10/using-source-code-pro-in-emacs.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/6700877722808487182'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/6700877722808487182'/><link rel='alternate' type='text/html' href='http://laclefyoshi.blogspot.com/2012/10/using-source-code-pro-in-emacs.html' title='using Source Code Pro in emacs'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/09934531596280495750</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJaFWPZu3gs_HsnjpLkRH5RKSMFI8om-1HGhBKUB9iBallW-bsAP-Z_mRCxYEjlS9r4h9S5Y_FYFt1FVTvE4uLp5PYXYo3qBF4dbH9Q8CZr58zE-GQ_ukcUwCs8Ny95QtHwxXmFiAz9zEo/s72-c/pep8.py+-+emacs%2540saeki-no-Mac-mini.local-1.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4078805449160415851.post-3144118604049119668</id><published>2012-10-13T15:21:00.000+09:00</published><updated>2012-10-13T15:21:28.064+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="chrome"/><category scheme="http://www.blogger.com/atom/ns#" term="xml"/><title type='text'>Google Chrome supports MathML</title><content type='html'>&lt;br /&gt;
According to &lt;a href=&quot;https://plus.google.com/+GoogleChromeDevelopers/posts/gUsetzmoLJM&quot;&gt;this post&lt;/a&gt;, Google Chrome (Canary build) supprts &lt;a href=&quot;http://en.wikipedia.org/wiki/MathML&quot;&gt;MathML&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
The version of Google Chrome Canary build is 24.0.1293.0 currently. The version of Google Chrome Stable build is 22.0.1229.94.&lt;br /&gt;
&lt;br /&gt;
Firstly, I wrote MathML file with &lt;a href=&quot;http://www.libreoffice.org/features/math/&quot;&gt;LibreOffice formula editor&lt;/a&gt; and saved as a MathML 1.01 file (&lt;code&gt;math.mml&lt;/code&gt;). I think that MathML is not much better format by hand than LaTeX.&lt;br /&gt;
&lt;br /&gt;
The gist is &lt;a href=&quot;https://gist.github.com/3883443&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhY-KYHRurH0vfXryeVlUC6W-vVy65rAXk1BBIN06hpZ2pOxMziD5iHBfcyD04cM9v_cfAr3KWLx6fVc7o2UPfTWF1QRV7s89y4Z0YcU1k_G47XWccM1AmBL29-JliAako1nf5f4XdePgnf/s1600/libremath.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left:1em; margin-right:1em&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;304&quot; width=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhY-KYHRurH0vfXryeVlUC6W-vVy65rAXk1BBIN06hpZ2pOxMziD5iHBfcyD04cM9v_cfAr3KWLx6fVc7o2UPfTWF1QRV7s89y4Z0YcU1k_G47XWccM1AmBL29-JliAako1nf5f4XdePgnf/s400/libremath.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
When I opened this mml file with Google Chrome Stable, it was shown as below. Chrome knew the file is XML document but couldn&#39;t read MathML.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpeEl0xMQJ3uoj6pk702oOLPl0VZZ6WbiBwAhyphenhyphenhGnm09bB9htYggkb9I8jBkB5rVuoYe-donG2WCfsAXwFxLF8_dwrPpYRaIjTqOSVutPwe4QfxfT6-U32LPmx9Trh76HVyX_vWnadHXIn/s1600/math.mml.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left:1em; margin-right:1em&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;299&quot; width=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpeEl0xMQJ3uoj6pk702oOLPl0VZZ6WbiBwAhyphenhyphenhGnm09bB9htYggkb9I8jBkB5rVuoYe-donG2WCfsAXwFxLF8_dwrPpYRaIjTqOSVutPwe4QfxfT6-U32LPmx9Trh76HVyX_vWnadHXIn/s400/math.mml.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
When I opened it with Google Chrome Canary, it was shown as below. Chrome could read MathML approximately right.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfv9Y3T4DWzWPeCa3zjkf3cxx3Hzvc4owBKiCURkk1-A6rOrshLBkqW0ejA7mL0bsGqb-3ALftkv6o43TVt2xRlRtKyqyNKUgdBAoSbvF6yCQMGyyeN8yDUvN8NhE60hlNqT9DHamG6gec/s1600/math.mml-1.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left:1em; margin-right:1em&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;209&quot; width=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfv9Y3T4DWzWPeCa3zjkf3cxx3Hzvc4owBKiCURkk1-A6rOrshLBkqW0ejA7mL0bsGqb-3ALftkv6o43TVt2xRlRtKyqyNKUgdBAoSbvF6yCQMGyyeN8yDUvN8NhE60hlNqT9DHamG6gec/s400/math.mml-1.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
MathML can be written in XHTML document. After this, the web browser can interpret numeral information and mathematical formula. For example when I open a web page providing statistical information, the web browser will be able to show me the richer information.&lt;br /&gt;
&lt;br /&gt;
Thanks.&lt;br /&gt;
</content><link rel='replies' type='application/atom+xml' href='http://laclefyoshi.blogspot.com/feeds/3144118604049119668/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://laclefyoshi.blogspot.com/2012/10/google-chrome-supports-mathml.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/3144118604049119668'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/3144118604049119668'/><link rel='alternate' type='text/html' href='http://laclefyoshi.blogspot.com/2012/10/google-chrome-supports-mathml.html' title='Google Chrome supports MathML'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/09934531596280495750</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhY-KYHRurH0vfXryeVlUC6W-vVy65rAXk1BBIN06hpZ2pOxMziD5iHBfcyD04cM9v_cfAr3KWLx6fVc7o2UPfTWF1QRV7s89y4Z0YcU1k_G47XWccM1AmBL29-JliAako1nf5f4XdePgnf/s72-c/libremath.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4078805449160415851.post-6018874967812056397</id><published>2012-09-08T21:52:00.000+09:00</published><updated>2012-09-08T21:52:45.301+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C"/><category scheme="http://www.blogger.com/atom/ns#" term="C++"/><title type='text'>measuring the similarity between two images</title><content type='html'>&lt;br /&gt;
When I searched methods for measuring the similarity between two images, I found two implementations: &lt;a href=&quot;http://www.pureftpd.org/project/libpuzzle&quot;&gt;libpuzzle&lt;/a&gt; and &lt;a href=&quot;http://www.phash.org/&quot;&gt;pHash&lt;/a&gt;. &lt;code&gt;libpuzzle&lt;/code&gt; specializes in the comparison of images. &lt;code&gt;pHash&lt;/code&gt; supports the comparison of images, audios and movies.&lt;br /&gt;
&lt;br /&gt;
These can be installed with homebrew. I compared these libraries.&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;libpuzzle&lt;/h4&gt;&lt;br /&gt;
The license of &lt;code&gt;libpuzzle&lt;/code&gt; is BSD license. It depends on &lt;a href=&quot;http://www.boutell.com/gd/&quot;&gt;gd library&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ brew info libpuzzle
libpuzzle: stable 0.11
http://libpuzzle.pureftpd.org/project/libpuzzle
Depends on: gd
Not installed
https://github.com/mxcl/homebrew/commits/master/Library/Formula/libpuzzle.rb

$ brew install libpuzzle
Warning: It appears you have MacPorts or Fink installed.
Software installed with other package managers causes known problems for
Homebrew. If a formula fails to build, uninstall MacPorts/Fink and try again.
==&gt; Installing libpuzzle dependency: libpng
==&gt; Downloading http://downloads.sf.net/project/libpng/libpng15/1.5.12/libpng-1.5.12.tar.gz
######################################################################## 100.0%
==&gt; ./configure --prefix=/opt/homebrew/Cellar/libpng/1.5.12
==&gt; make install
/opt/homebrew/Cellar/libpng/1.5.12: 14 files, 1.0M, built in 15 seconds
==&gt; Installing libpuzzle
==&gt; Downloading http://download.pureftpd.org/pub/pure-ftpd/misc/libpuzzle/releases/libpuzzle-0.11.tar.bz2
######################################################################## 100.0%
==&gt; ./configure --prefix=/opt/homebrew/Cellar/libpuzzle/0.11
==&gt; make install
/opt/homebrew/Cellar/libpuzzle/0.11: 12 files, 104K, built in 17 seconds
&lt;/pre&gt;&lt;br /&gt;
I wrote a simple C code using &lt;code&gt;libpuzzle&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/3674068.js&quot;&gt; &lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ gcc -L/opt/homebrew/lib -I/opt/homebrew/include -lpuzzle test_libpuzzle.c
$ otool -L ./a.out 
./a.out:
        /opt/homebrew/lib/libpuzzle.1.dylib (compatibility version 2.0.0, current version 2.0.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 169.3.0)

$ ./a.out tokyo_skytree.jpg tokyo_skytree.jpg
distance: 0
&lt;/pre&gt;&lt;br /&gt;
I prepared five pictures from &lt;a href=&quot;http://www.flickr.com/photos/laclef_yoshiyasu/7709915558/sizes/m/in/photostream/&quot;&gt;flickr&lt;/a&gt; for testing. &lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;code&gt;tokyo_skytree.jpg&lt;/code&gt;: original (960 × 1280)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tokyo_skytree_500.jpg&lt;/code&gt;: reduced (375 × 500)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tokyo_skytree_75.jpg&lt;/code&gt;: reduced and cut (75 × 75)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tokyo_skytree_thumbnail.jpg&lt;/code&gt;: reduced (75 × 100)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;wrong_image.jpg&lt;/code&gt;: non-related (640 × 960)&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ time for i in `/bin/ls *.jpg`; do  for j in `/bin/ls *.jpg`; do  echo -ne &quot;$i &lt;-&gt; $j\t:\t&quot;; ./a.out $i $j; done; done

tokyo_skytree.jpg &lt;-&gt; tokyo_skytree.jpg :       distance: 0
tokyo_skytree.jpg &lt;-&gt; tokyo_skytree_500.jpg     :       distance: 0.0981159
tokyo_skytree.jpg &lt;-&gt; tokyo_skytree_75.jpg      :       distance: 0.549193
tokyo_skytree.jpg &lt;-&gt; tokyo_skytree_thumbnail.jpg       :       distance: 0.290368
tokyo_skytree.jpg &lt;-&gt; wrong_image.jpg   :       distance: 0.710145
tokyo_skytree_500.jpg &lt;-&gt; tokyo_skytree.jpg     :       distance: 0.0981159
tokyo_skytree_500.jpg &lt;-&gt; tokyo_skytree_500.jpg :       distance: 0
tokyo_skytree_500.jpg &lt;-&gt; tokyo_skytree_75.jpg  :       distance: 0.547736
tokyo_skytree_500.jpg &lt;-&gt; tokyo_skytree_thumbnail.jpg   :       distance: 0.272873
tokyo_skytree_500.jpg &lt;-&gt; wrong_image.jpg       :       distance: 0.715105
tokyo_skytree_75.jpg &lt;-&gt; tokyo_skytree.jpg      :       distance: 0.549193
tokyo_skytree_75.jpg &lt;-&gt; tokyo_skytree_500.jpg  :       distance: 0.547736
tokyo_skytree_75.jpg &lt;-&gt; tokyo_skytree_75.jpg   :       distance: 0
tokyo_skytree_75.jpg &lt;-&gt; tokyo_skytree_thumbnail.jpg    :       distance: 0.56704
tokyo_skytree_75.jpg &lt;-&gt; wrong_image.jpg        :       distance: 0.716492
tokyo_skytree_thumbnail.jpg &lt;-&gt; tokyo_skytree.jpg       :       distance: 0.290368
tokyo_skytree_thumbnail.jpg &lt;-&gt; tokyo_skytree_500.jpg   :       distance: 0.272873
tokyo_skytree_thumbnail.jpg &lt;-&gt; tokyo_skytree_75.jpg    :       distance: 0.56704
tokyo_skytree_thumbnail.jpg &lt;-&gt; tokyo_skytree_thumbnail.jpg     :       distance: 0
tokyo_skytree_thumbnail.jpg &lt;-&gt; wrong_image.jpg :       distance: 0.756318
wrong_image.jpg &lt;-&gt; tokyo_skytree.jpg   :       distance: 0.710145
wrong_image.jpg &lt;-&gt; tokyo_skytree_500.jpg       :       distance: 0.715105
wrong_image.jpg &lt;-&gt; tokyo_skytree_75.jpg        :       distance: 0.716492
wrong_image.jpg &lt;-&gt; tokyo_skytree_thumbnail.jpg :       distance: 0.756318
wrong_image.jpg &lt;-&gt; wrong_image.jpg     :       distance: 0

real    0m1.118s
user    0m0.963s
sys     0m0.100s
&lt;/pre&gt;&lt;br /&gt;
&lt;table border=&quot;1&quot;&gt;  &lt;tr&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      &lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      orig&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      500&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      75&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      thumbnail&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      wrong&lt;br /&gt;
    &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      orig&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      0&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      0.0981159&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      0.549193&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      0.290368&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      0.710145&lt;br /&gt;
    &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      500&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      0.0981159&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      0&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      0.547736&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      0.272873&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      0.715105&lt;br /&gt;
    &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      75&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      0.549193&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      0.547736&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      0&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      0.56704&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      0.716492&lt;br /&gt;
    &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      thumbnail&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      0.290368&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      0.272873&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      0.56704&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      0&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      0.756318&lt;br /&gt;
    &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      wrong&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      0.710145&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      0.715105&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      0.716492&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      0.756318&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      0&lt;br /&gt;
    &lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;&lt;br /&gt;
If the two images are similar, the distance approaches 0 (if these are different, the distance approaches 1). When the different images are compared, it appears that the distance is more than 0.7.&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;phash&lt;/h4&gt;&lt;br /&gt;
The license of &lt;code&gt;pHash&lt;/code&gt; is GPLv3. It depends on &lt;a href=&quot;http://cimg.sourceforge.net/&quot;&gt;CImg&lt;/a&gt; for processing images.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ brew info phash
phash: stable 0.9.4
http://www.phash.org/
Depends on: cimg, ffmpeg, libsndfile, libsamplerate, mpg123
Not installed
https://github.com/mxcl/homebrew/commits/master/Library/Formula/phash.rb
==&gt; Options
--disable-audio-hash
        Disable audio hash
--disable-video-hash
        Disable video hash
--disable-image-hash
        Disable image hash

$ brew install phash --disable-audio-hash --disable-video-hash
Warning: It appears you have MacPorts or Fink installed.
Software installed with other package managers causes known problems for
Homebrew. If a formula fails to build, uninstall MacPorts/Fink and try again.
==&gt; Installing phash dependency: cimg
==&gt; Downloading http://downloads.sourceforge.net/cimg/CImg-1.5.0.zip
######################################################################## 100.0%
/opt/homebrew/Cellar/cimg/1.5.0: 425 files, 31M, built in 6 seconds
==&gt; Installing phash
==&gt; Downloading http://www.phash.org/releases/pHash-0.9.4.tar.gz
######################################################################## 100.0%
==&gt; Patching
patching file src/cimgffmpeg.cpp
==&gt; ./configure --prefix=/opt/homebrew/Cellar/phash/0.9.4 --enable-shared --disable-video-hash --disable-audio-hash
==&gt; make install
/opt/homebrew/Cellar/phash/0.9.4: 10 files, 900K, built in 47 seconds
&lt;/pre&gt;&lt;br /&gt;
I wrote a simple C++ code using &lt;code&gt;pHash&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/3674378.js&quot;&gt; &lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ g++ -L/opt/homebrew/lib -I/opt/homebrew/include -lpHash test_phash.cpp
$ otool -L a.out 
a.out:
        /opt/homebrew/lib/libpHash.0.dylib (compatibility version 1.0.0, current version 1.0.0)
        /usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 56.0.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 169.3.0)

$ ./a.out tokyo_skytree.jpg tokyo_skytree.jpg
distance: 0
&lt;/pre&gt;&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ time for i in `/bin/ls *.jpg`; do  for j in `/bin/ls *.jpg`; do  echo -ne &quot;$i &lt;-&gt; $j\t:\t&quot;; ./a.out $i $j; done; done

tokyo_skytree.jpg &lt;-&gt; tokyo_skytree.jpg :       distance: 0
tokyo_skytree.jpg &lt;-&gt; tokyo_skytree_500.jpg     :       distance: 8
tokyo_skytree.jpg &lt;-&gt; tokyo_skytree_75.jpg      :       distance: 22
tokyo_skytree.jpg &lt;-&gt; tokyo_skytree_thumbnail.jpg       :       distance: 8
tokyo_skytree.jpg &lt;-&gt; wrong_image.jpg   :       distance: 30
tokyo_skytree_500.jpg &lt;-&gt; tokyo_skytree.jpg     :       distance: 8
tokyo_skytree_500.jpg &lt;-&gt; tokyo_skytree_500.jpg :       distance: 0
tokyo_skytree_500.jpg &lt;-&gt; tokyo_skytree_75.jpg  :       distance: 20
tokyo_skytree_500.jpg &lt;-&gt; tokyo_skytree_thumbnail.jpg   :       distance: 2
tokyo_skytree_500.jpg &lt;-&gt; wrong_image.jpg       :       distance: 30
tokyo_skytree_75.jpg &lt;-&gt; tokyo_skytree.jpg      :       distance: 22
tokyo_skytree_75.jpg &lt;-&gt; tokyo_skytree_500.jpg  :       distance: 20
tokyo_skytree_75.jpg &lt;-&gt; tokyo_skytree_75.jpg   :       distance: 0
tokyo_skytree_75.jpg &lt;-&gt; tokyo_skytree_thumbnail.jpg    :       distance: 20
tokyo_skytree_75.jpg &lt;-&gt; wrong_image.jpg        :       distance: 32
tokyo_skytree_thumbnail.jpg &lt;-&gt; tokyo_skytree.jpg       :       distance: 8
tokyo_skytree_thumbnail.jpg &lt;-&gt; tokyo_skytree_500.jpg   :       distance: 2
tokyo_skytree_thumbnail.jpg &lt;-&gt; tokyo_skytree_75.jpg    :       distance: 20
tokyo_skytree_thumbnail.jpg &lt;-&gt; tokyo_skytree_thumbnail.jpg     :       distance: 0
tokyo_skytree_thumbnail.jpg &lt;-&gt; wrong_image.jpg :       distance: 32
wrong_image.jpg &lt;-&gt; tokyo_skytree.jpg   :       distance: 30
wrong_image.jpg &lt;-&gt; tokyo_skytree_500.jpg       :       distance: 30
wrong_image.jpg &lt;-&gt; tokyo_skytree_75.jpg        :       distance: 32
wrong_image.jpg &lt;-&gt; tokyo_skytree_thumbnail.jpg :       distance: 32
wrong_image.jpg &lt;-&gt; wrong_image.jpg     :       distance: 0

real    0m3.215s
user    0m3.007s
sys     0m0.173s
&lt;/pre&gt;&lt;br /&gt;
&lt;table border=&quot;1&quot;&gt;  &lt;tr&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      &lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      orig&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      500&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      75&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      thumbnail&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      wrong&lt;br /&gt;
    &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      orig&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      0&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      8&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      22&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      8&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      30&lt;br /&gt;
    &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      500&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      8 &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      0 &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      20 &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      2 &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      30 &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;
    &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      75 &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      22 &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      20 &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      0 &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      20 &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      32 &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;
    &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      thumbnail&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      8 &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      2 &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      20 &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      0 &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      32 &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;
    &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      wrong&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      30 &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      30 &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      32 &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      32 &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;
    &lt;/td&gt;
    &lt;td align=&quot;left&quot; valign=&quot;top&quot;&gt;&lt;br /&gt;
      0 &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;
    &lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;&lt;br /&gt;
If the two images are similar, the distance approaches 0 (if these are different, the distance is large number). When the different images are compared, it appears that the distance is more than 30.&lt;br /&gt;
&lt;br /&gt;
The result of &lt;code&gt;libpuzzle&lt;/code&gt; and &lt;code&gt;pHash&lt;/code&gt; are similar. But the processing time of &lt;code&gt;pHash&lt;/code&gt; takes 3 times longer than &lt;code&gt;libpuzzle&lt;/code&gt;. I will use &lt;code&gt;libpuzzle&lt;/code&gt; for my task.&lt;br /&gt;
&lt;br /&gt;
Thanks.&lt;br /&gt;
</content><link rel='replies' type='application/atom+xml' href='http://laclefyoshi.blogspot.com/feeds/6018874967812056397/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://laclefyoshi.blogspot.com/2012/09/measuring-similarity-between-two-images.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/6018874967812056397'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/6018874967812056397'/><link rel='alternate' type='text/html' href='http://laclefyoshi.blogspot.com/2012/09/measuring-similarity-between-two-images.html' title='measuring the similarity between two images'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/09934531596280495750</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4078805449160415851.post-3682493277898003845</id><published>2012-06-16T17:20:00.001+09:00</published><updated>2012-06-16T17:20:10.535+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="python"/><title type='text'>getting unused port number</title><content type='html'>&lt;br /&gt;
A simple way to get unused port number on local machine is creating a socket.&lt;br /&gt;
&lt;br /&gt;
I wrote a Python code.&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/2940414.js&quot;&gt; &lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
But in Jython, this behavior is a bit different.&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/2940449.js&quot;&gt; &lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
I think that the behavior of Python is correct.&lt;br /&gt;
&lt;br /&gt;
Thanks.&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://laclefyoshi.blogspot.com/feeds/3682493277898003845/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://laclefyoshi.blogspot.com/2012/06/getting-unused-port-number.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/3682493277898003845'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/3682493277898003845'/><link rel='alternate' type='text/html' href='http://laclefyoshi.blogspot.com/2012/06/getting-unused-port-number.html' title='getting unused port number'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/09934531596280495750</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4078805449160415851.post-2545372689160429712</id><published>2012-06-01T23:15:00.000+09:00</published><updated>2012-06-01T23:15:13.989+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="security"/><title type='text'>verifying keys with openssl</title><content type='html'>&lt;br /&gt;
For verifying that a private key and a public key are right combination, we can use Modules field of the keys.&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://stackoverflow.com/questions/274560/how-do-you-test-a-public-private-keypair&quot;&gt;encryption - How do you test a public/private keypair? - Stack Overflow&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
I got &lt;a href=&quot;http://www.reddit.com/r/netsec/comments/u26pv/yahoo_included_their_cert_private_key_inside_the/&quot;&gt;a private key of Yahoo! from Yahoo! Axis&lt;/a&gt;. And the Axis extension for Google Chrome includes &lt;a href=&quot;http://code.google.com/chrome/extensions/crx.html&quot;&gt;a public key field&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
I checked the two keys were right combination.&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/2792392.js&quot;&gt; &lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ python check_keys.py 
warning [YAxis_Chrome_v1_0_20120520.crx]:  306 extra bytes at beginning or within zipfile
  (attempting to process anyway)
Public key modulus:   D609E9C990D38EFADFB21AFBD227EDBAFCFE4C2E6A9ECE84B0A95DF9914E93DC832B7A70BF07FFE1D29317544EE57B6F249E740707919C364340FFD05F1EB2E2A5C321D8447BFBC4D18FA97C5E6ABB24AF3D60F0C37E46D2C820522EE2BE1ECB0D528B7A2A9C9309EC1E542A06BCFAFF2A3239C0F739F8C54E7BD9C5B52BEA65
Private key modulus:  D609E9C990D38EFADFB21AFBD227EDBAFCFE4C2E6A9ECE84B0A95DF9914E93DC832B7A70BF07FFE1D29317544EE57B6F249E740707919C364340FFD05F1EB2E2A5C321D8447BFBC4D18FA97C5E6ABB24AF3D60F0C37E46D2C820522EE2BE1ECB0D528B7A2A9C9309EC1E542A06BCFAFF2A3239C0F739F8C54E7BD9C5B52BEA65
match!
&lt;/pre&gt;&lt;br /&gt;
Unfortunately (?), the keys are right. Thus, we can create certified extensions as Yahoo!.&lt;br /&gt;
&lt;br /&gt;
It seems that the Axis development team uses ant for building the extension. Because the sources and product were in same location, an incident like this occurred. There may not be a person with much knowledge about Google Chrome extensions in the team.&lt;br /&gt;
&lt;br /&gt;
Thanks.&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://laclefyoshi.blogspot.com/feeds/2545372689160429712/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://laclefyoshi.blogspot.com/2012/06/verifying-keys-with-openssl.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/2545372689160429712'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/2545372689160429712'/><link rel='alternate' type='text/html' href='http://laclefyoshi.blogspot.com/2012/06/verifying-keys-with-openssl.html' title='verifying keys with openssl'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/09934531596280495750</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4078805449160415851.post-8029861403514375632</id><published>2012-05-20T15:40:00.000+09:00</published><updated>2012-05-20T15:40:45.546+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="chrome"/><category scheme="http://www.blogger.com/atom/ns#" term="javascript"/><title type='text'>Using socket API with Google Chrome Canary build</title><content type='html'>&lt;br /&gt;
I knew that &lt;a href=&quot;https://tools.google.com/dlpage/chromesxs&quot;&gt;Google Chrome Canary build&lt;/a&gt; supports &lt;code&gt;chrome.experimental.socket&lt;/code&gt; API.&lt;br /&gt;
&lt;br /&gt;
I searched &lt;a href=&quot;http://blog.alexmaccaw.com/chrome-tcp-udp&quot;&gt;some sample codes on the Web&lt;/a&gt;, but these can&#39;t run on the current version. I don&#39;t know whether these codes will be right on the future version. First of all, I wrote executable codes on the current version according to &lt;a href=&quot;http://code.google.com/chrome/extensions/experimental.socket.html&quot;&gt;documents&lt;/a&gt; and &lt;a href=&quot;http://src.chromium.org/viewvc/chrome/trunk/src/chrome/test/data/extensions/api_test/socket/api/&quot;&gt;test codes&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://github.com/laclefyoshi/chrome_socket_sample&quot;&gt;laclefyoshi/chrome_socket_sample&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
This extension is a UDP socket client with &lt;code&gt;chrome.experimental.socket&lt;/code&gt; API. I checked this on Google Chrome canary 21.0.1137.1 canary and 21.0.1143.0 canary for Mac. We can send string messages to a given UDP server. &lt;code&gt;udpserver.py&lt;/code&gt; is a simple UDP server written in Python.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9Tl_XJw1EQkslrP9-HOabtuNoDeYps3Ud17io1_r3Bpaq6p17WmTRP3JxVGpXPh0Lb6ce7qTY0rYs1BPujr_44Sc6XRb4pScxNoMjTSmJTPEvFd9Z-2jG2GQj4pZ3zCa59XhSs7st52Ao/s1600/Google+Chrome.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left:1em; margin-right:1em&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;226&quot; width=&quot;165&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9Tl_XJw1EQkslrP9-HOabtuNoDeYps3Ud17io1_r3Bpaq6p17WmTRP3JxVGpXPh0Lb6ce7qTY0rYs1BPujr_44Sc6XRb4pScxNoMjTSmJTPEvFd9Z-2jG2GQj4pZ3zCa59XhSs7st52Ao/s400/Google+Chrome.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
When the &lt;code&gt;send&lt;/code&gt; button pushes, the below function calls.&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/2710304.js&quot;&gt; &lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
In the document, the type of second argument of &lt;code&gt;chrome.experimental.socket.write(..)&lt;/code&gt; is String. But actually, it is ArrayBuffer.&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;udpserver.py&lt;/code&gt; displays the client info and the sent message.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ python udpserver.py
127.0.0.1:49623 wrote: Hello!
&lt;/pre&gt;&lt;br /&gt;
And the logs are left on the JavaScript console.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEho7gXdaqBI1xId-HcbzSqbGm9Q7ofpJ5FVyhUMTvbnr6DN39APuMqpgItlywC_M9-yWA7kOL53TFQ1RlOD4eO3LF-thrH6yDcAF0BS7z6T0K4iBIdK3ghJ1BACniegf_bvdMQ-ZJHsSF1L/s1600/Developer+Tools+-+chrome-extension___ojaejemdegbdocongadnghoghilgjplo_background.html.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left:1em; margin-right:1em&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;95&quot; width=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEho7gXdaqBI1xId-HcbzSqbGm9Q7ofpJ5FVyhUMTvbnr6DN39APuMqpgItlywC_M9-yWA7kOL53TFQ1RlOD4eO3LF-thrH6yDcAF0BS7z6T0K4iBIdK3ghJ1BACniegf_bvdMQ-ZJHsSF1L/s400/Developer+Tools+-+chrome-extension___ojaejemdegbdocongadnghoghilgjplo_background.html.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
We can use socket API directly with Developer tools.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;&amp;gt; udp_socket_writer(&quot;127.0.0.1&quot;, 9998, &quot;Hello!&quot;)
undefined
  ▼Object
    bytesWritten: 6

&amp;gt; udp_socket_writer(&quot;127.0.0.1&quot;, 9998, &quot;こんにちは、ソケット&quot;)  // multibyte string is OK, too
undefined
  ▼Object
    bytesWritten: 30
&lt;/pre&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCO93pni3p98xHRtneG_zb7ugupcvVikCI9D-yPoMxkgtR0UQC22u9t1VVpOq2BXxyS-yugLR08MIN9WC1yH4lLR_rBivxd9QXYCybx2NFF-P_Jz5-Fpdo8VTacNVaiWrRoiffa-xwOcbx/s1600/1.+screen+%2528screen%2529.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left:1em; margin-right:1em&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;50&quot; width=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCO93pni3p98xHRtneG_zb7ugupcvVikCI9D-yPoMxkgtR0UQC22u9t1VVpOq2BXxyS-yugLR08MIN9WC1yH4lLR_rBivxd9QXYCybx2NFF-P_Jz5-Fpdo8VTacNVaiWrRoiffa-xwOcbx/s400/1.+screen+%2528screen%2529.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
I haven&#39;t yet checked server mode and TCP connection. When the socket API becomes stable, I want to make IRC client running on Google Chrome. P2P communication between Google Chromes  isn&#39;t a dream.&lt;br /&gt;
&lt;br /&gt;
Thanks.&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://laclefyoshi.blogspot.com/feeds/8029861403514375632/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://laclefyoshi.blogspot.com/2012/05/using-socket-api-with-google-chrome.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/8029861403514375632'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/8029861403514375632'/><link rel='alternate' type='text/html' href='http://laclefyoshi.blogspot.com/2012/05/using-socket-api-with-google-chrome.html' title='Using socket API with Google Chrome Canary build'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/09934531596280495750</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9Tl_XJw1EQkslrP9-HOabtuNoDeYps3Ud17io1_r3Bpaq6p17WmTRP3JxVGpXPh0Lb6ce7qTY0rYs1BPujr_44Sc6XRb4pScxNoMjTSmJTPEvFd9Z-2jG2GQj4pZ3zCa59XhSs7st52Ao/s72-c/Google+Chrome.png" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4078805449160415851.post-7055160314896448579</id><published>2012-04-15T14:37:00.000+09:00</published><updated>2012-04-15T14:37:08.378+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="emacs"/><category scheme="http://www.blogger.com/atom/ns#" term="java"/><title type='text'>flymake and checkstyle</title><content type='html'>&lt;br /&gt;
In our Java project, &lt;a href=&quot;https://wiki.jenkins-ci.org/display/JENKINS/Checkstyle+Plugin&quot;&gt;Checkstyle Plugin for Jenkins&lt;/a&gt; is used. Because I had never cared about &lt;a href=&quot;http://www.oracle.com/technetwork/java/codeconv-138413.html&quot;&gt;Java coding style&lt;/a&gt; too much, I receive warning mails every commitment to svn.&lt;br /&gt;
&lt;br /&gt;
So. I wrote &lt;code&gt;.emacs&lt;/code&gt; for displaying warnings of checkstyle with flymake on emacs.&lt;br /&gt;
&lt;br /&gt;
Firstly, I wrote shell script for calling checkstyle as a command. I put this script into &lt;code&gt;/opt/bin/checkstyle.sh&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/2390005.js&quot;&gt; &lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
Finally, I wrote &lt;code&gt;.emacs&lt;/code&gt;. I use &lt;a href=&quot;http://www.emacswiki.org/emacs/FlymakeCursor&quot;&gt;flymake-cursor.el&lt;/a&gt; for displaying messages on minibuffer.&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/2389979.js&quot;&gt; &lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
However, I didn&#39;t know how importunate coding style is.&lt;br /&gt;
&lt;br /&gt;
Thanks.&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://laclefyoshi.blogspot.com/feeds/7055160314896448579/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://laclefyoshi.blogspot.com/2012/04/flymake-and-checkstyle.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/7055160314896448579'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/7055160314896448579'/><link rel='alternate' type='text/html' href='http://laclefyoshi.blogspot.com/2012/04/flymake-and-checkstyle.html' title='flymake and checkstyle'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/09934531596280495750</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4078805449160415851.post-2786720228508707050</id><published>2012-04-01T11:14:00.000+09:00</published><updated>2012-04-01T11:14:48.079+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="jython"/><category scheme="http://www.blogger.com/atom/ns#" term="scala"/><title type='text'>defining custom URL using URLStreamHandler</title><content type='html'>&lt;br /&gt;
On Mac, iOS and Android, we can define custom URL schemes and behaviors for their URL. In Java, &lt;code&gt;java.net.URL&lt;/code&gt; can manage every URL and we can add/change the behavior by defining and setting &lt;code&gt;java.net.URLStreamHandler&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
I wrote a handler for URL which has a protocol: &lt;code&gt;sum://&lt;/code&gt; in Scala. For example, an URL: &lt;code&gt;sum://1,2,3&lt;/code&gt; has a content: &lt;code&gt;6&lt;/code&gt; (= 1 + 2 + 3).&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/2270355.js&quot;&gt; &lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
This completes a registration of a protocol: &lt;code&gt;sum://&lt;/code&gt;. We can use &lt;code&gt;sum://&lt;/code&gt; as like regular URL.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;scala&gt; :load &quot;SumURLHandler.scala&quot;
scala&gt; val url:URL = new URL(&quot;sum://1,2,3,4,5,6,7,8/foo/bar?a=A&amp;b=B#head&quot;)

scala &gt; println(&quot;ptorotol: %s\nhost: %s\npath: %s\nquery: %s\nref: %s&quot;.format(
     | url.getProtocol, url.getHost, url.getPath, url.getQuery, url.getRef))

ptorotol: sum
host: 1,2,3,4,5,6,7,8
path: /foo/bar
query: a=A&amp;b=B
ref: head
&lt;/pre&gt;&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;scala&gt; val url:URL = new URL(&quot;sum://1,2,3,4,5,6,7,8&quot;)
scala&gt; val isr:InputStreamReader = new InputStreamReader(url.openStream)
scala&gt; var result:String = &quot;&quot;
scala&gt; while(isr.ready()) {
     | result += isr.read.toChar
     |}

scala&gt; println(result)
36
&lt;/pre&gt;&lt;br /&gt;
In Jython:&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/2270603.js&quot;&gt; &lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
By using of elements of URL wisely, we can define useful URL in own applications.&lt;br /&gt;
&lt;br /&gt;
Thanks.&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://laclefyoshi.blogspot.com/feeds/2786720228508707050/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://laclefyoshi.blogspot.com/2012/04/extending-url-using-urlstreamhandler.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/2786720228508707050'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/2786720228508707050'/><link rel='alternate' type='text/html' href='http://laclefyoshi.blogspot.com/2012/04/extending-url-using-urlstreamhandler.html' title='defining custom URL using URLStreamHandler'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/09934531596280495750</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4078805449160415851.post-6675416326345822763</id><published>2012-03-24T22:22:00.000+09:00</published><updated>2012-03-25T10:10:42.823+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C"/><category scheme="http://www.blogger.com/atom/ns#" term="java"/><category scheme="http://www.blogger.com/atom/ns#" term="perl"/><category scheme="http://www.blogger.com/atom/ns#" term="python"/><title type='text'>identifying whether a binary is 32-bit or 64-bit in itself</title><content type='html'>&lt;br /&gt;
For example, when I use a C library with 32-bit Python interpreter on a 64-bit machine, I need to compile the library as 32-bit binary. &lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;file&lt;/code&gt; command provides such information.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ file /usr/lib/libpython2.6.so.1.0
/usr/lib/libpython2.6.so.1.0: ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked, stripped
&lt;/pre&gt;&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ file /usr/lib/libpython2.6.dylib 
/usr/lib/libpython2.6.dylib: Mach-O universal binary with 2 architectures
/usr/lib/libpython2.6.dylib (for architecture x86_64):  Mach-O 64-bit dynamically linked shared library x86_64
/usr/lib/libpython2.6.dylib (for architecture i386):    Mach-O dynamically linked shared library i386
&lt;/pre&gt;&lt;br /&gt;
But here I show some methods for identifying the binary&#39;s bit-mode inside program.&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;C&lt;/h4&gt;&lt;br /&gt;
gcc (llvm-gcc) can build a binary in the 32-bit or 64-bit mode. The choice can be made by adding compile option: &lt;code&gt;-m32&lt;/code&gt; or &lt;code&gt;-m64&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
The difference of modes comes in size of pointer. If size of pointer is 4, the binary or interpreter is 32-bit mode. If size of pointer is 8, the binary or interpreter is 64-bit mode. That is, the size of pointer shows memory bandwidth (byte unit).&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/2182023.js&quot;&gt; &lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ gcc -m32 mode.c
$ file ./a.out 
./a.out: Mach-O executable i386
$ ./a.out 
4

$ gcc -m64 mode.c 
$ file ./a.out 
./a.out: Mach-O 64-bit executable x86_64
$ ./a.out 
8
&lt;/pre&gt;&lt;br /&gt;
&lt;h4&gt;Python&lt;/h4&gt;&lt;br /&gt;
Python can also get size of pointer with &lt;code&gt;struct&lt;/code&gt; module.&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/2182138.js&quot;&gt; &lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ file `which python2.6`
/usr/bin/python2.6: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, stripped
$ python mode.py
4

$ file `which python2.7`
/usr/bin/python2.7: Mach-O universal binary with 2 architectures
/usr/bin/python2.7 (for architecture x86_64):   Mach-O 64-bit executable x86_64
/usr/bin/python2.7 (for architecture i386):     Mach-O executable i386
$ python mode.py
8
&lt;/pre&gt;&lt;br /&gt;
&lt;h4&gt;Perl&lt;/h4&gt;&lt;br /&gt;
Perl doesn&#39;t have a function for showing size of pointer. But &lt;code&gt;Config&lt;/code&gt; module shows it.&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/2182225.js&quot;&gt; &lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ file `which perl`
/usr/bin/perl: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, stripped
$ perl mode.pl
4

$ file `which perl`
/usr/bin/perl: Mach-O universal binary with 2 architectures
/usr/bin/perl (for architecture x86_64):        Mach-O 64-bit executable x86_64
/usr/bin/perl (for architecture i386):  Mach-O executable i386
$ perl mode.pl 
8
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;Java / Jython&lt;/h4&gt;&lt;br /&gt;
We usually don&#39;t treat pointer in Java. But Java Virtual Machine (JVM) has a value of size of pointer for handling data effectively.&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/2182605.js&quot;&gt; &lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ javac Mode.java

$ java -d32 Mode  # option:-d32 specifies that JVM runs in 32-bit mode
32

$ java -d64 Mode  # option:-d64 specifies that JVM runs in 64-bit mode
64
&lt;/pre&gt;&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ jython -J-d32  # option:-J-d32 has the same effect as a option:-d32 of java
Jython 2.5.2 (Release_2_5_2:7206, Mar 2 2011, 23:12:06) 
[Java HotSpot(TM) Client VM (Apple Inc.)] on java1.6.0_29
Type &quot;help&quot;, &quot;copyright&quot;, &quot;credits&quot; or &quot;license&quot; for more information.
&gt;&gt;&gt; from java.lang import System
&gt;&gt;&gt; System.getProperty(&quot;sun.arch.data.model&quot;)
u&#39;32&#39;

$ jython -J-d64  # option:-J-d64 has the same effect as a option:-d64 of java
Jython 2.5.2 (Release_2_5_2:7206, Mar 2 2011, 23:12:06) 
[Java HotSpot(TM) 64-Bit Server VM (Apple Inc.)] on java1.6.0_29
Type &quot;help&quot;, &quot;copyright&quot;, &quot;credits&quot; or &quot;license&quot; for more information.
&gt;&gt;&gt; from java.lang import System
&gt;&gt;&gt; System.getProperty(&quot;sun.arch.data.model&quot;)
u&#39;64&#39;
&lt;/pre&gt;&lt;br /&gt;
Thanks.&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://laclefyoshi.blogspot.com/feeds/6675416326345822763/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://laclefyoshi.blogspot.com/2012/03/identifying-whether-binary-is-32-bit-or.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/6675416326345822763'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/6675416326345822763'/><link rel='alternate' type='text/html' href='http://laclefyoshi.blogspot.com/2012/03/identifying-whether-binary-is-32-bit-or.html' title='identifying whether a binary is 32-bit or 64-bit in itself'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/09934531596280495750</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4078805449160415851.post-5356465975422084840</id><published>2012-03-17T22:10:00.001+09:00</published><updated>2012-03-17T22:10:30.696+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="java"/><title type='text'>class for manipulating URL</title><content type='html'>&lt;br /&gt;
A problem of &lt;a href=&quot;http://docs.oracle.com/javase/6/docs/api/java/net/URL.html&quot;&gt;java.net.URL&lt;/a&gt; is that is doesn&#39;t provide APIs for rewriting components of URL. For example, When I need to normalize hostname of URL (hostname can be wholly uncapitalized), I must get the components of URL, make a String instance as hostname, and make a new URL instance.&lt;br /&gt;
&lt;br /&gt;
So I wrote &lt;code&gt;MyURL&lt;/code&gt; class for manipulating URL.&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/2058551.js&quot;&gt; &lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
As central feature of this class, query string of URL is held as list of pairs. This makes it easy for us to search query parameters.&lt;br /&gt;
&lt;br /&gt;
I don&#39;t provide &lt;code&gt;Pair&amp;lt;L, R&amp;gt;&lt;/code&gt; class. But there are &lt;a href=&quot;http://stackoverflow.com/questions/156275/what-is-the-equivalent-of-the-c-pairl-r-in-java&quot;&gt;many examples on the Web&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Thanks.&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://laclefyoshi.blogspot.com/feeds/5356465975422084840/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://laclefyoshi.blogspot.com/2012/03/class-for-manipulating-url.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/5356465975422084840'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/5356465975422084840'/><link rel='alternate' type='text/html' href='http://laclefyoshi.blogspot.com/2012/03/class-for-manipulating-url.html' title='class for manipulating URL'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/09934531596280495750</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4078805449160415851.post-6144917155440725016</id><published>2012-02-25T19:24:00.001+09:00</published><updated>2012-02-25T19:25:17.799+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="emacs"/><category scheme="http://www.blogger.com/atom/ns#" term="vim"/><title type='text'>open file and search term in vim and emacs</title><content type='html'>&lt;br /&gt;
vim has command line option for searching text when vim opens a file.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ vim /usr/share/emacs/22.1/etc/TODO +/iff
   # it opens TODO, searches &quot;iff&quot; and moves cursor the first appearance position
&lt;/pre&gt;&lt;br /&gt;
But emacs doesn&#39;t have the similar command line option apparently. And so, I imitated the vim&#39;s option by using &lt;code&gt;-eval&lt;/code&gt;: a command line option for evaluating emacs lisp expressions when emacs starts.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ /usr/bin/emacs  /usr/share/emacs/22.1/etc/TODO -eval &#39;(search-forward-regexp &quot;iff&quot;)&#39;
&lt;/pre&gt;&lt;br /&gt;
There is a difference in these results. vim moves cursor to starting point of search term. On the other hand, emacs moves cursor to end point of search term. Additionally, vim remember the search term given by command line option, but emacs doesn&#39;t.&lt;br /&gt;
&lt;br /&gt;
For improving the emacs&#39;s behavior, I need to write a little more complicated command. Doesn&#39;t emacs have a system for extending command line option by writing emacs lisp in init file?&lt;br /&gt;
&lt;br /&gt;
Thanks.&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://laclefyoshi.blogspot.com/feeds/6144917155440725016/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://laclefyoshi.blogspot.com/2012/02/open-and-search-file-in-vim-and-emacs.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/6144917155440725016'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/6144917155440725016'/><link rel='alternate' type='text/html' href='http://laclefyoshi.blogspot.com/2012/02/open-and-search-file-in-vim-and-emacs.html' title='open file and search term in vim and emacs'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/09934531596280495750</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4078805449160415851.post-725827754263920210</id><published>2012-02-18T21:38:00.000+09:00</published><updated>2012-02-18T21:38:29.790+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="mac"/><title type='text'>another way of creating RAM disc in Mac</title><content type='html'>&lt;br /&gt;
I wrote about &lt;a href=&quot;http://laclefyoshi.blogspot.com/2011/05/tmpfs-on-linux-and-mac.html&quot;&gt;a way of creating RAM disc in Mac&lt;/a&gt;. But I knew that using &lt;code&gt;discutil&lt;/code&gt; is better than &lt;code&gt;mount&lt;/code&gt; for creating RAM disc in Mac.&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://osxdaily.com/2007/03/23/create-a-ram-disk-in-mac-os-x/&quot;&gt;Create a RAM Disk in Mac OS X&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ diskutil erasevolume HFS+ &quot;ramdisk&quot; `hdiutil attach -nomount ram://1165430`
Started erase on disk1
Unmounting disk
Erasing
Initialized /dev/rdisk1 as a 569 MB HFS Plus volume
Mounting disk
Finished erase on disk1 ramdisk
&lt;/pre&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiejlBIAnUFXKw95e2QkwquGJ75FNlI4KF6oGlCR36NF4iGJ8gGCAvAO3tEDmXEIj-jIPzEXHxufaiYe27UGBRct-RIsdpM4cukKBq8IhFySwJjyXuGMvxYwe0bbCFupW6lv92ZcPzBBUeD/s1600/ramdisk.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left:1em; margin-right:1em&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;84&quot; width=&quot;218&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiejlBIAnUFXKw95e2QkwquGJ75FNlI4KF6oGlCR36NF4iGJ8gGCAvAO3tEDmXEIj-jIPzEXHxufaiYe27UGBRct-RIsdpM4cukKBq8IhFySwJjyXuGMvxYwe0bbCFupW6lv92ZcPzBBUeD/s400/ramdisk.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
The good thing is the disc is visible on Finder. Of course, the disk free space can be checked easily.&lt;br /&gt;
&lt;br /&gt;
Thanks.&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://laclefyoshi.blogspot.com/feeds/725827754263920210/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://laclefyoshi.blogspot.com/2012/02/another-way-of-creating-ram-disc-in-mac.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/725827754263920210'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/725827754263920210'/><link rel='alternate' type='text/html' href='http://laclefyoshi.blogspot.com/2012/02/another-way-of-creating-ram-disc-in-mac.html' title='another way of creating RAM disc in Mac'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/09934531596280495750</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiejlBIAnUFXKw95e2QkwquGJ75FNlI4KF6oGlCR36NF4iGJ8gGCAvAO3tEDmXEIj-jIPzEXHxufaiYe27UGBRct-RIsdpM4cukKBq8IhFySwJjyXuGMvxYwe0bbCFupW6lv92ZcPzBBUeD/s72-c/ramdisk.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4078805449160415851.post-1668378346653923193</id><published>2012-02-11T17:06:00.001+09:00</published><updated>2012-02-11T17:06:08.219+09:00</updated><title type='text'>af* command for treating audio files in Mac</title><content type='html'>&lt;br /&gt;
I knew that there are commands for treating audio files in Mac by default.&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;afinfo&lt;/h4&gt;&lt;br /&gt;
&lt;a href=&quot;https://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man1/afinfo.1.html&quot;&gt;afinfo&lt;/a&gt; is a command for showing information of audio file.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ afinfo happykids.wav 
File:           happykids.wav
File type ID:   WAVE
Data format:     1 ch,  11025 Hz, &#39;lpcm&#39; (0x00000008) 8-bit unsigned integer
                no channel layout.
estimated duration: 5.576417 sec
audio bytes: 61480
audio packets: 61480
bit rate: 88200 bits per second
packet size upper bound: 1
audio data file offset: 44
optimized
source bit depth: I8
----
&lt;/pre&gt;&lt;br /&gt;
&lt;h4&gt;afconvert&lt;/h4&gt;&lt;br /&gt;
&lt;a href=&quot;https://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man1/afconvert.1.html&quot;&gt;afconvert&lt;/a&gt; is a command for converting format of audio file. The supported formats are showed by option: &lt;code&gt;-hf&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ afconvert -hf
Audio file and data formats:
    &#39;3gpp&#39; = 3GP Audio (.3gp)
               data_formats: &#39;Qclp&#39; &#39;aac &#39; &#39;aace&#39; &#39;aach&#39; &#39;aacl&#39; &#39;aacp&#39; 
                             &#39;samr&#39; 
    &#39;3gp2&#39; = 3GPP-2 Audio (.3g2)
               data_formats: &#39;Qclp&#39; &#39;aac &#39; &#39;aace&#39; &#39;aach&#39; &#39;aacl&#39; &#39;aacp&#39; 
                             &#39;samr&#39; 
    &#39;adts&#39; = AAC ADTS (.aac, .adts)
               data_formats: &#39;aac &#39; &#39;aach&#39; &#39;aacp&#39; 
    &#39;ac-3&#39; = AC3 (.ac3)
               data_formats: &#39;ac-3&#39; 
    &#39;AIFC&#39; = AIFC (.aifc, .aiff, .aif)
               data_formats: I8 BEI16 BEI24 BEI32 BEF32 BEF64 UI8 &#39;ulaw&#39; 
                             &#39;alaw&#39; &#39;MAC3&#39; &#39;MAC6&#39; &#39;ima4&#39; &#39;QDMC&#39; &#39;QDM2&#39; 
                             &#39;Qclp&#39; &#39;agsm&#39; 
    &#39;AIFF&#39; = AIFF (.aiff, .aif)
               data_formats: I8 BEI16 BEI24 BEI32 
    &#39;amrf&#39; = AMR (.amr)
               data_formats: &#39;samr&#39; 
    &#39;m4af&#39; = Apple MPEG-4 Audio (.m4a, .m4r)
               data_formats: &#39;aac &#39; &#39;aace&#39; &#39;aach&#39; &#39;aacl&#39; &#39;aacp&#39; &#39;alac&#39; 
    &#39;caff&#39; = CAF (.caf)
               data_formats: &#39;.mp1&#39; &#39;.mp2&#39; &#39;.mp3&#39; &#39;QDM2&#39; &#39;QDMC&#39; &#39;Qclp&#39; 
                             &#39;Qclq&#39; &#39;aac &#39; &#39;aace&#39; &#39;aach&#39; &#39;aacl&#39; &#39;aacp&#39; 
                             &#39;alac&#39; &#39;alaw&#39; &#39;dvi8&#39; &#39;ilbc&#39; &#39;ima4&#39; I8 BEI16 
                             BEI24 BEI32 BEF32 BEF64 LEI16 LEI24 LEI32 
                             LEF32 LEF64 &#39;ms\x00\x02&#39; &#39;ms\x00\x11&#39; &#39;ms\x001&#39; 
                             &#39;paac&#39; &#39;samr&#39; &#39;ulaw&#39; 
    &#39;MPG1&#39; = MPEG Layer 1 (.mp1, .mpeg, .mpa)
               data_formats: &#39;.mp1&#39; 
    &#39;MPG2&#39; = MPEG Layer 2 (.mp2, .mpeg, .mpa)
               data_formats: &#39;.mp2&#39; 
    &#39;MPG3&#39; = MPEG Layer 3 (.mp3, .mpeg, .mpa)
               data_formats: &#39;.mp3&#39; 
    &#39;mp4f&#39; = MPEG-4 Audio (.mp4)
               data_formats: &#39;aac &#39; &#39;aace&#39; &#39;aach&#39; &#39;aacl&#39; &#39;aacp&#39; 
    &#39;NeXT&#39; = NeXT/Sun (.snd, .au)
               data_formats: I8 BEI16 BEI24 BEI32 BEF32 BEF64 &#39;ulaw&#39; 
    &#39;Sd2f&#39; = Sound Designer II (.sd2)
               data_formats: I8 BEI16 BEI24 BEI32 
    &#39;WAVE&#39; = WAVE (.wav)
               data_formats: UI8 LEI16 LEI24 LEI32 LEF32 LEF64 &#39;ulaw&#39; 
                             &#39;alaw&#39; 
&lt;/pre&gt;&lt;br /&gt;
There is &quot;MPG3&quot; in a list of supported formats, but &lt;a href=&quot;http://stackoverflow.com/questions/435349/how-to-use-afconvert-to-convert-from-caf-to-mp3-format&quot;&gt;Mac doesn&#39;t provide any MP3 encoder&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ afconvert -f MPG3 -d &#39;.mp3&#39; happykids.wav 
Error: ExtAudioFileSetProperty (&#39;cfmt&#39;) failed (&#39;fmt?&#39;)

$ afconvert -f m4af -d aac happykids.wav

$ afinfo happykids.m4a 
File:           happykids.m4a
File type ID:   m4af
Data format:     1 ch,  11025 Hz, &#39;aac &#39; (0x00000000) 0 bits/channel, 0 bytes/packet, 1024 frames/packet, 0 bytes/frame
Channel layout: Mono
estimated duration: 5.576417 sec
audio bytes: 15950
audio packets: 63
audio 61480 valid frames + 2112 priming + 920 remainder = 64512
bit rate: 21806 bits per second
packet size upper bound: 399
audio data file offset: 4096
optimized
format list:
[ 0] format:     1 ch,  11025 Hz, &#39;aac &#39; (0x00000000) 0 bits/channel, 0 bytes/packet, 1024 frames/packet, 0 bytes/frame
     Channel layout: Mono
source bit depth: I8
----
&lt;/pre&gt;&lt;br /&gt;
&lt;h4&gt;afplay&lt;/h4&gt;&lt;br /&gt;
&lt;a href=&quot;https://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man1/afplay.1.html&quot;&gt;afplay&lt;/a&gt; is a command for playback of audio file. Probably, the supported formats are same as afconvert.&lt;br /&gt;
&lt;br /&gt;
I found some weblogs which said that the sound quality of afplay is better than iTunes. But I can&#39;t tell the difference.&lt;br /&gt;
&lt;br /&gt;
Thanks.&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://laclefyoshi.blogspot.com/feeds/1668378346653923193/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://laclefyoshi.blogspot.com/2012/02/af-command-for-treating-audio-files-in.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/1668378346653923193'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/1668378346653923193'/><link rel='alternate' type='text/html' href='http://laclefyoshi.blogspot.com/2012/02/af-command-for-treating-audio-files-in.html' title='af* command for treating audio files in Mac'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/09934531596280495750</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4078805449160415851.post-6633026828374768608</id><published>2012-01-30T22:20:00.000+09:00</published><updated>2012-01-31T20:24:42.188+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="applescript"/><category scheme="http://www.blogger.com/atom/ns#" term="pdf"/><title type='text'>Removing margins of PDF generated by iBooks Author</title><content type='html'>&lt;br /&gt;
&lt;a href=&quot;http://www.apple.com/ibooks-author/&quot;&gt;iBooks Author&lt;/a&gt; is very solicitous and beautiful Desktop publishing tool. But I have a complaint about this. It is that margins and a watermark break into PDF generated by iBooks Author.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijCvQhV2ticy79m2VDxCJ5XD-Pur5Z6h1f4_jSN0KICp2TxxDfbiEXY8eriYBgGk8nRrBHEjFtdPdlS2BgpTlNgcPrYcBqrxyEhgIp-fR_3MmJ4erP0bo15ttngUz9Bk7OyDrqgGTgO4bd/s1600/toaru.pdf%25EF%25BC%25884_4%25E3%2583%259A%25E3%2583%25BC%25E3%2582%25B8%25EF%25BC%2589.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left:1em; margin-right:1em&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;294&quot; width=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijCvQhV2ticy79m2VDxCJ5XD-Pur5Z6h1f4_jSN0KICp2TxxDfbiEXY8eriYBgGk8nRrBHEjFtdPdlS2BgpTlNgcPrYcBqrxyEhgIp-fR_3MmJ4erP0bo15ttngUz9Bk7OyDrqgGTgO4bd/s400/toaru.pdf%25EF%25BC%25884_4%25E3%2583%259A%25E3%2583%25BC%25E3%2582%25B8%25EF%25BC%2589.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Probably, Apple indicate PDF generated by iBooks Author should not be published because they think that the function of exporting PDF should be used for confirming the content and layout on Mac when we don&#39;t have iPad accidentally.&lt;br /&gt;
&lt;br /&gt;
But, I want to make ebooks with iBooks Author and publish them in good-looking and widely-used PDF on the Web, too.&lt;br /&gt;
&lt;br /&gt;
I tried to remove margins from PDF generated iBooks Author in two ways.&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;pdfcrop&lt;/h4&gt;&lt;br /&gt;
&lt;a href=&quot;http://pdfcrop.sourceforge.net/&quot;&gt;pdfcrop&lt;/a&gt; is a software for removing margins from PDF. This is supplied with &lt;a href=&quot;http://www.tug.org/texlive/&quot;&gt;TeX Live&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
pdfcrop automatically recognizes margins in PDF. But pdfcrop without options yields a disappointing result from PDF genetated by iBooks Author because there is a watermark &quot;&amp;#63743; iBooks Author&quot; in the bottom of it. Therefore, we need to add options for specifying the size of the bottom margin.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ time pdfcrop --margins &quot;0 0 0 -55&quot; ibooks_pdf.pdf ibooks_pdf_cropped.pdf
PDFCROP 1.32, 2011/08/10 - Copyright (c) 2002-2011 by Heiko Oberdiek.
==&amp;gt; 4 pages written on `ibooks_pdf_cropped.pdf&#39;.

real    2m51.121s
user    2m43.072s
sys     0m0.714s
&lt;/pre&gt;&lt;br /&gt;
It took a few minutes to remove margins of 4 pages of PDF.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfHTMclUHIwtv5bsJgsJ1Fq3xCjProC1t7oPCMPkJY7kl3Qj2QlysAPegymRWieLfFcPqpTKZI4YpR7hiIxUfCHPN7n4Lf2LfXd8LlpSR9B3IUw_4TCLn_IyxNiQ2ffMGssEUBjKAEM832/s1600/toaru2.pdf%25EF%25BC%25884_4%25E3%2583%259A%25E3%2583%25BC%25E3%2582%25B8%25EF%25BC%2589.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left:1em; margin-right:1em&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;265&quot; width=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfHTMclUHIwtv5bsJgsJ1Fq3xCjProC1t7oPCMPkJY7kl3Qj2QlysAPegymRWieLfFcPqpTKZI4YpR7hiIxUfCHPN7n4Lf2LfXd8LlpSR9B3IUw_4TCLn_IyxNiQ2ffMGssEUBjKAEM832/s400/toaru2.pdf%25EF%25BC%25884_4%25E3%2583%259A%25E3%2583%25BC%25E3%2582%25B8%25EF%25BC%2589.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ identify ibooks_pdf.pdf
ibooks_pdf.pdf[0] PDF 1024x748 1024x748+0+0 16-bit Bilevel DirectClass 95.8KB 0.010u 0:00.009
ibooks_pdf.pdf[1] PDF 1024x748 1024x748+0+0 16-bit Bilevel DirectClass 95.8KB 0.000u 0:00.009
ibooks_pdf.pdf[2] PDF 1024x748 1024x748+0+0 16-bit Bilevel DirectClass 95.8KB 0.000u 0:00.009
ibooks_pdf.pdf[3] PDF 1024x748 1024x748+0+0 16-bit Bilevel DirectClass 95.8KB 0.000u 0:00.009

$ identify ibooks_pdf_cropped.pdf
ibooks_pdf_cropped.pdf[0] PDF 922x598 922x598+0+0 16-bit Bilevel DirectClass 69.4KB 0.000u 0:00.019
ibooks_pdf_cropped.pdf[1] PDF 922x598 922x598+0+0 16-bit Bilevel DirectClass 69.4KB 0.000u 0:00.019
ibooks_pdf_cropped.pdf[2] PDF 922x598 922x598+0+0 16-bit Bilevel DirectClass 69.4KB 0.000u 0:00.019
ibooks_pdf_cropped.pdf[3] PDF 922x598 922x598+0+0 16-bit Bilevel DirectClass 69.4KB 0.000u 0:00.019
&lt;/pre&gt;&lt;br /&gt;
The result is good, but character information of all pages are lost. Thus, we can&#39;t select text on the processed PDF because all pages are imaged.&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;PDF hack&lt;/h4&gt;&lt;br /&gt;
PDF can have information for the paper size (&lt;code&gt;MediaBox&lt;/code&gt;) and the display size (&lt;code&gt;CropBox&lt;/code&gt;). There is &lt;code&gt;MediaBox&lt;/code&gt; in PDF generated by iBooks Author, but there is not &lt;code&gt;CropBox&lt;/code&gt;. I added &lt;code&gt;CropBox&lt;/code&gt; into PDF with shell command. The size was decided by the result of being processed by pdfcrop.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ time sed -e &#39;s;/MediaBox;/CropBox [52 75 973 673] /MediaBox;g&#39; ibooks_pdf.pdf &gt; ibooks_pdf_cropped.pdf

real    0m0.004s
user    0m0.002s
sys     0m0.003s
&lt;/pre&gt;&lt;br /&gt;
The process was complete in a moment. I confirmed that the processed PDF can be rendered with Preview.app and Google Chrome (Chrome PDF Viewer plugin). But it seems that some application can&#39;t reder the processed PDF.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicDpoI32Qt9wKHO3RijOUKRZz2fmA8mzlJux7UvyC1vdzOA7737pFX7A1wQusaxYiWga19YGddn1i_I9q2MJrhhyy7Tdq4inp7QOGlBgCxpqNnquzY9y_jxo5t1hTbx6mWvdQ_bHS56vP0/s1600/%25E3%2582%25A4%25E3%2583%25B3%25E3%2582%25B9%25E3%2583%259A%25E3%2582%25AF%25E3%2582%25BF.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left:1em; margin-right:1em&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;166&quot; width=&quot;333&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicDpoI32Qt9wKHO3RijOUKRZz2fmA8mzlJux7UvyC1vdzOA7737pFX7A1wQusaxYiWga19YGddn1i_I9q2MJrhhyy7Tdq4inp7QOGlBgCxpqNnquzY9y_jxo5t1hTbx6mWvdQ_bHS56vP0/s400/%25E3%2582%25A4%25E3%2583%25B3%25E3%2582%25B9%25E3%2583%259A%25E3%2582%25AF%25E3%2582%25BF.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ identify ibooks_pdf_cropped.pdf 
   **** Warning:  An error occurred while reading an XREF table.
   **** The file has been damaged.  This may have been caused
   **** by a problem while converting or transfering the file.
   **** Ghostscript will attempt to recover the data.

   **** This file had errors that were repaired or ignored.
   **** The file was produced by: 
   **** &amp;gt;&amp;gt;&amp;gt;&amp;gt; Mac OS X 10.7.2 Quartz PDFContext &amp;lt;&amp;lt;&amp;lt;&amp;lt;
   **** Please notify the author of the software that produced this
   **** file that it does not conform to Adobe&#39;s published PDF
   **** specification.

ibooks_pdf_cropped.pdf[0] PDF 1024x748 1024x748+0+0 16-bit Bilevel DirectClass 95.8KB 0.010u 0:00.019
ibooks_pdf_cropped.pdf[1] PDF 1024x748 1024x748+0+0 16-bit Bilevel DirectClass 95.8KB 0.000u 0:00.019
ibooks_pdf_cropped.pdf[2] PDF 1024x748 1024x748+0+0 16-bit Bilevel DirectClass 95.8KB 0.000u 0:00.009
ibooks_pdf_cropped.pdf[3] PDF 1024x748 1024x748+0+0 16-bit Bilevel DirectClass 95.8KB 0.000u 0:00.009
&lt;/pre&gt;&lt;br /&gt;
I wrote AppleScript droplet and created the project for simplifying the process to crop PDF by sed.&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/1652708.js&quot;&gt; &lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://bitbucket.org/laclefyoshi/cropping_ibooksauthor_pdf&quot;&gt;laclefyoshi / cropping_ibooksauthor_pdf / overview — Bitbucket&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
Thanks.&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://laclefyoshi.blogspot.com/feeds/6633026828374768608/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://laclefyoshi.blogspot.com/2012/01/removing-margins-of-pdf-generated-by.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/6633026828374768608'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/6633026828374768608'/><link rel='alternate' type='text/html' href='http://laclefyoshi.blogspot.com/2012/01/removing-margins-of-pdf-generated-by.html' title='Removing margins of PDF generated by iBooks Author'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/09934531596280495750</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijCvQhV2ticy79m2VDxCJ5XD-Pur5Z6h1f4_jSN0KICp2TxxDfbiEXY8eriYBgGk8nRrBHEjFtdPdlS2BgpTlNgcPrYcBqrxyEhgIp-fR_3MmJ4erP0bo15ttngUz9Bk7OyDrqgGTgO4bd/s72-c/toaru.pdf%25EF%25BC%25884_4%25E3%2583%259A%25E3%2583%25BC%25E3%2582%25B8%25EF%25BC%2589.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4078805449160415851.post-5944242416681441779</id><published>2012-01-21T12:44:00.000+09:00</published><updated>2012-01-21T12:44:25.675+09:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="jython"/><category scheme="http://www.blogger.com/atom/ns#" term="python"/><title type='text'>Outputting data for people with tablib</title><content type='html'>&lt;br /&gt;
In order to show some data in processing to others (that are boss or client in business), I think it tiresome to copy and paste data into Excel sheets or export HTML tables.&lt;br /&gt;
&lt;br /&gt;
I found &lt;a href=&quot;http://pypi.python.org/pypi/tablib&quot;&gt;tablib&lt;/a&gt; that is a library for formatting data as tabular form or semistructured form.&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/1651161.js&quot;&gt; &lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;== show attributes of Dataset ==
[&#39;_Dataset__headers&#39;, &#39;__class__&#39;, &#39;__delattr__&#39;, &#39;__delitem__&#39;, &#39;__dict__&#39;, &#39;__doc__&#39;, &#39;__format__&#39;, &#39;__getattribute__&#39;, &#39;__getitem__&#39;, &#39;__hash__&#39;, &#39;__init__&#39;, &#39;__len__&#39;, &#39;__module__&#39;, &#39;__new__&#39;, &#39;__reduce__&#39;, &#39;__reduce_ex__&#39;, &#39;__repr__&#39;, &#39;__setattr__&#39;, &#39;__setitem__&#39;, &#39;__sizeof__&#39;, &#39;__str__&#39;, &#39;__subclasshook__&#39;, &#39;__weakref__&#39;, &#39;_clean_col&#39;, &#39;_data&#39;, &#39;_formatters&#39;, &#39;_get_dict&#39;, &#39;_get_headers&#39;, &#39;_package&#39;, &#39;_register_formats&#39;, &#39;_separators&#39;, &#39;_set_dict&#39;, &#39;_set_headers&#39;, &#39;_validate&#39;, &#39;add_formatter&#39;, &#39;append&#39;, &#39;append_col&#39;, &#39;append_separator&#39;, &#39;csv&#39;, &#39;dict&#39;, &#39;filter&#39;, &#39;headers&#39;, &#39;height&#39;, &#39;html&#39;, &#39;insert&#39;, &#39;insert_col&#39;, &#39;insert_separator&#39;, &#39;json&#39;, &#39;lpop&#39;, &#39;lpush&#39;, &#39;lpush_col&#39;, &#39;ods&#39;, &#39;pop&#39;, &#39;rpop&#39;, &#39;rpush&#39;, &#39;rpush_col&#39;, &#39;sort&#39;, &#39;stack&#39;, &#39;stack_cols&#39;, &#39;title&#39;, &#39;transpose&#39;, &#39;tsv&#39;, &#39;width&#39;, &#39;wipe&#39;, &#39;xls&#39;, &#39;xlsx&#39;, &#39;yaml&#39;]

== output as dict ==
[OrderedDict([(&#39;name&#39;, &#39;Alice&#39;), (&#39;age&#39;, 21)]), OrderedDict([(&#39;name&#39;, &#39;Bob&#39;), (&#39;age&#39;, 20)]), OrderedDict([(&#39;name&#39;, &#39;Carol&#39;), (&#39;age&#39;, 31)]), OrderedDict([(&#39;name&#39;, &#39;Taro&#39;), (&#39;age&#39;, 10)])]

== output as json ==
[{&quot;name&quot;: &quot;Alice&quot;, &quot;age&quot;: 21}, {&quot;name&quot;: &quot;Bob&quot;, &quot;age&quot;: 20}, {&quot;name&quot;: &quot;Carol&quot;, &quot;age&quot;: 31}, {&quot;name&quot;: &quot;Taro&quot;, &quot;age&quot;: 10}]

== output only female as json ==
[{&quot;name&quot;: &quot;Alice&quot;, &quot;age&quot;: 21}, {&quot;name&quot;: &quot;Carol&quot;, &quot;age&quot;: 31}]

== output as csv ==
name,age,e/o
Alice,21,odd
Bob,20,even
Carol,31,odd
Taro,10,even


== show attributes of Databook ==
[&#39;__class__&#39;, &#39;__delattr__&#39;, &#39;__dict__&#39;, &#39;__doc__&#39;, &#39;__format__&#39;, &#39;__getattribute__&#39;, &#39;__hash__&#39;, &#39;__init__&#39;, &#39;__module__&#39;, &#39;__new__&#39;, &#39;__reduce__&#39;, &#39;__reduce_ex__&#39;, &#39;__repr__&#39;, &#39;__setattr__&#39;, &#39;__sizeof__&#39;, &#39;__str__&#39;, &#39;__subclasshook__&#39;, &#39;__weakref__&#39;, &#39;_datasets&#39;, &#39;_package&#39;, &#39;_register_formats&#39;, &#39;add_sheet&#39;, &#39;html&#39;, &#39;json&#39;, &#39;ods&#39;, &#39;size&#39;, &#39;wipe&#39;, &#39;xls&#39;, &#39;xlsx&#39;, &#39;yaml&#39;]

== output 2 sheets as yaml ==
- !!python/object/apply:collections.OrderedDict
  - - - data
      - - !!python/object/apply:collections.OrderedDict
          - - [name, Alice]
            - [age, 21]
            - [e/o, odd]
        - !!python/object/apply:collections.OrderedDict
          - - [name, Bob]
            - [age, 20]
            - [e/o, even]
        - !!python/object/apply:collections.OrderedDict
          - - [name, Carol]
            - [age, 31]
            - [e/o, odd]
        - !!python/object/apply:collections.OrderedDict
          - - [name, Taro]
            - [age, 10]
            - [e/o, even]
    - [title, null]
- !!python/object/apply:collections.OrderedDict
  - - - data
      - - !!python/object/apply:collections.OrderedDict
          - - [name, Alice]
            - [age, 21]
            - [e/o, odd]
        - !!python/object/apply:collections.OrderedDict
          - - [name, Bob]
            - [age, 20]
            - [e/o, even]
        - !!python/object/apply:collections.OrderedDict
          - - [name, Carol]
            - [age, 31]
            - [e/o, odd]
        - !!python/object/apply:collections.OrderedDict
          - - [name, Taro]
            - [age, 10]
            - [e/o, even]
    - [title, null]


== output 2 sheets as html ==
&amp;lt;h3&amp;gt;Set 0&amp;lt;/h3&amp;gt;
&amp;lt;table&amp;gt;
&amp;lt;thead&amp;gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;name&amp;lt;/th&amp;gt;
&amp;lt;th&amp;gt;age&amp;lt;/th&amp;gt;
&amp;lt;th&amp;gt;e/o&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;
&amp;lt;/thead&amp;gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Alice&amp;lt;/td&amp;gt;
&amp;lt;td&amp;gt;21&amp;lt;/td&amp;gt;
&amp;lt;td&amp;gt;odd&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Bob&amp;lt;/td&amp;gt;
&amp;lt;td&amp;gt;20&amp;lt;/td&amp;gt;
&amp;lt;td&amp;gt;even&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Carol&amp;lt;/td&amp;gt;
&amp;lt;td&amp;gt;31&amp;lt;/td&amp;gt;
&amp;lt;td&amp;gt;odd&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Taro&amp;lt;/td&amp;gt;
&amp;lt;td&amp;gt;10&amp;lt;/td&amp;gt;
&amp;lt;td&amp;gt;even&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
&amp;lt;/table&amp;gt;
&amp;lt;h3&amp;gt;Set 1&amp;lt;/h3&amp;gt;
&amp;lt;table&amp;gt;
&amp;lt;thead&amp;gt;
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;name&amp;lt;/th&amp;gt;
&amp;lt;th&amp;gt;age&amp;lt;/th&amp;gt;
&amp;lt;th&amp;gt;e/o&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;
&amp;lt;/thead&amp;gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Alice&amp;lt;/td&amp;gt;
&amp;lt;td&amp;gt;21&amp;lt;/td&amp;gt;
&amp;lt;td&amp;gt;odd&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Bob&amp;lt;/td&amp;gt;
&amp;lt;td&amp;gt;20&amp;lt;/td&amp;gt;
&amp;lt;td&amp;gt;even&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Carol&amp;lt;/td&amp;gt;
&amp;lt;td&amp;gt;31&amp;lt;/td&amp;gt;
&amp;lt;td&amp;gt;odd&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Taro&amp;lt;/td&amp;gt;
&amp;lt;td&amp;gt;10&amp;lt;/td&amp;gt;
&amp;lt;td&amp;gt;even&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
&amp;lt;/table&amp;gt;


&lt;/pre&gt;&lt;br /&gt;
Unfortunately, tablib can&#39;t be used in Jython. According to error message, this problem is caused by &lt;code&gt;grammer.py&lt;/code&gt; in &lt;a href=&quot;http://pypi.python.org/pypi/odfpy&quot;&gt;odfpy&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ jython
Jython 2.5.2 (Release_2_5_2:7206, Mar 2 2011, 23:12:06)
[Java HotSpot(TM) 64-Bit Server VM (Apple Inc.)] on java1.6.0_29
Type &quot;help&quot;, &quot;copyright&quot;, &quot;credits&quot; or &quot;license&quot; for more information.
&amp;gt;&amp;gt;&amp;gt; import tablib
Traceback (most recent call last):
  File &quot;&amp;lt;string&amp;gt;&quot;, line 1, in &amp;lt;module&amp;gt;
  File &quot;tablib/__init__.py&quot;, line 3, in &amp;lt;module&amp;gt;
    from tablib.core import (
  File &quot;tablib/core.py&quot;, line 15, in &amp;lt;module&amp;gt;
    from tablib import formats
  File &quot;tablib/formats/__init__.py&quot;, line 6, in &amp;lt;module&amp;gt;
    from . import _csv as csv
  File &quot;tablib/formats/_csv.py&quot;, line 6, in &amp;lt;module&amp;gt;
    from tablib.compat import is_py3, csv, StringIO
  File &quot;tablib/compat.py&quot;, line 45, in &amp;lt;module&amp;gt;
    from tablib.packages.odf import opendocument, style, text, table
  File &quot;tablib/packages/odf/opendocument.py&quot;, line 26, in &amp;lt;module&amp;gt;
    import manifest, meta
  File &quot;tablib/packages/odf/manifest.py&quot;, line 24, in &amp;lt;module&amp;gt;
    from element import Element
  File &quot;tablib/packages/odf/element.py&quot;, line 28, in &amp;lt;module&amp;gt;
    import grammar
java.lang.ClassFormatError: Invalid method Code length 370403 in class file tablib/packages/odf/grammar$py
 at java.lang.ClassLoader.defineClass1(Native Method)
 at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
 at java.lang.ClassLoader.defineClass(ClassLoader.java:615)
 at org.python.core.BytecodeLoader$Loader.loadClassFromBytes(BytecodeLoader.java:119)

...

java.lang.ClassFormatError: java.lang.ClassFormatError: Invalid method Code length 370403 in class file tablib/packages/odf/grammar$py
&lt;/pre&gt;&lt;br /&gt;
When I disabled importing pyodf, tablib can be used in Jython.&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/1650970.js&quot;&gt; &lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ python
&amp;gt;&amp;gt;&amp;gt; import tablib
&amp;gt;&amp;gt;&amp;gt; print tablib.formats.available
(&amp;lt;module &#39;tablib.formats._json&#39; from &#39;tablib/formats/_json.py&#39;&amp;gt;, &amp;lt;module &#39;tablib.formats._xls&#39; from &#39;tablib/formats/_xls.py&#39;&amp;gt;, &amp;lt;module &#39;tablib.formats._yaml&#39; from &#39;tablib/formats/_yaml.py&#39;&amp;gt;, &amp;lt;module &#39;tablib.formats._csv&#39; from &#39;tablib/formats/_csv.py&#39;&amp;gt;, &amp;lt;module &#39;tablib.formats._tsv&#39; from &#39;tablib/formats/_tsv.py&#39;&amp;gt;, &amp;lt;module &#39;tablib.formats._html&#39; from &#39;tablib/formats/_html.py&#39;&amp;gt;, &amp;lt;module &#39;tablib.formats._xlsx&#39; from &#39;tablib/formats/_xlsx.py&#39;&amp;gt;, &amp;lt;module &#39;tablib.formats._ods&#39; from &#39;tablib/formats/_ods.py&#39;&amp;gt;)

$ jython
&amp;gt;&amp;gt;&amp;gt; import tablib
&amp;gt;&amp;gt;&amp;gt; print tablib.formats.available
(&amp;lt;module &#39;tablib.formats._json&#39; from &#39;tablib/formats/_json.py&#39;&amp;gt;, &amp;lt;module &#39;tablib.formats._xls&#39; from &#39;tablib/formats/_xls.py&#39;&amp;gt;, &amp;lt;module &#39;tablib.formats._yaml&#39; from &#39;tablib/formats/_yaml.py&#39;&amp;gt;, &amp;lt;module &#39;tablib.formats._csv&#39; from &#39;tablib/formats/_csv.py&#39;&amp;gt;, &amp;lt;module &#39;tablib.formats._tsv&#39; from &#39;tablib/formats/_tsv.py&#39;&amp;gt;, &amp;lt;module &#39;tablib.formats._html&#39; from &#39;tablib/formats/_html.py&#39;&amp;gt;, &amp;lt;module &#39;tablib.formats._xlsx&#39; from &#39;tablib/formats/_xlsx.py&#39;&amp;gt;)
&lt;/pre&gt;&lt;br /&gt;
Thanks.&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://laclefyoshi.blogspot.com/feeds/5944242416681441779/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://laclefyoshi.blogspot.com/2012/01/outputting-data-for-people-with-tablib.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/5944242416681441779'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4078805449160415851/posts/default/5944242416681441779'/><link rel='alternate' type='text/html' href='http://laclefyoshi.blogspot.com/2012/01/outputting-data-for-people-with-tablib.html' title='Outputting data for people with tablib'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/09934531596280495750</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>