32
$\begingroup$

In the newly released version 11.1, Mathematica introduces three new functions: WebSearch, WebImageSearch and TextTranslation that requires Service Credits. While I haven't found much information about it, there are several characteristics I notice.

  • It is a separated service from Cloud Credit, and they do not share credits. (It can be proved by evaluating $ServiceCreditsAvailable and $CloudCreditsAvailable)

  • Functions require Service Credits consumes a certain amount of credits on each evaluation locally(a fundamental difference with cloud credits).

  • WebSearch and WebImageSearch consume approximately 3 credits per run, while TextTranslation consumes 1 credit per run (at least).

  • These functions do not cache the content, even if the queries are the same. (screenshot below)

enter image description here

When writing scripts with such functions, sometimes a bug could cause evaluating expression repeatedly unintentionally. With this possibility, service credits can be used up quickly without notice. With the trend of Wolfram Language integrating more highly automated informational functions with external services, I expect to see more functions of this kind in the future.

So I think having some overall control writing/executing scripts with paid functions are necessary. I thought of function Once to cache the result, in case there are identical calls, credits will be saved. The code illustrating this idea looks like this:

saveMoney[fun_] := 
 Module[{code = DownValues[fun]}, 
  DownValues[fun] = 
   Replace[code, {(h : (WebSearch | WebImageSearch | 
           TextTranslation))[a___] :> Once[h[a]]}, Infinity]]

However, it requires manually applying this function on each symbol defined. And this function has no control when the content string for calls are different. It is also possible to limit the number of times those functions can execute during an evaluation, but I have not tried to implement this yet.

What are some more effective methods(code) to control the unintended usages of those functions?

$\endgroup$
  • 1
    $\begingroup$ This has been done many times before in Mathematica for a variety of purposes. This could probably be adapted for example. $\endgroup$ – C. E. Mar 17 '17 at 12:49
  • 2
    $\begingroup$ I sincerely hope this is a bug. Surely a local call should not be charged service rates. $\endgroup$ – Mr.Wizard Mar 17 '17 at 17:26
  • $\begingroup$ @Mr.Wizard It seems that these function don't have caching by default. So in default cases, all calls will be sent to Wolfram's server thus charge Service Credits. :( $\endgroup$ – Wjx Mar 17 '17 at 23:36
  • $\begingroup$ @Mr.Wizard I think Wolfram will be moving more services to the cloud in the future:( $\endgroup$ – happy fish Mar 18 '17 at 7:06
  • 1
    $\begingroup$ Violence is inappropriate. $\endgroup$ – Αλέξανδρος Ζεγγ Mar 24 '17 at 4:38
14
$\begingroup$

Run the following code before you start your work or directly add this piece into init.m would solve the problem (at least for a while).

Options@TextTranslation;
Function[{func},
   Once[
    Module[{dv},
     dv = DownValues@func;
     Unprotect@func;

     DownValues[func] = {};
     AppendTo[Options[func], SaveMoney -> True];
     func[content___, opts : OptionsPattern[func]] := 
      If[TrueQ[OptionValue@SaveMoney], Once, Identity][
       ReleaseHold[((# -> OptionValue@# & /@ 
             Options[func][[;; -2, 1]]) /. {optseq__} :> 
            Hold[func[content, optseq]]) /. dv]];

     Protect[func, SaveMoney];
     ]
    ]
   ] /@ {WebSearch, WebImageSearch, TextTranslation};

Effect Image

Or a slightly enhanced version with total Service Credit usage monitoring:

Options@TextTranslation;
$MaxSCUsage = 2(*Adjust the Maximum Service Credit Allowed to use Here!!!*);
$InitSC = $ServiceCreditsAvailable;
Function[{func},
   Once[
    Module[{dv},
     dv = DownValues@func;
     Unprotect@func;

     DownValues[func] = {};
     AppendTo[Options[func], SaveMoney -> True];
     func[content___, opts : OptionsPattern[func]] := 
      With[{sc = $ServiceCreditsAvailable}, 
       If[$InitSC - sc >= $MaxSCUsage, 
        Print["You've used " <> ToString[$InitSC - sc] <> 
          " Service Credits in this Session!!!\nONLY " <> 
          ToString[sc] <> 
          " Service Credits Left!!!\nYOUR WALLET is BLEEDING!!!!!!!!!"];
        Abort[],
        If[TrueQ[OptionValue@SaveMoney], Once, Identity][
         ReleaseHold[((# -> OptionValue@# & /@ 
               Options[func][[;; -2, 1]]) /. {optseq__} :> 
              Hold[func[content, optseq]]) /. dv]]]];

     Protect[func, SaveMoney];
     ]
    ]
   ] /@ {WebSearch, WebImageSearch, TextTranslation};

With SC Monitoring

Let me explain a bit:

  • For usage, one can use the extra option SaveMoney with default value True to enable and disable this feature.

  • For realization, I used Once to ensure identical TextTranslation would only evaluate once. In the previous result, we can see that duplicative evaluation of TextTranslation would cost no Service Credits and the response is quite sharp(Try it yourself~).(Goal Achieved!)

Hope this feature can really save some precious Service Credits ~ :P


Note 1: The previous code could be easily used in almost any occasion where one need to aviod duplicative evaluation(Except those extremely rare cases with both Protected and Locked enabled). Also, one can add the code without any modification to other codes as it add this feature without adding a new function.

Note 2: One can use the following function instead of using the internal TextTranslation(But as it's in some way violating terms of service as xtian777x said, I don't recommend extensive usage). Seriously, its faster and gives similar quality result at least when using google translation.

Now this piece of code aims to translate Chinese to English, a slight upgration of this code can enable multiple language to language translation:

MyTextTranslation[chn_] := 
 StringCases[
   Quiet@URLRead[
     "https://translate.google.com/m?hl=zh-CN&sl=zh-CN&tl=en&ie=UTF-8&\
prev=_m&q=" <> chn, "Body", FollowRedirects -> True, 
     CharacterEncoding -> None], 
   "<div dir=\"ltr\" class=\"t0\">" ~~ Shortest[c__] ~~ "</div>" :> 
    c][[1]]

(Special Note for Chinese users, use .cn instead of .com)

The result is of the same quality as TextTranslate's solution:

sample translation result

$\endgroup$
  • 5
    $\begingroup$ The answer you got is very excited. $\endgroup$ – happy fish Mar 17 '17 at 15:20
  • $\begingroup$ I won't strongly suggest using the function you wrote (MyTextTranslation) because you'll probably get blocked by Google since they don't have a free quota (cloud.google.com/translate/faq) and you'll probably be violating their terms of service. $\endgroup$ – xtian777x Mar 17 '17 at 20:41
  • 1
    $\begingroup$ @xtian777x The fact is I'm trying to visit Google translate site and fetch and proceed the HTMl I get instead of connecting to Google translate API. Thus probably it won't be blocked. Also, by using Google translate in this way I suppose I'm not violating the Google translate website's terms of service? $\endgroup$ – Wjx Mar 17 '17 at 23:31
  • $\begingroup$ @xtian777x Also, you can see that the result given is different, which I strongly suspect Google is providing a better translation service for paid API users. $\endgroup$ – Wjx Mar 17 '17 at 23:34
  • 1
    $\begingroup$ @Wjx I'm just guessing with some sort of confidence about the terms since they don't have a free API and I'm sure they want to make money and avoid overuse of the free web based version. If you don't use it too much they probably won't notice, but, even if used manually, they will block you after so many translations. Also: stackoverflow.com/questions/14339190/… $\endgroup$ – xtian777x Mar 18 '17 at 22:31

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.