10

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

matheorem
  • 17,132
  • 8
  • 45
  • 115
  • 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. – J. M.'s missing motivation May 14 '16 at 16:09
  • @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 : ) – matheorem May 14 '16 at 16:26
  • 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). – J. M.'s missing motivation May 14 '16 at 16:28
  • @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. – JungHwan Min May 14 '16 at 16:36
  • @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. – J. M.'s missing motivation May 14 '16 at 16:41
  • @J.M. ah, that's right. In fact, all of the names in the list except Arthur B McDonald (阿瑟 麦克唐纳 is the Chinese transliteration) are Japanese. Hm. – JungHwan Min May 14 '16 at 17:24
  • @J.M. Thank you very much for the wiki page. I learned a lot. It is really interesting for a single name like "Akiko" can have so many variation, that's complicated enough... : ) – matheorem May 15 '16 at 02:08

2 Answers2

13

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.)

Rashid
  • 1,523
  • 10
  • 18
  • 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」)"
    – matheorem May 15 '16 at 02:00
  • @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.) – Rashid May 15 '16 at 02:07
  • Oops, Now I got this "ReferenceError: "texts" is not defined.(行 6、ファイル「Code」、プロジェクト「doGet」)" – matheorem May 15 '16 at 02:23
  • 1
    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. – Rashid May 15 '16 at 02:32
  • 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. – matheorem May 15 '16 at 02:35
  • Thanks @matheorem for correcting onlineTran. I also edited to add an information about how to redeploy Apps Script, which I have to do all the time while debugging. – Rashid May 15 '16 at 02:48
  • Rashid, do you know why the translated result is not in the source html page? I thought every thing should be in the source page. I am not familiar with the web things. – matheorem May 15 '16 at 03:11
  • Sorry @matheorem, I am not a web expert myself, so I am not sure I understand your question. What source html page do you mean? (As far as I understand we are returning a plaintext answer with ContentService.createTextOutput. You may be able to do more with HtmlService.createHtmlOutput. These are the two options for Apps Script web apps) – Rashid May 15 '16 at 04:23
  • I mean in browser you can look at the source code of the web page. Source page I mean something describe here http://www.w3schools.com/html/ – matheorem May 15 '16 at 04:57
12
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.

Alexey Golyshev
  • 9,526
  • 2
  • 27
  • 57
  • 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. – J. M.'s missing motivation May 14 '16 at 17:35
  • @J.M. Thank you. I have edited. Feel free to modify my code. – Alexey Golyshev May 14 '16 at 17:43
  • @AlexeyGolyshev Hi, AlexeyGolyshev. I got errors like "StringJoin::string: "String expected at position 2 in !("https://translate.yandex.net/api/v1.5/tr.json/translate?key=")<>apikey<>!("&text=Hello World!&lang=en-zh&format=plain")." and "URLFetch::invurl: "!("https://translate.yandex.net/api/v1.5/tr.json/translate?key=" <> apikey <> "&text=Hello World!&lang=en-zh&format=plain") is not a valid URL" – matheorem May 15 '16 at 01:50
  • You need to replace apikey with the actual key you obtained through your Yandex registration, @matheorem. I thought Alexey made that clear. – J. M.'s missing motivation May 15 '16 at 02:05
  • @J.M. Oh, my bad. It works now. Thanks : ) – matheorem May 15 '16 at 02:14
  • Thanks @AlexeyGolyshev. +1, yandex works great for translation, and this code is really compact. Btw - for transliteration and translation, you can get free calls to Google Translate using Google Apps Script. I've tried to show how to set this up in my answer. – Rashid May 15 '16 at 02:18
  • 2
    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? – Alexey Golyshev May 15 '16 at 05:40
  • 3
    @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. – Rashid May 15 '16 at 06:23