Eamonn O'Brien-Strain

MastodonBlueskyThreads


date: '2010-02-13 15:21:26' layout: post slug: 50-most-frequently-used-chinese-characters-presented-in-an-easy-to-learn-way status: publish title: 50 Most Frequently Used Chinese Characters Presented in an Easy-to-Learn Way wordpress_id: '722' categories: Language


I created this list of Chinese characters for my own benefit in trying to learn them. I took Jun Da's list of most frequently used characters and added a Google image search to provide some mnemonics. I added tone-color and exaggerated tone marks to the pinyin to help remind me of the the tones.

See this on a separate page with links to shorter and longer lists of characters.

(Note, this may look ugly if you are using Internet Explorer. It should look better on Firefox, Chrome, or Safari. I need to do a bit more CSS-hacking to make it work on IE.)

Loading ...

的 de di´di`

(possessive particle)/of, really and truly, aim/clear

Loading ...

一 yi¯

one/1/single/a(n)

Loading ...

是 shi`

is/are/am/yes/to be

Loading ...

不 bu`bu´

(negative prefix)/not/no

Loading ...

了 le liao˘liao`

(modal particle intensifying preceding clause)/(completed action marker), to know/to understand/to know, clear, look afar from a high place

Loading ...

在 zai`

(located) at/in/exist

Loading ...

人 ren´

man/person/people

Loading ...

有 you˘

to have/there is/there are/to exist/to be

Loading ...

我 wo˘

I/me/myself

Loading ...

他 ta¯

he/him

Loading ...

这 zhezhei

this/these, this/these/(sometimes used before a measure word, especially in Beijing)

Loading ...

个 ge`

(a measure word)/individual

Loading ...

们 men

(plural marker for pronouns and a few animate nouns)

Loading ...

中 zhong¯zhong`

within/among/in/middle/center/while (doing sth)/during/China/Chinese, hit (the mark)

Loading ...

来 lai´

to come

Loading ...

上 shang`

on/on top/upon/first (of two parts)/previous or last (week, etc.)/upper/higher/above/previous/to climb/to go into/above/to go up

Loading ...

大 dadai

big/huge/large/major/great/wide/deep/oldest/eldest, doctor

Loading ...

为 wei´wei`

act as/take...to be/to be/to do/to serve as/to become, because of/for/to

Loading ...

和 he´hehuo´huo

and/together with/with/peace/harmony/union, cap (a poem)/respond in singing, soft/warm, mix together/to blend

Loading ...

国 guo´

country/state/nation

Loading ...

地 de di`

(subor. part. adverbial)/-ly, earth/ground/field/place/land

Loading ...

到 dao`

to (a place)/until (a time)/up to/to go/to arrive

Loading ...

以 yi˘

to use/according to/so as to/in order to/by/with/because/Israel (abbrev.)

Loading ...

说 shui`shuo¯

persuade (politically), to speak/to say

Loading ...

时 shi´

o'clock/time/when/hour/season/period

Loading ...

要 yao¯yao`

demand/ask/request/coerce, important/vital/to want/to be going to/must

Loading ...

就 jiu`

at once/then/right away/only/(emphasis)/to approach/to move towards/to undertake

Loading ...

出 chu¯

to go out/to come out/to occur/to produce/to go beyond/to rise/to put forth/to occur/to happen/(a measure word for dramas, plays, or operas)

Loading ...

会 huikuai

can/be possible/be able to/to assemble/to meet/to gather/to see/union/group/association, to balance an account/accounting

Loading ...

可 ke˘

can/may/able to/certain(ly)/to suit/(particle used for emphasis)

Loading ...

也 ye˘

also/too

Loading ...

你 ni˘

you

Loading ...

对 dui`

couple/pair/to be opposite/to oppose/to face/for/to/correct (answer)/to answer/to reply/to direct (towards sth)/right

Loading ...

生 sheng¯

to be born/to give birth/life/to grow

Loading ...

能 neng´

can/may/capable/energy/able

Loading ...

而 er´

and/as well as/but (not)/yet (not)/(shows causal relation)/(shows change of state)/(shows contrast)

Loading ...

子 zi˘zi

11 p.m.-1 a.m./1st earthly branch/child/midnight/son/child/seed/egg/small thing, (noun suff.)

Loading ...

那 na˘nanei

how/which, that/those, that/those/(sometimes used before a measure word, especially in Beijing)

Loading ...

得 de´de dei˘

obtain/get/gain/proper/suitable/proud/contented/allow/permit/ready/finished, a sentence particle used after a verb to show effect/degree or possibility, to have to/must/ought to/to need to

Loading ...

于 yu´

(surname), in/at/to/from/by/than/out of

Loading ...

着 zhao¯zhao´zhe zhu`zhuo´

catch/receive/suffer, part. indicates the successful result of a verb/to touch/to come in contact with/to feel/to be affected by/to catch fire/to fall asleep/to burn, -ing part. (indicates an action in progress)/part. coverb-forming after some verbs, to make known/to show/to prove/to write/book/outstanding, to wear (clothes)/to contact/to use/to apply

Loading ...

下 xia`

under/second (of two parts)/next (week, etc.)/lower/below/underneath/down(wards)/to decline/to go down/latter

Loading ...

自 zi`

from/self/oneself/since

Loading ...

之 zhi¯

(literary equivalent of 的)/(subor. part.)/him/her/it

Loading ...

年 nian´

year

Loading ...

过 guo`

(experienced action marker)/to cross/to go over/to pass (time)/to celebrate (a holiday)/to live/to get along/(surname)/excessively/too-

Loading ...

发 fa¯fa`

to send out/to show (one's feeling)/to issue/to develop, hair

Loading ...

后 hou`

empress/queen/surname, back/behind/rear/afterwards/after/later

Loading ...

作 zuo`

to regard as/to take (somebody) for/to do/to make

Loading ...

里 li˘

inside/internal/interior, village/within/inside, Chinese mile/neighborhood/li, a Chinese unit of length = one-half kilometer/hometown



date: '2010-01-23 12:25:27' layout: post slug: see-real-example-results-of-website-optimization-ab-tests status: publish ref: https://web.archive.org/web/20121225101145/http://www.abtests.com:80/browse/ title: See real example results of website optimization A/B tests wordpress_id: '632' categories: Programming


One of the big advantages of creating Web products is that effectiveness can be immediately measured. One lucrative example of this is click-through web advertising.

Another example is A/B testing where you can put up two different versions of a web page, each visitor randomly seeing one version or the other. You can then measure the comparative effectiveness of each version of the web page, measured in terms that you care about, such as the percentage of visitors that buy your product.

Here is one example from the Firefox download page Try Firefox 3Download Now - Free

The only difference between these two versions is that the download button in the first has the text “Try Firefox 3” while in the second it has “Download Now – Free”. Over almost 300,000 trials the first one resulted in 9.7% of the visitors downloading Firefox, while the second one resulted in 10.1% downloads. By repeatedly doing A/B tests, changing one thing at a time, you can incrementally increase your conversion rate — using actual evidence rather than guesses or conventional wisdom.

This and many other examples are on the abtests.com web site, which provides a fascinating insight into this technique. Here people share the results of their A/B tests, rarely available because most companies regard them as proprietary.

What is particularly interesting is that these are not all good A/B tests. Some are badly designed, and some have such small sample size that the results are not statistically significant. By reading through the comments that people make you can learn best practices to follow and also bad practices to avoid.

All in all abtests.com is an interesting site, and I hope people keep on sharing tests there.



date: '2010-01-23 22:17:40' layout: post slug: add-a-button-to-your-browser-to-translate-selected-chinese-characters-from-a-web-page status: publish title: Add a button to your browser to translate selected Chinese characters from a web page wordpress_id: '643' categories: Futzing


You can now use Google to do some pretty readable translation of Chinese-language web sites.

However if you are trying to learn Chinese it would be better to be able to look at a page in its original Chinese, try to figure out the meaning and pronunciation of the characters, and to selectively translate the just ones you do not understand. Hopefully, just like using flashcards, you would eventually learn more and more characters.

As a first step I built a simple crude tool to do this. It is a little web-browser add-on button (a bookmarklet).

(So far, it seems to only work properly on Firefox. I have had some problems on Chrome and IE. I have not yet tested it on Safari.)

To install it, drag this button Explain Chinese;window.open('http://www.mdbg.net/chindict/chindict.php?page=worddict&wdrst=0&wdqb='+s,'b');})()) into your browser's links bar or bookmark bar. You should end up with an “Explain Chinese” button in your browser.

To use this button, highlight some Chinese characters, such as these ones 你好, and click the “Explain Chinese” button. It should open up two new pages with translations of the characters, one by Google which usually gives a fairly idiomatic translation of the text, and another one by the MDBG dictionary which breaks the translation down into the individual words and characters, and gives the pinyin and audio pronunciation.

Enjoy!

(Properly formatted version of this article is at http://www.eamonn.org/blog/?p=643 )



date: '2010-01-21 14:40:24' layout: post slug: learning-from-graphic-designers-grids-as-scaffolding-for-automatic-layout status: publish ref: http://www.slideshare.net/eobrain/learning-from-graphic-designers-grids-as-scaffolding-for-automatic-layout title: Learning from Graphic Designers — Grids as Scaffolding for Automatic Layout wordpress_id: '626' categories: Product


A presentation I gave yesterday at the “Imaging and Printing in a Web 2.0 World” conference (part of the broader Electronic Imaging Conference) in San Jose:

Learning from Graphic Designers — Grids as Scaffolding for Automatic Layout

View more presentations from Eamonn O'Brien-Strain.


Sure you can program in Scala just like you would in Java and get all the advantages of the cleaner syntax. But if you really want to explore the power of Scala you should try some functional programming.

One way to tell if you are programming in a largely functional manner is if you prefer val declarations to var declarations and if you prefer immutable to mutable classes.

To implement matrices, let's leverage the immutable lists generated by Scala's default List(...) call.

Arbitrarily choosing a row-major representation, we will represent a row of a matrix as as a list of doubles. For convenience let's create a type alias for that:

type Row = List[Double]

A matrix can then be a list of rows:

type Matrix = List[Row]

One fundamental operation we will be doing is a dot product. Let's implement this in map-reduce style:

def dotProd(v1:Row,v2:Row) =
  v1.zip( v2 ).map{ t:(Double,Double) => t._1 * t._2 }.reduceLeft(_ + _)

The zip method combines together two parallel lists of numbers into a single list of pairs of numbers. The map method multiplies the elements of each of these pairs together. The reduceLeft method sums the numbers of the list to create a single number.

OK, now let's see how we can create some of the standard matrix functions.

First here is how we can transpose a matrix:

def transpose(m:Matrix):Matrix =
  if(m.head.isEmpty) Nil else m.map(_.head) :: transpose(m.map(_.tail))

Notice this is a recursive function. It uses the construct _firstRow_ :: _remainderOfRows_ to form the list of rows that is the output matrix. It calculates the first row of the output matrix by using map to get the first element of each row of the input matrix. It gets the remainder of the rows by recursively getting the transpose of the matrix formed by the tail of each input row (i.e. every element except the first one).

How about matrix multiplication? That turns out to be pretty straightforward using standard Scala “for comprehensions”:

def mXm( m1:Matrix, m2:Matrix ) =
  for( m1row <- m1 ) yield
    for( m2col <- transpose(m2) ) yield
  dotProd( m1row, m2col )

Here we directly implement the matrix multiplication formula, iterating through the rows of the first matrix and the columns of the second matrix, and calculating the dot-product of each. Note that to iterate over the columns of a matrix we actually iterate over the rows of the transpose of the matrix.

However it would be nice to be able to use standard mathematical operators like A*B and AT when coding with matrices. Well, we can using the power of Scala's operator identifiers, infix syntax, and implicit conversion:

case class RichMatrix(m:Matrix){

  def T = transpose(m)

  def *(that:RichMatrix) = mXm( this.m, that.m )

}

implicit def pimp(m:Matrix)  = new RichMatrix(m)

The user of this library need never explicitly instantiate any RichMatrix objects — they are automatically created from List[Double[Double]] object whenever the T or * method is called on it.

This allows you to do things like:

        val M = List(
          List( 1.0, 2.0, 3.0 ),
          List( 4.0, 5.0, 6.0 )
        )
        val MT = List(
          List( 1.0, 4.0 ),
          List( 2.0, 5.0 ),
          List( 3.0, 6.0 )
        )

        M.T  must_==  MT

        val A = List(List( 2.0, 0.0 ),
    		 List( 3.0,-1.0 ),
    		 List( 0.0, 1.0 ),
    		 List( 1.0, 1.0 ))
        val B = List(List( 1.0,  0.0, 2.0 ),
    		 List( 4.0, -1.0, 0.0 ))
        val C = List(List(  2.0,  0.0, 4.0 ),
    		 List( -1.0,  1.0, 6.0 ),
    		 List(  4.0, -1.0, 0.0 ),
    		 List(  5.0, -1.0, 2.0 ))
        A * B  must_==  C

While we are at it we might as well add a few more convenience methods to the RichMatrix:

    case class RichMatrix(m:Matrix){

      ...

      def apply(i:Int,j:Int) = m(i)(j)

      def rowCount = m.length
      def colCount = m.head.length

      def toStr = "\n"+m.map{
        _.map{"\t" + _}.reduceLeft(_ + _)+"\n"
      }.reduceLeft(_ + _)

    }

The apply method is a special method invoked when the parenthesis operator is applied to an object. It allows you to, for example, do c(1,3) to get the number on the second row, fourth column of the matrix. Note that this method should not be used in performance-sensitive inner loops because it is not efficient. A matrix uses linked-lists as storage so the element access is O(N) not O(1) as would be the case if the matrix used arrays.

The rowCount and colCount methods are I hope obvious.

The toStr returns a string representation of the matrix in a nice tabular format that is much easier to than the default toString method if List[List[Double]], Note how this is done with two nested map/reduce pairs.

Now, creating a matrix using the List( List(...), List(...), ... ) syntax is fine for small matrices, but what if we want to generate large matrices? One way to do this is:

    object Matrix{
      def apply( rowCount:Int, colCount:Int )( f:(Int,Int) => Double ) = (
          for(i <- 1 to rowCount) yield
    	( for( j <- 1 to colCount) yield f(i,j) ).toList
        ).toList
    }

This allows you do do things like:

        // 100x200 matrix containing random elements
        val A =  Matrix(100,200) { (i:Int,j:Int) =>
          random
        }

        // 5x5 identity matrix
        val I = Matrix(5,5) { (i:Int,j:Int) =>
          if(i==j) 1.0 else 0.0
        }

Note that everything above is pure-functional: all the objects are immutable and each function is implemented as a single expression.

That's it for now. There is obviously a lot more we would have to add to make this a useful, production-quality library,

(If you want to try this yourself, you can download the complete source code and the BDD-style regression test that demonstrates its use.)



layout: post title: “How you might create a Scala matrix library in a functional programming style” date: 2010-01-10 category: Programming


Sure you can program in Scala just like you would in Java and get all the advantages of the cleaner syntax. But if you really want to explore the power of Scala you should try some functional programming.

One way to tell if you are programming in a largely functional manner is if you prefer val declarations to var declarations and if you prefer immutable to mutable classes.

To implement matrices, let's leverage the immutable lists generated by Scala's default List(...) call.

Arbitrarily choosing a row-major representation, we will represent a row of a matrix as as a list of doubles. For convenience let's create a type alias for that:

type Row = List[Double]

A matrix can then be a list of rows:

type Matrix = List[Row]

One fundamental operation we will be doing is a dot product. Let's implement this in map-reduce style:

def dotProd(v1:Row,v2:Row) = 
v1.zip( v2 ).
map{ t:(Double,Double) => t._1 * t._2 }.
reduceLeft(_ + _)

The zip method combines together two parallel lists of numbers into a single list of pairs of numbers. The map method multiplies the elements of each of these pairs together. The reduceLeft method sums the numbers of the list to create a single number.

OK, now let's see how we can create some of the standard matrix functions.

First here is how we can transpose a matrix:

def transpose(m:Matrix):Matrix =
if(m.head.isEmpty) Nil
else m.map(_.head) :: transpose(m.map(_.tail))

Notice this is a recursive function. It uses the construct firstRow :: remainderOfRows to form the list of rows that is the output matrix. It calculates the first row of the output matrix by using map to get the first element of each row of the input matrix. It gets the remainder of the rows by recursively getting the transpose of the matrix formed by the tail of each input row (i.e. every element except the first one).

How about matrix multiplication? That turns out to be pretty straightforward using standard Scala “for comprehensions”:

 def mXm( m1:Matrix, m2:Matrix ) =
 for( m1row <- m1 ) yield
 for( m2col <- transpose(m2) ) yield
 dotProd( m1row, m2col )

Here we directly implement the matrix multiplication formula, iterating through the rows of the first matrix and the columns of the second matrix, and calculating the dot-product of each. Note that to iterate over the columns of a matrix we actually iterate over the rows of the transpose of the matrix.

However it would be nice to be able to use standard mathematical operators like A*B and AT when coding with matrices. Well, we can using the power of Scala's operator identifiers, infix syntax, and implicit conversion:

case class RichMatrix(m:Matrix){

 def T = transpose(m)

 def *(that:RichMatrix) = mXm( this.m, that.m )

}

 implicit def pimp(m:Matrix) = new RichMatrix(m)

The user of this library need never explicitly instantiate any RichMatrix objects — they are automatically created from List[Double[Double]] object whenever the T or * method is called on it. This allows you to do things like:

val M = List(
 List( 1.0, 2.0, 3.0 ),
 List( 4.0, 5.0, 6.0 )
)
val MT = List(
 List( 1.0, 4.0 ),
 List( 2.0, 5.0 ),
 List( 3.0, 6.0 )
)

M.T must_== MT

val A = List(List( 2.0, 0.0 ),
 List( 3.0,-1.0 ),
 List( 0.0, 1.0 ),
 List( 1.0, 1.0 ))
val B = List(List( 1.0, 0.0, 2.0 ),
 List( 4.0, -1.0, 0.0 ))
 val C = List(List( 2.0, 0.0, 4.0 ),
 List( -1.0, 1.0, 6.0 ),
 List( 4.0, -1.0, 0.0 ),
 List( 5.0, -1.0, 2.0 ))

A * B must_== C

While we are at it we might as well add a few more convenience methods to the RichMatrix:

case class RichMatrix(m:Matrix){

 ...

 def apply(i:Int,j:Int) = m(i)(j)

 def rowCount = m.length
 def colCount = m.head.length

 def toStr = "\n"+m.map{
 _.map{"\t" + _}.reduceLeft(_ + _)+"\n"
 }.reduceLeft(_ + _)

}

The apply method is a special method invoked when the parenthesis operator is applied to an object. It allows you to, for example, do c(1,3) to get the number on the second row, fourth column of the matrix. Note that this method should not be used in performance-sensitive inner loops because it is not efficient. A matrix uses linked-lists as storage so the element access is O(N) not O(1) as would be the case if the matrix used arrays.

The rowCount and colCount methods are I hope obvious.

The toStr returns a string representation of the matrix in a nice tabular format that is much easier to than the default toString method if List[List[Double]], Note how this is done with two nested map/reduce pairs.

Now, creating a matrix using the List( List(...), List(...), ... ) syntax is fine for small matrices, but what if we want to generate large matrices? One way to do this is:

object Matrix{
 def apply(
  rowCount:Int, colCount:Int
 )(
  f:(Int,Int) => Double
 ) = 
 (
  for(i <- 1 to rowCount) yield
  (for(j <- 1 to colCount) yield f(i,j)).toList
 ).toList
}

This allows you do do things like:

 // 100x200 matrix containing random elements
 val A = Matrix(100,200) { (i:Int,j:Int) =>
 random
 }
 // 5x5 identity matrix
 val I = Matrix(5,5) { (i:Int,j:Int) =>
 if(i==j) 1.0 else 0.0
 }

Note that everything above is pure-functional: all the objects are immutable and each function is implemented as a single expression.

That's it for now. There is obviously a lot more we would have to add to make this a useful, production-quality library,

(If you want to try this yourself, you can download the complete source code and the BDD-style regression test that demonstrates its use.)

[Originally published on my old blog on 10 Jan 2010.]



date: '2010-01-07 16:46:31' layout: post slug: scala-tip-making-it-easier-to-add-attributes-to-an-xml-element status: publish title: 'Scala tip: Making it easier to add attributes to an XML element' wordpress_id: '609' categories: Programming


In most respects Scala makes it very easy to handle XML, but there are a few things that are hard to do. One is changing the value of an existing attribute on an element, or adding a new attribute to an element.

The simplest way I found to add new attributes c="CCC" d="DDD" is to do:

val modified = elem % new UnprefixedAttribute(“c”,“CCC”,Null) % new UnprefixedAttribute(“d”,“DDD”,Null)

This is a bit verbose. What if instead you could do

val modified = elem % Map( “c”–>“CCC”, “d”–>“DDD” )

Well you can, if you add the following implicit somewhere in scope:

implicit def pimp(elem:Elem) = new { def %(attrs:Map[String,String]) = { val seq = for( (n,v) <– attrs ) yield new UnprefixedAttribute(n,v,Null) (elem /: seq) ( _ % _ ) } }

This uses the library pimping pattern discussed elsewhere to effectively add a new version of the % operator to Elem that takes a Map of attributes.

The new % operator uses a for-yield construct to convert the attrs Map into a sequence of UnprefixedAttribute objects. It then uses the /: fold operator to repeatedly apply the built-in % operator, reducing down to an element with all the attributes added.



date: '2009-12-21 13:14:23' layout: post slug: scala-class-an-online-resource-to-make-it-easier-to-learn-the-next-big-language status: publish ref: https://web.archive.org/web/20150303015136/http://www.scalaclass.com/ title: Scala Class, an online resource to make it easier to learn the Next Big Language wordpress_id: '595' categories: Programming


I believe that Scala is poised to take off as the successor to Java as the main programming language for programming on the Java virtual machine. However, I have found the online resources for learning the language to be a bit weaker than for some other programming languages, so I set up scalaclass.com where I gather together material to get you started and support your continued development in this interesting new language. The site is still in embryonic form, but I welcome your initial comments.



date: '2009-12-19 16:53:35' layout: post slug: an-idiom-for-cleaner-pimping-of-libraries-in-scala status: publish title: An idiom for cleaner pimping of libraries in Scala wordpress_id: '592' categories: Programming


In dynamic languages like JavaScript and Ruby you can modify existing classes, including system classes, with extra methods. This can be a very handy, if dangerous, technique.

Scala, being a static language does not allow this same technique. But it does allow the use of implicit functions to get the same effect. For example the standard idiom to add sine and cosine methods to the Double class is

class PimpedDouble(x:Double){ def sin = Math.sin(x) def cos = Math.cos(x) } implicit def pimpDouble(x:Double) = new PimpedDouble(x)

This has the effect of adding sin and cos methods to Double, though what is actually happening is that Double values are automatically converted to PimpedDouble values when doing so would correctly compile.

This is very clever and very handy, but the idiom is a little clumsy, compared to most of Scala's elegant features. It is annoying to have to invent two names PimpedDouble and pimpDouble that are never referred to anywhere else in the code.

Can we do better? Yes we can. We can make the extra class be an anonymous class, which leaves only one arbitrary unreferenced name and also reduces the size of the code.

implicit def pimpDouble(x:Double) = new { def sin = Math.sin(x) def cos = Math.cos(x) }

That seems a lot nicer to me.

Using either of the above techniques you can now do things like

val x = 0.5 cos val y = 0.5 sin

which is taking the cosine and sine of the Double value 0.5

(Thanks to Daniel whose stackoverflow posting first brought this idiom to my attention.)



date: '2009-12-14 16:07:18' layout: post slug: sproutcore-a-rails-like-approach-to-creating-the-client-side-web-programming status: publish ref: http://www.sproutcore.com/ title: Sproutcore, a Rails-like approach to client-side web programming wordpress_id: '545' categories: Programming


A different approach to creating rich JavaScript/AJAX web apps. The programming and development methodology is basically the same as for Ruby on Rails, though it is all client-side and can work with any Server backend. (tags: programming web2.0 library design ruby javascript code web ajax css)