おもこん

おもこんは「思いつくままにコンピュターの話し」の省略形です

英語版「はじめてのRake」

このところブログの更新ができていませんでした。

その理由は、「はじめてのRake」の英語版を書いていて、忙しかったからです。

レポジトリはこちら

先日、「Google先生に英語を習う」で、「日本語のドキュメントをGoogle翻訳で英訳し、その英語を手直しすれば短時間で翻訳が完成する」と書きました。 その手法を使って、「はじめてのRake」英語版はあっという間にできるはずでした。

ところが、そうでもなかった。 ある意味、自分の考えの実証実験にもなったので、その結果分析をここに書きたいと思います。

なぜ予想より時間がかかったのか? 2つの理由があったと思います。

第1に、元の日本語をGoogleが理解しにくかった。 この原因は元の日本語にあります。 私は日本語ネイティブなので、手を抜いた日本語でも分かってしまうが、Google翻訳にはそれがマッチしなかった。 論理的で必要かつ十分な説明文であれば、もっとGoogleの英語は良かったでしょう。

第2に、英語が自然でない。 Googleは正確を期すため、直訳に近い形で翻訳します。 これについて、Google 先生に失礼のないように補足すると、訳された文章は英語としては完璧に合っていて意味は通ります。 しかし、いまひとつしっくりこない。 全体に説明がくどい感じがするんですね。 例えば、

日本語「Rakeは複数のコマンドやメソッドの実行を管理するプログラムです。」

=> 英語「Rake is a program that manages the execution of multiple commands and methods.」

日本語もややくどい感じはあるものの、不自然ではないと思うのですが、英語はa bit more complicatedな感じがします。

「Rake manages multiple commands and methods.」 ぐらいの方がシンプルで良いと思うんですが・・・どうでしょう?

このような箇所がいたるところにあり、その修正に時間ががかかってしまいました。 また、時間がかかると思い始めたら、余計その翻訳に手をつけるのが面倒になり、モチベーション低下がさらに作業時間増加に拍車をかけることになりました。 結果、一週間近くかかってしまいました。

冒頭に書いた先日のブログの内容については、「そういう方法もあるけれど、翻訳が早くなるとは限らない」と修正させていただきます。 申し訳ありません。 反省します。

次にドキュメントを英訳することがあれば、自分で英訳を作りGoogleで日本語に訳してもらい、不自然でないかチェックする方法をとろうと思います。 そして、その方が翻訳が速いのかどうか、結果を報告したいと思います。

そんなわけで、今日疲れておりますのでこの辺で失礼いたします。

(2022/8/9 追記) その後あらためて英語版「はじめてのRake」を見直したところ、おかしな部分が続出、2日かけて全部見直しました。

はあーーー

英語力全然無いなーー

【森を見よ】(−7)÷3のあまりはいくつ?

今日は数学ネタです。 「木を見て森を見ない」(小さなことにとらわれて全体を見ない)にならないよう「森を見よ」シリーズ2回めです。

7÷3=2・・・1

小学校で習うことですが、7割る3の商は2、あまりは1です。 では、「マイナス7割る3」のあまりはいくつでしょうか?

「(−7)÷3」のあまりは
(1) −1 (2) 1 (3) −2 (4) 2

正解は(4)の2です。 正解した方はさすが! −1と答えた方も少なからずいるのでは?

で、ここからが本題ですが、それはなぜでしょうか? それは、「(−7)÷3」だけでなく、整数全体を考えることにより分かってきます。 「森を見よ」ということですね。

1÷3=0・・・1
2÷3=0・・・2
3÷3=1・・・0
4÷3=1・・・1
5÷3=1・・・2
6÷3=2・・・0
7÷3=2・・・1
8÷3=2・・・2
9÷3=3・・・0
10÷3=3・・・1

これを注意深く観察すると、

  • 3で割ってあまり0の数は2つおきに現れる
  • 3で割ってあまり1の数は2つおきに現れる
  • 3で割ってあまり2の数は2つおきに現れる

そこで、これらを色分けすると

                  10
  • シアン・・・3で割ると1余る数
  • 黄色・・・3で割ると2余る数
  • ピンク・・・3で割り切れる数

これを「2つおきに同じ色」になるように、マイナスの数まで伸ばしてみましょう。

−9   −8   −7   −6   −5   −4   −3   −2   −1                       10

−7は黄色だから、3で割って2余る数に入っていますね。

あまりは常に3の倍数から右に(正の方向に)いくつずれるかを表します。 たとえば8であれば3の倍数6から2だけ右にずれています(つまり+2だけあまる)。 同じように、−7は3の倍数−9から右に2だけずれているので、あまり2となります。

より正確に言えば「あまりは0以上割る数未満」です。 3で割るときは、「0以上3未満」すなわち0,1,2です。

計算上は、

7÷3=2・・・1
7=3✕2+1

から、

−7=3✕(−2)+(−1)
あまりは常に正(右にずれる)から、商を−3にして
−7=3✕(−3)+2
−7÷3=−3・・・2

このように、商をひとつずらして考えることで計算できます。 ポイントは「あまりは0以上割る数未満」ということです。

Google 先生に英語を習う

私は Google 翻訳をよく使っています。

使い方は様々です。

  • 英語の単語を入力して日本語にする=>翻訳欄の下に、辞書のようにいくつかの訳が出る
  • 英語のワンセンテンスを入力して日本語にする
  • 英語のウェブサイトを丸ごと日本語にする=>画面上の「ウェブサイト」ボタンをクリックしてURLを入力すると、そのページがそっくり翻訳されて表示される(便利!!)
  • 英語のドキュメント(PDFとか)を日本語にする=>画面上の「ドキュメント」ボタンをクリック=>「パソコンを参照」をクリック=>翻訳したいドキュメント(PDFなど)のファイルを指定=>「翻訳」をクリック=>「翻訳をダウンロード」をクリック=>翻訳されたドキュメントができる(便利!!)
  • 日本語の(主に自分で作った)ドキュメントを英語にする=>翻訳された英語を手直し=>英語ドキュメントの完成(短時間で完成!!)=>2022/8/8追記:実際に英訳に応用してみたところ、さほど時間短縮にはなりませんでした。
  • 自分で書いた英語を日本語に翻訳=>正しい英語だったのかを検証できる

特に最後の、英語の検証には良く使いますが、これに適するのはドキュメントのような「書き言葉」です。 会話文は上手くいかないケースがあるかもしれません。

ところで Google翻訳はどれくらい変換精度がいいのでしょうか?

  • 「グーグル先生に英語を習う」=>「learn english with google teacher」(ダメ)
  • 「グーグル先生に英語を習うことに決めた。」=>「I decided to learn English from Mr. Google.」(OK・・・完了形ならもっと良いかも)
  • 「グーグル先生に英語を教わった。」=>「I was taught English by Mr. Google.」(教わったは受け身になるんだね、なるほど)
  • 「グーグル、国会の英語は?」=>「Google, what is the English of the Diet?」(日本の場合はOK、イギリスはparliamentアメリカはcongress、でも入力の日本語は、たぶん日本の国会を指してるよね)
  • 「グーグル、議会の英語は?」=>「Google, parliamentary English?」(???)

書き言葉は一般に必要十分な情報が含まれるので、Googleは、ほぼ正しい翻訳ができそうです。 それに対して会話文は省略が多いので翻訳できないケースが少なくない、と考えられます。 英会話は、英会話スクールやラジオ講座じゃないとダメのようですね・・・

さて、最初に書いたGoogle翻訳の使い方、きっと皆さんの役に立つと思います。 とくに、ウェブサイトやドキュメントを丸ごと翻訳してくれる機能は凄い!! 活用してください。

NHK「笑わない数学」

NHKの「笑わない数学」(水曜23時〜)を見ている。 今まで3回放送されていて、「素数」「無限」「四色問題」がテーマだった。 全12回シリーズだそうだ。

www.nhk.jp

自分は大学で数学を専攻した。 その経験にもとづくと、数学には2つある。 抽象数学と応用数学

多くの人が「数学はいろんなところで使われている」「数学はビジネスで大活躍」というとき、それは応用数学であることが多い。 一方、抽象数学はごく一部の専門家のみが研究している、完全に閉じられた世界の学問だ。

数学者の会話(注:易しい方)

  • 自然数ってバラバラな感じだよね」
  • 「そうだね、有理数になると少しくっつく感じかな」
  • 「でも穴空いてるでしょう」
  • 「実数なら完全にくっついているけどね」

私が大学で数学を勉強していたときは、こちらの「現実世界」とあちらの「数学の世界」を行き来していたような感覚がした。 いわば「バーチャル」と「リアル」を行き来するようなものだ。 数学者の生きている世界というのは隔離された純粋な世界なのだ。

その抽象数学を庶民の世界に引きずり出そうというのが「笑わない数学」だから、凄い挑戦だと思う。

MCがお笑いの尾形貴弘だというのが身近な感じで良い。 何しろテーマが「数学の難問」で普通の人には全く馴染みが無いから、MCだけでも視聴者サイドであることはありがたい。

私は大学卒業後は研究の道には進まず、数学の研究からは遠ざかってしまったので、この番組を見ると懐かしさがこみ上げてくる。 もう研究は無理だが、自分のできる範囲で「数学の世界」を散歩するのも良いかも・・・と思った。

Githubに「はじめてのRake」チュートリアルを書きました

Githubに「はじめてのRake」というチュートリアルを書きました。 このブログ「おもこん」に書いた「はじめてのRake(1)〜(4)」をもとに、さらに内容を発展させました。 MarkdownからPDFを作成する実用例、名前空間、引数、ディスクリプション、マルチタスク、テストタスクなどをカバーしています。 HTMLで読めるGithub pagesもあります。

github.com

toshiocp.github.io

Rakeは古いソフトなので今まで紹介記事はありましたが、それよりは深堀りできたと思っています。 RubyやRakeに関心ある人はぜひご覧ください。

なぜ英語は(数学は・・・)勉強しなければならないのか?

はてなブログをランダムに読んでいたら、「なぜ英語を勉強しないといけないのか」というテーマのブログがありました。 それに触発されて、自分もそのことを考えてみました。 なお、そのブログでは「高校生からこう聞かれたら教員は何と答えるか」というテーマで書かれていました。

まず思ったのは、「このような質問は英語に限らないな」ということです。 「なぜ数学は・・・」も英語に引けを取らないと思います。

今の自分だったら、これらのどれに対してもこう答えるでしょう。

「それは高校生のうちは分からないよ」

ちょっと突き放した言い方に聞こえるかもしれませんが、そういうわけではないんです。

私は年を取っているので、「あのときこれを勉強しておいて良かった」とか、逆に「あのときこれを勉強しておけばなあ」と思うことがあります。 若いときはそんなこと思いませんよね。 つまり、若いときにはそのことの重要性は分からないけれど、人生の後半になれば分かってくるのです。

人生は十人十色なので、すべての人に英語が必要ではないでしょう。 でも「英語をやっておいて良かった」という人は少なからずいるし、逆に英語ができなかったから別の道に行った人もいると思います。

英語や数学に限らず、勉強しておけば将来の選択肢は間違いなく広がります。 後から後悔しないためには、やれるだけやる方が良いに決まっています。

iPhoneマッキントッシュで有名なスティーブ・ジョブズ氏がスタンフォード大学で講演をしました。 有名な講演でYoutubeにビデオがあります。 その中で、彼が成功に至るまでに、彼の人生の中のいくつかの重要な経験が関わっていると言っています。 それを彼は点(ドット)と言い、ドットとドットがつながって彼の素晴らしい業績に結びついたというのです。 彼も若いときには個々のドットがどのように結びついて将来の成功につながるかは分からなかったそうです。

インターネットの盛んな今の時代ですから、英語の重要性は枚挙にいとまがないのですが、数学も負けず劣らずです。 理系に限らず、文系でも数学は使います。 先日Youtubeで知りましたが、公認会計士の試験でも一部数学の知識が必要なものがあるということでした。

結論としては「後から後悔しないためには、やれるだけやる方が良い」ってことなんじゃないかと思います。

はじめてのRake(4)

「はじめてのRake」の第4回です。 今回はRakeの応用です。 Pandocを使ってマークダウンからHTMLを作る例を紹介します。

はじめてこのブログを見る方は「はじめてのRake(1)」からご覧になってください。

文中に[R]という記号で始まる段落は、「Ruby上級者向けの解説」です。 上級とは、ほぼ「クラスを記述できるレベル」を指します。 上級以外の方はこの部分を飛ばしてください。

Pandoc

まず、Pandocがどのようなアプリケーションなのかを説明します。 Pandocは、文書の形式を変換するアプリケーションです。 例えば、

  • Wordの文書をHTML文書にする
  • Markdownの文書をPDF文書にする

これ以外にも多数の文書形式がサポートされています。 詳しくはPandocのウェブサイトをご覧ください。

例としてexample.docxというワードファイルをHTMLにしてみましょう。 ワードファイルはこんな感じです。

example.docx

$ pandoc -so example.html example.docx

これにより、example.htmlというファイルができます。 ダブルクリックするとブラウザで内容が表示されます。

example.html

画面の見栄えはともかく、ワードで書いた内容がHTMLとして表示されていることが確認できるでしょう。

では、どのようなHTMLが生成されたのでしょうか。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<head>
  <meta charset="utf-8" />
  <meta name="generator" content="pandoc" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
  <title>example</title>
  <style>
    code{white-space: pre-wrap;}
    span.smallcaps{font-variant: small-caps;}
    span.underline{text-decoration: underline;}
    div.column{display: inline-block; vertical-align: top; width: 50%;}
    div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
    ul.task-list{list-style: none;}
  </style>
</head>
<body>
<h2 id="pandocのインストール"><strong>P</strong>andocのインストール</h2>
<p>以下ではUbuntu22.04でのインストールを説明する。</p>
<p>端末から、apt-getを使ってインストールする。</p>
<p>$ sudo apt-get install pandoc</p>
<p>これでインストールできるPandocはたいていの場合、最新版ではない。Pandocの最新版は、
そのホームページからダウンロードできる。インストーラがあるので、それを用いるのが簡単である。</p>
<h2 id="rubyのインストール">Rubyのインストール</h2>
<p>端末から、apt-getを使ってインストールする。</p>
<p>$ sudo apt-get install ruby</p>
<p>最新版のRubyをインストールにはrbenvが良いが、rbenvをマスターするには時間がかかる。
詳しくは<a href="https://github.com/rbenv/rbenv">rbenv</a><a href="https://github.com/rbenv/ruby-build">ruby-build</a>のウェブサイトを参照してほしい。</p>
</body>
</html>

HTMLのソースコードから分かることで最も重要なことは、ヘッダが追加されていることです。 これはpandocに-sオプションをつけたからです。 -sをつけなければ、bodyタグで挟まれた本文の部分だけが生成されます。

マークダウンをHTMLに変換する

ここからは、マークダウンをHTMLに変換し、さらにRakeで作業を自動化する方法を学びます。

ソースファイルはすべてカレントディレクトリにあるとします。 生成するHTMLはdocsディレクトリに作成します。 マークダウンファイルは、「sec1.md」「sec2.md」「sec3.md」「sec4.md」ですが、将来ファイルが増えても対応できるようにRakefileを作ります。

※ 「sec1.md」は「はじめてのRake(1)」の編集画面に書き込んだマークダウンファイルに手を加えたものです。 「sec2.md」「sec3.md」「sec4.md」も同様に「はじめてのRake」のマークダウンファイルです。 これらのソースコードとほぼ同じものがGithubのRake-tutorial-for-beginners-jpレポジトリにアップロードしてあります。 Rakefileを試すときにはそこからダウンロードしてください。 RakefileのコードはGithubとブログでは若干違います。 そのため、試すときはダウンロードした方のRakefileで試してください。 また、できあがったHTMLがGithub Pagesで確認できます。

Pandocでは、最初に%とともにメタデータを書きます。 これは、タイトル、著者、日付を表します。

% はじめてのRake
% ToshioCP
% 2022/7/25

タイトルはHTMLのヘッダのタイトル・タグの内容にもなります。

PandocでHTMLにすると画面全面を使うので、横幅のあるPCでは広がりすぎて読みにくくなります。 それを解消するために、次のCSSファイル「style.css」を用意しました。

body {
  padding-right: 0.75rem;
  padding-left: 0.75rem;
  margin-right: auto;
  margin-left: auto;
}

@media (min-width: 576px) {
  body {
    max-width: 540px;
  }
}
@media (min-width: 768px) {
  body {
    max-width: 720px;
  }
}
@media (min-width: 992px) {
  body {
    max-width: 960px;
  }
}
@media (min-width: 1200px) {
  body {
    max-width: 1140px;
  }
}
@media (min-width: 1400px) {
  body {
    max-width: 1320px;
  }
}

このCSSはBootstrapのcontainerクラスの定義を参考に作りました。 CSSの内容説明は省略します。

これをstyle.cssという名前のファイルにしてRakefileのあるディレクトリに保存します。

Pandocで-cオプションを使うと、生成されたHTMLのヘッダでstyle.cssを取り込むようになります。

Rakefileの作成

それでは、「sec1.md」から「sec4.md」までの4つのファイルからHTMLファイルを作るRakefileを作ってみましょう。 ここで、2つの考え方があります。

  • sec1からsec4までを別々のHTMLファイルにし、それらをリンクでつなぐ。 目次を含むトップページはそれらとは別に作る
  • sec1.mdからsec4.mdまでを一つのファイルにつなげ、それをHTMLにする。

どちらにも一長一短があります。 ここでは、作成の簡単な2番目の方法を採用しましょう。

sources = FileList["sec*.md"]

task default: %w[docs/はじめてのRake.html docs/style.css]

file "docs/はじめてのRake.html" => %w[はじめてのRake.md docs] do |t|
  sh "pandoc -s --toc -c style.css -o #{t.name} #{t.source}"
end

file "はじめてのRake.md" => sources do |t|
  firstrake = t.sources.inject("") {|s1, s2| s1 << File.read(s2) + "\n"}
  File.write("はじめてのRake.md", firstrake)
end

file "docs/style.css" => %w[style.css docs] do |t|
  cp t.source, t.name
end

directory "docs"

少しタスクの間の関連が複雑になっています。

  • デフォルトのタスク「default」の事前タスクは「docs/はじめてのRake.html」と「docs/style.css」です
  • 「docs/はじめてのRake.html」はマークダウン「はじめてのRake.md」とディレクトリ「docs」に依存しています
  • 「はじめてのRake.md」は4つのファイル(「sec1.md」から「sec4.md」)に依存しています
  • 「docs/style.css」はそのコピー元の「style.css」とディレクトリ「docs」に依存しています
  • 「docs」はディレクトリタスクで、directoryメソッドで定義されます

6行目のshは、Rubysystemメソッドと似ています。 引数を外部コマンドとして実行します。 6行目の場合、シェルを介してpandocを起動します。 shメソッドはRakeがFileUtilsに拡張したもので、オリジナルのFileUtilsにはありません。

Pandocの--tocオプションは目次を自動生成するオプションです。 デフォルトでは#から###までが目次になります。

10行目のinjectメソッドは畳み込みを行う、配列インスタンスのメソッドです。 引数を初期値として、配列の値を次々にs2に代入して計算し、結果を次のs1に代入します。 順を追って説明しましょう

  • 初期値は引数の空文字列""です。 それがブロックのs1に代入されます
  • s2には最初の配列の要素である「sec1.md」が代入され、ブロック本体のs1 << File.read(s2) + "\n"が実行されます。 これにより、s1には「sec1.mdの内容+改行」が代入され、それが次のブロックのs1に代入されます。
  • 2回目のブロック実行で、s1は「sec1.mdの内容+改行」、s2には次の配列要素の「sec2.md」が代入されます。 ブロック本体が実行され、「s1」には「sec2.mdの内容+改行」が追加されます。 その結果、s1は「se1.mdの内容+改行+sec2.mdの内容+改行」となります。 これが次のs1に代入されます。
  • 3回目のブロック実行で、s1には前回実行の結果、s2には次の配列要素の「sec3.md」が代入されます。 前と同様に「sec3.mdの内容+改行」が追加されます。
  • 4回目(最後)のブロック実行で、s1には前回実行の結果、s2には次の配列要素の「sec4.md」が代入されます。 前と同様に「sec4.mdの内容+改行」が追加されます。
  • 以上の結果、firstrakeには「sec1.mdの内容+改行+sec2.mdの内容+改行+sec3.mdの内容+改行+sec4.mdの内容+改行」が代入されます。 要するに、4つのファイルを改行を挟んで結合した文字列になります。 11行目でそれがファイル「はじめてのRake.md」として保存されます。

改行をファイルの末尾に足したのは、一般に「テキストファイルの末尾は改行がある場合とない場合がある」からです。 改行が無い場合に次のファイルを接続すると、2番めのファイルの先頭の文字が行頭に来ません。 すると、見出しの「#」が行頭からずれて見出しでなくなるということが起こりえます。 これを避けるために改行を足しているのです。

cleanとclobber

この処理において「はじてのRake.md」というファイルは中間ファイルです。 重要なのはソースファイルと結果ファイルだと考えれば、処理後に中間ファイルは削除したいと思うかもしれません。 そのような操作を行うのがcleanタスクです。 cleanタスクを使うには

  • rake/cleanをrequireする
  • 定数CLEANの指すファイルリスト・オブジェクト(それも「CLEAN」と呼ぶことにします)に中間ファイルを追加する。 ファイルリストには配列と同様のメソッドが備わっているので、<<またはappendpushメソッドで追加ができる。

また、結果ファイルも含めて全て生成ファイルを消去するタスクがclobberです。

  • clobberタスクは、CLEANに登録されたファイルを削除する
  • さらに、ファイルリストCLOBBERに登録されたファイルも削除する

以上を付け加えたRakefileは次のようになります。

require 'rake/clean'

sources = FileList["sec*.md"]

task default: %w[docs/はじめてのRake.html docs/style.css]

file "docs/はじめてのRake.html" => %w[はじめてのRake.md docs] do |t|
  sh "pandoc -s --toc -c style.css -o #{t.name} #{t.source}"
end
CLEAN << "はじめてのRake.md"

file "はじめてのRake.md" => sources do |t|
  firstrake = t.sources.inject("") {|s1, s2| s1 << File.read(s2) + "\n"}
  File.write("はじめてのRake.md", firstrake)
end

file "docs/style.css" => %w[style.css docs] do |t|
  cp t.source, t.name
end

directory "docs"
CLOBBER << "docs"

中間ファイルを削除するには

$ rake clean

生成ファイル全てを削除するには

$ rake clobber

とします。

以上で4回にわたった「はじめてのRake」を終わります。 ここでは基本的な事項に限定して説明しましたが、それだけでもRakefileを書くのに十分な知識は得られたと思います。 このブログで触れなかった事項には、

  • タスクをマルチスレッドで実行し、高速化するためのmultitaskメソッド
  • Rakefileをカレントディレクトリ以外に置くこと、複数のRakefileを使うこと
  • タスクの名前空間
  • タスクの説明をするためのdescribeメソッド
  • rakeコマンドのオプション、とくにトレースなどのデバッグに使えるもの

などがあります。 今後はこれらの学習をしていくと良いと思います。

また、Rakeの機能を学習するだけでなく、ビルドをどのように構成するかについての学習も大事です。 これには経験を重ねることが一番大事だと思います。