Jan
11
2010
2

Let’s Hatsumoude!

The journey to Japan started off really well on the 7th when I unexpectedly met my Japanese teacher on the train. I had wanted to meet with her before leaving but I never had the chance, so I was really delighted to have the chance to catch up before I left. When I arrived at the airport things suddenly got a lot worse: the flight to London was cancelled, and then the later flight was delayed. I ended up missing my connection and sleeping in a corridor in Heathrow, which is just as awful as it sounds but at least I made an interesting friend who kept me company. Bob was on his way to Thailand, heading back to keep his farm running and to look after his go-go bar in Bangkok. He is a jiujitsu grand-master, has professional bodyguard experience, and is full of amazing stories. I think Satomi’s quite sick of hearing about Bob, though.

I finally arrived in Narita, to much warmer weather than Ireland/London—about 10°C with a little bit of sun.

Then it was off to Akihabara where I picked up a dual SATA to USB adapter for my hard drives (36€… it was about 115€ in Maplin in Limerick), introduced Satomi to the world of maid cafés, and had some dinner.

Yesterday we went to Kawasaki Daishi for Hatsumoude (初詣: the first shrine visit of the year). There were dozens of stalls selling various hot food and sweets prepared right in front of you. Everything you could want was right there, including sugar-glazed strawberries and apples, chocolate-covered bananas, octopus balls, Japanese “pancakes” (okonomiyaki.. not at all like a pancake really) in Osaka and Hiroshima style, hot dogs, candy floss, and lots of things that would take a lot of prose to explain but is very delicious!

IMG_0978
IMG_1034

They even had Fried Pikachu!

IMG_0977

After passing through all the stalls, everyone was corralled into a narrow residential street and waited to enter the shrine.

IMG_0983

Everyone was very orderly and quiet so even waiting there for about 30 minutes didn’t feel stressful or tiring. There were lots of nice decorations to look at around the shrine too.

IMG_0992
IMG_0996
IMG_0999

Finally we got to the entrance of the shrine and got into a second queue.
IMG_1012
IMG_1009
IMG_1013
IMG_1028

The shrine itself was very beautiful.

IMG_1019
IMG_1024
IMG_1025
IMG_1017

Fun was had by all, especially me and my tanuki friend.
IMG_1037

2 comments »
Written by ダニエル氏 in: Uncategorized |
Oct
30
2009
2

Ultra JLPT and Eircom Wi-Fi tool (dessid)

I released a couple of new apps last night: Ultra JLPT and dessid.

Ultra JLPT

Homepage | App Store

Ultra JLPT is the Japanese language trainer/tester I blogged about writing recently. There are five different apps for sale: one for each level of the JLPT test (1, 2, 3, 4) and then one simply called “Ultra JLPT” which contains vocabulary for all levels.

Ultra JLPT is totally focused on JLPT. For example, if you are studying JLPT4 there is much vocabulary that uses kanji that’s not on the syllabus. Ultra JLPT only displays these words in Hiragana, but of course there is an option to display all kanji characters in JLPT4 words, even if they are not required for the exam.

Logs are recorded and can be used to track progress, vocabulary can be refined by its type (only display kanji words, or only katakana words, or only those two, etc), and tests and be enabled/disabled in any combination, so if you want to focus on kanji reading that’s no problem.

dessid

Homepage | App Store

There have been many occasions where I’ve gone to a friend’s house and they’ve told me they have a wireless network, but they have to go searching for the password and when they do find it, it’s a long string of hex characters. This app discovers the password for many Eircom wireless networks so the password can just be put in your pasteboard and pasted in when the iPhone/iPod touch asks you for the password.

The password is also displayed on the screen so if you have some other device you need to connect, the password can be taken down from the iPhone/iPod touch screen, saving you from having to look up the password on the router.

2 comments »
Written by ダニエル氏 in: Uncategorized |
Sep
27
2009
0

Checking vocabulary against JLPT level 4

JLPT level 4 only has about 100 kanji and I wanted to check a database of vocabulary to see which entries are readable by people with JLPT4 and which need me to convert to a phonetic reading.

I first thought I’d do my standard regex check for hiragana and katakana, then compare the rest of the characters against an array of JLPT4 kanji.

I then realised I might as well just use a regex for the whole thing, and this monster was born:

^[ぁ-ゖ~ァ-ヶー一七万三上下中九二五人今休会何先入八六円出分前北十千午半南友口古右名四国土外多大天女子学安小少山川左年店後手新日時書月木本来東校母毎気水火父生男白百目社空立耳聞花行西見言話語読買足車週道金長間雨電食飲駅高魚]+$

Breaking it down:

  • ぁ-ゖ: Hiragana
  • ~: Handle prefixes/suffixes in the dictionary (such as “~枚” or “第~”)
  • ァ-ヶー: Katakana
  • The rest is the entire JLPT4 kanji list, in no particular order.
No comments »
Written by ダニエル氏 in: Uncategorized |
Sep
22
2009
11

Optimising JLPT

This year is the first year that the JLPT (Japanese Language Proficiency Test) will be run in Ireland. I’ve submitted my application form and now just have to wait until December. I searched the App Store for some apps that might help me brush up on my kanji and vocabulary for level 2, but I couldn’t find anything that worked the way I wanted it to. That left me with a great opportunity to make my own!

I’m using Core Data to store all the vocabulary. This allows me search through all the vocabulary somewhat quickly by specifying appropriate NSPredicates. An NSPredicate might look something like so

(isKanji == YES OR isKanjiHiragana == YES) AND level == 'JLPT 2'

This will give every JLPT level 2 word with a kanji character in it.

DatabaseIt has three different types of test, and seven tests including variations. The three tests are

  • Reading input: you must type in the correct reading.
  • Choose correct answer: you must select the correct answer from a list of potential answers.
  • Hide answer: the answer is hidden under a button. This one is pretty much a flash-card.

Test TypesThese three become seven when you see that you can take a Choose Correct Answer test and ask the user to select the correct meaning of a word, select the correct reading of a word, or select the correct word for a particular meaning. This extends to other tests and we end up with seven. Three classes exist, but there are seven objects with various different instance variables determining how they behave.

There are various categories of vocabulary: Katakana words, Hirgana words, Kanji words, Kanji+Hiragana words, prefixes, suffixes, miscellaneous (mix) and untestable (do not have reading or meaning available).

There are four JLPT levels (for now), and each of these levels has the categories above.

Every time a particular test has to generate a question, it has to find a word in the database suitable for the particular test. For example, if it’s Reading Input, there’s no point in testing a katakana word because it will be phonetic to begin with. It only makes sense to pick words with kanji in them somewhere. This means choosing a random managed object (i.e., a random row) that matches a particular NSPredicate from Core Data.

It turns out that this is slow. When I’d load a test, the screen would freeze up for a couple of seconds until it had sifted through the 5k~ rows of the database with a complex predicate. There were a few things I did to get this going faster.

Cache query results for each test

Word TypesThe first place I ran to was to cache the array of possible questions/answers for each test in the test object. When a test queries Core Data for a list of objects matching a predicate, save that list for next time so it won’t have to do a search again. A test’s predicate will not change through-out its life so caching everything with no expiry defined is safe to do.

This meant that the second time a particular search ran, it was fast. The first time, however, it was just as slow as before. And with seven different tests, that meant the user would have to experience seven slow-downs.

Load all data into a shared array and search manually

Next I decided to try to centralise the slow-downs to one place. I loaded everything in the database into an array at startup, which takes a couple of seconds but no longer than it took for each individual test.

When a test would need to find a value matching its predicate, it would pull a random one from the shared array and check it against the predicate. It would keep doing this until it found one. Except, sometimes it didn’t ever find one. Or it would take a really really long time before it came across one that would work! If it was never going to find one, there was no way that it could know that… so this was starting to look like a dead end.

Preload all data

Trying to centralise the slow-down without using a big, dumb shared array of vocabulary meant that each test would just fetch its own set of vocabulary matching its predicate at application start-up. Of course, this took many times longer than the previous method… but I had a plan…

Use a disk cache

The plan was to use a disk cache so that the hit wasn’t repeated across application launches. I implemented this, adding NSCoding to my Core Data object, but it was slow. Really slow. Writing or reading the file to disk took many times longer than querying the database to generate that array for me dynamically.

This was going to require a bit more intelligence…

Shared memory cache

Now knowing that querying the database directly was faster than loading query results saved to disk, I went about creating a memory cache shared across the whole app. This is basically an NSMutableDictionary with some fancy-pants methods around it. When the database is queried with a particular predicate, that predicate is stored as a key in the dictionary and the results from the database as the key’s object.

This meant that if you ran queries (or “fetch requests”, if you will… still not 100% comfortable with Core Data terminology) from different objects in the application but with the same predicates, the first would take time but the others would return immediately.

This meant that out of my seven tests, only five had to query the database and the other two could just pull from the cache.

Eliminate redundancy in level checking

The predicates I was generating at first were a total mess. To check for all vocabulary in JLPT 1, it would look something like this:

level == 'JLPT 1' AND (
  isKatakana == YES OR
  isHiragana == YES OR
  isKanji == YES OR
  isKanjiHiragana == YES OR
  isPrefix == YES OR
  isSuffix == YES OR
  isMiscellaneous == YES OR
  isUntestable == YES
)

Out of all those properties beginning with “is”, every single object will have at least one set. Therefore, when the user has not disabled any category (i.e., checking for all vocabulary as above), we might as well just use

level == 'JLPT 1'

This meant that to check for everything in the database, rather than having that big mess above multiplied by 4 (as there are four levels), the following can be used instead:

level == 'JLPT 1' OR level == 'JLPT 2' OR level == 'JLPT 3' OR level == 'JLPT 4'

Right? Right… but wait a minute! When the user has not disabled any level the above can be simplified to:

TRUEPREDICATE

:)

So when I was building a predicate to select everything in the database, it went from this

(level == 'JLPT 1' AND ( isKatakana == YES OR isHiragana == YES OR isKanji == YES OR isKanjiHiragana == YES OR isPrefix == YES OR isSuffix == YES OR isMiscellaneous == YES OR isUntestable == YES )) OR (level == 'JLPT 2' AND ( isKatakana == YES OR isHiragana == YES OR isKanji == YES OR isKanjiHiragana == YES OR isPrefix == YES OR isSuffix == YES OR isMiscellaneous == YES OR isUntestable == YES )) OR (level == 'JLPT 3' AND ( isKatakana == YES OR isHiragana == YES OR isKanji == YES OR isKanjiHiragana == YES OR isPrefix == YES OR isSuffix == YES OR isMiscellaneous == YES OR isUntestable == YES )) OR (level == 'JLPT 4' AND ( isKatakana == YES OR isHiragana == YES OR isKanji == YES OR isKanjiHiragana == YES OR isPrefix == YES OR isSuffix == YES OR isMiscellaneous == YES OR isUntestable == YES ))

to this

TRUEPREDICATE

This gave a ~300% speed increase. If a user deselects one category from each level, the speedup will be totally lost. However, I do not expect users to do this too much. The default settings have everything on, and I expect that users may wish to disable a full category (possibly the extremes?—too easy and/or too hard?).

Order operands by property name in logic operators

As I said earlier, by caching the query results against its predicate, I only had to run five of the seven queries. However, I noticed that a couple of these looked the same, except with the order of “sub-predicates” reversed. What I mean is that I saw

TEXT != nil AND reading != nil

together with

reading != nil AND TEXT != nil

These are obviously the same thing, logically, but as strings they are completely different. There is no way to prove predicates are logically equivalent on the iPhone so to solve this, I made sure that when I construct these predicates with logic operators such as AND and OR, I order the operands based on the property name’s alphabetic order. What that means is that either of the above will become

reading != nil AND TEXT != nil

This is because “reading” < “text”.

This reduced the number of queries from five down to three!

Skip != nil if the property is not optional

Finally, I noticed that many of my predicates contained

TEXT != nil

The text property is not “optional”. That’s the same as having a “not null” column in the normal database world. So why bother checking if it’s nil if it’s never going to be nil?

NSEntityDescription can provide an NSDictionary of NSPropertyDescriptions, which let you know if any property isOptional or not. I used this to eliminate these redundant tests.

And this brought the number of unique queries down from three to just two!!

Conclusions

By simplifying predicates to logically equivalent but more sensible versions where possible, I reduced loading time to a third with default settings.

By shuffling around operand ordering and removing redundant comparisons, less obviously logically-equivalent predicates were discovered: for the seven tests there is only actually two predicates required.

By using a shared memory cache there is the overhead of a few seconds at application startup, but this means that queries with equal (not equivalent) predicates are only run once. It’s up to the rest of the application to make sure that equivalent predicates end up being equal as much as possible.

11 comments »
Written by ダニエル氏 in: Uncategorized |
Sep
09
2009
1

Dublin

Quite a productive few days in Dublin! In no particular order.. at all..

Got an IBM.. er.. Lenovo Thinkpad from IBM and presented my FYP at their Dublin location. Thanks, IBM! It was a great event!

Got shouted at by a PC World employee for saying that I didn’t need Norton and would be using AVG. I was told it was “crap” and I “think I’m safe but probably have trojans on my PC”. I know he definitely knew what he was talking about because he told me he “used to be an engineer”.

Downloaded iTunes 9! Thanks, Steve!

Got Muse’s new album! Thanks, Matt!

Visited my grandma and a few relatives. Had a nice stir fry. Thanks, Stan!

Never got lost! Thanks Google+Apple!

Had a very interesting lunch! Thanks, Gavin!

PC World machine didn’t work in the end. No thanks to you, PC World :(

1 comment »
Written by ダニエル氏 in: Uncategorized |
Jul
26
2009
0

Call of Juarez: Who is William?

I started playing the new Call of Juarez game today: a first-person shooter set in the wild west. You can play as one of two confederate-soldiers-turned-gunslinger brothers Ray and Thomas. Ray seems to have more health and is really a DPS (damage per second) character: he can throw dynamite and dual-wield pistols. Thomas, on the other hand, feels a bit quicker, can climb around more easily (with the use of a lasso) and is better with ranged weapons than pistols.

This presents a nice choice to the player. I play as Ray, but this is just because his set of abilities best matches my style of playing. I have friends who would feel much more comfortable playing as Thomas. It’s quite easy to associate with either and put yourself into the game. At least it’s immersive once you’re running around on horseback through the desert of Arizona shooting other outlaws. Here’s the problem: there is another brother.

This third brother, William, is not a gunslinger; he’s a priest. He’s younger than Ray and Thomas and disagrees with everything they do. He follows them around the game complaining about their actions. The problem is, the player is going to be playing as either Ray or Thomas and doing exactly what the game tells them to do: in order to actually enjoy the game and see the plot unfold. However, while the user is playing the game there’s this whiny character appearing all the time, nagging the player for actually playing the game!

Now that’s not affecting the immersion right away; it’s just an unpleasant character to have in the game. (Or rather, a character that’s too pleasant and therefore conflicts with every other character in the gritty unpleasant world of Call of Juarez.) The immersion immediately disappears at regular intervals (at least for me) due to one design decision: William is narrating the story. I don’t like all the cut-scenes in general and would prefer if the plot would unfold entirely through gameplay. However, I can live with them if it’s my own character (or at least his brother) narrating it. But when William is narrating it, he is always complaining about how his brothers are behaving (or rather, how the player is playing the game).

After playing a level from the point-of-view of a hardened gunslinger, then suddenly to have narration from an observer who a totally opposite (and predictable and repetitive, rather than thought-provoking) view of the events of the game, I immediately want to hammer the escape key until we get to the next level. I have been avoiding that very thing so far though, as I don’t want to miss any plot elements.

When Medal of Honor: Allied Assault came out with a D-Day scene exactly like Saving Private Ryan, I was delighted! I really loved that scene and it was so exciting to play it. Bringing in Eli Sunday from There Will Be Blood into Call of Juarez isn’t something I’m so excited about (even though I really loved Eli Sunday!) I just can’t get used to William narrating the story.

Still, it’s a great game and I’m looking forward to trying out the multiplayer part of it next time some friends are having a game!

That’s all the ranting for tonight. :)

No comments »
Written by ダニエル氏 in: Uncategorized |
Jul
13
2009
0

Enviro-bear: Best iPhone Game to date?

I saw this on Boing Boing today and downloaded it. The video is the PC version but there’s an iPhone one now too. It’s one of the most bizarre things I’ve ever had the fortune to play and actually a really fun game too! The only problem is that it seems to crash half way through “Year 2″.

I love the badgers that fall into your car and start savaging you and eating your food, and the other cars which can be seen to be driven by angry bears when you get close enough.

No comments »
Written by ダニエル氏 in: Uncategorized |
Jul
13
2009
0

Call of Duty 4 server

I’ve been working with Terran on setting up a Call of Duty 4 server ever since he got a loan of a dedicated Linux box somewhere in Europe (I can’t remember if it was France or Germany).

I started uploading the 6GB of files from my installation necessary to run the server, but the rsync kept failing. Even without this trouble it was still going to take ages to upload 6GB, so Terran downloaded an ncurses (command-line) BitTorrent client and started downloading a CoD4 ISO. This finished last night so I went about getting those precious install files out of it.

  1. First I dropped in my SSH public key with SCP
    locomoco:~ scp ~/.ssh/id_rsa.pub root@123.123.123.123:.
  2. I made sure that I had an up-to-date X11 install.
  3. I opened X11 to get an xterm up and SSH’d into the server with X-forwarding on (and xauth junk turned off by using -Y instead of -X).
    locomoco:~ ssh -Y root@123.123.123.123
  4. Adding my public key to authorised_keys so I won’t be asked for passwords anymore when SSH’ing in as root.
    remote:~ cat id_rsa.pub >> .ssh/authorised_keys
    remote:~ rm id_rsa.pub
  5. Installing wine:
    remote:~ apt-get install wine
  6. Mounted the ISO:
    remote:~ mkdir /mnt/cod4
    remote:~ mount -o loop ~/cod4.iso /mnt/cod4
  7. The server has a small partition (/dev/sda1) for / and a large one (/dev/sda2) for /home, so I moved ~root’s .wine folder out of /root to have some more room for the virtual C: drive:
    remote:~ mkdir /home/cod4/
    remote:~ mv ~root/.wine /home/cod4/
    remote:~ ln -s /home/cod4/.wine .wine
  8. Then it’s ready to be installed! (I hope your X server is set up right!)
    remote:~ wine /mnt/cod4/setup.exe
  9. Once it’s installed I pulled extra files from home into the install directory (/home/cod4/install/):
    remote:~ rsync --progress -avz daniel@locomoco:/cygdrive/c/Games/CoD4/Main /home/cod4/install/
  10. I repeated this for the zone and Mods folders
  11. Unmount the ISO:
    umount /mnt/cod4
    rmdir /mnt/cod4
  12. Now I just need Terran to set up the server!
No comments »
Written by ダニエル氏 in: Uncategorized |
Jul
01
2009
1

Device Naming

When two computers were in this house I wanted to give meaningful names to them, in anticipation for when there would be a lot on the network and they would all need unique names.

Obligatory Cliché

First I started off with Lord of the Rings. This was about a year before the first movie came out and I had just read all the books, so that was pretty much all I thought about for a few months. If it wasn’t for LotR lore, I would have ended up using ancient Greek gods or some other cliché popular with young teenage geeks. Gandalf was the more powerful one (1.2GHz P4 I think), and Frodo the 350MHz thing.

Breaking the pattern (Does 2 even make a pattern?)

The first machine I made I called Frank. This was short for “Frankenstein’s Monster”, since I had put it together myself from parts bought from places all over the net and all over Limerick. That meant that the LotR naming scheme had gone out the window (or off the Bridge of Khazad Dum, rather).

Japanese, of course

When I started getting Macs I wanted to start using Japanese names. I named the iMac G5 Nozomi, after a female character from a favourite game of mine: Shenmue. However, I couldn’t think of name appropriate for a machine when I got the white MacBook, so I just called it “Nanashi”, which means “no-name”.

Another scheme breakdown

Last year I built a PC and named it Honeybee, just because I really liked the name. It’s a far too cute for a big black powerful Windows box, and I thought it was funny to give it a name like that.

Revisiting Japanese

Quickly I came up with a new scheme for the next machine: Japanese onomatopoeic vocabulary. After just about getting a PC to work after many failed install attempts, I called it “girigiri” which means “just about”. In this case, the install had worked, but just about.

Slightly adjusting this, I decided to use Japanese “bikkuri” words. These are a set of words (mostly adverbs but plenty of verbs) which all rhyme. I called one PC “gakkari”, meaning disappointment. Next one was “yukkuri”, meaning slowly.

Delicious naming

And most recently? My MacBook Pro is called Loco Moco. This is a Hawaiian dish that’s popular in Japan. It’s rice, a burger patty, and a friend egg, in that order, from bottom up, in a bowl. The virtual machines are named Tamago (Windows XP.. “egg”) and Burger (Ubunutu). My iPhone is named Shoyu (“soy-sauce”), a popular Japanese condiment. I figured it didn’t really deserve another full dish name or ingredient, but being a portable device can be given a condiment name. Just waiting for a pair of devices to call Salt and Pepper :D

What’s in a name?

I don’t ever anticipate having a meaningful scheme across all my machines. The problem is that I keep getting machines a year or two apart, and I always have a different set of interests by the time I need to think of a new name. I also get bored of my great ideas very quickly. What seems like the best idea I’ve ever had one day will seem really stupid in a week’s time, once I’ve had time to think about it enough. Where’s the fun if you can remember the names of all the machines in the house anyway? To be honest I usually just end up finding which machine is which with nmap -v -sP.

1 comment »
Written by ダニエル氏 in: Uncategorized |
Jun
26
2009
0

Compu b talk

Update (30 Jun): Talks are not being swapped—it@cork and Compu b talks will both be delivered by yours truly.
Update (29 Jun): I had the old Compu b location on the map below. It’s updated to the right place now.

Due to some scheduling conflicts, I have ended up swapping talks with Patrick. He will present at it@cork and I will be presenting this Tuesday (30th June) at Compu b in Limerick, from 8.00pm. (Beside Brown Thomas. Map below.)

The original title of the talk was “iPhone SDK” but after talking with a few people in Compu b about it, I have decided to change the topic to “What is an iPhone App?” I will introduce Apps, explain why they’re different and exciting, and give an overview of the life of an App, from an idea in someone’s head to an icon on iPhone screens around the world.


View Limerick Businesses in a larger map

Written by ダニエル氏 in: Uncategorized |

Powered by WordPress | Theme: Aeros 2.0 by TheBuckmaker.com