# Learning Japanese the Python Way

Leonora Tindall 2016/08/29

Now that I’m in college, I’m taking a lot of non-computer science classes, and one of them is Japanese. I’m just starting out, and I need to be able to rapidly read numbers in Japanese and think about them without translating them consciously. I could make a bunch of flash cards, or use a service like Quizlet… or I could write some Python!

For those of you who are unfamiliar, Japanese doesn’t have the ridiculous numerical system that English does. One through ten are defined, and eleven is simply (ten)(one). Twenty three, for example, is (two)(ten)(three) (に じゅう さん). This means that rather than having a long list of numbers and special cases, I can just have the numbers zero to ten “hard coded”.

After that, the program is pretty simple: if the number is less than 11, simply look it up. If it’s more than 11 but less than 20, build it with じゅう plus the second digit. If it’s larger than 20, build it with the first digit plus じゅう plus the second digit.

The interactive part is pretty simple too: it runs a loop that randomly generates numbers, checking that they haven’t been done before, translates them, and asks me to translate them back. If I succeed, it moves on; if not, it doesn’t record the number as having been completed, so I have to do it again at some point in the same run.

This simple program came out to 136 lines of very verbose and error-checked Python. It’s a good piece of code for a beginner to try and modify - for example, can you get it to incorporate the alternate form of four (し) as well as the primary form? Can you make one that teaches Kanji numbers? (I plan to do both of those things at some point.)

``````#!/usr/bin/env python3

"""
It currently goes from 0 to 99; I will extend it at a later date.

It can be executed as follows:

./numerica.py

which will do all the available numbers, or

./numberica.py 10

which will go only up to 10.
"""

numbers = ['ZERO',
'いち',
'に',
'さん',
'よん',
'ご',
'ろく',
'なな',
'はち',
'きゅう',
'じゅう',
]

class OutOfRangeException(Exception):
pass

def small_to_japanese(n):
"Convert a number (0-10) to Japanese."
if n > 10 or n < 0:
raise OutOfRangeException

return numbers[n]

def medium_to_japanese(n):
"Convert a number from 11 - 100 to Japanese"
if n > 100 or n < 11:
raise OutOfRangeException

digits = list(map(
int, str(n)
))

out = ""

# Omit いち in numbers > 10
if digits > 1:
out += numbers[digits] + " "
out += numbers + " "
out += numbers[digits]
return out

def number_to_japanese(n):
try:
return small_to_japanese(n)
except OutOfRangeException:
pass

try:
return medium_to_japanese(n)
except OutOfRangeException:
pass

print("No way to represent numbers of that magnitude!")

if __name__ == "__main__":
from random import randint
from sys import argv

# Check if there is a command line option for max numbers
if len(argv) >= 2:
try:
MAX_NUM = int(argv)
except ValueError:
MAX_NUM = -1

# A little edge case handling
if MAX_NUM > 99:
print("Impossible - this program doesn't "
"work with numbers over 99.")
exit(1)

else:
# If a max wasn't given, default to 99
MAX_NUM = 99

given = ""
done_so_far = []
number_done = 0

while True:
n = randint(0, MAX_NUM)
# If and as long as n has already been done, get a new number.
while n in done_so_far:
n = randint(0, MAX_NUM)

try:
given = input("What is {} in Roman numbers? ".format(
number_to_japanese(n)))
except KeyboardInterrupt:
print("Bye!")
exit(1)
except EOFError:
print("Bye!")
exit(1)

if given.lower() == 'quit':
print("Bye!")
exit(0)
if number_done >= MAX_NUM:
print("You did all the numbers in that set!")
exit(0)

try:
given_n = int(given)
except ValueError:
given_n = -1

if given_n == n:
print("You got it!")
done_so_far.append(n)
number_done += 1
else:
print("No, that's incorrect. This is {}.".format(n))
``````