教師の役割

僕は教員免許も持ってないし教育のこともなにも勉強してないからあくまで個人の考えなのだけど、勉強を教える時はどうするべきか思ったこと。

問題をとかせる時に僕はそれを見守っているのだが、一部の生徒はわからないとすぐに解答へと手が入ってしまうようだ。僕は気づいたら見ないように制している。*1
そのときはどうするべきか。解答をわかりやすく説明すればいいのだろうか。

僕はそれはspoilingだと思う。結局解答を読むのと同じで、自分で考えなくなってしまって身につかないと思う。*2
だから僕は、ヒントを小出しにしていって正解にたどりつくまで自分で考えさせるようにしてる。
でもこれは自分の勉強のスタイルにのせようと思ってる面もある気がする。

どう教えるのがためになるのだろうか。

*1:だからといって4stepの解答を取り上げてしまう母校はおかしいと思うけど。

*2:spoilした結果、僕みたいな優柔不断な大人になってしまいますよ。

Linuxの遅延書込みをどうにかしたい

Linuxで書き込み速度の遅いフラッシュメモリに大きいファイルを書き込もうとすると、最初のうちはものすごい高速で書き込まれ、途中から遅くなったりひどい場合ずっと止まったようになってしまう。ファイルサイズまで達した時に止まったままになることもある。(実際には待っていれば完了する。)でも、書き込みの速いメディア上だとそういうことは起こらない(ように見える)。なんだこれは。
おそらく非同期で書き込んでいるのではないか、ということで検証プログラム。

#include <fcntl.h>
#include <unistd.h>

#include <stdio.h>
#include <stdlib.h>

int main(const int argc, char* const argv[])
{
  // O_SYNCの有無で比較しよう
  const int fd = open(argv[1], O_WRONLY | O_TRUNC | O_SYNC);
  fprintf(stderr, "fd: %d\n", fd);

  const int sizebuf = 1024*1024;
  char* const buf = (char*)malloc(sizebuf);

  int i;
  for(i=0; i<1024; ++i) {
    fprintf(stderr, "%d\n", i);
    write(fd, buf, sizebuf);
  }
  free(buf);

  close(fd);

}

O_SYNCが無しだと前述のような状況になり、O_SYNCが有りだと同期書込するので待たされることはない。(ただし、遅い。)

つまり遅延書き込みを行なっているせいのようだ。たしかに遅延書き込みはパフォーマンスを上げるのでありがたいのだが、プログレスバーが止まっているように見えるのはいただけない。MacWindowsではこんなことはおこらない。

いまのところ最善の策は見つけていないのだが、カーネルパラメータを調整して遅延書き込みの閾値を下げると若干改善した。
例えば

sudo /sbin/sysctl -w vm/dirty_bytes=16777216

とかどうでしょう。小さすぎるとパフォーマンスが悪くなるので、連続アクセスが一番速い媒体の速度ぐらいにあわせておくのがいいのだろうか。

dirty_bytesって何?って場合は、このページが参考になる。

できればバッファサイズに上限を設定できたらいいなと思うんだけど、見当たらない。

こういうソフトウェア的な仕組みはまだまだ不勉強なことが多いなぁ。

Gnuplotから動画をつくる

研究の関係でGnuplotの出力を動画にしたいことがある。

Gnuplotで動画を作る方法は以前にも紹介しているのだが、正直言ってちょっと面倒だし気に入らない点があったりする。


そこで、別の方法を考えた。
Gnuplotで画像データを標準出力に連続的に出力させ、それを1フレーム毎に読み込み、それをリアルタイムにAVIに変換し、さらにそれをffmpegに渡すことで動画を作成するという方法だ。(ffmpegのところは単に圧縮したいだけなのでなくても良い。)
先に断っておくと、今回はソースをつけない。なんとなく面倒だったので。(欲しい人は直接僕に凸してくれれば差し上げます。)
かわりに、もう少し詳しく具体的に説明する。

Gnuplotで動画にしたいものをPNG形式で連続的にplotしていく。たとえば

#!/usr/bin/env gnuplot
set term png
phi=0
while(phi<=6*pi) {
  plot cos(x+phi), sin(x+phi)
  phi=phi+pi*0.1
}

とか。(できれば無圧縮なビットマップ形式で出力させたいのだが、その方法が見当たらないので仕方なくPNGにした。)

GnuplotからのPNG出力を受け取るプログラムはC言語で記述する。
libpngを使用すると、都合よく1フレーム分ずつ読み取ることができる。(なので、画像毎にGnuplotを起動し終了させる必要がない。)Gnuplotの出力するPNGはパレット形式なので、AVIに変換するためにフルカラーに変換して読み込むように記述すること。
libpngの扱い方はここが参考になると思う。

読み込んだPNGの画像をAVIとして出力する。それにはこのサイトのソースを参考にすると良い。

標準出力はseekできないので、AVIのインデックスに関係する部分や長さを指定する部分は無視して、ストリーミング的に出力するのがポイント。

これによって出力されるAVIをffmpegで好きな形式に圧縮すると良い。H.264にすると大分容量が抑えられると思う。


当の自分は、結局動画を作らなくてもなんとかなることになってしまったのだが。


追記 (2013/04/19) 実はPNGを連番で出力してもさほど容量を使わない(たまたま自分のケースだけかもしれないけれど)事に気づいたので、結局のところPNG連番にして、ffmpegで-vcodec copyを指定して動画化するのが一番スマートな気がする。PNG形式のまま動画になるのでエンコードは一瞬。

反発係数がよくわからない

塾で教えてて混乱してしまったのだけど、反発係数ってよくわからない。
反発係数の定義の捉え方によって答えが変わる問題をだされたらたまらない。
所詮、経験的な法則だからそこまでこだわるべきことではないのかもしれないけれど。


普通、反発係数と言ったら衝突前後の相対速度の比で定義するものだと思う。
だけど、なめらかな壁に斜めにボールを衝突させる問題だったら法線成分だけにして考えたと思う。
(この時点でもう定義置き去りなのだが百歩譲ることにする。)
それじゃ、衝突の法線成分についての相対速度比で定義するというのだろうか。
でも衝突面ってどう決めるのだろか。
生徒に聞かれた問題はモンキーハンティングの問題で、お猿さんの肌なんて複雑に入り組んでるから衝突面なんてそう簡単にわからないはず。
なのに解答は鉛直に衝突面を決めてるよう。もうわけがわからないよ。


高校物理の反発係数の問題は、一次元衝突だけにしてほしいものだ。もとい、するべきだ。と主張してみる。

等差数列×等比数列の総和

塾で教えてるせいかこういうことに意欲が湧いてしまうのだけれど、ある雑誌の記事に書いてあった等差数列と等比数列の積の数列の総和の計算方法が特殊だったので簡単に記しておく。

有名な計算方法はこのふたつだと思う。

  • S-rSによって項をずらして求める。
  • 等比数列の和を公比で微分する。

書いてあったのは
\sum_{k=1}^{n} k r^{k-1} = \sum_{k=1}^{n} \sum_{l=1}^{k} r^{k-1} = \sum_{l=1}^{n} \sum_{k=l}^{n} r^{k-1} = ...
という感じで計算していくもの。こんな方法があったとは知らなかった。

Ubuntu 12.04上のSaneによってスキャナを共有

最近ファイルサーバー用に新しいマシンを組み立てたついでに、心機一転でプリンタやスキャナも共有しちゃえと思いやってみた。
プリンタの共有はsystem-config-printerを開いて、メニューのサーバー->設定に共有する旨のチェックボックスがあるのでOnにすればよい。

スキャナなんて本体から近いところでしか使わないから共有の必要なんてないんじゃないかと思うかもしれないけれど、ノートにいちいちUSBを繋いで行動範囲が制限されるのがなくなるのは意外と良い。
ぐぐって出てくる情報だと微妙にうまくいかない点があるので、Ubuntu12.04 Precise用にまとめておく。

当方ではスキャナは複合機EPSON PX-A720を使用。ドライバはデフォルトで入っているようだ。

サーバー

必要なパッケージをインストール。

sudo apt-get install sane sane-utils xsane xinetd

スキャナを認識しているか確認してみよう。

sane-find-scanner

scanimage -L

# output
device `epson2:libusb:002:006' is a Epson CX6000 flatbed scanner

許可する接続元IPアドレスを記述。

sudo -e /etc/sane.d/saned.conf

開くと英語の注意書きでIPアドレスはCIDR表記が使えるとある。大学の講義で習った気がするがよく覚えてなかった。Wikipediaが参考になる。(Classless Inter-Domain Routing)
ローカルネットワーク内のアドレス全部許可したいと思い、192.168.*.*に該当するアドレスに許可したければ、192.168.0.0/16と記述すれば良いようである。

接続先アドレスを記述する。

sudo -e /etc/sane.d/net.conf 

このファイルにlocalhostを書いておこう。自分のアドレスを参照することで、問題発生時に直接スキャナにアクセスする機能に問題があるのか、それともネットワーク共有に問題があるのか切り分けできて便利だといっているサイトがあり、その通りなのでそうすることを勧める。

参考までにnet.confにlocalhostを記述した状態でのscanimage -Lの結果は

device `epson2:libusb:002:006' is a Epson CX6000 flatbed scanner
device `net:localhost:epson2:libusb:002:006' is a Epson CX6000 flatbed scanner

となった。

追記 2014/03/29

間違えてました。net:localhostの方は下記のxinetdの設定までやらないと出ないハズです。
ちなみにMacのlaunchdの場合は こちら を使ってください。
これを参考にしました。 Portfile.diff on Ticket #27791 – Attachment – MacPorts
追記終わり。


xinetdにsaneを対応させる

sudo -e /etc/xinetd.d/saned 

ここに

service sane-port
{
    disable = no
    port = 6566
    socket_type = stream
    wait = no
    user = root
    server = /usr/sbin/saned
}

と記述。

/etc/default/sanedを編集

sudo -e /etc/default/saned 

RUNをyesに、USERはsanedではうまくいかないので、rootにする。

RUN=yes
RUN_AS_USER=root

以上で準備完了なのでdaemonを作動させよう。

sudo service saned restart
sudo service xinetd restart

クライエント

勝手ながらとりあえずMac OS X Lionの場合のみ記します。あとで追記するかもです。

MacPortsでsane関係のportをインストール。

sudo port install sane-backends sane-frontends twain-sane xsane

接続先アドレスをnet.confに記述。

sudo -e /opt/local/etc/sane.d/net.conf 

開いたらどこかにサーバーのIPアドレスかホスト名など記述しておこう。bonjourホスト名でも解決がうまく行っていれば大丈夫のようだ。

そしたら共有スキャナを認識していることを確認。

scanimage -L

#output
device `net:some_server:epson2:libusb:002:006' is a Epson CX6000 flatbed scanner

これで準備完了だ。
xsaneを使えばちょっとした機能付きでスキャンできる。scanimageを使うとコマンドライン上でスキャンできるようだ。LibreOfficeGimpでもスキャンできるようだ。Macの標準アプリではできなかった。(そのためのtwain-saneのはずなのに・・・)
まぁxsaneでほぼ用が足りそうなので良しとしよう。