ノーベル賞雑感

twitterからの覚え書き。

鴨澤眞夫(@kamosawa)/2016年10月03日 - Twilog より。

今後の日本で世界的な研究がしたかったら旧帝大じゃ無理で、在野のままどうにかなる数学系の分野か、豊田工業大学みたいに企業のバックアップのある私大に限られるということになるかも。そこまでして日本に居なくてもいいのでは、というのがオレの感覚。

構造的に戦略不在の日本では90年代みたいに社会に合わせて増える以外で研究予算は増えようがないし、その機会は今後50年は来ない。必要な費用は増大し続けてるので80年代レベルの予算で出来ることはわずか。一流の人ほど海外に移らないことがリスクになる。30年後にノーベル賞?ありえない。

大学の先生の事務負担が激増したのは90年代半ばと記憶するけど、その後10年くらいは日本の論文数は諸外国と似たようなペースで増えてたんだよね。21世紀になってからのことはオレはよくわからないけど、日本の研究環境の破壊については、postmortem studyをやるべきだと思う。

身近な話をすれば、大学時代の恩師で山ほど論文を書いておられたO先生が事務負担に音を上げて「オレはサポートに回る」と宣言したのが2003年くらいのはず。

2009年だったかに大学を移られるときのお別れ会で、オレら古い学生が言う先生のイメージと、今の学生から見たイメージが合わないであろうという話をしておられた。古い学生は衝撃を受けたものである。

財務省については、ノーベル賞を取ったから、だからなに? くらいの感覚だと思う。彼らはあらゆる方面からの「絶対的に重要な案件についての予算交渉」に常にさらされているので、削れるならなんでも削る。知をもつ者なら理解せよって言っても無駄で、とにかく政治的に強い交渉をするほかない。

けっきょく戦略の不在が日本の研究環境を殺したわけだけど、その戦略とは、誰が持ってるべきものだったのかねえ。市民社会と学問の乖離はまだまだ大きいままなので、全体のコンセンサスとして研究重視に舵を切ることはできなかったし、政治にもジャーナリズムにもそんなものは無かった。

とすると、やっぱり戦略は誰一人持つことなく、世間との横並びでしか予算は確保できなかったのかなとも思うんだよね。国が衰えても知は衰えず…なんてことができるような国ではなかったのだということで。

もう日本のアカデミズムは残り物をどう生かして今後につなげるかという段階に入ってると思う。その文脈で考えると、大学の先生方がまだまだ非常にハイレベルであることが目立つ。だから学部生に高い教育を施して先進国に送り出すのが正しい道ではないかと思う。

ノーベル賞をきっかけに、実に暗い方向に頭が整理されてしまったのであった。

「2番じゃダメなんでしょうか」

蓮舫さんをここぞと叩く人たちが、また「2番じゃダメ?」を攻撃してたので、そこらについて判断材料になりそうなことを置いておきます。


そもそもこの発言は根本的に誤解されたままになってて、当時から気持ち悪かったんだけど、放置してても正確なことは伝わらず、伝説が残るばかりなので、書いておく必要があるように思うのです。


ニコニコには全やり取りの音録が残ってます。 http://www.nicovideo.jp/watch/sm8793858
また、これについての2011年のやり取りも要点をよく示していると思います。
http://togetter.com/li/214426


音録を最初から聞くとよくわかるんだけど、そもそも事業仕分けってのは

  • 財務省が「これはダメだろ」というのをピックアップして
  • やりたい側に必要性を説明させたうえで
  • 意義があるなら残す

というプロセスです。俎上に上がる時点で半分死んでるものが多い。


当時の次世代スパコン、いまの「京」の開発は、NECと日立の撤退でベクターマシンを捨てて、にもかかわらずそのまま膨大な予算を取って、そのまま進むことだけ考えているという、だいぶ無理筋なものでした。利権的な配分でぜんぜん擁護できない。


そこらへんは自民党河野太郎議員も当時の仕分けの方々と同じ認識だし
http://web.archive.org/web/20111115193950/http://www.taro.org/2011/11/post-1117.php

HPCの専門家として仕分けに参加した金田教授の認識もそうです。
http://itpro.nikkeibp.co.jp/article/COLUMN/20091225/342666/


仕分けにおける「首切り役人」は財務省主計局です。彼らの基準は妥当性や透明性ですが、論述はわりに簡潔で短い。これに対して予算を取る側が長めの時間をもらって防衛する。そしてさまざまな立場の仕分け人が質問する。


このスーパーコンピュータの仕分けのプレゼンは、最初の方からぐだぐだです。要点を外したまま、質問されても同じ方針で説明を続けるばかり。予算の妥当性について聞かれているのに、ふわーっとした話しかできてません。研究者仕分け人からは、もっと本質的というか、プロジェクトの妥当性そのものについても聞かれてますが、やっぱりふわーっとした説明。


蓮舫さんの「2番じゃダメなんでしょうか」は、上の動画の30数分からの流れで金田教授がメタメタに切ったあと、まだ文科省理研の側が同じようなことを繰り返すばかりなので、もっと具体的に予算の意義を、という意味合いで48分ごろに発言されてます。予算を付ける方向で発言してるのは蓮舫さんだけで、完全に助け船であることが見て取れると思います。


これに対する文科省理研の回答までお聞きになられるとよいと思うけど、やっぱりロマンがどうのこうのと、ふわーっとお答えになります。


廃止1、休止6、削減5、という結果になったのは「2番じゃダメなんでしょうか?」発言とはぜんぜん関係ありません。今回聞き直して思ったけど、よく言われてるようにプレゼンが悪かったというのも主因ではなく、プロジェクトそのものが間違っていた感じです。最終的に復活したのは完全に政治的な動きでしかありませんでした。


「2番じゃダメなんでしょうか?」を文脈無視でマスコミが騒いで、ノーベル賞級の方々も、明らかにそれだけを読んで勘違いして騒いでました(彼らは明らかにプロセスを見てません。そんな時間はないということでしょう)、科学予算が減る!という雰囲気が出たためにやり玉にあげられますが、それは彼女の罪ではありません。


1100億を費やして「京」をそのまま続けたことが正解だったか、ほかの使い道はなかったか(たとえば東工大TSUBAMEシリーズは年間10億程度の予算だそうです)、あれをシンボルに「科学立国」を語った皆さんは、考えた方がよいように思っています。

libhoge.laを排除する

9.1Rくらいのシステムから引き継いだpkgなんかがあったりして無駄な苦労が絶えないうちのサーバ。
FreeBSD10 で netatalk3 を使って TimeMachine サーバにする
を参考にnetatalk3を入れなおそうとしてたら止まりました。

libtool:   error: cannot find the library '/usr/local/lib/libiconv.la' or unhandled argument '/usr/local/lib/libiconv.la'
Makefile:575: ターゲット 'afpd' のレシピで失敗しました
gmake[6]: *** [afpd] エラー 1
・
・
Stop.
make: stopped in /usr/ports/net/netatalk3
root@heliopora:/usr/ports/net/netatalk3 # 

libiconv.laが無い、またはその引数がおかしくてlibtoolがエラー。エラーメッセージをそのままぐーぐるさまに突っ込んだところ、libiconv.laをコンパイルしなおしてコピればいいという情報もあったけど、freebsd.orgのフォーラムに、"consolekit fails to compile | The FreeBSD Forums "というスレッドがあって、最後のところにこんなコメントが:

/usr/ports/UPDATING:

20140909:
  AFFECTS: users seeing build errors about missing *.la files
  AUTHOR: tijl@FreeBSD.org

  We are in the process of adjusting or, if possible, removing libtool archives
  (*.la files) from all ports because they can otherwise cause overlinking
  between packages.  This is the problem where in the dependency chain A->B->C
  an extra link is added from A to C even if A does not use C directly.  This
  makes some updates to port C expensive because then both A and B have to be
  rebuilt instead of just B.

  This is mostly behind the scenes work that you won't notice.  In fact most
  ports have already been converted.  You may however run into build errors
  about missing *.la files if a port update in the past went wrong and left
  behind *.la files with references to other *.la files that are no longer
  there.  In this case, please run the following command:

  find /usr/local/lib -name '*.la' | xargs grep -l 'libfoo\.la' | xargs pkg which
  (Replace libfoo\.la with the *.la file that is missing.)

  This command will print a list of *.la files that refer to the missing *.la
  file and what package they belong to.  First, where it says "not found in the
  datatbase", remove the *.la file.  After removing all such files, where it
  says "installed by package X", rebuild X.  Eventually the list printed by
  that command will be empty and the build error should be gone.

これでした。.laファイル(libtool archive)は依存解決で損だから廃止だよ、解決法はこちら。という内容です。
手順はこんな感じ:

  1. 問題のlibiconv.laを参照してる他の.laファイルを洗い出す。コマンドは find /usr/local/lib -name '*.la' | xargs grep -l 'libfoo\.la' | xargs pkg which です。(libfoo\.laは問題の.laファイル、今回ならlibiconv.laに置き換える)
  2. 出てきたXX.laについて、"was not found in the database"ならそのまま消す。
  3. 消し終わったら"installed by package X"のXをビルドし直す。
  4. ビルドエラーは消える。

とのことなので、さっそく実行。

find /usr/local/lib -name '*.la' | xargs grep -l 'libiconv\.la' | xargs pkg which
/usr/local/lib/libcdio.la was not found in the database
・
・
/usr/local/lib/librpmbuild.la was installed by package rpm-3.0.6_15
・
・
/usr/local/lib/gtk-2.0/2.10.0/printbackends/libprintbackend-cups.la was not found in the database
/usr/local/lib/gtk-2.0/2.10.0/engines/libpixmap.la was not found in the database

20個くらい見つかった"was not found in..."の.laファイルは全部削除。
"was installed by package..."であるところのrpm-3.0.6_15は最新のportsに無いので再ビルドできず、試しにpkg removeしてみると:

#	pkg remove rpm-3.0.6_15
Checking integrity... done (0 conflicting)
Deinstallation has been requested for the following 1 packages (of 0 packages in the universe):

Installed packages to be REMOVED:
	rpm-3.0.6_15

The operation will free 3 MiB.

Proceed with deinstalling packages? [y/N]: y
[1/1] Deinstalling rpm-3.0.6_15...
[1/1] Deleting files for rpm-3.0.6_15: 100%

依存するパッケージは無いようなので、もうそのまま削除。
なんかさらに問題が爆発したらどうしよう、と思いながらnetatalk3のディレクトリに戻ってmake install cleanしたところ、コンパイルもサクッと通ってあっというまに解決!
なんかすげースッキリしました。

netatalk3 on FreeBSD 10.2-RELEASE-p13

備忘録。

現状:

繋がった。旧サーバーから引き継いだTime Machineバックアップにちゃんと繋がったので一安心。

やったこと:

  • netatalk3のコンパイルとインストール
  • /usr/local/etc/afp.confの設定
  • /etc/rc.confの設定
  • /etc/pam.d/netatalkの設定
  • 試しに起動(接続できず):
# /usr/local/etc/rc.d/dbus start
# /usr/local/etc/rc.d/avahi start
# /usr/local/etc/rc.d/avahi-daemon start
# /usr/local/etc/rc.d/avahi-dnsconfd start
# afpd -d -F /usr/local/etc/afp.conf
  • 接続できなかったのでafpdを止めて以下のコマンドを使って起動したら接続できた。
# /usr/local/etc/rc.d/netatalk start

参考:

[http
//www.omakase.org/freebsd/timemachine_netatalk3.html:title] : 全般的に。
  • 「以下のパッケージもインストールする」のdatabases/py-bsddb、databases/py-gdbm、databases/py-sqlite3、x11-toolkits/py-tkinterは入れなくても動いた。
  • /etc/pam.confを作ることになってるけど、/etc/pam.d/があったので、この中にnetatalkというファイルを作り、次のようにした:
auth    required        pam_unix.so     try_first_pass
account required        pam_unix.so     try_first_pass
session required        pam_permit.so
[http
//borg4.vdomains.jp/~goro/diary/2014/2524:title] : afp.confのファイルパーミッションとかを。その他もいろいろ示唆的でよかった。

過去:

macから「サーバ”xxxxx”への接続で問題が起きました。 サーバ上に共有が存在しません。共有名を確認してから、やり直してください。」が出る。
サーバ側のログ(x.x.x.xはipアドレス、xxxxはユーザ名):

Mar 14 15:38:31.621074 afpd[38719] {dsi_tcp.c:241} (info:DSI): AFP/TCP session from x.x.x.x:54447
Mar 14 15:38:31.624242 afpd[38482] {main.c:151} (info:AFPDaemon): child[38719]: done
Mar 14 15:38:31.690958 afpd[38720] {dsi_tcp.c:241} (info:DSI): AFP/TCP session from x.x.x.x:54448
Mar 14 15:38:31.692346 afpd[38720] {uams_dhx2_pam.c:329} (info:UAMS): DHX2 login: xxxx
Mar 14 15:38:31.727305 afpd[38720] {uams_dhx2_pam.c:214} (info:UAMS): PAM DHX2: PAM Success
Mar 14 15:38:31.729145 afpd[38720] {uams_dhx2_pam.c:709} (info:UAMS): DHX2: PAM Auth OK!
Mar 14 15:38:31.729222 afpd[38720] {auth.c:236} (note:AFPDaemon): Login by xxxx (AFP3.4)
Mar 14 15:38:35.100606 afpd[38720] {cnid_dbd.c:160} (error:CNID): getfd: connect CNID server localhost: Connection refused
Mar 14 15:38:35.101066 afpd[38720] {cnid_dbd.c:160} (error:CNID): getfd: connect CNID server localhost: Connection refused
Mar 14 15:38:35.101547 afpd[38720] {cnid_dbd.c:176} (error:CNID): tsock_getfd: no suitable network config from CNID server (localhost:4700): Unknown error: 32767
Mar 14 15:38:35.102622 afpd[38720] {cnid_dbd.c:152} (error:CNID): getfd: getsockopt says: Connection refused
Mar 14 15:38:35.102895 afpd[38720] {cnid_dbd.c:160} (error:CNID): getfd: connect CNID server localhost: Connection refused
Mar 14 15:38:35.103026 afpd[38720] {cnid_dbd.c:176} (error:CNID): tsock_getfd: no suitable network config from CNID server (localhost:4700): Connection refused
Mar 14 15:38:35.103128 afpd[38720] {cnid_dbd.c:407} (error:CNID): transmit: connection refused (volume xxxx's home)
Mar 14 15:38:35.103337 afpd[38720] {volume.c:857} (error:AFPDaemon): afp_openvol(/home/xxxx): Fatal error: Unable to get stamp value from CNID backend
Mar 14 15:39:40.631764 afpd[38720] {auth.c:835} (note:AFPDaemon): AFP logout by xxxx
Mar 14 15:39:40.632498 afpd[38720] {dsi_stream.c:504} (error:DSI): dsi_stream_read: len:0, unexpected EOF
Mar 14 15:39:40.632658 afpd[38720] {afp_dsi.c:517} (note:AFPDaemon): afp_over_dsi: client logged out, terminating DSI session
Mar 14 15:39:40.633198 afpd[38720] {afp_dsi.c:108} (note:AFPDaemon): AFP statistics: 0.65 KB read, 0.55 KB written
Mar 14 15:39:40.633276 afpd[38720] {dircache.c:615} (info:AFPDaemon): dircache statistics: entries: 0, lookups: 0, hits: 0, misses: 0, added: 0, removed: 0, expunged: 0, evicted: 0
Mar 14 15:39:40.635542 afpd[38482] {main.c:151} (info:AFPDaemon): child[38720]: done

再起動すれば繋がる、という話があるけどまだ再起動してない。
↓(update) afpdの再起動。
<未解決>FreeBSD with Netatalk3ではまる - FreeBSDいちゃらぶ日記を参考に"afpd -d -F /usr/local/etc/afp.conf" でafpdを起動してたんだけど、こいつを止めて

# /usr/local/etc/rc.d/netatalk start

としたら接続成功。サーバ側ログ:

Mar 14 15:49:14.617975 afpd[38778] {dsi_tcp.c:241} (info:DSI): AFP/TCP session from x.x.x.x:54656
Mar 14 15:49:14.621114 afpd[38771] {main.c:151} (info:AFPDaemon): child[38778]: done
Mar 14 15:49:15.014611 afpd[38779] {dsi_tcp.c:241} (info:DSI): AFP/TCP session from x.x.x.x:54657
Mar 14 15:49:15.016669 afpd[38779] {uams_dhx2_pam.c:329} (info:UAMS): DHX2 login: xxxx
Mar 14 15:49:15.053005 afpd[38779] {uams_dhx2_pam.c:214} (info:UAMS): PAM DHX2: PAM Success
Mar 14 15:49:15.054865 afpd[38779] {uams_dhx2_pam.c:709} (info:UAMS): DHX2: PAM Auth OK!
Mar 14 15:49:15.054942 afpd[38779] {auth.c:236} (note:AFPDaemon): Login by xxxx (AFP3.4)
Mar 14 15:49:15.897419 afpd[38781] {dsi_tcp.c:241} (info:DSI): AFP/TCP session from x.x.x.x:54658
Mar 14 15:49:15.901445 afpd[38771] {main.c:151} (info:AFPDaemon): child[38781]: done
Mar 14 15:49:15.935422 afpd[38782] {dsi_tcp.c:241} (info:DSI): AFP/TCP session from x.x.x.x:54659
Mar 14 15:49:15.939814 afpd[38771] {main.c:151} (info:AFPDaemon): child[38782]: done
Mar 14 15:50:09.714009 afpd[38785] {dsi_tcp.c:241} (info:DSI): AFP/TCP session from x.x.x.x:54662
Mar 14 15:50:09.717024 afpd[38771] {main.c:151} (info:AFPDaemon): child[38785]: done
Mar 14 15:50:09.721605 afpd[38786] {dsi_tcp.c:241} (info:DSI): AFP/TCP session from x.x.x.x:54663
Mar 14 15:50:09.724419 afpd[38771] {main.c:151} (info:AFPDaemon): child[38786]: done

ようやく解決っぽい。

ブッ壊れたFreeBSDシステムを復旧

freebsd-updateしてカーネルが入れ替わってリブートして、まではちゃんとできてたのに、次にリブートしたらシステムドライブ(USBメモリ)のrootファイルシステムどころかパーティション情報まで消滅してて入れなおしてる。これは作業ログ。

インストール

FreeBSD-10.2-RELEASE-amd64-memstick.img
普通に「全部入り」でインストールしたけど、最小構成で入れてZFS(5台のRAID-Z)が復旧してからソースとかポートを入れればよかった。

  • todo: postfixが入ってないのをどうにかすること。

PPP

pppoeでルータにしてるので、これが復活しないと家のネットから外に出ていけない。

普通につながっただけですばらしい気分になった。

  • todo: ファイヤウオールの設定

WiFiアクセスポイント

いろいろあってちびファイをアクセスポイントにしている。
外に持ちだした時にもそのまま使えるように、Freebsdマシンをdhcpサーバにしてたらしく、WAN側のIPアドレスが取れず繋がらなかった。固定IPアドレスとか設定して解決。当初アドレスの打ち間違いで繋がらず、なんかdhcpの呪いかなにかかと思った。

  • todo: dhcpd復活

zfsの復活

zfsはいろいろ賢いから自動で復帰してくれると思ったけどそうはいかなかった。
http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1281671767 を見て
# zpool import
# zpool import tank
で復活。
# zfs list
で見てみたら、マウントポイントが設定されてるやつはそのままマウントされてた。
マウントされてないやつはあらためて
# zfs set mountpoint=/usr/local tank/local
てな具合で設定してマウント。ここらは http://docs.oracle.com/cd/E19253-01/819-6260/6n89n6cii/index.html とかを参考に。

/usr以下などのインストール済みシステムファイルを踏み潰さないようにzfsのマウントポイントをうごかすのは
# zfs set mountpoint=none tank/usr
などとする。

  • todo: /usr以下などのインストール済みシステムファイルをzfsUSBメモリから移す
  • todo: なぜか/usr/local/etc/以下にどっかにいってしまった設定ファイルがある。特にpostfixの仮想ホストがやばい。

電源管理

CPU

インストール時にpowerdを動かすようにしたら普通に動いた。
ただし sysctl -a dev.cpu.0.freq で800MHzまでしか落ちない。sysctl -a dev.cpu.0.freq_levels で確認しても1300/4406 1100/3550 800/2356の3段階しかなかった。

HDD

サーバを止めてたときにすばらしく静かだった。HDDの音がわりにうるさいことに気づいた。
camcontrol idle ada0 -t 600
camcontrol idle ada1 -t 600
camcontrol idle ada2 -t 600
camcontrol idle ada3 -t 600
camcontrol idle ada4 -t 600
とやったけど、zfsを動かしたら定期的にアクセスするのであんまり意味はないもよう。

  • todo: もうちょっと意味の有りそうな設定をさがす。

その他

死んだUSBメモリはそのまま持ってるけど、どうにかならないかしら。

Unicodeでは濁点や半濁点を別扱いしてることがあるので結合した

PDFをテキストに変換して使うことがときどきあります。

今日処理してたPDFな電子書籍の中に、テキストデータは持っているのに、なんかしらんけど検索がうまくかからないことが多い、という変なファイルがありました。ぜんぜん検索できないならまだわかるんだけど、できる検索語とできない検索語があるかんじ。

pdftotextでテキストファイルにしてみたところ、なんとこのテキストファイルが同じように検索できたりできなかったりする。さすがにちょっと不思議。

で、「が」という文字が入ってると検索がかからないのに気がついたので、「が」だけ切り出したテキストファイルを作り、ほかに普通のエディタで「が」だけ入力したテキストファイルを作って、PythonUnicodeコードポイントを見てみました。ga.txtが検索のかからないもの、ga2.txtがかかるものです。

>>> for line in open('ga.txt'):
...  line.decode('utf-8')
... 
u'\u304b\u3099'
>>> for line in open('ga2.txt'):
...  line.decode('utf-8')
... 
u'\u304c'

2文字です。

これ、普通にcat ga2.txtとやると1文字の「が」しか出てこないし、テキストエディタで見ても1文字だし、コピペしようと選択するときも1文字としてしか選べない。でも2文字のコードポイントを持っています。

ちょっと調べてみると、Unicodeには合成文字というシステムがあり、濁点付き、半濁点付きの文字(たとえば「が」)を表現するのに「が」1文字のコードポイントで表現してもいいし(U+304C)、「か(U+304B)」+「濁点(U+3099)」で表現してもいい、ということになっているのです。

検索置換してくれよう。と思ったんですが、普通にキーボードから日本語入力システムで入力できる「濁点」や「半濁点」では、こうした合成文字は入力できません。

それではこの合成文字を生成するのはどうしたらいいでしょう。Pythonではユニコードのコードポイントをそのまま入力してやれば文字列が生成できるので、これを使います。

また、「chr(コードポイントの数値表現)」で文字を生成できます。1文字で表現する濁点つきの文字は元の文字のコード+1、や半濁点つきの文字は+2のコードポイントに存在するので、人間は最初の「かきくけこ…」だけ入力し、あとはできるだけコンピュータまかせで生成してやれば間違いが少ないので、そんな感じで変換辞書を作ってやります。

Pythonのコマンドインタープリタを起動して辞書を初期化してから、先に半濁点付きの部分を作ってやります。

$ python3.4
Python 3.4.2 (v3.4.2:ab2c023a9432, Oct  5 2014, 20:42:22) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 
>>> repdict=dict()
>>> for tap in [(c +'\u309a' , chr(ord(c)+2)) for c in u'はひふへほハヒフヘホ']:
...   repdict.update({tap[0]:tap[1]})
... 
>>> repdict
{'パ': 'パ', 'プ': 'プ', 'ぴ': 'ぴ', 'ポ': 'ポ', 'ピ': 'ピ', 'ぷ': 'ぷ', 'ぽ': 'ぽ', 'ぱ': 'ぱ', 'ぺ': 'ぺ', 'は': '゚', 'ペ': 'ペ'}
>>> 

最初にrepdict=dict()で空の辞書を作ります。

for tap in [(c +'\u309a' , chr(ord(c)+2)) for c in u'はひふへほハヒフヘホ']:
の部分はうしろから読みます。まず
「はひふへほハヒフヘホ」
という文字列を1文字ずつ取ってcに代入します。

このcを使って2種類の文字を生成し、カッコでまとめておきます。
2つの文字とは「c +'\u309a'」と「chr(ord(c)+2)」です。
「c +'\u309a'」はcに入ってる文字そのものと半濁点('\u309a')を足した合成文字です。
「chr(ord(c)+2)」はord(c)でcのコードポイントを数値にして、それに2を足すことで半濁点付きの文字を1文字で表現したものを指定してます。

この処理を各文字についておこなってリスト(でまとめた形式)にしているので、この行の内の部分は

[('ぱ', 'ぱ'), ('ぴ', 'ぴ'), ('ぷ', 'ぷ'), ('ぺ', 'ぺ'), ('ぽ', 'ぽ'), ('パ', 'パ'), ('ピ', 'ピ'), ('プ', 'プ'), ('ペ', 'ペ'), ('ポ', 'ポ')]

というデータを作ります。

このリストの各タプルをまたループで処理します。「for (変数) in (シーケンス型):」でシーケンス型データ(リストやタプル)の1要素ずつを「変数」に取って処理するので、まず変数tapに最初のタプル「('ぱ', 'ぱ')」を取り、ようやく2行目に行きます。

repdict.update({tap[0]:tap[1]})

これは変換辞書repdictに新しい項目を追加するものです。
tapの1番目の要素(tap[0])をキーに、2番目の要素(tap[1])を値とした項目を追加しています。
for tap in []:のループなので、この処理をリストの各タプルについておこなっています。
最後にrepdictと入力して、中味を確かめてるわけです。

同様の処理を「かきくけこ…」と濁点についてもおこないます。

>>> for tap in [(chr(ord(c)) +'\u3099' , chr(ord(c)+1)) for c in u'かきくけこさしすせそたちつてとはひふへほカキクケコサシスセソタチツテトハヒフヘホ']:
...   repdict.update({tap[0]:tap[1]})
... 
>>> repdict
{'ヂ': 'ヂ', 'グ': 'グ', 'ボ': 'ボ', 'ぎ': 'ぎ', 'ず': 'ず', 'プ': 'プ', 'デ': 'デ', 'パ': 'パ', 'ゼ': 'ゼ', 'ぴ': 'ぴ', 'ぞ': 'ぞ', 'ブ': 'ブ', 'ギ': 'ギ', 'だ': 'だ', 'バ': 'バ', 'ぽ': 'ぽ', 'ズ': 'ズ', 'ぷ': 'ぷ', 'ポ': 'ポ', 'じ': 'じ', 'ぢ': 'ぢ', 'べ': 'べ', 'ぱ': 'ぱ', 'ジ': 'ジ', 'ザ': 'ザ', 'び': 'び', 'げ': 'げ', 'が': 'が', 'ビ': 'ビ', 'ベ': 'ベ', 'ぶ': 'ぶ', 'ば': 'ば', 'ざ': 'ざ', 'ペ': 'ペ', 'ぼ': 'ぼ', 'ヅ': 'ヅ', 'ゲ': 'ゲ', 'ぺ': 'ぺ', 'ガ': 'ガ', 'ゴ': 'ゴ', 'ゾ': 'ゾ', 'ピ': 'ピ', 'で': 'で', 'ぜ': 'ぜ', 'ぐ': 'ぐ', 'ド': 'ド', 'ど': 'ど', 'ダ': 'ダ', 'づ': 'づ', 'ご': 'ご'}

だいぶゴチャゴチャして、ほんとにちゃんと全部の要素が入ってるか心配なので確かめてみます。

>>> sorted(repdict.keys())
['が', 'ぎ', 'ぐ', 'げ', 'ご', 'ざ', 'じ', 'ず', 'ぜ', 'ぞ', 'だ', 'ぢ', 'づ', 'で', 'ど', 'ば', 'ぱ', 'び', 'ぴ', 'ぶ', 'ぷ', 'べ', 'ぺ', 'ぼ', 'ぽ', 'ガ', 'ギ', 'グ', 'ゲ', 'ゴ', 'ザ', 'ジ', 'ズ', 'ゼ', 'ゾ', 'ダ', 'ヂ', 'ヅ', 'デ', 'ド', 'バ', 'パ', 'ビ', 'ピ', 'ブ', 'プ', 'ベ', 'ペ', 'ボ', 'ポ']
>>> 

sorted(シーケンス型)は、ソート可能なシーケンス型をソートした結果を別のリストに入れて返す関数です。
これに食わせてるrepdict.keys()は、ディクショナリ型(辞書型)がソート不能なので、キーだけ取り出したリストを作っている、ということです。

              • -


まあこんな感じで用意しておいた変換辞書を使って、実際に2文字な「がぎぐ…」を1文字の「がぎぐ…」に置換するとしましょう。
普通こういう処理をするには文字列string型のtranslate()というメソッドを使うと便利なんですが、translate()は1文字を1文字に置き換える処理しかしてくれないので、元が2文字の今回は不適です。

まずはファイルを読み込みます。

>>> f=open('対象テキストファイル名')
>>> contents=f.read()
>>> f.close()

これで元ファイルの内容はcontentsに格納されました。
さて変換。ちょっと遅い処理になるけど、変換辞書のキーごとに元テキストをスキャンして置き換えていきます。
とか書くと長そうだけど、ループさせるので2行で書けます。

>>> for key in repdict.keys():
...   contents=contents.replace(key, repdict.get(key))
... 
    
「文字列.replace(元, 新)」は「文字列」の中の「元」を「新」に置き換えるメソッドです。 「辞書.get(キー)」はキーの項目の内容を呼び出すメソッドですから、repdictのキー(たとえば2文字版の「が」)ごとに検索をかけて、見つかったらそのキーの値(1文字版の「が」)に置き換える処理です。これを「がぎぐげご…」について繰り返したら終了です。人間がやったら死んじゃうけど、コンピュータなら一瞬です。 最後に置き換え済の内容をファイルに書き出します。本当にちゃんと変換できてるか心配だし、わけのわからない処理をしちゃっていても後戻りできるように別のファイルに書き出します。
>>> w=open('書きだすファイル名', 'w')
>>> w.write(contents)
>>> w.close()
これで変換前のファイルと変換後のファイルが存在してる状態になっててるはず。 Pythonを終了し、
$ diff 対象テキストファイル 書きだすファイル名
とか、
$ grep 'が' 書きだすファイル名
とかやって心ゆくまで確かめたら作業は終了です。 (コードの解説はPythonをやりはじめたばかりの人、およびリハビリ中の人向けに書きました) (もっと標準的な方法も存在してるようです http://tech.albert2005.co.jp/blog/2014/11/21/mco-normalize/

科学の祭典沖縄大会 2015年1日目

今年も参加しています。題目は
「はじめてのハンダ付け - うなり鉛筆をつくろう」
です。


うなり鉛筆というのはdrawdioのことで、去年基板を起こしたのが山ほどあるので使っています。今年は部品と基板に直径3mmのシールを貼り、さらに簡単に作れるようにしました。


http://farm1.staticflickr.com/415/20164958058_341259258b_c.jpg
アルバム


楽しそうでしょ!!


小学生以上を対象にしたら低学年の子ばかり来て、えらいことになりました。慣れてる人なら10分くらいのキットですが、555を逆に入れる子などが続出。ニッパでもいで予備部品を無理やり装着、などのエクストリームなハンダ付けを体験してもらってしまいました。


1回1時間としていましたが、ぜんぜん無理。二日目は1回2時間にします。


ちょう簡単なLEDバッジをつくるコーナーは、沖縄ハッカースペース木曜こども開放によく来る中学生のりんほさんにお願いしました。

https://farm1.staticflickr.com/318/20344474942_50307da632_c.jpg

彼が本当にすばらしく、ものすごく助かりました!


二日目(8月7日)もあります。時間は10:00〜16:30、場所は沖縄県中頭郡北谷町のちゃたんニライセンター(googleマップ)です。


きてね〜。