HTMLで簡単な数学の小テストを作る(紙・1段組・1枚物)

少し前であるが、Wordの旧式数式プラグインが突然削除されて話題になった。TeXを使っている私からすると、旧式の数式エディタプラグインがどうなろうと関係ない。

授業でWordの数式エディタの存在を教えるときも新式エディタで教えているので何も問題ない。なお、新型エディタはwordと一体化しているため、Alt+Shift+=のショートカットなども使えて便利である。

私の近傍でも数式エディタプラグイン削除の余波

しかし、私と関係ない半径3m以内ではプラグイン削除の影響があったらしい。業務機で数学のテストが作れないという騒ぎが発生したのである。別に他にもやり方があるだろうにね・・・

ただ、一企業の気分で業務が振り回されるのは困る。そこで、どんなマシンであろうと絶対にインストールされているであろうWebブラウザを使って業務ができるようにしておけば良いのではないか?と感じた。Microsoftの気分よりオープンなHTMLのほうが、こういう事件はおこりにくいはずである。

なお、完全に以下はネタである。

1段組・1枚もののテスト

複雑なものは気が向いたら考えていくとして、今回は小テストレベルのプリントの作成を考える。次のようなテストを考える。

f:id:baruku07:20180211155251p:plain

以下がソースである。

<!DOCTYPE html>
<meta charset="UTF-8">
<style>
@page{size:A4;margin:15mm 15mm;}
.yokool{display:flex;justify-content:space-between;flex-wrap:wrap;height:14cm;}
.namaeran{margin-left:auto;width:8cm;border-bottom:solid 1pt;}
.item3 {width:30%;}
</style>
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
  tex2jax: {
    inlineMath: [ ['$','$'], ['\\(','\\)'] ],
    processEscapes: true
  }
});
</script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/MathJax.js?config=TeX-MML-AM_CHTML'></script>
<body>
<div class="namaeran">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp&nbsp;&nbsp&nbsp;&nbsp;氏名
</div>
<h3>方程式小テスト</h3>
1. 次の方程式を解け
<ol class="yokool">
   <li class="item3">$3x+2=5$</li>
   <li class="item3">$4x+8=15$</lI>
   <li class="item3">$2x-3=5x-6$</li>
   <li class="item3">$0.4x+5=0.1$</li>
   <li class="item3">$\dfrac{1}{2}x+3=4$</lI>
   <li class="item3">$x^2=10$</li>
   <li class="item3">$2x^2+1=5$</li>
   <li class="item3">$x^2+4x+3=0$</lI>
   <li class="item3">$2x^2+3x+5=0$</li>
</ol>

2. 2次方程式$x^2+ax+5=0$の実数解の個数が2個になるような$a$の範囲を求めよ。

</body>

MacChromeのみで動作を確認している。Safariでは微妙にうまくいかない。IEではそのうち確認する。以下、いくつかポイントを解説しておく。(class名の命名ルールが美しくないのは許してほしい。)

@pageでA4のサイズと余白を設定

プリント用のCSSを使う。なお、bodyにもA4の幅を設定しておかないとプレビューが合わないという問題はある。それはまた後日考える。

複数ページ対応も何かあるらしい。これも次回以降の課題とする。

数式はMathjaxで書く

数式はMathjaxを使う。標準的な解決策で、特に言及することもない。

氏名記入欄はdivでブロックを作って右寄せ

TeXやWordの感覚で、spanでテキストを修飾すると良いと思っていた。特に、氏名の後の欄は、nbspを並べると個数が多すぎるのでCSS側で幅を確保したい。しかし、spanは基本は幅を持てない。そのため、長い空白の幅を作るという目的には使いにくい。代わりにdivに幅を設定して、右に寄せることが問題を解決した。

flexboxで横並び・番号付き箇条書き

この方法を学んだのが今回の収穫である。最初、display:table;やinline-blockで横に要素を並べれば良い、と思っていた。しかし、このようにすると、箇条書きの番号が消える。どうやら有名な問題らしい。

"display:flex;"を使えば、この問題は解決した。ただし、上のソースを見てわかるように、TeXほど気軽には書けていない。まあ我慢するしかない。

単一行の場合は、"justify-content:space-between;"のみの記述で済むので、かなり簡単である。

しかし、複数行の場合はli側に幅を指定してやらないとならない。class="item3"は3段を想定していて、30%に幅を設定している。あとは、余白を適当に親要素の"justify-content:space-between"に調整してもらうという方針である。1行のカラム数が指定できると良いのだが・・・・

箇条書き番号は、大問番号と重ならないように(1)などとするべきである。この点も、面倒なので後日の課題とする。

Wordの箇条書きは私には使いにくい(余談)

Wordで私がプリントを作成したくない理由の人つに、箇条書きが気軽に使えない(特に横並び)ことがある。順番の入れ替えや余白の調整がTeXほど気軽にできないことにいらいらするのである。「絶対に修正しない」という人であればWordでも問題ないのであろう。しかし、私は頻繁に修正をする人なのでそうはいかない。

自分にとってはHTMLで色々できると大きい(余談)

ネタといいつつ、実は自分にとってはHTMLで仕事が片付くかは大きな問題である。もし、プライベートのPCでなく、業務機で絶対に教材を作れと言われるとTeXが使えないからである。

絶対にレイアウトを厳密にコントロールしないとならないもの(テスト)などは、ちゃんとした環境で作らないとどうしようもない。しかし、簡単なものぐらいは業務機で作れた方が良いに決まっているのである。

このブログで、emathを抜きで色々できる方法を考えて行っているのも、この問題意識がある。できるだけTeX Liveの標準環境で作業できるようにしておきたいのである。クラウド環境(overleaf)とかTeXライブをDVDマウントして教材を作ることなどなども想定をしている。

そのリテラシーはどうなの?(余談)

冒頭のお方、Wordの旧式の数式エディタを使っていて(若いのになぜ?と言いたいが)、かつ、それしか使い方がわからない(そのリテラシーで大丈夫?)のはどうかと思う。

特に、簡単な代替手段は存在するのに慌てるのはいかがなものかと。そもそも、新型の数式エディタ(もう新型というには随分たったが)に切り替えれば良い。新規で作成する文章はそれで問題ない。また、StudyAidは使える環境なので、StudyAidを使えば済むだけである。

何であれ、若いのだから学習したほうがね・・・

タイピング練習に目隠しを使ってみた

タッチタイピングの初期指導の方法の一つとして、手首にタオルをかけてタイピングをさせるという方法がある。しかし、この方法は私は嫌いである。手首に物が乗る感触で集中力が削がれるのが許せないからである。

シールを貼ってキーを隠す

最近、タオルをかけることに近い練習として、キーにシールを貼ってキーを隠して練習をするという方法を取り入れた。すると、キー暗記の段階の練習時間が相当に短縮された。

しかし、キーを暗記した後でもなお下を見る人が何人か出た。手とキーボードの位置をアジャストするためである。これは、手首をタオルにかけた練習では発生しない問題である。

実は、この問題の発生は事前に予想していた。しかし、速い速度でタイピングをする練習をする段階で、タイプそれ自体に熱中していくことで、自然と下を見なくなると読んでいた。しかし、そうならない人が思ったより多かった。

目隠しをすると手の位置を合わせることに意識が向いた

最近、別の目的で、目隠しをさせてキーボードを打たせる練習をさせていた。すると、自分の手の状態の問題を自覚できた、と言う人がでてきた。また、その状態で練習をすることにより、自然とキーの位置でてのみを探る練習ともなっていることにも気づいた。これを見て、目隠し練習が、手首とキーの位置の関係を見るために下に目線を送るという問題の解消になるのではないのか、と考えた。

元々は暗記できる文章の長さを増やすための練習

この練習、元々はタイピングの際に、紙から読み取った文章を頭に貯めておけない、という問題を解消させるために始めた練習である。目隠しの意図は、絶対に文章の塊を覚えないと打てない、という状況を作るためであった。また、目で文章の塊を読み取るという負担を省略するということもある。

ところが、この練習を始めて見ると、手元の感触に意識がいくことがわかった。そこで、手元の強化の練習としても使えないかと考えるようになった。現在は、対象者を増やして効果を確認しているが、相変わらず手に意識が行っているコメントが多く聞かれる。

手の動きの細かな部分については、自分で自覚して直してもらうのが一番である。人それぞれのタイピングの動作を録画して指導者が確認するわけにはいかないからである。目隠しをすると、自分で自分の手に気づける、という意味でも、この練習は貴重であると感じている。

この練習は、他にも色々と意図に応じて使うことができそうな気がする。少し研究を深めていこうと思っている。

アイマスクは100均で調達(余談1)

この練習、最初は目隠しの代わりに目を閉じてやらせていた。しかし「目を閉じること自体が疲れる」とのことだったので、目隠しを用意することにした。バンダナを大量に買ってきて巻けば良いと考えたのだが、「100均に行けば目隠しがある」との指摘を受けて、100均で目隠し(アイマスク)を調達してきた。

空烈斬のネタが通じない(余談2)

見ずにスラスラ打つのは無理だというので、思わず「心の目で感じれば打てる。そういう漫画あったよね。」といってもさっぱり。ダイの大冒険はもう知らないよね・・・

tikzのcalcを使って帯グラフの帯の幅を計算してみた

前の記事で書いたtikzで描いた帯グラフを、calcを使って書き換えてみた。帯の真ん中に入る線をcalcで計算してみた。

f:id:baruku07:20180208003936p:plain

\documentclass[uplatex,dvipdfmx]{jsarticle}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}
{
\def\hakotakasa{2}
\def\hakohaba{10}
\def\wariai{0.55}
\draw (0,0) rectangle (\hakohaba , \hakotakasa );
%%真ん中の線。calcで計算した。
\draw (0,0) rectangle ($\wariai*(\hakohaba,0) + (0,\hakotakasa)$);
}
\end{tikzpicture}
\end{document}
  • \defを使った変数定義は、{}で閉じておくとスコープを絞れるらしいので、{}をつけた(本当にそうなってるから検証してない)
  • calcはベクトル計算をするためのものらしいので、それに合わせるために回りくどい式で計算をしている。
  • 計算した結果の外側の()がないとエラーがでる。この()は必須みたい。
  • 文字を入れる位置の計算も原理的にはできるはず。それはまた追記か後日で。ここには使っていないが、内分の計算を簡単に書ける機能が使えそうという実感がある。

tikzでやっつけ仕事の帯グラフを描く

tikzでまともな図を描こうとすると、それなりに苦労する。

しかし、やっつけで割り切った図を描くと決めてあえば、それなりに楽に使える。

例えば、ちょっとした帯グラフを手計算で描くぐらいのことは大した手間ではない。

下は、某社の情報の教科書にあった簡単な帯グラフを参考に描いてみたやっつけのグラフ。

f:id:baruku07:20180206203318p:plain

\documentclass[uplatex,dvipdfmx]{jsarticle}
\usepackage{tikz}
\begin{document}
begin{tikzpicture}[scale=0.7]
 \draw (0,0) rectangle (10,2);
 \draw (0,0) rectangle (5.5,2);
 \node at (2.75,1) {{\LARGE 男 55\%}} ;
 \node at (7.75,1) {{\LARGE 女 45\%}};
\end{tikzpicture}
\end{document}

下は、過去にpgfplotsのマニュアルを読む暇があったら、考えずに描くほうが早いなと思って描いたグラフである。一回限りの使い捨てなので、割合の変数を使って計算するなどということなどもせずに手計算でばりばりと描いたものである。

f:id:baruku07:20180206203430p:plain

\documentclass[uplatex,dvipdfmx]{jsarticle}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
    \draw(0,0) node[left,yshift=0.25cm]{睡眠6時間未満} rectangle +(5,0.5);   
    \draw[yshift=-1cm] (0,0) node[left,yshift=0.25cm]{睡眠6時間以上} rectangle +(5,0.5);   
    \draw[fill=black!20] (0,0) rectangle+(2.5,0.5); %明るい
    \draw[fill=black!20,yshift=-1cm] (0,0) rectangle+(1.25,0.5); %暗い
    %%凡例
    \draw[fill=black!20](6,0) rectangle +(0.5,0.5) node[right,yshift=-0.25cm]{居眠りをした};
    \draw[fill=black!20](6,-1) rectangle +(0.5,0.5) node[right,yshift=-0.25cm]{居眠りをしていない};
\end{tikzpicture}
\end{document}

この手のグラフを描くときには、四角の幅は、座標は5とか10とかの計算しやすい幅にしておくのがコツである。大きさをscaleで調整して欲しい大きさにする。

なんでもTeXでやろうとするな、いうツッコミもありそうなのはわかっているが。ただ、1つのファイルの中に全てのソースがあると再利用や整理が楽なので、つい他のソフトを使わずにできるだけTeXですませようとしてしまうのである。

tikzで3辺の長さを指定した三角形を描く

tikzはtexの本文に少し図をつけるときには便利なパッケージである。emathは図に関しては準備が大掛かりになるので、そういう準備をしたくないときには使いにくい。よって、一時期、tikzで業務に必要な図を描いていた。

最近、大昔にtikzで3辺を指定した三角形を描いた図が発見された。ソースを見ると、ひねったことをしていたのでここで紹介する。何かを参考にしてそれからアイデアをうまく取ってきたのか、ほとんどどこかにあったソースを改変したのかの記憶はない。

自分も忘れてたぐらいなので、ここに残しておけば何かのときに思い出せるかもしれない、ぐらいなので紹介しておく。

以下が画像。

f:id:baruku07:20180205230803p:plain

上を出力するためのソース。

\documentclass[uplatex,dvipdfmx]{jsarticle}
\usepackage{tikz}
\usetikzlibrary{intersections,calc}

\begin{document}
 \begin{tikzpicture}[scale=1]
 \def\lena{4} %aの長さ
 \def\lenb{2} %bの長さ
 \def\lenc{3} %cの長さ
 %%辺ABを紙と平行に描いている。
 \coordinate (A) at (0,0) ; %点Aの座標に(A)と命名。
 \coordinate (B) at (\lenc,0) ; %辺ABの長さはcなのでBの座標は(c,0)
 \node [left] at (A) {A} ; 
 \node [right] at (B) {B} ; 
 %点Aからbの半径で円を描く。実際の描画はしない。
 \path [name path=path1] ($(A)$) circle (\lenb)  ; 
%点Bからaの半径で円を描く。実際の描画はしない。
 \path [name path=path2] ($(B)$) circle (\lena)  ; %点Bからaの半径で円を描く。
 %2円の交点を求める。
 %coordinateのオプションではだめで、一度、空のpathを描くことに注意。
\path [name intersections={of=path1 and path2,by=x} ] ; 
\coordinate (C) at (x) ; 
 \node [above] at (C) {C};
 %ABCを線で結んで三角形を描く。
 \draw (B) to [edge label'= \lena]  (C) to [edge label'=\lenb] (A) to [edge label'=\lenc]cycle;
 \end{tikzpicture}
 
\end{document}

やっていることは、コンパスで円を描いて交点を求めてそれを使って三角形を描いているだけである。中学生の気分な解法である。交点は2つできるはずだが、まあなぜかこれでうまくいっている。どちらか適当に1個選択されるらしい。

このいい加減さが気になるのであれば、複数の交点を配列に入れて、いずれかを明示的に選択することもできるらしい。あるいは、円でなく180度の円弧を描いて交点を一つにすれば良い。

引っかかるところは、coordinateにオプションを設定しても交点を計算してくれないところである。マニュアルのintersectionのsectionの例が、drawのオプションで交点を計算させている。そのため、同じノリでいかないといけないと思ってしまう。しかし、前半のtutorialの例で出てくるintersectionの例では、pathが多用されている。よって、交点のみを求めて他に何もしたくないときにはpathを使えば良いことがわかる。

上の図の使用目的

上は、三角形の図を与えて、その図から余弦定理でcosを求めさせる問題を作るときに使ったもの。よって、角をの名前や辺の長さを書く部分もあえてつけてある。高校数学的には、この形のほうが需要がありそうなので、参考になるかと思ってあえて残した。

点線を長さの数値の前後につけることも頑張ればできるが(たぶん頑張らない方法もあるが)、そこはコストと成果のバランスであえてしていない。

三角形の大きさの調整はscaleの値を調整すれば良い。その他、tikzを色々読めばいろいろな調整方法は見つかるはず。

どうしてこの方法にたどりついたか(余談)

3辺なら三角比の座標計算で目的の三角形を描くのも難しく無い(私は計算が嫌だけど)。しかし、4辺を指定した四角形を描くために計算となると、もう嫌以外の何者でもない。

この解法は、三角形にもう一つ四角形をくっつけて四角形を描こうとしたときに思いついたものである。座標軸に対して斜めになっている辺を底辺として考えないとならない状況だったので、なんとか計算無しでしようとして考えた方法。

2/8追記

studyaidで、コンパスを使って正確に三角形を描く方法を解説していたblogを見て思いついたものだったことを思い出した。

なお、この手のネタはあくまでネタです。当然、こういうものが業務で要求される場合は、普通はStudyaidなどでやっつけるべきです。

pgfplotsで5数要約から箱ひげ図を描く

高校数学でデータの分析の話をするときに(次期指導要領では中学だが)箱ひげ図を描く必要があることがある。

このとき、5数要約から箱ひげ図を描きたいという需要がある。Studyaidは良きに計らってくれるはずである。しかし、そんなものに縁の無い私はTeXで頑張るしかない。

数年前に色々とgoogleに聞いてみたところ、pgfplotsで簡単に描けることがわかった。そのときに描いた図を下に示す。

f:id:baruku07:20180204201217p:plain

%\usepackage{tikz} %プリアンプルに
%\usepackage{pgfplots} %プリアンプルに
%\usepgfplotslibrary{statistics} %プリアンプルに

   \begin{tikzpicture}
    \begin{axis}[
     boxplot/draw direction = y,
    xtick={1,2},
    xticklabels={Pチーム, Qチーム},
    ]
   \addplot+[
   black, 
    boxplot prepared={
      median=5, 
      upper quartile=9,
      lower quartile=3,
      upper whisker=10,
      lower whisker=1
    },
    ] coordinates {};
   \addplot+[
   black, 
    boxplot prepared={
      median=6,
      upper quartile=11,
      lower quartile=2,
      upper whisker=12,
      lower whisker=1
    },
    ] coordinates {};
    \end{axis}
   \end{tikzpicture}

マニュアルの例を少しだけ触っただけである。特にオリジナリティーは無い。何をやっているかは上のソースをみればすぐにわかるので説明は略。

pgfplotsなので、軸の加工など色々できるようである。TeXなのでフォント周りのトラブルに巻き込まれないのも良い(Rは日本語の出力が面倒)。平均値をいれたバージョン(個人的には、これは箱ひげ図として邪道と考えるので絶対に認めない。)も作れるらしい。自分の場合は上の図で仕事が完了できたので、それ以上のことは追求していない。

個人的に高校数学の箱ひげ図に対して思う事(余談)

箱ひげ図はデータの傾向を大雑把に見るためにあるものである。元のデータから情報量を適度に落として適切なレイアウトで並べることで、大雑把な比較が簡単にできる図であると、私は認識している。よって、通常はデータから箱ひげ図を描くのが普通である。

しかし、高校数学では、箱ひげ図は色々な人工的な問題に加工されて扱われる。また、データから箱ひげ図を描くとしても、高校流の要約統計量の計算によって描かざるを得ない。これは、実際の統計ソフトで使うスタンダードとは別物である。よって、そのままコンピュータ実習に持っていくなどの現実への接続もしにくい。

箱ひげ図のメリットをわかっていない人もみかける。そういう人は、1個の箱だけ描かれた図を色々とこねくり回して議論をして終わりである。1個しか箱がないのなら、別に5数要約の数値そのまま示せば良いし、もっと情報量の多いヒストグラムもあるし、ということで箱ひげ図の存在価値はない。

なお、センターのような、きちんとした頭脳を結集して作られている問題については、そういう批判があたらないように細心の注意を払って作られているように見受けられる(それでも、無理矢理差をつけるために重箱の隅をつついていると思わないでもないが。ただ、質の悪い高校教師が適当に作った問題より100倍まし)。

しかし、高校数学の人工世界でしか通用しない作法を時間をかけて教えても意味がないようなと思う・・・こういう話は(受験数学や選別的な価値観を持つ)数学科でなく(実用本位の)情報科で扱った方が良い題材だと個人的には思っている。

こちらが、こうやって5数要約から箱ひげ図を描いて教えたり筆記試験をさせるのではなく、統計ソフトで現実データを使って箱ひげ図を生徒に描かせて色々とやる実習が中心になる日がくると良いけどな・・・まあ無理だろうけど。

tcbitemizeで横並び・下線の解答欄を作る

今日もtcolorboxで強引に解答用紙を作る話である。

以下のような解答欄を作ることを考える。

f:id:baruku07:20180203231422p:plain

上を出力するためのソースである。

\documentclass[uplatex,dvipdfmx]{jsarticle}
\usepackage[raster,skins]{tcolorbox}
\newcommand{\visible}{visible} %解答の表示と非表示の切り替え
%
\begin{document}

\begin{tcbitemize}[ 
colframe=white,colback=white,%枠線と背景色を白
raster columns=3,%カラムの数
detach title,raster valign=top,%
left=0pt, %箱とテキストの感覚を0にする。
%height=3pc,valign=center, %高さを手で調整したいとき入れる
sidebyside, %横並びにする
lefthand width=23pt, %番号を入れる部分の幅。
sidebyside gap=0mm, %番号と解答部分の間隔を0にする。
sidebyside align = top,%
before upper =(\thetcbrasternum),%
upperbox=visible,lowerbox=\visible, %\tcbsetでグローバルにinvisibleがセットされても良いようにしておく。
skin = enhanced,%tikzでoverlayの線を描くために必要
overlay = {
    \draw[black]  ([xshift=22pt]frame.south west)--(frame.south east);
}
]
 \tcbitem \tcblower りんご
 \tcbitem \tcblower みかん
 \tcbitem \tcblower いちご
  \tcbitem \tcblower なし
 \tcbitem \tcblower マンゴー
 \tcbitem \tcblower キウイ
\end{tcbitemize}


\end{document}

ポイントはoverlayで線を描いていることである。これにより、箱の途中から線を引くことができる。xshiftやyshiftで線の位置の微調整も可能である。

解答の文字の開始位置はlefthand width((1)などの入っている部分の箱の幅)で調整する。

オプションが大量にあるので、実際に使うときには適度にマクロを定義して使うべきである。\newtcolorboxのraster版は、私の調査能力では発見できなかった。

もっとまともな方法はありそうだが、現在はここまでの調査が限界。

なお、今回は規則的な幅で解答を並べていくケースを扱った。ばらばらの幅で解答欄を並べていく場合には、

  • tcolorboxのnobeforeafterオプションを使って、1つ1つ幅を指定しながら並べていく
  • tcbrasterのraster columnsをやや細かめに指定しておき、\tcbitem1つ1つについてグリッドの幅を指定していく(例えば、12分割して3つ分の幅を指定すれば4分割にできる)

などが考えられる。いずれのケースでもskinで下線を引くことによって小問番号+下線をセットにした箱を作る、というテクニックは応用できるはず。

\tcblowerを書かないとならないのも気に入らない。しかし、個人的には、横に並べるだけでemathEyのedaenumerateを呼び出しすという状態が脱却できているので、この程度で問題ない。

なお、言うまでもなく楽に作りたければemathも含めて世の中には楽で良い選択肢がある。このやり方は、あくまでtcolorboxのみで頑張ると言う趣味に近い。