Showing posts with label yoruba. Show all posts
Showing posts with label yoruba. Show all posts

Friday, 2 March 2012

a backlog of lightbulb moments

Okay I admit. The title of the blog posts are usually as random as a phrase from a song I'm listening to while I write or something. Any way, I've been toiling with the idea of starting an open source project to create a download-able 'text' yoruba bible (I admit that there's probably one but I've not found it yet).

Thanks to the qbiblefree app (yes, I still use my N900 - and I'm not changing it till something better - read more hackable - comes along), I found out about Zefania XML format. So now I kinda know what format the bible would be in if I were ever to consider starting the project. The next question - were to get actual yoruba bible data from was kinda solved with a quick google search. The good people at http://www.africanportal.net/ABO/BibeliAtoka/ have uploaded pdf files containing bible books. Yes, there's still the problem of breaking it down into chapters and perhaps verses. Sejda has been a little helpful there - the books can be broken down into pages. It's not a one-to-one mapping with the chapters but it's a start. I figure I can actually use the pages as they are now with a little of meta data stored in a noSQL database or just flat files.

Then there's the really crazy part of how to type of all the pdf text through a web interface. My javascript is presentable at best. Or put another way, I program better in scala than in javascript - and you won't want to gamble your life on the quality of my scala code. Any way today something cool happened. I found this site here: http://www.jawish.org/blog/archives/314-Javascript-Thaana-Keyboard-version-3.0.html. It's basically the same problem as I'm trying to solve but for a different language. So I've spent the last two hours adding little modifications and I think it's works... almost. In fact, here's an example., there's an example text field at the end of this post that uses the modified script to allow you to type yoruba alphabets. Hopefully you can toil with it and probably even leave a comment on what you think.

I realize now that there's very little excuse for me not to go ahead with this project now - that's the scary part. I even found an example of how the keyboard interface can be designed: http://www.branah.com/dhivehi. But maybe it's time I started it anyway. I know it's time to sleep - lightbulb!

I'll upload a downloadable script with tutorials and all that. For now - use the non-yoruba letters (q, z, c, x, and v) on the keyboard for the non-english letters (Ọ, Ṣ, Ẹ) in the yoruba alphabet. The x and v are for acute and grave marks (ami) - type them before typing yoruba alphabets that require ami - hope it works :)

Saturday, 28 February 2009

Ayo and Scala 3.5

Ayo is a game that played in various forms across parts of west africa. I learnt it as a kid growing up in Benin City but with a different set of rules from what the way it's played in large parts of the yoruba people. The Yorubas call it Ayo but you've probably heard of it by the more popular name of mencala. Needless to say I'm implementing the game as explained here. Find out more about the game here.

Last time around I gave a quick overview of the scala implementation. Today I'll be looking at each component in a little more detail starting with the board. The board of ayo is made up of 12 holes, 6 on each side. Each one of these 12 holes has 4 seeds to start with. Each player also 'owns' all the houses (6) on one side of the board.

Here's a list of what I've design the board to be able to do:

- draw itself out to the console
- carry out a complete sequence of moves

So how do we implement this in scala?


object Board {


A scala object is a singleton class. So one rather crude and incorrect way of looking at a scala object is that you are looking at a java static class.


Declarations in scala are done using the def, val, and var keywords among other stuff. 'def' is used to define a method. In the case where a method takes no parameters you can leave the () brackets off the definition of the method. 'val' defines what can be called, in java parlance, a constant. Variables defined with 'val' can never be reassigned to another value. Then there's the 'var' keyword that defines regular good old fashion variables. These can be reassigned and all that...

There'd be no point in using scala if it didnt have a good enough library of containers among other things. The cool thing about scala is that it not only has libraries of its own but it also can leverage java libraries transparently - kind of like what python is to c/c++. In scala though, and largely because of its cool functionaly idiosyncresis, there're 2 types of container objects - mutable and immutable (actually there are 3 packages but that's besides the point here). A very popular example of a mutable object is java string class. Nothing can be done to the class itself that doesn't result in the creation of a brand new string. Well in scala you have lists and iterable elements that have this characteristic (we'll talk about this a little more later). I've digressed... let's take a look at the code again.


def roll(index:Int, stoneBuffer:Int, list:Array[Int]):(List[Int],Int) =
if(stoneBuffer==0)
(list.toList, position(index-1))
else{
list(position(index)) += 1; draw(list.toList)
roll(index+1, stoneBuffer-1, list)
}


The roll function is a recursive one. The signature of the method is that had to grasp. Where java would say int i, scala would say i:Int. So this is a method that takes 3 parameters. The method returns a 2 tuple containning an array and an integer. The contents of the tuple actually are the stones as they are arranged on the board after a sequence of moves and the position where the sequence of moves ended.
You'd also notice that the method contains just one if block and that there are no return statements. Well, that's because in scala all expressions are ... ok I dont know how to put it but by default the last expression in a method is returned. So one of the last statement in each of 'if' block's conditional subunits gets returned when the method is called.

What the roll function actually does is to check if there are any stones left to move about, if there isn't it returns the board and the current location. Otherwise, it adds one stone to the current location, reduces the number of stones left to move by one and then calls itself again... simple!

Next stop is the Rules object.

object Rules {
def canMove(plantedSeeds:Int) = plantedSeeds!=0
def canKeep(plantedSeeds:Int) = plantedSeeds==4
def hasHouse(houses:Set[Int]) = !houses.isEmpty
def gameOver(list:List[Int]) = list.reduceLeft(_+_) < 4
}

One thing you may have noticed is that I appear to be passing around a lot of excess luggage from function to function. Well that, I've heard, is one of the features of functional programming. Functional programming avoids side effects - which means I only deal with what the function returns and not with any changes that the function may have made to the parameters that I passed to it. One way of implementing this is to make sure that only immutable objects are used and passed along from method to method. That way I'm sure that if I sent you a parameter you wont be able to change it and all i'll have to worry about is what you've passed back to me. Consequently it's becomes pretty easy to test methods as everything is easily compartmentalized.

The Rules object basically just contains the rules of the game. For instance a player can only start a move (canMove) when there are seeds in the hole from which he wants to start the move. But this is an incomplete rule because a player cannot start a move from a house he doesn't own (Perhaps this is a design flaw).

Now it makes perfect sense to use singletons for both the Rules and the Board classes because both classes dont really have any fields. In essence, I'm trying my best to make this a fully working functional game (I think I wont succeed though, it's so paaaaainful). The other methods in the Rules object appear to be straight forward or in the words of one of my fav college teachers - "think small" (go figure)

Now let's talk interesting stuff

There's a class that stores the current configuration of the game. It's called Config. This class is a case class (what?). Well, in scala there's this cool type of class you can create that will authomatically create a toString method and comparison (equals/compareTo) method that works off of the toString method (I may be wrong here but's that how I understand it). The major advantage of this is that you can do some pattern matching on this class and generally write less code. So we define a case class that actually stores the seeds won by each player, the houses won by each player, the player whose turn it is to play and the arrangement of the stones left over on the board.
Now you cant change the values of the fields of a case class without really running into trouble since the toString class is created at class initialization (I need to verify this... but when I started learning scala way back on 1.6 or thereabout this appears to have been the case). In any case, each method of this config class that appears to modify any of its fields actually creates and returns a brand new Config object (cool eh?).

The constructor of a class in scala is the same of what appears to be the parameter list of the class itself, so in our case stones:List[Int], houses:List[Set[Int]], turn:Int, list:List[Int] are the parameters of the constructor of the Config class. The methods of this class are pretty straight forward so I wont be talking about them at all.


case class Config(stones:List[Int], houses:List[Set[Int]], turn:Int, list:List[Int]){

def plusStone(count:Int):Config = plusStone(count, turn)
def plusStone(count:Int, player:Int) = {
val s = stones.toArray
s(player) += count
Config(s.toList, houses, turn, list)
}
.
.
.
.


Ha! That's all for this week folks. I'll talk about how it all comes together when I look at the last part of the game (an object called 'Game') next week maybe.

Sunday, 8 June 2008

Yoruba Custom Keyboard in Ubuntu

I found it interesting that there was any support at all for yoruba when I first started using ubuntu two years ago. So since I'm not in school this summer and work is getting progressively more boring - i never thot I'd get fed up programming - I decided to spend the better part of this sunday getting the yoruba keyboard working on my system. Here are the steps I took to get it to work:

1. Create a file called yo.
2. Copy the following lines into the file you just created

// $XKeyboardConfig: xkeyboard-config/symbols/gb,v 1.11 2006-10-03 22:25:41 svu Exp $
// based on a keyboard map from an 'xkb/symbols/gb' file
// $XFree86: xc/programs/xkbcomp/symbols/gb,v 1.6 2003/10/04 10:25:14 pascal Exp $

partial default alphanumeric_keys
xkb_symbols "basic" {

// Describes the differences between a very simple en_US
// keyboard and a very simple yoruba keyboard layout defined by ... blah blah blah

include "latin"

name[Group1]="Yoruba Nigeria";

key { [ obelowdot, Obelowdot, q, Q ] };
key { [ U1E63, U1E62, z, Z ] };
key { [ ebelowdot, Ebelowdot, x, X ] };

//grave
key { [ U0340, U0341, v, V ] };
//acute
key { [ U0341, U0340, c, C ] };

include "level3(ralt_switch_multikey)"
};

3. Move the file to /etc/X11/xkb/symbol

- open your terminal
- run the following command. (I'm assuming that the file you just created was stored your desktop). Also note that you may have to specify your admin password to successful complete this command.

sudo mv ~/Desktop/yo /etc/X11/xkb/symbols/yo

4. Append the following lines to the file /etc/X11/xkb/rules/xorg.xml under the layout section


<layout>
<configitem>
<name>yo</name>
<shortdescription>Yo</shortdescription>
<description>Yoruba</description>
</configitem>
<variantlist>
</variantlist>
</layout>

5. Append the following line to the file /etc/X11/xkb/rules/xorg.lst under the ! layout section

yo Yoruba

6. Load the custom keyboard we just created.
- Open System -> Preferences -> Keyboard
- Select the Layouts Tab and Click the Add button. Look for the Layout matching the description you entered in step 4. If you've been following this tutorial verbatim then you should be looking for a layout called Yoruba
- One last thing you may want to do is make sure you know what the shortcut for switching keyboard layouts on your computer is. On my laptop pressing both Alt buttons together switches the keyboard layout. I also added you the MS Icon button. You can edit the shortcut for switching keyboard layouts by clicking the "Layout Options" button and then selecting "Layout Switching". Check/Uncheck whatever keys you wish to use for your shortcuts.
- You can close the keyboard configuration window now.

7. logout and log báck in. (Ctrl-Alt-Backspace if you like)

As always Ubuntu (and X based systems in general) rox.

Ok. Now if you want to know the how and why of all the voodoo that just took place here are a few links you can look up...

http://wikisource.org/wiki/Transwiki:Table_of_Unicode_characters,_32_to_9999
http://people.uleth.ca/~daniel.odonnell/Blog/custom-keyboard-in-linuxx11
http://www.linux.com/articles/113715

http://www.alt-i.org/projects.htm

you'd also want to look up /usr/include/X11/keysymdef.h which contains the key name definitions

On a final note, I've got to say thanks to Daniel O' Donnell for blogging on how to create custom keyboards. Also if you click on the last link I gave above you'd notice that the keymap I used in this tutorial is based on the QWERTY keyboard you've in that project. I figured since they say that they've done their research theirs would be a good example to follow.



I might put up pictures if the need arises but I'm lazy so dont count on it :D



Just for the fun of it... here's some stuff I typed on my keyboard: ... Eniyan ni eyi ṣòro fun; ṣugbọn fun Ọlọrun ohun gbogbo ni ṣiṣe

Thursday, 1 November 2007

Yoruba & Scala

Okay! I'm really bored... but then that's what this blog is about... and by the way i'll be posting a lot about scala (my new night time hobby) from now on :)

I've been playing around some with SCALA recently (for more info on scala see www.scala-lang.org). So I figured let's say some one has a free dictionary and he wants to make the search feature that's real neat. So he offers alternative spellings of the search word that the user enters. Well functional programming and SCALA in particular makes this really easy to do. Just take a look at the code below.

object YorubaOptions {
def alternative(info:String):List[String]={
if(info==null || info.length==0) List("")
else if (info.length==1)
info match {
case "e"=>List("e", "\\u232", "\\u233")
case "o"=>List("o", "\\u242", "\\u243")
case "i"=>List("i", "\\u236", "\\u237")
case "u"=>List("u", "\\u249", "\\u250")
case "a"=>List("a", "\\u224", "\\u224")
case "s"=>List("s", "\\u7779")
case _=>List(info)
}
else
combine(alternative(info.substring(0, info.length-1)), alternative(info.substring(info.length-1)))
}

def combine(lhs:List[String], rhs:List[String]):List[String]=for(word1<-lhs;word2<-rhs)yield word1+word2

def main(args : Array[String]) : Unit = {
YorubaOptions.alternative("akin").foreach(println)
}
}



It's a divide and conquer algorithm. Really straight forward... Divide the search word until it's lenght is '1'. Then either produce a list of alternatives.

Now it's true that this code only makes sense when run in a unicode environment but porting it to javascript and setting the html encoding will take care of this. On the other hand, code like this can be in the back end (PHP, JEE, ASP.NET, whatever your fancy) so that search results can be generated based on the user's search key word.

So what's next...

I've written a small script to change the keyboard so that you can practically change type yoruba characters with the normal english keyboard in an html control. I'll probably look into creating a linux xkeyboard symbols file so that I can type yoruba straight up from my OS too. Then when I'm really bored I'll look at a windows solution (let's not get me started on why poor naija students, like I was, should jump on the linux band wargon if nothing to save cost and learn practically).

Phew... I did all this typing and I've still got about 24 minutes before SUPERNATURAL starts... now what I'm going to do for the next 20 minutes :(