UTCの時刻を任意のタイムゾーンに変換する

ActiveSupport::TimeWithZone を使うのが便利。active_support/time を require する。

2.1.1 :001 > require 'active_support/time'
 => true 

UCT 時刻を America/Chicago 時刻に変換してみる。

2.1.1 :002 > t = Time.now.utc
 => 2014-11-16 11:14:17 UTC 
2.1.1 :003 > tc = t.in_time_zone('America/Chicago')
 => Sun, 16 Nov 2014 05:14:17 CST -06:00 

tc のクラスは Time ではなくて、ActiveSupport::TimeWithZone。

2.1.1 :004 > tc.class
 => ActiveSupport::TimeWithZone

Time と比較もできる。

2.1.1 :005 > t == tc
 => true

TimeZone が違うと時刻表示は当然違うけど、UTC に直すと同じ時刻なので true になる。

Ubuntuにsshで接続する

Windowsマシンから、Ubuntuのマシンにsshで接続できるようにする。
↓このページが参考になった。

 cf. http://www.server-world.info/query?os=Ubuntu_14.04&p=ssh

まずは、ssh サーバを atp-get でインストール。

takatoh@nightschool $ sudo apt-get install openssh-server
[sudo] password for takatoh: 
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています                
状態情報を読み取っています... 完了
以下のパッケージが自動でインストールされましたが、もう必要とされていません:
  firefox-locale-en linux-headers-3.13.0-34 linux-headers-3.13.0-34-generic
  linux-image-3.13.0-34-generic linux-image-extra-3.13.0-34-generic
これを削除するには 'apt-get autoremove' を利用してください。
以下の特別パッケージがインストールされます:
  libck-connector0 openssh-sftp-server ssh-import-id
提案パッケージ:
  rssh molly-guard monkeysphere
以下のパッケージが新たにインストールされます:
  libck-connector0 openssh-server openssh-sftp-server ssh-import-id
アップグレード: 0 個、新規インストール: 4 個、削除: 0 個、保留: 12 個。
374 kB のアーカイブを取得する必要があります。
この操作後に追加で 1,214 kB のディスク容量が消費されます。
続行しますか? [Y/n] Y
取得:1 http://jp.archive.ubuntu.com/ubuntu/ trusty/main libck-connector0 amd64 0.4.5-3.1ubuntu2 [10.5 kB]
取得:2 http://jp.archive.ubuntu.com/ubuntu/ trusty-updates/main openssh-sftp-server amd64 1:6.6p1-2ubuntu2 [34.1 kB]
取得:3 http://jp.archive.ubuntu.com/ubuntu/ trusty-updates/main openssh-server amd64 1:6.6p1-2ubuntu2 [319 kB]
取得:4 http://jp.archive.ubuntu.com/ubuntu/ trusty/main ssh-import-id all 3.21-0ubuntu1 [9,624 B]
374 kB を 0秒 で取得しました (397 kB/s)
パッケージを事前設定しています ...
以前に未選択のパッケージ libck-connector0:amd64 を選択しています。
(データベースを読み込んでいます ... 現在 421617 個のファイルとディレクトリがインストールされています。)
Preparing to unpack .../libck-connector0_0.4.5-3.1ubuntu2_amd64.deb ...
Unpacking libck-connector0:amd64 (0.4.5-3.1ubuntu2) ...
以前に未選択のパッケージ openssh-sftp-server を選択しています。
Preparing to unpack .../openssh-sftp-server_1%3a6.6p1-2ubuntu2_amd64.deb ...
Unpacking openssh-sftp-server (1:6.6p1-2ubuntu2) ...
以前に未選択のパッケージ openssh-server を選択しています。
Preparing to unpack .../openssh-server_1%3a6.6p1-2ubuntu2_amd64.deb ...
Unpacking openssh-server (1:6.6p1-2ubuntu2) ...
以前に未選択のパッケージ ssh-import-id を選択しています。
Preparing to unpack .../ssh-import-id_3.21-0ubuntu1_all.deb ...
Unpacking ssh-import-id (3.21-0ubuntu1) ...
Processing triggers for man-db (2.6.7.1-1ubuntu1) ...
Processing triggers for ureadahead (0.100.0-16) ...
ureadahead will be reprofiled on next reboot
Processing triggers for ufw (0.34~rc-0ubuntu2) ...
libck-connector0:amd64 (0.4.5-3.1ubuntu2) を設定しています ...
openssh-sftp-server (1:6.6p1-2ubuntu2) を設定しています ...
openssh-server (1:6.6p1-2ubuntu2) を設定しています ...
Creating SSH2 RSA key; this may take some time ...
Creating SSH2 DSA key; this may take some time ...
Creating SSH2 ECDSA key; this may take some time ...
Creating SSH2 ED25519 key; this may take some time ...
ssh start/running, process 16328
ssh-import-id (3.21-0ubuntu1) を設定しています ...
Processing triggers for libc-bin (2.19-0ubuntu6.3) ...
Processing triggers for ureadahead (0.100.0-16) ...
Processing triggers for ufw (0.34~rc-0ubuntu2) ...

次に /etc/ssh/sshd_config ファイルを編集。28行目を次のように no にする。

PermitRootLogin no

root でのログインを拒否するわけだね。ちなみにデフォルトでは without-password となっていて、これは鍵認証が必要な設定らしい。

22番ポートを開ける。というか開いていた。

takatoh@nightschool $ sudo ufw status
状態: アクティブ

To                         Action      From
--                         ------      ----
3000/tcp                   ALLOW       Anywhere
9000/tcp                   ALLOW       Anywhere
22/tcp                     ALLOW       Anywhere
8080/tcp                   ALLOW       Anywhere
80                         ALLOW       Anywhere
3000/tcp (v6)              ALLOW       Anywhere (v6)
9000/tcp (v6)              ALLOW       Anywhere (v6)
22/tcp (v6)                ALLOW       Anywhere (v6)
8080/tcp (v6)              ALLOW       Anywhere (v6)
80 (v6)                    ALLOW       Anywhere (v6)

最後に、sshを再起動。

takatoh@nightschool $ initctl restart ssh
initctl:不明なジョブ: ssh

あれ、ダメだ。上の参考ページのマシンとなにか違うのかも。
しょうがないから、/etc/init.d/ssh を直接叩いて再起動。

takatoh@nightschool $ /etc/init.d/ssh restart

これで Ubuntu 側は OK。今度は Windows 側。
接続には Tera Term を使う。

TeraTerm-connect

ホストに IPアドレスを指定して、OKボタンを押す。上に書いたとおり、ポートはデフォルトの22番。

TeraTerm-auth

ユーザー名とパスワードを入力して OK ボタンを押すと、無事接続できた。

TeraTerm-remote

Pythonでリストのtranspose

Python には Ruby の Array#transpose に当たるメソッドがない。
で、最初こう書いた。

def transpose(list_of_lists):
    ary = []
    for i in range(len(list_of_lists[0])):
        ary.append(map(lambda x: x[i], list_of_lists))
    return ary

でも、これって内包表記でできそうだよな。と思い直してちょっと悩んで書いたのがこれ。

def transpose(list_of_list):
    return [[x[i] for x in list_of_list] for i in range(len(list_of_list[0]))]

最初のより短くなったけど、二重の内包表記はわかりにくい。もうちょっとわかりやすくはいかないもんだろうか。で、ググってみたら zip と引数展開を使うやり方を見つけた。

 cf. Transpose a matrix in Python – stackoverflow

def transpose(list_of_list):
    return map(list, zip(*list_of_list))

これは分かりやすい。zip の引数に * をつけて渡すことで、引数を展開している。で、このままだとタプルのリストになるので、map を使ってリストのリストに直してるわけだ。

>>> l = [[1,2,3], [4,5,6], [7,8,9]]
>>> zip(*l)
[(1, 4, 7), (2, 5, 8), (3, 6, 9)]
>>> map(list, zip(*l))
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]

lengthのもうひとつの実装

リストの個数を返す手続き。

 cf. lengthの別の実装 – 理想のユーザ・インターフェイスを求めて

名前付きletの使い方を忘れてて調べた^^;

(define length
  (lambda (l)
    (let loop ((len 0) (lis l))
      (if (null? lis)
          len
          (loop (+ len 1) (cdr lis))))))

(print (length '(1 2 3 4 5)))
takatoh@nightschool $ gosh length.scm
5

問: 組み体操で10段のピラミッドを作ったとき、最も重量がかかるのはどの場所で、それはおよそ何kgか

Twitter で流れてきたので、Scheme でやってみた。

(define main
  (lambda (args)
    (print (reaction-of-kumitaiso (string->number (cadr args))))))

(define self-weight
  (lambda (n)
    (if (= n 1)
        (list 0.5 0.5)
        (cons 0.5 (append (make-list (- n 1) 1.0) '(0.5))))))

(define reaction-of-kumitaiso
  (lambda (n)
    (if (= n 1)
        (self-weight 1)
        (let ((u (map (lambda (x) (/ x 2.0)) (reaction-of-kumitaiso (- n 1)))))
          (map + (cons 0.0 u) (append u '(0.0)) (self-weight n))))))

1人分の体重を1.0として10段だと、一番下の支点にかかる重量は、

takatoh@nightschool $ gosh kumitaiso.scm 10
(0.9990234375 2.986328125 4.9091796875 6.6171875 7.841796875 8.29296875 7.841796875 6.6171875 4.9091796875 2.986328125 0.9990234375)

最大になるのは真ん中の支点で、8.29296875。1人の体重が60kgだと仮定すれば、

gosh> (* 8.29296875 60.0)
497.578125

となって、およそ500kg。うへぇ!

Amazon EC2を試してみた:(4)インスタンスに固定IPをつける

Elastic IP というのを使うようだ。

EC2 の Dashboard ページから、Elastic IPs を選んでページを移動、Allocate New Address をクリックする。
これだけで、新しい IP アドレスが作成された。

今できたアドレスを右クリックして Associate Address を選ぶ。出てきたダイアログでひもづけるインスタンスを選んで、Associate ボタンをクリック。
これで OK のようだ。

ちゃんと Elastic IP がひもづけられているのを、次の2つで確認した。

  • ssh で接続できる
  • ブラウザで接続できる(Nginx のページが表示される)

追記

インスタンスをいったん停止して、再度起動してからも同じ IP で接続できることも確認した。

Amazon EC2を試してみた:(3)Nginx

今回は Nginx をインストールして web ページを確認するまで。

インストールはとっても簡単、yum コマンドでインストールするだけ。

[ec2-user@ip-172-31-3-244 ~]$ sudo yum install nginx

起動。

[ec2-user@ip-172-31-3-244 ~]$ sudo /etc/init.d/nginx start
nginx を起動中:                                            [  OK  ]

ブラウザで確認すると、ちゃんと動いている。

nginx-on-amazon-ec2

Amazon EC2を試してみた:(2)S3バケットをマウントする

S3のバケットをファイルシステムとしてマウントするには、s3fs-fuse というツールを使う。今回使ったヴァージョンは最新の 1.77

依存するツールのインストール

まずは依存するツールをインストールする。

[ec2-user@ip-172-31-3-244 ~]$ sudo yum install gcc
[ec2-user@ip-172-31-3-244 ~]$ sudo yum install libstdc++-devel
[ec2-user@ip-172-31-3-244 ~]$ sudo yum install gcc-c++
[ec2-user@ip-172-31-3-244 ~]$ sudo yum install fuse
[ec2-user@ip-172-31-3-244 ~]$ sudo yum install fuse-devel
[ec2-user@ip-172-31-3-244 ~]$ sudo yum install curl-devel
[ec2-user@ip-172-31-3-244 ~]$ sudo yum install libxml2-devel
[ec2-user@ip-172-31-3-244 ~]$ sudo yum install openssl-devel
[ec2-user@ip-172-31-3-244 ~]$ sudo yum install mailcap
[ec2-user@ip-172-31-3-244 ~]$ sudo yum install automake

ダウンロードしてインストール

[ec2-user@ip-172-31-3-244 ~]$ wget https://github.com/s3fs-fuse/s3fs-fuse/archive/v1.77.tar.gz -O s3fs-fuse-v1.77.tar.gz
[ec2-user@ip-172-31-3-244 ~]$ tar xvzf s3fs-fuse-v1.77.tar.gz
[ec2-user@ip-172-31-3-244 ~]$ cd s3fs-fuse-1.77
[ec2-user@ip-172-31-3-244 s3fs-fuse-1.77]$ ./autogen.sh
[ec2-user@ip-172-31-3-244 s3fs-fuse-1.77]$ ./configure --prefix=/usr
[ec2-user@ip-172-31-3-244 s3fs-fuse-1.77]$ make
[ec2-user@ip-172-31-3-244 s3fs-fuse-1.77]$ sudo make install

認証

S3に接続するには認証の必要がある。つまり Access Key ID と Secret Access Key が必要だってこと。方法は4つあるようだけど、今回は /etc/passwd-s3fs ファイルを作る方法にした。

[ec2-user@ip-172-31-3-244 s3fs-fuse-1.77]$ sudo vim /etc/passwd-s3fs
[ec2-user@ip-172-31-3-244 s3fs-fuse-1.77]$ sudo chmod 640 /etc/passwd-s3fs

マウント

[ec2-user@ip-172-31-3-244 ~]$ sudo s3fs lathercraft-storage2 /mnt/lcstorage -o rw,allow_other,default_acl=private

さあ、うまくいってるかな?

[ec2-user@ip-172-31-3-244 ~]$ echo Hello > /mnt/lcstorage/hello.txt
[ec2-user@ip-172-31-3-244 ~]$ ls /mnt/lcstorage
hello.txt
[ec2-user@ip-172-31-3-244 ~]$ df -kh
ファイルシス   サイズ  使用  残り 使用% マウント位置
/dev/xvda1       7.8G  1.3G  6.5G   16% /
devtmpfs         990M   56K  990M    1% /dev
tmpfs           1003M     0 1003M    0% /dev/shm
s3fs             256T     0  256T    0% /mnt/lcstorage

OK、うまくいった。

参考になったページ

 cf. Amazon EC2からS3をファイルシステムとしてマウントする – mooapp
 cf. s3fs を使って EC2 に S3 の Bucket をマウントする – Qiita
 cf. Installation Notes – s3fs-fuse/s3fs-fuse

追記

インスタンスを再起動した時に自動でマウントするには、/etc/fstab ファイルに次の行を追加する。

s3fs#lathercraft-storage2 /mnt/lcstorage fuse rw,allow_other,default_acl=private 0 0

Amazon EC2を試してみた:(1)SSHで接続するまで

Amazon Web Service のホームから EC2 をクリックすると、EC2 のホーム画面になる。Launch Instance を選んで、スタート。

Step 1: Choose an Amazon Machine Image (AMI)

まずは、OS を選ぶところから。ここは素直に、Amazon Linux AMI 2014.03.2 (HVM) にしておいた。

Step 2: Choose an Instance Type

次にインスタンスタイプを選ぶ画面になる。インスタンスタイプはちょっとだけ欲張って t2.small にする。右下の Next: Configure Instance Details をクリック。

Step 3: Configure Instance Details

ここはデフォルトのまま、Next: Add Storage をクリック。

Step 4: Add Storage

ここもデフォルトのまま。

Step 5: Tag Instance

Name に lathercraft-storage2 を指定して、Next: Configure Security Group。

Step 6: Configure Security Group

Assign a security group はデフォルトの Create a new security group。Security group name は launch-wizard-3 となっていたのでそのまま。3 になってるのは、前にもちょっとだけ試したことがあるからかな。
HTTP のサーバとして使う予定なので Add Rule から HTTP を選んで追加した。

Step 7: Review Instance Launch

最終確認画面。このまま Launch をクリック。すると、Select an existing key pair or create a new key pair というダイアログが出たので、Create a new key pair をえらんで、amazon2 という名前をつける。でもって Download key pair をクリックすると鍵がダウンロードできる。これは SSH でインスタンスに接続するときに使う。ダウンロードした鍵は amazon2.pem というファイル名になっている。
それから、あらためて Launch Instance をクリック。

これでインスタンスの起動は完了。View Instaces をクリックして、EC2 のホーム画面に戻ると、新しいインスタンスが running 状態になっているのが確認できた。

SSHで接続

上でダウンロードした鍵 amazon2.pem ファイルを .ssh ディレクトリに移動してパーミッションを変更。

takatoh@nightschool $ mv Downloads/amazon2.pem .ssh
takatoh@nightschool $ chmod 400 .ssh/amazon2.pem
takatoh@nightschool $ ls -l .ssh | grep amazon2
-r-------- 1 takatoh takatoh 1692  9月  6 08:26 amazon2.pem

さあ、インスタンスに接続してみよう。インスタンスの IPアドレスは、インスタンスリストの Public IP の欄で確認できる。ユーザーは ec2-user だ。

takatoh@nightschool $ ssh -i .ssh/amazon2.pem [email protected]
Last login: Fri Sep  5 23:44:47 2014 from fntsitm001026.sitm.fnt.ngn.ppp.infoweb.ne.jp

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2014.03-release-notes/
9 package(s) needed for security, out of 28 available
Run "sudo yum update" to apply all updates.