kei0425tan’s blog

技術的なことを主に

ポモドーロ・テクニック

2016/8課会資料

ポモドーロ・テクニックについて

ポモドーロ・テクニックとは
短時間の集中作業を繰り返すことにより、常に集中力を保ちながら作業を行う方法。
もともとはトマト(ポモドーロ)型のキッチンタイマーを用いて行ったことが由来。

基本的には、集中タイム(25分)休憩タイム(5分)(これで1ポモドーロと呼ぶ)を4回繰り返し、長い休憩を取る。

集中タイムは決めたタスク以外は一切やらず(メールチェックなど)作業に集中する。
もし、中断させられた場合には、そのポモドーロは失敗とし、やり直し。

メリット
・作業にメリハリがつき集中しやすい。
・作業見積もりをポモドーロ単位で行うことにより、見積もりがしやすくなる。

なお、1日は通常7.5時間労働のため、単純計算すると12ポモドーロほど可能だが、実際には1日8ポモドーロほどと見積もるほうがよい。

Bash on Ubuntu on Windowsについて その2

はじめに

以前、Bash on Ubuntu on Windowsについて記事にしました。

kei0425tan.hatenablog.com


実はうちのPCで、Windows 10 Insider PreviewでBash on Ubuntu on Windowsを試していたのですが、インストール時にブルースクリーンになりPCがとても不安定になったため、あきらめていました。

しかし、先日リリースされた、Windows 10 Insider Preview 14385でやっと実行できるようになりました。
(一度クリーンインストールしたせいかもしれませんが)

初期設定

bashを実行するとWindows Storeより自動的にダウンロードして実行できるようになります。
最後に、bash上でのユーザ名とパスワードを設定します。
以前のバージョンでは、ここは未設定で勝手にrootとしてログインされるようです。

ここでは以下に設定したものとします。

ユーザ名:username
コンピュータ名(Windowsの設定):computername

コンピュータ名がホスト名になります。

調査開始

まずは、カーネル情報

username@computername:~$ uname -a
Linux computername 3.4.0+ #1 PREEMPT Thu Aug 1 17:06:05 CST 2013 x86_64 x86_64 x86_64 GNU/Linux

ubuntuのバージョンは以下になります。

username@computername:~$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=14.04
DISTRIB_CODENAME=trusty
DISTRIB_DESCRIPTION="Ubuntu 14.04.4 LTS"

ちょっと古いですね。でもLTSなのでサポート内で、14.04.4は2016/2/17にリリースされました。
Wikipedia情報では、14.04はカーネルは3.13のようですが、なぜか食い違っていました。

続いてネットワークについて調べてみました。

username@computername:~$ /sbin/ifconfig
警告: /proc/net/devを開けません(そのようなファイルやディレクトリはありません). 限定された出力です.

なぜかみえませんでした;;

pingもエラーが出て利用できません。
しかし、curlは実行できました。
ネットワークに関しては、一部のクライアントアプリのみ利用できるようです。

(つづく)

なんで5回

2016/7課会資料

なんで5回

「なぜなぜ5回」や「なぜなぜ分析」とも呼ばれる手法。

ある問題を解決するためなどに用いられることが多い。
ある問題についての要因を考え、その要因が発生する要因を考える。これを5回行うと真の要因にたどり着くというもの。(5回は目安であり必ず5回という意味ではない。)

例:
「ラインが突然停止」→「モーターに負荷がかかりすぎた結果、配電盤のヒューズが飛んだ」→「モーターに負荷がかかりすぎたのはモーターの潤滑油が不足していた」→「モーターの潤滑油が不足していたのは、ポンプの性能に難があり十分に潤滑油をくみ上げていない」→「ポンプの性能は軸が磨り減っていた」→「潤滑油をためるタンクの中にラインから出る切り粉が大量に混入し、それがポンプの軸を異常に磨り減らしていた」

問題を解明する他にもいろいろなことにも応用が可能。
例:
「先生になりたい」→「子どもにモノを教えたいから」→「先生をリスペクトしてる」→「その先生の授業がマジ面白くて苦手だった数学の成績もマジアップしちゃって先生マジすごいって思ったから」→「数学の苦手な僕のために付きっ切りで教えてくれて、そんな先生今までいなかった」
(「テストの花道 ニューベンゼミ」より)

似たようなものに、マインドマップやマンダラートなどもある。


録画した「テストの花道 ニューベンゼミ」を見ていたら
www6.nhk.or.jp
ネットで話題のアニメ「寿司くん」が、「将来やりたいワケ」を見つけるツール『なんで5回』を伝授!

というのがやっていたため、ちょっと気になって調べてみました。
デバッグする際には、なんで?なんで?と原因をたどっていくのはよくやりますが(途中でよくわかんなくなって、例外をキャッチして終わりにする人もいますが。。。)デバッグ以外にもいろいろなことに応用が効くとは今まで気が付きませんでした。
高校生向けの番組なのですが、意外と侮れないですね。

POH7「サンタ服」ゲットチャレンジ!

POH8の問題を全部解いてしまったので、昔のにも挑戦してみます。

paiza.jp

問題

(適当に省略しています。)

幅 X cm、奥行き Y cm、高さ Z cm の直方体の形をしたケーキがあります。 このケーキに「側面と平行な方向」および「前面と平行な方向」に何回か包丁を入れて、小さなケーキに切り分けることを考えます。 上面と平行な方向(水平方向)には包丁を入れません。

包丁を入れる場所が与えられたとき、切り分けられたケーキの中で最も体積が小さいものを求めてください。

条件

すべてのテストケースにおいて、以下の条件をみたします。

1 ≦ X, Y, Z, N ≦ 100
d_i は 0 または 1
d_i = 0 のとき 1 ≦ a_i ≦ X-1
d_i = 1 のとき 1 ≦ a_i ≦ Y-1
同じ場所に 2 回以上包丁を入れることはない
入力される値はすべて整数

今回も範囲が狭いため普通に探せば問題なさそうです。
単純に、横に切った一番小さいとこと縦に切った一番小さいところを探してかければOK

切った幅を出すのに、reduceを利用しています。
普通にインデックスを使っても全然いいのですが、こんなやり方もあるよということで。
reduce使うなら、minも統合できるのですが、pythonのlambdaが複雑なこと書きにくいのでやっていません。
普通に関数別に書けばよいのですが。。。。

POH7「プログラミングで彼女をつくる」「めがね」ゲットチャレンジ!

POH8の問題を全部解いてしまったので、昔のにも挑戦してみます。

paiza.jp

問題

(適当に省略しています。)

あなたはクライアントから画像分析の仕事を受けました。

N × N ピクセルの白黒画像と M × M ピクセルの白黒画像が与えられます。 白黒画像の各画素は 0 または 1 のいずれかです。 N × N ピクセルの画像を入力、M × M ピクセルの画像をパターンと呼ぶことにします。

あなたの仕事は、入力からパターンとの完全一致を探すことです。

入力とパターンがピクセルの位置 (y, x) で完全一致するとは、 全ての i, j (i = 0, 1, ... M - 1, j = 0, 1, ... M - 1) について、 (入力の位置 (y + j, x + i) におけるピクセル) = (パターンの位置 (j, i) におけるピクセル) が成立することをいいます。

また、依頼主からは、入力にはパターンと完全一致する箇所は必ず 1 つだけ存在するということを 伝えられています。

条件

すべてのテストケースにおいて、以下の条件をみたします。

10 ≦ N ≦ 100, 2 ≦ M ≦ 10
q_{i, j}, p_{i, j} は 0 または 1
パターンと完全一致する箇所は必ず1つだけ存在します

入力例1

入力
4
0 0 1 0
0 1 1 0
0 1 0 1
1 1 1 0
3
0 1 1
0 1 0
1 1 1

出力
1 0

今回は範囲が狭いため(高々1万個)普通に探せば問題なさそうです。
さらに、一致するかどうかもいったん文字列化すると簡単に比較できるのでよいでしょう。

POH7「プログラミングで彼女をつくる」「水着」ゲットチャレンジ!

POH8の問題を全部解いてしまったので、昔のにも挑戦してみます。

paiza.jp

問題

階乗とは数学の演算の一つで、N の階乗をN! と書きます。N が自然数であるとき、階乗は次のように計算できます。

N! = N * (N - 1) * ... * 2 * 1


N が与えられたとき、N! のすべての桁の代わりに、N! の最下位桁から続く0 をすべて除いた値の下位9桁を求めるプログラムを作成してください。
9桁ではあるが先頭が0であるような場合は先頭の0を取り除いた値を出力してください。先頭に0のついた値を出力すると誤答となります。
例えば N = 38 の時は以下のようになります。

f:id:kei0425tan:20160707141134p:plain

条件

すべてのテストケースにおいて、以下の条件をみたします。

1 ≦ N ≦ 1000000

入力例1

入力
15

出力
307674368

入力例2

入力
10

出力
36288

ちょっと見、ただ単に階乗を求めて、ちょこちょこっと条件に合うように変更するだけにみえますが、実はトラップが何個も仕掛けてありました。
2つの入力例だけの場合は、上記の通り何も考えずにトラップに引っかからずに通ってしまいます。

トラップ1

整数型では単に階乗を求めてしまうとかなり早い段階でオーバーフローを起こしてしまいます。
LL言語で動的型で解こうとしても、JavaScriptなどは内部で浮動小数点型に変換されてしまうため、正確な値がでなくなります。

トラップ2

入力範囲が1000000まで。そのため、何も考えずに再帰で書いてしまうとほぼスタックオーバーフローになります。

トラップ3

トラップ1にかからないように、巨大な値になる前に、常に下の0を削除して9桁で計算してしまおう。と思っていると引っかかります。
5の倍数をかけると実質割り算になるので、途中が9桁しかないと答えが合いません。

以上を踏まえて、scalaで解いてみました。
scalaの理由は末尾再帰最適化があるから!

PostgreSQLのtemplate0,template1,postgresとかバックアップとか

仕事でPostgreSQLを利用しているのですが、いろいろと理解できていなかったところがあったので、その中でもtemplate0,template1,postgresについて

template0とtemplate1の違いについて

template1

createdb実行時に-Tで指定しない場合はデフォルトで雛形として利用されます。
雛形のため、template1を変更しても、変更以前に作成されたDBにはその変更は適用されません。
変更後に作成したDBには同じ変更が適用されます。

主に、コードセットの設定や、拡張コマンドなどをいれるとよいでしょう。
テーブルなども作成しておくことは可能ですが、あまり有効な利用方法は思いつきません。

template0

PostgreSQLの最低限必要もののみが設定されています。
変更はできません。
余計な変更が入っていると困る場合は、createdb実行時に-T template0を指定します。

posgres(DB名)について

デフォルトのDB名。qsqlなどコマンドで接続先を指定しない場合に利用されます。
サードパーティのユーティリティも、postgresDBに接続していろいろなコマンドを実行することが多いです。
削除はできません。

initdbについて

initdbを実行すると、まずtemplate1が作成されて、それをtemplate0とpostgresにコピーします。
マニュアルを読むと、template0を雛形にしてtemplate1が作成されるとありますが、実際には上記の順番で作成。
ただし、実質initdbした直後はtemplate0とtemplate1は同一のため、それほど気にする必要はなさそうです。

initdb /tmp/posttestを実行したログ

The files belonging to this database system will be owned by user "postgres".
This user must also own the server process.

The database cluster will be initialized with locale "en_US.UTF-8".
The default database encoding has accordingly been set to "UTF8".
The default text search configuration will be set to "english".

Data page checksums are disabled.

creating directory /tmp/posttest ... ok
creating subdirectories ... ok
selecting default max_connections ... 100
selecting default shared_buffers ... 128MB
creating configuration files ... ok
creating template1 database in /tmp/posttest/base/1 ... ok
initializing pg_authid ... ok
initializing dependencies ... ok
creating system views ... ok
loading system objects' descriptions ... ok
creating collations ... ok
creating conversions ... ok
creating dictionaries ... ok
setting privileges on built-in objects ... ok
creating information schema ... ok
loading PL/pgSQL server-side language ... ok
vacuuming database template1 ... ok
copying template1 to template0 ... ok
copying template1 to postgres ... ok
syncing data to disk ... ok

WARNING: enabling "trust" authentication for local connections
You can change this by editing pg_hba.conf or using the option -A, or

    • auth-local and --auth-host, the next time you run initdb.

Success. You can now start the database server using:

/usr/local/pgsql/bin/postgres -D /tmp/posttest
or
/usr/local/pgsql/bin/pg_ctl -D /tmp/posttest -l logfile start

バックアップ pg_dump について

バックアップファイルには、そのDB作成時に利用したテンプレートの内容も含まれます。

https://www.postgresql.jp/document/9.3/html/backup-dump.html#BACKUP-DUMP-RESTORE

重要項目: pg_dumpで作成されるダンプはtemplate0と相対関係にあります。 つまりtemplate1を経由して追加されたあらゆる言語、プロシージャなどもpg_dumpによりダンプされます。 その結果としてリストアする際に、カスタマイズされたtemplate1を使用している場合は、上記の例のように、template0から空のデータベースを作成する必要があります。

DBをリストアする場合に、事前にDBを作成してリストアする場合には
template0を利用しないと、template1の変更点が重複するため、template0を利用するのがおすすめのようです。

https://www.postgresql.jp/document/9.3/html/app-pgrestore.html

template1データベースに対し独自の変更を行っている場合、pg_restoreの出力は、確実に空のデータベースにロードするよう注意してください。 そうしないと、おそらく追加されたオブジェクトの重複定義によってエラーが発生します。 独自の追加が反映されていない空のデータベースを作成するには、template1ではなくtemplate0をコピーしてください。 以下に例を示します。

リストア時には、新規データベースにて、template1で使えるようにした拡張コマンドがそのままでは利用できなくなります。

バックアップ pg_dumpallについて

pg_dumpallでは、以下をバックアップします。

  • 各ロール、ユーザ
  • 各ユーザ追加DB
  • template1の変更点
  • postgres(DB)の変更点
各ユーザ追加DB

バックアップファイルには、create database -T template0で作成するようになっています。
そのため、リストアした新規データベースでは、リストア前にtemplate1に対して行った変更は反映されません。

template1,postgres

バックアップファイルには、create databaseはなく、変更点のみになっています。
そのため、リストアした新規データベースでは、リストア前にtemplate1に対して行った変更はそのままで、さらに、バックアップ元で行った変更が行われます。
よって、拡張コマンドなどはそのまま利用できます。