10
$\begingroup$

As far as I know, there are two posts on this topic: Can I use Mathematica to translate a English word to a Chinese characters? and *How can I use Mathematica to get the translated result from the Google Translate webpage?

But to my surprise, they both received no answers and no upvotes (until I upvoted them...). The second post was marked as duplicates to Export to Google Spreadsheet with OAuthAuthentication which I really don't understand. Why does translation have something to do with authentication?

To make my question specific, for example, I have a list of names

namelist={"Takaaki Kajita", "Arthur B. McDonald", "Isamu Akasaki", "Hiroshi \
Amano", "Shuji Nakamura"}

I want to translate this list into Chinese using Google Translate or other translation services:

{"隆明朱音", "阿瑟 麦克唐纳", "赤崎勇", "天野浩", "中村修二"}

I want to have a function, onlineTran. So

onlineTran[namelist,"Chinese"]

will give the translated list.

I found there are no translated results in the source HTML page, so I think Import probably won't work.


update

Both Alexey Golyshev and Rashid provide great solutions, though in terms of the quality of translation, Rashid's Google Translate solution is much better.

I want to add a workaround that is only specific to my example. My example actually comes from my recent post : How to make a picture grid of all Nobel Laureates in physics?

So the these names are all famous! They all got wikipedia pages! Fortunately, I just found Mathematica provides a function called WikipediaData which is quite useful. So here is the specific solution.

Clear[wikiTranslation];
wikiTranslation[word_,language_:"Chinese"]:=language/.WikipediaData[word,"TitleTranslationRules"]

so

wikiTranslation/@ namelist

gives result

{"梶田隆章", "阿瑟 麦克唐纳", "赤崎勇", "天野浩", "中村修二"}

And actually this results are more accurate than google translation. e.g. 梶田隆章 is the official translation appears on all media in China

I think this wikipedia method should be the best solution for proper names: such as celebrity, countries, famous place etc

$\endgroup$
  • $\begingroup$ A problem I see, at least with the Japanese names, is that different kanji (which as you know are repurposed Chinese characters) can have the same transliteration. $\endgroup$ – J. M. is away May 14 '16 at 16:09
  • $\begingroup$ @J.M. I am always curious about those Chinese characters used in Japanese. To be frank, I don't quite understand your question about kanji and transliteration : ) $\endgroup$ – matheorem May 14 '16 at 16:26
  • $\begingroup$ Here is one example I'm familiar with; I'm sure there are others. There is also the inverse problem of a particular set of characters having a different transliteration (e.g. on-yomi vs. kun-yomi). $\endgroup$ – J. M. is away May 14 '16 at 16:28
  • $\begingroup$ @J.M. When names in foreign language is transliterated in Japanese, kanji is almost never used (kanji is used only for Japanese names and words; for foreign loan words, katakana is used). I don't think it will be a problem when going from English to Japanese (Japanese to English may be problematic, but Google Translate is pretty smart and can output accurate English transliterations most of the time). Also, in Chinese, there is a single commonly-accepted transcription rule, as seen here. $\endgroup$ – JungHwan Min May 14 '16 at 16:36
  • $\begingroup$ @JHM, Yes, I know about the use of katakana for gairaigo; I had mentioned the transliteration only on account of seeing Japanese names in the OP's list. $\endgroup$ – J. M. is away May 14 '16 at 16:41
12
$\begingroup$

Since the Google Translate API requires authentication, a simple work around is to deploy as a web app a Google Apps Script that uses Google's LanguageApp, and then call that using URLExecute[].

To setup the Apps Script, go to script.google.com and create a new script with the following doGet function that uses the LanguageApp.translate method:

function doGet(e) {
  textlist=e.parameters.textlist;
  language=e.parameters.language[0];

  translation=[];
  for (nn in textlist){
    translation.push(LanguageApp.translate(textlist[nn], 'en',language));
   }
  outstring=JSON.stringify(translation)
  return ContentService.createTextOutput(outstring)
}

Save your script and then under the Publish menu, select Deploy as web app. Set the Who has access to the app to anyone, even anonymous to bypass login requirements. When you deploy, you will get a URL that looks like "https://script.google.com/macros/s/alphaNumericSequence/exec" with some alphaNumericSequence.

Now you can use URLExecute in Mathematica as follows:

webAppURL="https://script.google.com/macros/s/alphaNumericSequence/exec"
onlineTran[textList_, languageCode_] := 
  URLExecute[webAppURL, {"textlist" -> textList, "language" -> languageCode}]

Executing: onlineTran[{"Takaaki Kajita", "Arthur B. McDonald", "Isamu Akasaki", "Hiroshi Amano", "Shuji Nakamura"}, "zh-CN"]

Returns: {"隆明朱音","阿瑟·麦克唐纳","赤崎勇","天野浩","中村修二"}

The list of languageCodes supported by Google's LanguageApp can be found here

PS - In the event you need to edit the Google Apps Script, you will need to redeploy as a new version, because deployed scripts are static (see version documentation here). To deploy a new version of a script, save your changes and then go back to Deploy as web app under the Publish pulldown menu. Then select, the new option under Project version. Note that the deployed URL does not usually change, so you don't have to edit your Mathematica code. (This comes in handy when debugging Apps Script, especially when I make lots of typos -- sorry about that.)

$\endgroup$
  • $\begingroup$ Hi, Rashid. Your approach seems great. I have followed your step. But I got this error: "TypeError: Cannot read property "0" from undefined.(行 \ 3、ファイル「Code」、プロジェクト「doGet」)" $\endgroup$ – matheorem May 15 '16 at 2:00
  • $\begingroup$ @matheorem, thanks for the comment. Sorry about that. There was an inconsistency between the parameters in onlineTrans and in line 3 of the Google script. Please change the last onlineTran parameter to be "language" instead of "languagecode". I will edit right now. (Sorry, I must have introduced this while tying to cleanup the code.) $\endgroup$ – Rashid May 15 '16 at 2:07
  • $\begingroup$ Oops, Now I got this "ReferenceError: "texts" is not defined.(行 6、ファイル「Code」、プロジェクト「doGet」)" $\endgroup$ – matheorem May 15 '16 at 2:23
  • 1
    $\begingroup$ Sorry, @matheorem , I really botched this with my late edits to variable names. There is a typo now on lines 6 and 7 of the script, "texts" should be "textlist". Once you correct, you will need to "deploy again" and select "new" under the version options. (PS -The URL won't change, so you can leave the Mathematica code alone. ) will edit to correct now --learning my lesson that I should retest from scratch when posting edited code. $\endgroup$ – Rashid May 15 '16 at 2:32
  • $\begingroup$ Thank you so much. I actually corrected "texts" to "textlist" before, however I selected the wrong version. I selected "1"... Anyway, there was another typo in your onlineTran, I corrected it now. $\endgroup$ – matheorem May 15 '16 at 2:35
12
$\begingroup$
ClearAll[YandexTranslate];
YandexTranslate[string_String, lang_String, apikey_String: apikey] :=
 StringCases[
   URLFetch[
    "https://translate.yandex.net/api/v1.5/tr.json/translate?key=" <> 
     apikey <> "&text=" <> string <> "&lang=" <> lang <> 
     "&format=plain"
    ],
   "[\"" ~~ x___ ~~ "\"]}" :> x
   ][[1]]

YandexTranslate["Hello World!", "en-zh"]

"你好世界!"

You can receive your API key here: https://tech.yandex.com/translate/

The daily request limit is 1,000,000 characters. The monthly limit is 10,000,000 characters. To increase the request limit, switch to the fee-based version of the service.

It should be noted that Yandex can not transliterate your names. Google can do it but Google Translate API has no free quota.

$\endgroup$
  • $\begingroup$ For full flexibility, you could maybe add the target language as an additional argument. Also, it's a good idea to have the apikey argument take a default value, such as your assigned key: YandexTranslate[string_String, apikey_String: (* API key goes here *)] := (* stuff *). Then, YandexTranslate["Hello World!"] suffices. $\endgroup$ – J. M. is away May 14 '16 at 17:35
  • $\begingroup$ @J.M. Thank you. I have edited. Feel free to modify my code. $\endgroup$ – Alexey Golyshev May 14 '16 at 17:43
  • $\begingroup$ @AlexeyGolyshev Hi, AlexeyGolyshev. I got errors like "StringJoin::string: "String expected at position 2 in \!(\"translate.yandex.net/api/v1.5/tr.json/translate?key=\")<>apikey<>\!(\"&text=Hello World!&lang=en-zh&format=plain\")." and "URLFetch::invurl: "\!(\"translate.yandex.net/api/v1.5/tr.json/translate?key=\" <> apikey <> \"&text=Hello World!&lang=en-zh&format=plain\") is not a valid URL" $\endgroup$ – matheorem May 15 '16 at 1:50
  • 2
    $\begingroup$ Thank you, @Rashid! +1 from me. It's interesting: "The decision to ... replace it [Google Translate API] with the paid service was made due to the substantial economic burden caused by extensive abuse" (link) But over Apps Scripts their API is available for free :-) If I understand correctly, we can do 20,000 translations per day (URL Fetch calls), no characters limit. (link) Am I right? $\endgroup$ – Alexey Golyshev May 15 '16 at 5:40
  • 3
    $\begingroup$ @AlexeyGolyshev, I think that's right, but there are still runtime and size limits. For example, when I tried sending in a 9,000 character request, I got this error Your client issued a request that was too large. Assuming 20,000 calls/day and 8,000 characters/call though, that's a lot of translation. Let's hope this doesn't get turned off too due to abuse. $\endgroup$ – Rashid May 15 '16 at 6:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.