先日、apt で fcgiwrap をインストールした時に、不要なパッケージがいっぱいあるよ、sudo apt autoremove
で削除できるよ、というようなメッセージが出た。
なのでやってみた。
takatoh@wplj $ sudo apt autoremove
takatoh's blog – Learning programming languages.
先日、apt で fcgiwrap をインストールした時に、不要なパッケージがいっぱいあるよ、sudo apt autoremove
で削除できるよ、というようなメッセージが出た。
なのでやってみた。
takatoh@wplj $ sudo apt autoremove
リストでも配列でもいいけど、つまりこういうのを
[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 式は使えない。
というわけで、上のようにベタに書いたほうがまだマシそうだ。何かいい書き方があったら、誰か教えてください。
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 は動かない。サポートしてないんだそうだ。まあ、いまどき 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行で書けた。
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 には実行ポリシーというのがあって、これの設定でスクリプトの実行を制御しているらしい。詳しくは上のメッセージにも書かれている、↓のページに説明がある。
このページに 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。
先日保留にしていた 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
もうおとといの話になるけど、注文してあった Surface Go が届いたのでセットアップをした。
セットアップといっても Windows のそれは、画面の案内に沿ってやっていくだけなのでサクッと終了。どういうわけかホスト名を指定するところがなかったので、スタートメニューから[設定]→[システム]→[バージョン情報]と辿って、「このPCの名前を変更」ボタンを押して変更した。名前は flambay にした。
Surface Go の Windows は Sモードといって、Microsoft Store のアプリしか使えないようになている(その代わり安全でパフォーマンスも悪くならないらしい)ので、これを解除して普通の Windwos 10 Home にする。このページから Microsoft Store を開くとSモードを解除するページに飛んだので(今試したら出てこなかったけど)、「インストール」を押して解除。なんだかすぐに終わったので大丈夫か?と思ったけど、大丈夫らしい。後に書くどちゃんと Microsoft Store 以外のアプリもインストールできるようになったのでOKのようだ。
アプリのインストールには Chocolatey という、Windows 用のパッケージマネージャーを使った。
cf. Chocolatey
要するに Ubuntu の apt や Mac の homebrew みたいなもの。インストールするには、PowerShell を管理者モードで開いて、インストールページにあるコマンドをコピペして実行する。インストール出来たら、いろんなアプリをコマンドだけでインストールできるようになる。とりあえずは次のアプリをインストールした。
Gauche はパッケージがなかったので公式サイトから msi インストーラをダウンロードして普通にインストールした。
あと、Python をインストールしたいんだけど、今回は Jupyter notebook も使ってみたいので、どうしようか考えている。
とりあえずこんなところでいったん終了。
hostnamectl
コマンドを使う。
引数無しで使うと、現在の情報を表示してくれる。
takatoh@envelopes $ hostnamectl Static hostname: envelopes Icon name: computer-desktop Chassis: desktop Machine ID: 51e97893a0e54d888a7bc435e3cb10be Boot ID: 528cc17f21ef4185b0697228e4d092b5 Operating System: Ubuntu 16.04.5 LTS Kernel: Linux 4.4.0-133-generic Architecture: x86-64
hostnamectl set-hostname
コマンドでホスト名変更。
takatoh@envelopes $ sudo hostnamectl set-hostname apostrophe [sudo] takatoh のパスワード:
確認。
takatoh@envelopes $ hostnamectl Static hostname: apostrophe Icon name: computer-desktop Chassis: desktop Machine ID: 51e97893a0e54d888a7bc435e3cb10be Boot ID: 528cc17f21ef4185b0697228e4d092b5 Operating System: Ubuntu 16.04.5 LTS Kernel: Linux 4.4.0-133-generic Architecture: x86-64
ちゃんと変わっている。
/etc/hosts ファイルを編集。
127.0.0.1 localhost 127.0.1.1 apostrophe # ←ここを修正した。 192.168.1.21 muffinman 192.168.1.15 montana 192.168.1.6 wplj (以下略)
ネットワークの再起動。
takatoh@envelopes $ sudo service networking restart
これでOK。プロンプトのホスト名が変わっていないけど、これは端末を起動し直すと直る。
HTML + JavaScript ツール第3弾。
HTML5 の canvas 要素で画像のリサイズができるというので、やってみた。
cf. 画像のリサイズ
Size を指定しておいて、リサイズしたい画像を選ぶとリサイズされた画像が画面に並ぶようになっている。画像をクリックすればダウンロードもできる。
参考にしたページはいくつかあるけど、↓ここを挙げておこう。
cf. クライアント側でcanvasを使って画像をリサイズする – Qiita
以下、ソース。
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Resize image</title> <script type="text/javascript"> function resizeImage(base64image, callback) { const MAX_SIZE = Number(document.getElementById("size").value); let canvas = document.createElement("canvas"); let ctx = canvas.getContext("2d"); let image = new Image(); image.crossOrigin = "Anonymous"; image.onload = function(evt) { let dstWidth, dstHeight; if (this.width > this.height) { dstWidth = MAX_SIZE; dstHeight = this.height * MAX_SIZE / this.width; } else { dstHeight = MAX_SIZE; dstWidth = this.width * MAX_SIZE / this.height; } canvas.width = dstWidth; canvas.height = dstHeight; ctx.drawImage(this, 0, 0, this.width, this.height, 0, 0, dstWidth, dstHeight); callback(canvas.toDataURL("image/png")); }; image.src = base64image; } function buildFilename(origname) { let re = /(.*)(?:\.([^.]+$))/; let basename = origname.match(re)[1]; return "resized_" + basename + ".png"; } function handleFileSelect(evt) { let files = evt.target.files; for (let i = 0, f; f = files[i]; i++) { let reader = new FileReader(); reader.onload = (function(theFile) { return function(e) { resizeImage(e.target.result, function(imgUrl) { let dest = document.getElementById("list"); let fig = document.createElement("figure"); fig.style = "float: left;"; let a = document.createElement("a"); a.href = imgUrl; a.download = buildFilename(theFile.name); let image = document.createElement("img"); image.src = imgUrl; let caption = document.createElement("figcaption") caption.innerHTML = theFile.name + " resized."; a.appendChild(image); fig.appendChild(a); fig.appendChild(caption); dest.appendChild(fig); }); }})(f); reader.readAsDataURL(f); } } document.addEventListener("DOMContentLoaded", function() { document.getElementById("files").addEventListener("change", handleFileSelect, false); }, false); </script> </head> <body> <h1>Resize image</h1> <p>下のSizeで指定したサイズの正方形におさまるようにリサイズします。</p> <p>画像をクリックすればダウンロードできます。</p> Size: <input id="size" type="text" value="400"> pixel<br /> <input id="files" multiple="multiple" name="files[]" type="file"><br /> <div id="list"></div> </body> </html>
先週、華氏度と摂氏度の換算をする WEB ページを作ってみて、HTML と JavaScript だけでページを作れば、サーバなしで簡単なツールを作れることが分かった。
そこで、いくつか同じように WEB ページで動くツールを作ってみている。今日は、ローカルファイルの MD5 ハッシュ値を計算するツール(ページ)を紹介しよう。
cf. MD5ハッシュ値の計算
ページを作るにあたっては、次のページとそこからリンクされているページを参考にした。
cf. ローカルバイナリファイルからMD5ハッシュ値を計算する
特にローカルファイルの扱い方が参考になった。また、MD5 ハッシュ値の計算は、次のページで公開されている JavaScript のライブラリをそのまま使わせてもらった。
最後に HTML のソースを載せておく。
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>MD5 calculator</title> <script type="text/javascript" src="js/md5.js"></script> <script type="text/javascript"> const handleFileSelect = (evt) => { const files = evt.target.files; const output = document.getElementById("list"); output.innerHTML = "<ul>"; for (let i = 0, f; f = files[i]; i++) { const reader = new FileReader(); reader.onload = ((theFile) => { return (e) => { const hexdigest = MD5_hexhash(e.target.result); output.innerHTML += "<li>" + hexdigest + " " + theFile.name + "</li>"; } })(f); reader.readAsBinaryString(f); } output.innerHTML += "</ul>" } document.addEventListener("DOMContentLoaded", () => { document.getElementById("files").addEventListener("change", handleFileSelect, false); }, false); </script> </head> <body> <h1>MD5 calculator</h1> <input type="file" id="files" name="files[]" multiple /><br /> <output id="list"></output> </body> </html>