リスト(配列)の中で隣り合う同じ値をグループ化する(3)

しつこいようだけど、今度は Go でやってみた。

package main

import (
    "fmt"
)

func main() {
    var l1 = []int{1, 1, 2, 2, 3, 1, 1}
    var l2 = []int{}

    fmt.Printf("%v\n", adjacentGroup(l1))
    fmt.Printf("%v\n", adjacentGroup(l2))
}

func adjacentGroup(l []int) [][]int {
    var result [][]int

    if len(l) == 0 {
        return result
    }

    var current = []int{l[0]}
    for i := 1; i < len(l); i++ {
        if current[0] == l[i] {
            current = append(current, l[i])
        } else {
            result = append(result, current) current = []int{l[i]}
        }
    }
    result = append(result, current) return result
} 
^o^ > go run adjacentGroup.go
[[1 1] [2 2] [3] [1 1]]
[]

リスト(配列)の中で隣り合う同じ値をグループ化する(2)

こないだのやつを Scheme と Haskell でやってみた。

まずは Scheme 版。

(define adjacent-group
  (lambda (lis)
    (let loop ((l (cdr lis)) (c (car lis)) (r (cons (list (car lis)) '())))
      (if (null? l)
          (reverse (map reverse r))
          (if (= (car l) c)
              (loop (cdr l) c (cons (cons (car l) (car r)) (cdr r)))
              (loop (cdr l) (car l) (cons (list (car l)) r)))))))

(print (adjacent-group '(1 1 2 2 3 1 1)))
^o^ >gosh adjacent-group.scm
((1 1) (2 2) (3) (1 1))

基本的な考え方は、Ruby や Python のと同じ。ちょっと工夫したのは、先頭の要素を最初から結果のリストに入れたこと。これで分岐条件が1つ減った。
……のはいいんだけど、これって引数に空リストが来た時のことが考えられてないじゃないか。まあ、グループ化しようというんだから空リストは考えなくてもいいか……ホントか?

さて、Haskell 版。こっちはちゃんと空リストが来ても大丈夫(実行例は示さないけど)。

adjacentGroup :: [Int] -> [[Int]]
adjacentGroup [] = []
adjacentGroup (x:xs) = reverse $ map reverse $ foldl f [[x]] xs
  where
    f (y:ys) z = if head y == z
                 then (z:y):ys
                 else (z:[]):y:ys

main :: IO()
main = print $ adjacentGroup [1, 1, 2, 2, 3, 1, 1]
^o^ >runhaskell adjacentGroup.hs
[[1,1],[2,2],[3],[1,1]]

[追記](9/27)

Scheme 版を空リスト対応にした。分岐条件が1つ増えた。

(define adjacent-group
  (lambda (lis)
    (let loop ((l lis) (c (undefined)) (r '()))
      (if (null? l)
          (reverse (map reverse r))
          (cond
            ((undefined? c) (loop (cdr l) (car l) (cons (list (car l)) r)))
            ((= (car l) c) (loop (cdr l) c (cons (cons (car l) (car r)) (cdr r))))
            (else (loop (cdr l) (car l) (cons (list (car l)) r))))))))

(print (adjacent-group '(1 1 2 2 3 1 1)))
(print (adjacent-group '()))
^o^ >gosh adjacent-group2.scm
((1 1) (2 2) (3) (1 1))
()

[さらに追記](9/28)

分岐条件を工夫して2つに減らせた。cond じゃなく if になった。

(define adjacent-group
  (lambda (lis)
    (let loop ((l lis) (c (undefined)) (r '()))
      (if (null? l)
          (reverse (map reverse r))
          (if (and (not (undefined? c)) (= (car l) c))
              (loop (cdr l) c (cons (cons (car l) (car r)) (cdr r)))
              (loop (cdr l) (car l) (cons (list (car l)) r)))))))

(print (adjacent-group '(1 1 2 2 3 1 1)))
(print (adjacent-group '()))
^o^ > gosh adjacent-group3.scm
((1 1) (2 2) (3) (1 1))
()

サーバのOSをUbuntuからCentOSに変えた

やっと書く気になってきた。
インターネット回線を乗り換えたので、一昨日、その工事があった。その関係で外部公開している WEB サーバを止めなくちゃいけなかったので、ついでにサーバの OS をクリーンインストールすることにした。というのも、どういうわけだかわからないけどずっとサーバの調子が悪くてたびたび WEB サーバが落ちる、ということが続いていて、それも最近は頻度が多くなっていたから。で、ちょうどいいので OS のインストールからやり直すことにしたってわけ。OS はタイトルのとおり、Ubuntu から CentOS に変更した。この記事はその顛末。
といっても、CentOS のインストールと WEB サーバ、アプリの構築は去年の年末から今年にかけて一度やっているので、細かくは書かずにリンクを置くだけにする。

CentOS のインストール

最新の CentOS 7.5 1804 の ISO イメージをダウンロードして、DVD に焼いて使った。

cf. CentOS 7のインストール
cf. CentOSのアップデート

最低限のソフトウェアのインストール

Git、Ruby、ImageMagick をそれぞれ yum install でインストールした。今回、rbenv は使わなかった。yum でインストールした Ruby は 2.0.0 と古いけど、構築する予定の WEB アプリでは最近の新しい機能は使っていないのと、サービスとして rbenv の環境を使うのは煩わしいと感じたのでそうした。ImageMagick もアプリで使う。

一般ユーザーで sudo できるようにする

cf. 一般ユーザーでsudoできるようにする

USB 外付け HDD

cf. USBの外付けHDDを使ってみる
これはもとから使っていた HDD を繋いだ。OS が変わってうまく使えるか心配したけど、結果的には、ディレクトリとファイルの所有者を chown で変えてやればそのまま使えた。

Nginx

WEB サーバには前と同じ Nginx。
cf. CentOS 7にNginxをインストールする

WEBアプリの構築

cf. SinatraアプリをCentOSで動かす(2)

Nginxで仮想サーバー

cf. Nginxを使って仮想サーバーをたてる

問題発生と解決(暫定的)

さて、ここまでは順調にきた。けど、Nginx で立てた仮想サーバーにアクセスしても 502 Bad Gateway が返ってきてしまう。Nginx も WEB アプリも正常に動いているように見える。ここで行き詰まった。
長々と書くつもりはないので、結果を書くと、SELinux のセキュリティに引っかかっているようだった。で、その SELinux というのがよくわからない。ググってみるとちゃんと解決する方法は見つからなくて、無効にする方法ばかり。仕方がないので暫定的に SELinux を無効にして当面の解決策とすることにした。

SELinux を無効にするには、/etc/selinux/config ファイルのつぎの箇所を変更する。

#SELINUX=enforcing
SELINUX=disabled

上のコメントアウトしてある行がデフォルトの設定。これを下の行のように disabled にした。
これで再起動すれば OK。

本当は SELinux をちゃんと理解して使わなきゃいけないところだけど、なにせ情報が少ない。今後の課題だな。

あ、あと書き忘れてたけど、ホスト名は nightschool にした。

というところで、今日はここまで。

リスト(配列)の中で隣り合う同じ値をグループ化する

リストでも配列でもいいけど、つまりこういうのを

[1, 1, 2, 2, 3, 1, 1]

こうしたい。

[[1, 1], [2, 2], [3], [1, 1]]

Ruby でやってみた。

def adjacent_group(ary)
  result = []
  current = nil
  ary.each do |x|
    if current.nil?
      current = x
      result << [x]
    elsif x == current
      result[-1] << x
    else
      current = x
      result << [x]
    end
  end
  result
end

p adjacent_group([1, 1, 2, 2, 3, 1, 1])
^o^ >ruby adjacent_group.rb
[[1, 1], [2, 2], [3], [1, 1]]

おなじく Python で。

def adjacent_group(lis):
    result = []
    current = None
    for x in lis:
        if current is None:
            current = x
            result.append([x])
        elif x == current:
            result[-1].append(x)
        else:
            current = x
            result.append([x])
    return result

print(adjacent_group([1, 1, 2, 2, 3, 1, 1]))
^o^ >python adjacent_group.py
[[1, 1], [2, 2], [3], [1, 1]]

ちょっとベタだな。もう少しスマートにいかないものか、と考えて Ruby の Array#inject が使えそうだと思いついた。

def adjacent_group(ary)
  ary.inject([[]]) do |a, x|
    if a[-1].empty? || x == a[-1][-1]
      a[-1] << x
    else
      a << [x]
    end
    a
  end
end

p adjacent_group([1, 1, 2, 2, 3, 1, 1])
^o^ >ruby adjacent_group2.rb
[[1, 1], [2, 2], [3], [1, 1]]

うまくいった。

さて、じゃ、Python ではどうか。reduce を使えば同じことができると考えたけど、Python の reduce は初期値がとれない。まあ、それはリストの頭に初期値をつけてやれば済む話ではあるけど、もうひとつ問題がある。Ruby の Array#inject はブロックをとれるけど、Python の reduce には関数を渡してやらなきゃいけないので、関数定義がひとつ増えてしまう。一行では書けないので lambda 式は使えない。
というわけで、上のようにベタに書いたほうがまだマシそうだ。何かいい書き方があったら、誰か教えてください。

[追記](9/25)

Ruby の2つ目の実装では、引数に空の配列を渡したときに期待通りに動作しない([[]] が返ってきてしまう)。そこでちょっと直したのがこれ。

def adjacent_group(ary)
  ary.inject([]) do |a, x|
    if !a.empty? && x == a[-1][-1]
      a[-1] << x
    else
      a << [x]
    end
    a
  end
end

p adjacent_group([1, 1, 2, 2, 3, 1, 1])
p adjacent_group([])
^o^ >ruby adjacent_group.rb
[[1, 1], [2, 2], [3], [1, 1]]
[]

これでいいだろう。

NginxでCGIを動かす

Nginx では CGI は動かない。サポートしてないんだそうだ。まあ、いまどき CGI ってのも……という気はするけど、ちょっと古い CGI プログラムが必要になったのでやってみた。
参考にしたページはここ。

 cf. NginxでCGIを動かそうと頑張った話 – Qiita

これによると、fcgiwrap というのを使えば、CGI を FCGI にラップしてくれて、CGI プログラムを動かせるようだ。ラップするといってもインターフェイスの話で、中身はあくまで CGI なので FCGI なみに早く動作するわけではない。

とにかくやってみよう。
まずは fcgiwrap のインストール。apt でインストールできる。

takatoh@wplj $ sudo apt install fcgiwrap
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています                
状態情報を読み取っています... 完了
以下のパッケージが自動でインストールされましたが、もう必要とされていません:
  libllvm3.8 libllvm4.0 libllvm5.0 libmircommon5 libpango1.0-0 libpangox-1.0-0
  libqmi-glib1 libqpdf17 linux-headers-4.4.0-101
  linux-headers-4.4.0-101-generic linux-headers-4.4.0-103
  linux-headers-4.4.0-103-generic linux-headers-4.4.0-104
  linux-headers-4.4.0-104-generic linux-headers-4.4.0-109
  linux-headers-4.4.0-109-generic linux-headers-4.4.0-112
  linux-headers-4.4.0-112-generic linux-headers-4.4.0-116
  linux-headers-4.4.0-116-generic linux-headers-4.4.0-119
  linux-headers-4.4.0-119-generic linux-headers-4.4.0-121
  linux-headers-4.4.0-121-generic linux-headers-4.4.0-122
  linux-headers-4.4.0-122-generic linux-headers-4.4.0-124
  linux-headers-4.4.0-124-generic linux-headers-4.4.0-127
  linux-headers-4.4.0-127-generic linux-headers-4.4.0-128
  linux-headers-4.4.0-128-generic linux-headers-4.4.0-130
  linux-headers-4.4.0-130-generic linux-headers-4.4.0-131
  linux-headers-4.4.0-131-generic linux-headers-4.4.0-21
  linux-headers-4.4.0-21-generic linux-headers-4.4.0-64
  linux-headers-4.4.0-64-generic linux-headers-4.4.0-66
  linux-headers-4.4.0-66-generic linux-headers-4.4.0-67
  linux-headers-4.4.0-67-generic linux-headers-4.4.0-70
  linux-headers-4.4.0-70-generic linux-headers-4.4.0-71
  linux-headers-4.4.0-71-generic linux-headers-4.4.0-72
  linux-headers-4.4.0-72-generic linux-headers-4.4.0-75
  linux-headers-4.4.0-75-generic linux-headers-4.4.0-77
  linux-headers-4.4.0-77-generic linux-headers-4.4.0-78
  linux-headers-4.4.0-78-generic linux-headers-4.4.0-79
  linux-headers-4.4.0-79-generic linux-headers-4.4.0-81
  linux-headers-4.4.0-81-generic linux-headers-4.4.0-83
  linux-headers-4.4.0-83-generic linux-headers-4.4.0-87
  linux-headers-4.4.0-87-generic linux-headers-4.4.0-89
  linux-headers-4.4.0-89-generic linux-headers-4.4.0-91
  linux-headers-4.4.0-91-generic linux-headers-4.4.0-92
  linux-headers-4.4.0-92-generic linux-headers-4.4.0-93
  linux-headers-4.4.0-93-generic linux-headers-4.4.0-96
  linux-headers-4.4.0-96-generic linux-headers-4.4.0-97
  linux-headers-4.4.0-97-generic linux-headers-4.4.0-98
  linux-headers-4.4.0-98-generic linux-image-4.4.0-101-generic
  linux-image-4.4.0-103-generic linux-image-4.4.0-104-generic
  linux-image-4.4.0-109-generic linux-image-4.4.0-112-generic
  linux-image-4.4.0-116-generic linux-image-4.4.0-119-generic
  linux-image-4.4.0-121-generic linux-image-4.4.0-122-generic
  linux-image-4.4.0-124-generic linux-image-4.4.0-127-generic
  linux-image-4.4.0-128-generic linux-image-4.4.0-130-generic
  linux-image-4.4.0-131-generic linux-image-4.4.0-21-generic
  linux-image-4.4.0-64-generic linux-image-4.4.0-66-generic
  linux-image-4.4.0-67-generic linux-image-4.4.0-70-generic
  linux-image-4.4.0-71-generic linux-image-4.4.0-72-generic
  linux-image-4.4.0-75-generic linux-image-4.4.0-77-generic
  linux-image-4.4.0-78-generic linux-image-4.4.0-79-generic
  linux-image-4.4.0-81-generic linux-image-4.4.0-83-generic
  linux-image-4.4.0-87-generic linux-image-4.4.0-89-generic
  linux-image-4.4.0-91-generic linux-image-4.4.0-92-generic
  linux-image-4.4.0-93-generic linux-image-4.4.0-96-generic
  linux-image-4.4.0-97-generic linux-image-4.4.0-98-generic
  linux-image-extra-4.4.0-101-generic linux-image-extra-4.4.0-103-generic
  linux-image-extra-4.4.0-104-generic linux-image-extra-4.4.0-109-generic
  linux-image-extra-4.4.0-112-generic linux-image-extra-4.4.0-116-generic
  linux-image-extra-4.4.0-119-generic linux-image-extra-4.4.0-121-generic
  linux-image-extra-4.4.0-122-generic linux-image-extra-4.4.0-124-generic
  linux-image-extra-4.4.0-127-generic linux-image-extra-4.4.0-128-generic
  linux-image-extra-4.4.0-130-generic linux-image-extra-4.4.0-131-generic
  linux-image-extra-4.4.0-21-generic linux-image-extra-4.4.0-64-generic
  linux-image-extra-4.4.0-66-generic linux-image-extra-4.4.0-67-generic
  linux-image-extra-4.4.0-70-generic linux-image-extra-4.4.0-71-generic
  linux-image-extra-4.4.0-72-generic linux-image-extra-4.4.0-75-generic
  linux-image-extra-4.4.0-77-generic linux-image-extra-4.4.0-78-generic
  linux-image-extra-4.4.0-79-generic linux-image-extra-4.4.0-81-generic
  linux-image-extra-4.4.0-83-generic linux-image-extra-4.4.0-87-generic
  linux-image-extra-4.4.0-89-generic linux-image-extra-4.4.0-91-generic
  linux-image-extra-4.4.0-92-generic linux-image-extra-4.4.0-93-generic
  linux-image-extra-4.4.0-96-generic linux-image-extra-4.4.0-97-generic
  linux-image-extra-4.4.0-98-generic linux-signed-image-4.4.0-101-generic
  linux-signed-image-4.4.0-103-generic linux-signed-image-4.4.0-104-generic
  linux-signed-image-4.4.0-109-generic linux-signed-image-4.4.0-112-generic
  linux-signed-image-4.4.0-116-generic linux-signed-image-4.4.0-119-generic
  linux-signed-image-4.4.0-121-generic linux-signed-image-4.4.0-122-generic
  linux-signed-image-4.4.0-124-generic linux-signed-image-4.4.0-127-generic
  linux-signed-image-4.4.0-128-generic linux-signed-image-4.4.0-130-generic
  linux-signed-image-4.4.0-131-generic linux-signed-image-4.4.0-64-generic
  linux-signed-image-4.4.0-66-generic linux-signed-image-4.4.0-67-generic
  linux-signed-image-4.4.0-70-generic linux-signed-image-4.4.0-71-generic
  linux-signed-image-4.4.0-72-generic linux-signed-image-4.4.0-75-generic
  linux-signed-image-4.4.0-77-generic linux-signed-image-4.4.0-78-generic
  linux-signed-image-4.4.0-79-generic linux-signed-image-4.4.0-81-generic
  linux-signed-image-4.4.0-83-generic linux-signed-image-4.4.0-87-generic
  linux-signed-image-4.4.0-89-generic linux-signed-image-4.4.0-91-generic
  linux-signed-image-4.4.0-92-generic linux-signed-image-4.4.0-93-generic
  linux-signed-image-4.4.0-96-generic linux-signed-image-4.4.0-97-generic
  linux-signed-image-4.4.0-98-generic snap-confine ubuntu-core-launcher
これを削除するには 'sudo apt autoremove' を利用してください。
以下の追加パッケージがインストールされます:
  libfcgi0ldbl spawn-fcgi
以下のパッケージが新たにインストールされます:
  fcgiwrap libfcgi0ldbl spawn-fcgi
アップグレード: 0 個、新規インストール: 3 個、削除: 0 個、保留: 28 個。
193 kB のアーカイブを取得する必要があります。
この操作後に追加で 665 kB のディスク容量が消費されます。
続行しますか? [Y/n] Y
取得:1 http://jp.archive.ubuntu.com/ubuntu xenial/main amd64 libfcgi0ldbl amd64 2.4.0-8.3 [161 kB]
取得:2 http://jp.archive.ubuntu.com/ubuntu xenial/universe amd64 spawn-fcgi amd64 1.6.4-1 [14.5 kB]
取得:3 http://jp.archive.ubuntu.com/ubuntu xenial/universe amd64 fcgiwrap amd64 1.1.0-6 [17.5 kB]
193 kB を 0秒 で取得しました (1,165 kB/s)
以前に未選択のパッケージ libfcgi0ldbl を選択しています。
(データベースを読み込んでいます ... 現在 1351986 個のファイルとディレクトリがインストールされています。)
.../libfcgi0ldbl_2.4.0-8.3_amd64.deb を展開する準備をしています ...
libfcgi0ldbl (2.4.0-8.3) を展開しています...
以前に未選択のパッケージ spawn-fcgi を選択しています。
.../spawn-fcgi_1.6.4-1_amd64.deb を展開する準備をしています ...
spawn-fcgi (1.6.4-1) を展開しています...
以前に未選択のパッケージ fcgiwrap を選択しています。
.../fcgiwrap_1.1.0-6_amd64.deb を展開する準備をしています ...
fcgiwrap (1.1.0-6) を展開しています...
man-db (2.7.5-1) のトリガを処理しています ...
systemd (229-4ubuntu21.2) のトリガを処理しています ...
ureadahead (0.100.0-19) のトリガを処理しています ...
ureadahead will be reprofiled on next reboot
libfcgi0ldbl (2.4.0-8.3) を設定しています ...
spawn-fcgi (1.6.4-1) を設定しています ...
fcgiwrap (1.1.0-6) を設定しています ...
insserv: warning: script 'K01tonzlr' missing LSB tags and overrides
insserv: warning: script 'K01bruschetta' missing LSB tags and overrides
insserv: warning: script 'K01ellie' missing LSB tags and overrides
insserv: warning: script 'tonzlr' missing LSB tags and overrides
insserv: warning: script 'ellie' missing LSB tags and overrides
insserv: warning: script 'bruschetta' missing LSB tags and overrides
libc-bin (2.23-0ubuntu10) のトリガを処理しています ...
systemd (229-4ubuntu21.2) のトリガを処理しています ...
ureadahead (0.100.0-19) のトリガを処理しています ...

Nginx の設定。/etc/nginx/sites-available/default ファイルに以下を追記。

location ~ \.cgi$ {
    root /var/www/html;
    fastcgi_pass unix:/var/run/fcgiwrap.socket;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
}

これで .cgi 拡張子を持つファイルがすべて CGI プログラムとして認識されるはず。
/var/run/fcgiwrap.socket は fcgiwrap を apt でインストールすると自動的に作られている。

fcgiwrap の設定。/etc/init.d/fcgiwrap ファイルを編集する。

# FCGI_APP Variables
FCGI_CHILDREN="1"
FCGI_SOCKET="/var/run/$NAME.socket"
FCGI_USER="www-data"
FCGI_GROUP="www-data"
# Socket owner/group (will default to FCGI_USER/FCGI_GROUP if not defined)
FCGI_SOCKET_OWNER="www-data"
FCGI_SOCKET_GROUP="www-data"

デフォルトで上のようになっているのを下のように変えた。

# FCGI_APP Variables
FCGI_CHILDREN="1"
FCGI_SOCKET="/var/run/$NAME.socket"
FCGI_USER="www-data"
FCGI_GROUP="www-data"
# Socket owner/group (will default to FCGI_USER/FCGI_GROUP if not defined)
FCGI_SOCKET_OWNER="root"
FCGI_SOCKET_GROUP="root"

変えたのは FCGI_SOCKET_OWNER と FCGI_SOCKET_GROUP だ。

これで設定は終了のはず。fcgiwrap と Nginx を再起動しよう。

takatoh@wplj $ sudo systemctl restart fcgiwrap
takatoh@wplj $ sudo systemctl restart nginx

最後にテスト。/var/www/html ディレクトリにつぎのような hello.cgi ファイルを作って実行権限をつけた。

#!/usr/bin/ruby

print "Content-Type: text/html\n\n"
print ""
print ""
print ""
print "Hello CGI world!"
print ""
print ""

ブラウザでアクセスしてみると、ちゃんと Hello CGI world! と表示されたので OK。

要素の個数を数える

配列内の同じ要素それぞれの個数を数える。

 cf. 要素の個数を数える – 惰力飛行

Ruby でやってみる。Array#group_by が使えそう。

irb(main):001:0> lang = %w(perl python ruby perl python python ruby python ruby lisp)
=> ["perl", "python", "ruby", "perl", "python", "python", "ruby", "python", "ruby", "lisp"]
irb(main):002:0> lang.group_by{|x| x}.map{|k, v| [k, v.size]}.to_h
=> {"perl"=>2, "python"=>4, "ruby"=>3, "lisp"=>1}

いったん [[要素, 個数]] という配列の配列を作って、Array#to_h でハッシュにしている。うまく1行で書けた。

Windows PowerShellの実行ポリシーとプロンプトのカスタマイズ

PowerShell のデフォルトのプロンプトは、「PS カレントディレクトリのパス >」となっていて、ディレクトリが深くなるとすごく長くなる。これをもっとシンプルにしようと思った。具体的には、Ubuntu と同様に「ユーザー名@ホスト名 >」くらいでいい。
ググってみると、プロンプトは prompt 関数の返り値が使われるので、%USERPROFILE%\Documents\WindowsPowerShell\profile.ps1 ファイルに prompt 関数を書いておけばいいようだ。.ps1 てのは PowerShell のスクリプトの拡張子ね。
で、prompt 関数は次のようにした。

function prompt {
    $env:USERNAME + "@" + $env:COMPUTERNAME + " > "
}

さて、これで新しいシェルを立ち上げれば、profile.ps1 が読み込まれてプロンプトの変更が反映されるはず。

Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

. : このシステムではスクリプトの実行が無効になっているため、ファイル C:\Users\takatoh\Documents\WindowsPowerShell\profile
.ps1 を読み込むことができません。詳細については、「about_Execution_Policies」(https://go.microsoft.com/fwlink/?LinkID=1
35170) を参照してください。
発生場所 行:1 文字:3
+ . 'C:\Users\takatoh\Documents\WindowsPowerShell\profile.ps1'
+   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : セキュリティ エラー: (: ) []、PSSecurityException
    + FullyQualifiedErrorId : UnauthorizedAccess

おっと、エラーになった。何やらスクリプトの実行が無効になっているらしい。ググってみると、PowerShell には実行ポリシーというのがあって、これの設定でスクリプトの実行を制御しているらしい。詳しくは上のメッセージにも書かれている、↓のページに説明がある。

cf. about_Execution_Policies

このページに Windows10 については書かれていないけど、次のようにすると実行ポリシーが Restricted であることがわかる。

PS C:\Users\takatoh> Get-ExecutionPolicy
Restricted

Restricted というポリシーは、コマンドは実行できるがスクリプトは実行できない、というものらしい。なので、これを変更してやればいい。具体的には次のようにした。

PS C:\Users\takatoh> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -scope CurrentUser

実行ポリシーの変更
実行ポリシーは、信頼されていないスクリプトからの保護に役立ちます。実行ポリシーを変更すると、about_Execution_Policies
のヘルプ トピック (https://go.microsoft.com/fwlink/?LinkID=135170)
で説明されているセキュリティ上の危険にさらされる可能性があります。実行ポリシーを変更しますか?
[Y] はい(Y)  [A] すべて続行(A)  [N] いいえ(N)  [L] すべて無視(L)  [S] 中断(S)  [?] ヘルプ (既定値は "N"): Y

Y を入力してこれで実行ポリシーの変更はできたはず。RemoteSigned という実行ポリシーは、スクリプトの実行はできるがインターネットからダウンロードされたスクリプトは信頼された発行元によってデジタル署名されている必要がある、というもの。ローカルのスクリプトの実行には支障がないのでこれにした。

さて、改めて PowerShell を立ち上げてみよう。

Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

takatoh@FLAMBAY > Get-ExecutionPolicy -List

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process       Undefined
  CurrentUser    RemoteSigned
 LocalMachine       Undefined


takatoh@FLAMBAY > Get-ExecutionPolicy
RemoteSigned

期待通り、プロンプトが変更されていて、カレントユーザーの実行ポリシーも RemoteSigned になっているのがわかる。
これでOK。

Surface GoにAnaconda3をインストール

先日保留にしていた Python だけれど、結局 Jupyter Notebook を使ってみたくて Anaconda をインストールした。Anaconda は Python のディストリビューションのひとつで、科学計算関係のライブラリが多くバンドルされていて、そっち方面でよく使われているようだ。
まぁ、科学計算はともかく、Jupyter Notebook も使えるようになるというので Anaconda を選んだってわけ。
インストールは chocolatey を使った。

PS C:\Windows\system32> choco install anaconda3
Chocolatey v0.10.11
Installing the following packages:
anaconda3
By installing you accept licenses for the packages.
Progress: Downloading anaconda3 5.1.0... 100%

anaconda3 v5.1.0 [Approved]
anaconda3 package files install completed. Performing other installation steps.
The package anaconda3 wants to run 'chocolateyinstall.ps1'.
Note: If you don't run this script, the installation will fail.
Note: To confirm automatically next time, use '-y' or consider:
choco feature enable -n allowGlobalConfirmation
Do you want to run the script?([Y]es/[N]o/[P]rint): Y

WARNING: installing anaconda3, this can take a long time, because the installer will write tons of files on your disk
WARNING: Please sit back and relax
WARNING: This usually will take 10-15 mins on an SSD, and about 30 mins on HDD
WARNING:
WARNING: If you want to make sure the program is running, you can open Task Manager
WARNING: you will find the installer running in Background Process
WARNING: Url has SSL/TLS available, switching to HTTPS for download
Downloading anaconda3 64 bit
  from 'https://repo.continuum.io/archive/Anaconda3-5.1.0-Windows-x86_64.exe'
Progress: 100% - Completed download of C:\Users\takatoh\AppData\Local\Temp\chocolatey\anaconda3\5.1.0\Anaconda3-5.1.0-Windows-x86_64.exe (537.08 MB).
Download of Anaconda3-5.1.0-Windows-x86_64.exe (537.08 MB) completed.
Hashes match.
Installing anaconda3...
anaconda3 has been installed.
  anaconda3 can be automatically uninstalled.
 The install of anaconda3 was successful.
  Software installed to 'C:\tools\anaconda3'

Chocolatey installed 1/1 packages.
 See the log for details (C:\ProgramData\chocolatey\logs\chocolatey.log).

コマンドひとつでインストールできるのはいいけど、500MB 以上あるじゃないか。えらい時間がかかった。

で、これで Python が使えるようになったかというと、だめだった。python は C:\tools\Anaconda3 にインストールされているけど、パスが通っていない。chocolatey がやってくれなかったみたいだ。仕方がないので、自分でパスを通した。

PS C:\Users\takatoh> python -V
Python 3.6.4 :: Anaconda, Inc.

これでOK。

[追記]

上記で Python は使えるようになったけど、pip や Anaconda のパッケージマネージャである conda コマンドは相変わらず使えない。使えるようにするには C:\tools\Anaconda\Scripts にパスを通す。通したうえで conda list コマンドを実行してみると、これだけのパッケージがインストールされているのがわかる。

PS C:\Users\takatoh> conda list
# packages in environment at C:\tools\Anaconda3:
#
# Name                    Version                   Build  Channel
_ipyw_jlab_nb_ext_conf    0.1.0            py36he6757f0_0
alabaster                 0.7.10           py36hcd07829_0
anaconda                  5.1.0                    py36_2
anaconda-client           1.6.9                    py36_0
anaconda-navigator        1.7.0                    py36_0
anaconda-project          0.8.2            py36hfad2e28_0
asn1crypto                0.24.0                   py36_0
astroid                   1.6.1                    py36_0
astropy                   2.0.3            py36hfa6e2cd_0
attrs                     17.4.0                   py36_0
babel                     2.5.3                    py36_0
backports                 1.0              py36h81696a8_1
backports.shutil_get_terminal_size 1.0.0            py36h79ab834_2
beautifulsoup4            4.6.0            py36hd4cc5e8_1
bitarray                  0.8.1            py36hfa6e2cd_1
bkcharts                  0.2              py36h7e685f7_0
blaze                     0.11.3           py36h8a29ca5_0
bleach                    2.1.2                    py36_0
bokeh                     0.12.13          py36h047fa9f_0
boto                      2.48.0           py36h1a776d2_1
bottleneck                1.2.1            py36hd119dfa_0
bzip2                     1.0.6                hbe05fcf_4
ca-certificates           2017.08.26           h94faf87_0
certifi                   2018.1.18                py36_0
cffi                      1.11.4           py36hfa6e2cd_0
chardet                   3.0.4            py36h420ce6e_1
click                     6.7              py36hec8c647_0
cloudpickle               0.5.2                    py36_1
clyent                    1.2.2            py36hb10d595_1
colorama                  0.3.9            py36h029ae33_0
comtypes                  1.1.4                    py36_0
conda                     4.4.10                   py36_0
conda-build               3.4.1                    py36_0
conda-env                 2.6.0                h36134e3_1
conda-verify              2.0.0            py36h065de53_0
console_shortcut          0.1.1                h6bb2dd7_3
contextlib2               0.5.5            py36he5d52c0_0
cryptography              2.1.4            py36he1d7878_0
curl                      7.58.0               h7602738_0
cycler                    0.10.0           py36h009560c_0
cython                    0.27.3           py36h22f4c84_0
cytoolz                   0.9.0            py36hfa6e2cd_0
dask                      0.16.1                   py36_0
dask-core                 0.16.1                   py36_0
datashape                 0.5.4            py36h5770b85_0
decorator                 4.2.1                    py36_0
distributed               1.20.2                   py36_0
docutils                  0.14             py36h6012d8f_0
entrypoints               0.2.3            py36hfd66bb0_2
et_xmlfile                1.0.1            py36h3d2d736_0
fastcache                 1.0.2            py36hfa6e2cd_2
filelock                  2.0.13           py36h20000bf_0
flask                     0.12.2           py36h98b5e8f_0
flask-cors                3.0.3            py36h8a3855d_0
freetype                  2.8                  h51f8f2c_1
get_terminal_size         1.0.0                h38e98db_0
gevent                    1.2.2            py36h342a76c_0
glob2                     0.6              py36hdf76b57_0
greenlet                  0.4.12           py36ha00ad21_0
h5py                      2.7.1            py36he54a1c3_0
hdf5                      1.10.1               h98b8871_1
heapdict                  1.0.0                    py36_2
html5lib                  1.0.1            py36h047fa9f_0
icc_rt                    2017.0.4             h97af966_0
icu                       58.2                 ha66f8fd_1
idna                      2.6              py36h148d497_1
imageio                   2.2.0            py36had6c2d2_0
imagesize                 0.7.1            py36he29f638_0
intel-openmp              2018.0.0             hd92c6cd_8
ipykernel                 4.8.0                    py36_0
ipython                   6.2.1            py36h9cf0123_1
ipython_genutils          0.2.0            py36h3c5d0ee_0
ipywidgets                7.1.1                    py36_0
isort                     4.2.15           py36h6198cc5_0
itsdangerous              0.24             py36hb6c5a24_1
jdcal                     1.3              py36h64a5255_0
jedi                      0.11.1                   py36_0
jinja2                    2.10             py36h292fed1_0
jpeg                      9b                   hb83a4c4_2
jsonschema                2.6.0            py36h7636477_0
jupyter                   1.0.0                    py36_4
jupyter_client            5.2.2                    py36_0
jupyter_console           5.2.0            py36h6d89b47_1
jupyter_core              4.4.0            py36h56e9d50_0
jupyterlab                0.31.4                   py36_0
jupyterlab_launcher       0.10.2                   py36_0
lazy-object-proxy         1.3.1            py36hd1c21d2_0
libcurl                   7.58.0               h7602738_0
libiconv                  1.15                 h1df5818_7
libpng                    1.6.34               h79bbb47_0
libssh2                   1.8.0                hd619d38_4
libtiff                   4.0.9                h0f13578_0
libxml2                   2.9.7                h79bbb47_0
libxslt                   1.1.32               hf6f1972_0
llvmlite                  0.21.0           py36he0b0552_0
locket                    0.2.0            py36hfed976d_1
lxml                      4.1.1            py36hef2cd61_1
lzo                       2.10                 h6df0209_2
markupsafe                1.0              py36h0e26971_1
matplotlib                2.1.2            py36h016c42a_0
mccabe                    0.6.1            py36hb41005a_1
menuinst                  1.4.11           py36hfa6e2cd_0
mistune                   0.8.3                    py36_0
mkl                       2018.0.1             h2108138_4
mkl-service               1.1.2            py36h57e144c_4
mpmath                    1.0.0            py36hacc8adf_2
msgpack-python            0.5.1            py36he980bc4_0
multipledispatch          0.4.9            py36he44c36e_0
navigator-updater         0.1.0            py36h8a7b86b_0
nbconvert                 5.3.1            py36h8dc0fde_0
nbformat                  4.4.0            py36h3a5bc1b_0
networkx                  2.1                      py36_0
nltk                      3.2.5            py36h76d52bb_0
nose                      1.3.7            py36h1c3779e_2
notebook                  5.4.0                    py36_0
numba                     0.36.2          np114py36h12cb543_0
numexpr                   2.6.4            py36h30784b8_0
numpy                     1.14.0           py36h4a99626_1
numpydoc                  0.7.0            py36ha25429e_0
odo                       0.5.1            py36h7560279_0
olefile                   0.45.1                   py36_0
openpyxl                  2.4.10                   py36_0
openssl                   1.0.2n               h74b6da3_0
packaging                 16.8             py36ha0986f6_1
pandas                    0.22.0           py36h6538335_0
pandoc                    1.19.2.1             hb2460c7_1
pandocfilters             1.4.2            py36h3ef6317_1
parso                     0.1.1            py36hae3edee_0
partd                     0.3.8            py36hc8e763b_0
path.py                   10.5             py36h2b94a8f_0
pathlib2                  2.3.0            py36h7bfb78b_0
patsy                     0.5.0                    py36_0
pep8                      1.7.1                    py36_0
pickleshare               0.7.4            py36h9de030f_0
pillow                    5.0.0            py36h0738816_0
pip                       9.0.1            py36h226ae91_4
pkginfo                   1.4.1            py36hb0f9cfa_1
pluggy                    0.6.0            py36hc7daf1e_0
ply                       3.10             py36h1211beb_0
prompt_toolkit            1.0.15           py36h60b8f86_0
psutil                    5.4.3            py36hfa6e2cd_0
py                        1.5.2            py36hbcfbabc_0
pycodestyle               2.3.1            py36h7cc55cd_0
pycosat                   0.6.3            py36h413d8a4_0
pycparser                 2.18             py36hd053e01_1
pycrypto                  2.6.1            py36hfa6e2cd_7
pycurl                    7.43.0.1         py36h74b6da3_0
pyflakes                  1.6.0            py36h0b975d6_0
pygments                  2.2.0            py36hb010967_0
pylint                    1.8.2                    py36_0
pyodbc                    4.0.22           py36h6538335_0
pyopenssl                 17.5.0           py36h5b7d817_0
pyparsing                 2.2.0            py36h785a196_1
pyqt                      5.6.0            py36hb5ed885_5
pysocks                   1.6.7            py36h698d350_1
pytables                  3.4.2            py36h71138e3_2
pytest                    3.3.2                    py36_0
python                    3.6.4                h6538335_1
python-dateutil           2.6.1            py36h509ddcb_1
pytz                      2017.3           py36h1d3fa6b_0
pywavelets                0.5.2            py36hc649158_0
pywin32                   222              py36hfa6e2cd_0
pywinpty                  0.5              py36h6538335_1
pyyaml                    3.12             py36h1d1928f_1
pyzmq                     16.0.3           py36he714bf5_0
qt                        5.6.2           vc14h6f8c307_12  [vc14]
qtawesome                 0.4.4            py36h5aa48f6_0
qtconsole                 4.3.1            py36h99a29a9_0
qtpy                      1.3.1            py36hb8717c5_0
requests                  2.18.4           py36h4371aae_1
rope                      0.10.7           py36had63a69_0
ruamel_yaml               0.15.35          py36hfa6e2cd_1
scikit-image              0.13.1           py36hfa6e2cd_1
scikit-learn              0.19.1           py36h53aea1b_0
scipy                     1.0.0            py36h1260518_0
seaborn                   0.8.1            py36h9b69545_0
send2trash                1.4.2                    py36_0
setuptools                38.4.0                   py36_0
simplegeneric             0.8.1                    py36_2
singledispatch            3.4.0.3          py36h17d0c80_0
sip                       4.18.1           py36h9c25514_2
six                       1.11.0           py36h4db2310_1
snowballstemmer           1.2.1            py36h763602f_0
sortedcollections         0.5.3            py36hbefa0ab_0
sortedcontainers          1.5.9                    py36_0
sphinx                    1.6.6                    py36_0
sphinxcontrib             1.0              py36hbbac3d2_1
sphinxcontrib-websupport  1.0.1            py36hb5e5916_1
spyder                    3.2.6                    py36_0
sqlalchemy                1.2.1            py36hfa6e2cd_0
sqlite                    3.22.0               h9d3ae62_0
statsmodels               0.8.0            py36h6189b4c_0
sympy                     1.1.1            py36h96708e0_0
tblib                     1.3.2            py36h30f5020_0
terminado                 0.8.1                    py36_1
testpath                  0.3.1            py36h2698cfe_0
tk                        8.6.7                hcb92d03_3
toolz                     0.9.0                    py36_0
tornado                   4.5.3                    py36_0
traitlets                 4.3.2            py36h096827d_0
typing                    3.6.2            py36hb035bda_0
unicodecsv                0.14.1           py36h6450c06_0
urllib3                   1.22             py36h276f60a_0
vc                        14                   h0510ff6_3
vs2015_runtime            14.0.25123                    3
wcwidth                   0.1.7            py36h3d5aa90_0
webencodings              0.5.1            py36h67c50ae_1
werkzeug                  0.14.1                   py36_0
wheel                     0.30.0           py36h6c3ec14_1
widgetsnbextension        3.1.0                    py36_0
win_inet_pton             1.0.1            py36he67d7fd_1
win_unicode_console       0.5              py36hcdbd4b5_0
wincertstore              0.2              py36h7fe50ca_0
winpty                    0.4.3                         4
wrapt                     1.10.11          py36he5f5981_0
xlrd                      1.1.0            py36h1cb58dc_1
xlsxwriter                1.0.2            py36hf723b7d_0
xlwings                   0.11.5                   py36_0
xlwt                      1.3.0            py36h1a4751e_0
yaml                      0.1.7                hc54c509_2
zict                      0.1.3            py36h2d8e73e_0
zlib                      1.2.11               h8395fce_2