銀の弾丸

プログラミングに関して、いろいろ書き残していければと思っております。

Octave-Forge for Windows をインストールしてMinGW / MSYSから利用する

MinGW用(?)Octave-Forge for Windows を、Windows 10 にインストールして、MSYS(GitHub for WindowsについてるGitBash)で利用できるようにセットアップしたので、その手順を書いておきます。

f:id:takamints:20160626213022p:plain
photo credit: I23 - SPANning an octave via photopin (license)

しかし、ほとんど Windowsで利用するための手順であって、MinGW / MSYSに関連するのは、PATHとエイリアスの設定だけです。どこがどうMinGW向けなのか、いまだによくわかりませんが、まあいいです。

関係ないけど、いまだにMinGWとMSYSの関係がイメージとして把握できていないので、こういう記事でトンチンカンなことを書いていないか心配です。毎日使っているのにね。

ITエンジニアのための機械学習理論入門
技術評論社 (2015-10-17)
売り上げランキング: 2,235

ところで、Octaveってナンデスカ?

OctaveGNUフリーソフトウェアで、MATLAB互換の数値演算向け高水準プログラミング言語です。 MATLABは結構お高いのですが、Octaveは無料で利用可能です。

強力な行列演算の機能を備えていて、対話的にも利用できますから、とっても便利。

昨今世間を席巻している画像処理や機械学習人工知能など、行列演算に依存するアルゴリズム開発のプロトタイピングに利用しやすいというわけです。

OpenCVやNumpy等、行列を扱う各種ライブラリでも、似たような関数名が使えます(zerosやeye等)、使い方を覚えておいて損はないと思います。 理系の学生さんとかは私なんかが言うまでもなく使えるのだとは思いますが。

スタンフォード大学機械学習の講義でも使います

昨年(2015年)一部界隈で話題になったCourseraMOOCスタンフォード大学のMachine Learningの講義でも、MATLABOctaveを使用するのが前提です。MATLAB/Octaveで課題に取り組んで、コマンド打ってオンラインで提出するシステムになっていました。

※ しかし、Windows版のOctaveではオンラインでの課題提出機能にバグがあるらしく、Windowsユーザーが受講するには講義中だけ特別に無料利用できるMATLABを使っていました。 てことで今回、講義履修後一年近く経過して、テキスト使って復習したいと思いまして、やっぱりOctave入れなきゃね、となったわけです。

第一人者もお薦めです

CourseraのCEOであり、Machine Learningの第一人者でもある同講義の講師、Andrew NG 先生によれば、「まずはアルゴリズム(演算内容)をMATLAB/Octaveで確認すべし」とのことですよ。

他の開発言語でも行列演算は行えますが、アルゴリズムの開発に集中するために、MATLAB/Octaveを使いなさいと。格段に効率が上がるからと。

じゃあ、Octave-Forgeってなに?

実はよく知りませんでした(笑)

ダウンロードページには、「A collection of packages providing extra functionality for GNU Octave」と書いてあるので、GNU Octaveのための追加機能を提供しているパッケージを集めたものということでしょう。

ということで、インストール手順はこちらです

取り立てて難しいことはなく、敢えて言うなら英語でズラズラ書いてあるのと、ファイルの説明が長い点。 それからWindows 10についての言及が無かったところ。

作業は、圧縮ファイルをダウンロードして、フォルダに展開、実行モジュールへのショートカットを作れば、Windowsから利用するだけなら、ほぼ完了。 Windows 8 以降なら、コマンドラインスイッチの追加設定が必要ですね。

そして、繰り返しになりますが、MinGW / MSYS向けには、PATHの設定とエイリアス

ということで、詳細手順は以下のメニューでレッツゴー

  1. 事前準備:7-Zipのインストー
  2. 圧縮ファイルのダウンロード
  3. セットアップフォルダの作成
  4. 圧縮ファイルの展開
  5. Octave本体のファイルをコピー(もしくは移動)
  6. ショートカットの作成
  7. Windows 8 / 10でのコマンドラインスイッチの追加
  8. ショートカットのアイコン指定
  9. Octave-forge パッケージのコピー
  10. Octave-forge パッケージのビルド
  11. 起動時ワーニングの抑制
  12. オプショナルだが推奨される(?) エディタの設定

1.事前準備:7-Zipのインストー

ダウンロードする圧縮ファイルが、拡張子が7z7-Zipですので、必要な人は、7-Zipのダウンロードページから、お使いのシステムに応じたものをインストールしておきましょう。

2.圧縮ファイルのダウンロード

Octave 3.6.4 のダウンロードページから、 以下の2つをダウンロードします。

3.セットアップフォルダの作成

C:\Octaveというフォルダを作ります。実際にはどのような名前でも良いと説明書に書いてありますが、圧縮ファイルに入っているショートカットなどが、このフォルダを参照してるっぽいので、なるべくならこれに従ったほうが良いと思います。

4.圧縮ファイルの展開

ダウンロードした2つの7zC:\Octave以下にディレクトリごと展開します。以下のようになってるはず。

C:\Octave\
  +-- Octave3.6.4_gcc4.6.2_20130408\
  |    +-- Octave3.6.4_gcc4.6.2\
  |    +-- Octave3.6.4_gcc4.6.2(ショートカット)
  |    +-- octave3.6.4_gcc4.6.2_docs(ショートカット)
  |    +-- Octave3.6.4_gcc4.6.2_libblas_readme.txt
  |    +-- Octave3.6.4_gcc4.6.2_readme.txt
  +-- Octave3.6.4_gcc4.6.2_pkgs_20130402\
       +-- Octave3.6.4_gcc4.6.2\
       +-- Octave3.6.4_gcc4.6.2_pkgs_list.txt
       +-- Octave3.6.4_gcc4.6.2_pkgs_readme.txt

5.Octave本体のファイルをコピー(もしくは移動)

この時点でC:\Octave\以下に2つのフォルダがあって、そのどちらにも、Octave3.6.4_gcc4.6.2というサブフォルダがありますね。

このうち、Octave3.6.4_gcc4.6.2_20130408\Octave3.6.4_gcc4.6.2C:\Octave\の直下へフォルダごとコピー(または移動)します。

ここでインストールフォルダは以下のようになっているはず。

C:\Octave\
  +-- Octave3.6.4_gcc4.6.2\
  |    +-- bin\
  |    +-- doc\
  |    +-- etc\
  |          .
  |          .
  |          .
  |
  +-- Octave3.6.4_gcc4.6.2_20130408\
  |    +-- Octave3.6.4_gcc4.6.2\(移動したならこれはない)
  |    +-- Octave3.6.4_gcc4.6.2(ショートカット)
  |    +-- octave3.6.4_gcc4.6.2_docs(ショートカット)
  |    +-- Octave3.6.4_gcc4.6.2_libblas_readme.txt
  |    +-- Octave3.6.4_gcc4.6.2_readme.txt
  +-- Octave3.6.4_gcc4.6.2_pkgs_20130402\
       +-- Octave3.6.4_gcc4.6.2\
       +-- Octave3.6.4_gcc4.6.2_pkgs_list.txt
       +-- Octave3.6.4_gcc4.6.2_pkgs_readme.txt

Windows 7 で単に使うだけなら、この時点で、C:\Octave\Octave3.6.4_gcc4.6.2\bin\octave.exeを実行すれば使えます。残りの手順は、ショートカットを作ったり、ショートカットのアイコンを設定したりという手順です。

※ ちなみに、セットアップが完了したら、Octave3.6.4_gcc4.6.2_20130408Octave3.6.4_gcc4.6.2_pkgs_20130402の2つのフォルダは丸ごと消してかまいません。

6.ショートカットの作成

ということで、任意の場所に Octave の実行ファイルへのショートカットを作成します。

Octave の実行ファイル C:\Octave\Octave3.6.4_gcc4.6.2\bin\octave.exeを右クリックして、コンテキストメニューから「ショートカットの作成」を選択して、あとは任意の場所へ移動します。 とりあえずデスクトップでいいと思います。

f:id:takamints:20160626173232p:plain

7.Windows 8 / 10でのコマンドラインスイッチの追加

Windows 8では、対話式のコマンドラインの入力機能がうまく動かないそうで、ショートカットにコマンドラインスイッチ(オプション)の設定が必要です。 Windows 10でも同様です。

上で作ったショートカットを右クリックして、[プロパティ]を選択して、リンク先の最後にスペースを空けて、-i --line-editing と追加します。

f:id:takamints:20160626173304p:plain

これで対話式のコマンドラインの編集機能が正しく動作するらしいです。

8.ショートカットのアイコン指定

動作にはまったく関係ありませんが、ショートカットのアイコンをOctaveのものに変更します。

「アイコンの変更」をクリックして、
f:id:takamints:20160626222228p:plain

C:\Octave\Octave3.6.4_gcc4.6.2\doc\octave\iconsのアイコンファイルを指定します。
f:id:takamints:20160626222311p:plain

アイコン選んで「OK」「OK」でOKです。
f:id:takamints:20160626222434p:plain

9.Octave-forge パッケージのコピー

次に、Octave3.6.4_gcc4.6.2_pkgs_20130402\Octave3.6.4_gcc4.6.2C:\Octave\の直下へフォルダごとコピー(または移動)します。

フォルダの見た目は特に変わりませんね。

C:\Octave\
  +-- Octave3.6.4_gcc4.6.2\
  |    +-- bin\
  |    +-- doc\
  |    +-- etc\
  |          .
  |          .
  |          .
  |
  +-- Octave3.6.4_gcc4.6.2_20130408\
  |    +-- Octave3.6.4_gcc4.6.2\
  |    +-- Octave3.6.4_gcc4.6.2(ショートカット)
  |    +-- octave3.6.4_gcc4.6.2_docs(ショートカット)
  |    +-- Octave3.6.4_gcc4.6.2_libblas_readme.txt
  |    +-- Octave3.6.4_gcc4.6.2_readme.txt
  +-- Octave3.6.4_gcc4.6.2_pkgs_20130402\
       +-- Octave3.6.4_gcc4.6.2\(移動したならこれはない)
       +-- Octave3.6.4_gcc4.6.2_pkgs_list.txt
       +-- Octave3.6.4_gcc4.6.2_pkgs_readme.txt

10.Octave-forge パッケージのビルド

実はこの部分について、ちゃんと理解していないのですが、「Octaveを使ってMinGW用パッケージをビルドして、Octave起動時に自動的に読み込むように設定するそうです(棒読み)」

上で作ったショートカットをダブルクリックして、Octaveを起動して、以下の5つのコマンドを実行します。 不要なものもあるようですが、とりあえず全部実行して問題は発生しませんでした。

pkg rebuild -auto
pkg rebuild -noauto ad
pkg rebuild -noauto nan
pkg rebuild -noauto gsl
pkg rebuild -auto java

11.起動時ワーニングの抑制

これまでの手順で、ほとんどの設定が完了していますが、この時点で実行すると、大量のワーニングが出ます。

このワーニングは、統計パッケージのfstat関数に関するものらしく、古くて使用されないfstatも多重定義されているというもので、無視してよいと説明されています。

抑制するには、octave起動時に実行されるスタートアップファイルC:\Octave\Octave3.6.4_gcc4.6.2\share\octave\site\m\startup\octavercに、以下の一行を付け加えます。場所はとりあえずプロンプト設定の直後としました。

## System-wide startup file for Octave.
##
## This file should contain any commands that should be executed each
## time Octave starts for every user at this site.

more off
PS1('octave:\#> ')
## ワーニング抑制
warning('off', 'Octave:shadowed-function')

これで大量のワーニングは抑制されましたが、まだ2つほどワーニングが出ています。 この2つは、ワーニングの情報が表示されないので、どうやって抑制してよいかわかりませんでした。ま、2つなので我慢してます。

12.オプショナルだが推奨される(?) エディタの設定

オプショナルですが推奨されるエディタの設定です。 こちらもスタートアップファイルC:\Octave\Octave3.6.4_gcc4.6.2\share\octave\site\m\startup\octavercに設定します。 エディタとしてはNOTEPAD++が推奨されているみたいで、コメントを外せばいいよとされていますが、私はKaoriyaさんのGvimを使っているので以下のように設定しました。

## Uncomment and change any of the following lines for your preferred editor
## EDITOR('C:\\Program Files (x86)\\Notepad++\\notepad++.exe');
## EDITOR('C:\\Program Files\\Notepad++\\notepad++.exe');
EDITOR('C:\\Program Files\\vim74-kaoriya-win32\\gvim.exe');

ただ、実際この設定が、どこに効いてくるのか知りません。


お疲れ様です。以上で設定完了です。

あとは、MSYSでC:\Octave\Octave3.6.4_gcc4.6.2\binにPATHを通して、Windows 8 / 10のユーザーならば ~/.bash_profile.bashrcで、alias octave=octave -i --line-editingと、エイリアスを設定しておけば便利に使えます。

以下、5x5の魔法陣を表示してみました。やあ、数学は美しいですね。

$ octave
GNU Octave, version 3.6.4
Copyright (C) 2013 John W. Eaton and others.
This is free software; see the source code for copying conditions.
There is ABSOLUTELY NO WARRANTY; not even for MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  For details, type `warranty'.

Octave was configured for "i686-pc-mingw32".

Additional information about Octave is available at http://www.octave.org.

Please contribute if you find this software useful.
For more information, visit http://www.octave.org/get-involved.html

Read http://www.octave.org/bugs.html to learn how to submit bug reports.

For information about changes from previous versions, type `news'.

warning: gmsh does not seem to be present some functionalities will be disabled
warning: dx does not seem to be present some functionalities will be disabled
octave:1> magic(5)
magic(5)
ans =

   17   24    1    8   15
   23    5    7   14   16
    4    6   13   20   22
   10   12   19   21    3
   11   18   25    2    9

octave:2>

リンク

ダウンロードサイト

WPFのDataGrid:カラムの表示・非表示をバインディングで切り替える

WPFのDataGridで、特定の列の表示・非表示をバインディングで切り替える方法を書いておきます。

f:id:takamints:20160614163925p:plain
photo credit: National Building Museum via photopin (license)

当初、「Visibilityをバインドするんでしょ?」と、簡単にやってみたけど無理でした。 調査の結果「プロキシー(代替)オブジェクトで中継する」と。 「なんのこっちゃ」と思いながらも試行錯誤。どうにか機構を把握して、自力で書けるようになりました。

ここでは、DataGridTextColumnVisibilityCheckBoxIsCheckedへプロキシを介してバインドしていますが、 他のバインディングターゲットにも適用できると思います。

作って覚えるVisual C# 2015 デスクトップアプリ入門
荻原 裕之 宮崎 昭世
秀和システム
売り上げランキング: 24,773
.NET開発テクノロジ入門2016年版Visual Studio 2015対応版
五十嵐 祐貴 生形 可奈子 大田 一希 古賀 慎一 酒井 達明 芝村 達郎 田淵 義人
日経BP
売り上げランキング: 11,454

以下、チェックボックスによって切り替えるコードです。XAMLだけで出来るのですね。

MainWindow.xaml

gist.github.com

XAMLの基礎については、こちら(↓)もご参考に。

takamints.hatenablog.jp

コードの説明

  • 12~13行目: BooleanからVisibilityの値へ変換するコンバーターを宣言しています。チェックボックスのIsCheckedをVisibilityへ変換するためのものです。

  • 15~16行目<FrameworkElement x:Key="ProxyColumnVisibility" DataContext="{Binding Path=IsChecked, ElementName=checkBoxShowColumn}"/>
    GridのResource内に、DataContextをCheckBoxのIsCheckedへバインドしたFrameworkElementを宣言。

  • 20~21行目<ContentControl Visibility="Collapsed" Content="{StaticResource ProxyColumnVisibility}"/>
    非表示にしたContentControlのContentに上で定義しているProxyColumnVisibilityを入れています。

  • 22~24行目<CheckBox x:Name="checkBoxShowColumn"
    FrameworkElementからバインドされるチェックボックスです。

  • 32行目Visibility="{Binding DataContext, Source={StaticResource ProxyColumnVisibility},Converter={StaticResource BooleanToVisibilityConverter}}"
    Visibilityを、ProxyColumnVisibilityのDataContextへバインド。

参考にさせていただいたURL

以下のサイトにお世話になりました。ありがたい。

いくつになってもお勉強

WPFXAMLも年に一度、数か月程しか使わないので、毎年「ややこしいわーわけわからんわー」から始まって、同じところでつまづいて、調べなおして「へぇー」とか言って、そのうち「うわ、これ便利やん」にたどり着く感じ。

系統立てた知識がないのが問題かなと。これを機会に明快な理解を試みようと思っています。

いくつになってもお勉強です。

関連情報(MSDNへのリンク)

「FrameworkElementって何者なの?」「てかResourceってなに?」「ContentControlは必要?」とか、フツフツと沸いてくる疑問に、うまく答えられないワタシがいる。なので、以下にMSDNWPF関連のリンクを並べておきます。そのうち自分で調べる用です。

WPF・MVVM関連記事はこちら:

takamints.hatenablog.jp

takamints.hatenablog.jp

takamints.hatenablog.jp

ShellでZIPの特定ディレクトリ以下全ファイルをUnzip

CLIのunzipで、ZIPファイルから特定ディレクトリ以下の全ファイルを取り出す方法の覚書き。

f:id:takamints:20160612171903p:plain
photo credit: A Bag of Colors via photopin (license)

GUIのツールだと何も問題ありませんが、シェルから使うunzip(Info-Zipのunzip?)では、取り出すファイルを全て指定する必要があるようです。数によっては現実的にちょっと無理。ひとつふたつならOKですけどね。

「なんでオプション無いのかねえ・・・」と、しばらく途方に暮れていたのですが、以下のようにして解決しました。

$ unzip -d Foo Foo.zip `zipinfo -1 Foo.zip | grep '^Path\\/To\\/Target'` 
  1. バッククォート内で、zipinfoコマンドを使って、全ファイル名を標準出力へ出力。-1オプションでファイル名(だけ)の出力。
  2. 同じバッククォート内で、パイプで標準出力をgrepへ渡して、正規表現で特定のパス以下のファイル名だけに絞り込み。
  3. その出力を、コマンド置換で、unzipのコマンドラインに展開して抽出。ここでは-dオプションは出力先ディレクトリを指定しています。無くてもいいけど念のため。

何が有り難いってバッククォートでのコマンド置換(標準出力をコマンドラインへ展開)。 さらに今回初めて知ったのですが、$(command) でも同じことらしいですね。

知ってるつもりでも、調べてみると、さらに深い発見があったりして、いくつになってもお勉強ですな。


エクストラクター ポイズンリムーバー AP011
エクストラクター
売り上げランキング: 230
bashクックブック
bashクックブック
posted with amazlet at 16.06.12
Carl Albing JP Vossen Cameron Newham
オライリージャパン
売り上げランキング: 574,097

参考

unzipとzipinfoのヘルプ出力。

$ unzip -h
UnZip 6.00 of 20 April 2009, by Info-ZIP.  Maintained by C. Spieler.  Send
bug reports using http://www.info-zip.org/zip-bug.html; see README for details.

Usage: unzip [-Z] [-opts[modifiers]] file[.zip] [list] [-x xlist] [-d exdir]
  Default action is to extract files in list, except those in xlist, to exdir;
  file[.zip] may be a wildcard.  -Z => ZipInfo mode ("unzip -Z" for usage).

  -p  extract files to pipe, no messages     -l  list files (short format)
  -f  freshen existing files, create none    -t  test compressed archive data
  -u  update files, create if necessary      -z  display archive comment only
  -v  list verbosely/show version info       -T  timestamp archive to latest
  -x  exclude files that follow (in xlist)   -d  extract files into exdir
modifiers:
  -n  never overwrite existing files         -q  quiet mode (-qq => quieter)
  -o  overwrite files WITHOUT prompting      -a  auto-convert any text files
  -j  junk paths (do not make directories)   -aa treat ALL files as text
  -U  use escapes for all non-ASCII Unicode  -UU ignore any Unicode fields
  -C  match filenames case-insensitively     -L  make (some) names lowercase
  -X  restore UID/GID info                   -V  retain VMS version numbers
  -K  keep setuid/setgid/tacky permissions   -M  pipe through "more" pager
See "unzip -hh" or unzip.txt for more help.  Examples:
  unzip data1 -x joe   => extract all files except joe from zipfile data1.zip
  unzip -p foo | more  => send contents of foo.zip via pipe into program more
  unzip -fo foo ReadMe => quietly replace existing ReadMe if archive file newer
$ zipinfo -h
ZipInfo 3.00 of 20 April 2009, by Greg Roelofs and the Info-ZIP group.

List name, date/time, attribute, size, compression method, etc., about files
in list (excluding those in xlist) contained in the specified .zip archive(s).
"file[.zip]" may be a wildcard name containing *, ?, [] (e.g., "[a-j]*.zip").

   usage:  zipinfo [-12smlvChMtTz] file[.zip] [list...] [-x xlist...]
      or:  unzip -Z [-12smlvChMtTz] file[.zip] [list...] [-x xlist...]

main listing-format options:             -s  short Unix "ls -l" format (def.)
  -1  filenames ONLY, one per line       -m  medium Unix "ls -l" format
  -2  just filenames but allow -h/-t/-z  -l  long Unix "ls -l" format
                                         -v  verbose, multi-page format
miscellaneous options:
  -h  print header line       -t  print totals for listed files or for all
  -z  print zipfile comment   -T  print file times in sortable decimal format
  -C  be case-insensitive     -M  page output through built-in "more"
  -x  exclude filenames that follow from listing

DynamoDB:条件式のプレースホルダを自動生成してみましょう

コンソールから AWSを操作するコマンドセットを提供するNodeモジュール(npm)のご紹介。 DynamoDBのクエリやスキャンでプレースホルダーを自動生成するAPIも提供してます。

f:id:takamints:20160604133023p:plain

DynamoDBから条件付きでQueryやScanを行う場合、条件式等の中で使われている単語がDynamoDBのキーワード(予約語)と一致する場合、その単語をプレースホルダーに変換して、別途指定しなければなりません。

プレースホルダーは2種類あります。属性名を置き換える属性名のプレースホルダと、検索条件等で指定する値を置き換える値のプレースホルダで、それぞれ別の対応が必要です。DynamoDBのキーワードの数はかなり多く、全部覚えていられないし、一般的な単語がたくさん含まれてるので厄介なんです。

てなことで、怒りに任せて、条件式をテーブルの属性名や値をそのまま使って記述してDynamoDBからクエリできるnode.jsのコマンド群をnpmとして公開しているのでご紹介。DynamoDB関係以外のコマンドセットも含まれています(Lambda, API Gateway, IoT, IAM等)。 コンソールからデータの有無や内容を、軽く確認する時に、ちょっと便利。

最新バージョン(v0.8.6以降)では、DynamoDBをSQLで扱うためのステートメントクラスも使えるようになりました。 これについては、以下の記事で説明してます。

takamints.hatenablog.jp

npmは以下↓からどうぞ。

www.npmjs.com



DynamoDBのプレースホルダを気にせず使える3つのコマンド

  1. aws-dynamodb-put-item - 項目の追加と更新
  2. aws-dynamodb-query - 項目のクエリ
  3. aws-dynamodb-scan - 項目のスキャン

AWS CLIのデフォルトユーザー、デフォルトリージョンで接続します。

セットアップ

npmでグローバルにインストールしてください。

$ npm install aws-node-util --global

1. aws-dynamodb-putItem - 項目追加・更新

テーブルに項目を追加、または更新します。item-expressionで指定したキーがすでにあるなら上書きされ、なければ追加されます。

aws-dynamodb-put-item [options] <tableName> <item-expression>

パラメータ

  • tableName - 操作対象のテーブル名

  • item-expression - 追加・更新する項目を属性名=属性値,属性名=属性値という形式で記述します。

項目には、少なくともテーブルの全てのキー属性が含まれていなくてはなりません。キーの値によって項目が追加されるか更新されるかが決まるからです。これはDynamoDBの仕様です。

属性名と属性値のプレースホルダーは自動的に生成されるので、気にする必要はありません。

実行例

$ aws-dynamodb-put-item stars "mainStar = 'SUN',
    role='planet', orbitOrder=3,
    name='EARTH', mass=5.97, diameter=12756, density=5514,
    gravity=9.8, escapeVelocity=11.2, rotation=23.9";
OK.

$ aws-dynamodb-put-item stars "mainStar = 'EARTH',
    role='satellite', orbitOrder=1,
    name='MOON', mass=0.0073, diameter=3475, density=3340,
    gravity=1.6, escapeVelocity=2.4, rotation=655.7";
OK.

$

値の型

属性値は、文字列、数値、ブーリアンの3つの型に対応しています。 文字列は引用符でくくられている必要があり、ブーリアンtruefalseのどちらかです。

MAP型のデータを表現するには

MAP型のデータは、属性名をドットで区切ってpath.to.the.subitemという形式で記述します。これによって、指定されたキーの名前を持つMAP型のデータを自動生成します。

2. aws-dynamodb-query - 項目のクエリ

キーを指定してテーブルから項目を抽出します。

aws-dynamodb-query [options] <tableName> <keyConditionExpression>

オプション

オプション 長いオプション 説明
-p --projection-expression=ARG 表示する属性名をカンマ区切りで指定
-f --filter-expression=ARG 検索後のフィルター条件式
-c --max-items=ARG 表示する件数(既定値は20)
-s --sort-item=ARG 表示時に並び替える項目名を指定
-d --desc 降順の並び替えを指定

パラメータ

  • tableName - 操作対象のテーブル名
  • keyConditionExpression - 抽出するキーの条件式を与えます。

実行例

$ aws-dynamodb-query stars 'mainStar="SUN"'\
    --projection-expression 'name,orbitOrder,mass,diameter,
        gravity,density,rotation'\
    --sort-item orbitOrder
Count: 9
ROWNUM mass      rotation name    gravity orbitOrder density diameter
     1    0.33     1407.6 MERCURY     3.7          1    5427     4879
     2    4.87    -5832.0 VENUS       8.9          2    5243    12104
     3    5.97       23.9 MARS        9.8          3    5514    12756
     4    0.642      24.6 MARS        3.7          4    3933     6792
     5 1898.0         9.9 JUPITER    23.1          5    1326   142984
     6  568.0        10.7 SATURN      9.0          6     687   120536
     7   86.8       -17.2 URANUS      8.7          7    1271    51118
     8  102.0        16.1 NEPTUNE    11.0          8    1638    49528
     9    0.0146   -153.3 PLUTO       0.7          9    2095     2370
ScannedCount: 9

$

上記表形式でのコンソール出力は、以下の記事でご紹介している npm list-itを利用しています。

takamints.hatenablog.jp

3. aws-dynamodb-scan - 項目のスキャン

テーブルをScanします。キーの条件式は指定できませんが、その他の使い方はQueryとほぼ同じです。

aws-dynamodb-scan [options] <tableName>

オプション

オプション 長いオプション 説明
-p --projection-expression=ARG 表示する属性名をカンマ区切りで指定
-f --filter-expression=ARG 検索後のフィルター条件式
-c --max-items=ARG 表示する件数(既定値は20)
-s --sort-item=ARG 表示時に並び替える項目名を指定
-d --desc 降順の並び替えを指定

パラメータ

  • tableName - 操作対象のテーブル名

実行例

$ aws-dynamodb-scan stars \
    --projection-expression 'name,orbitOrder,mass,diameter,
        gravity,density,rotation'\
    --filter-expression 'role="planet"'\
    --sort-item orbitOrder --desc
Count: 10
ROWNUM mass      rotation name    gravity orbitOrder density diameter
     1    0.0146   -153.3 PLUTO       0.7          9    2095     2370
     2  102.0        16.1 NEPTUNE    11.0          8    1638    49528
     3   86.8       -17.2 URANUS      8.7          7    1271    51118
     4  568.0        10.7 SATURN      9.0          6     687   120536
     5 1898.0         9.9 JUPITER    23.1          5    1326   142984
     6    0.642      24.6 MARS        3.7          4    3933     6792
     7    5.97       23.9 MARS        9.8          3    5514    12756
     8    4.87    -5832.0 VENUS       8.9          2    5243    12104
     9    0.33     1407.6 MERCURY     3.7          1    5427     4879
ScannedCount: 10

$

共通オプション

以下は各コマンド共通のオプションです。

オプション 長いオプション 説明
-j --output-json AWSのレスポンスを複数行のJSONとして表示
-J --output-json-oneline AWSのレスポンスを1行のJSONとして表示
-h --help ヘルプを表示。

※ ヘルプは、オプションの説明しか表示しません。

参考

オプション --projection-expression--filter-expression--key-condition-expressionと、パラメータkeyConditionExpressionの表記内容や使用可能な演算子については、Query - Amazon DynamoDB、または、Scan - Amazon DynamoDBを参考にしてください。 ただし、プレースホルダ―については、自動的に変換しますので気にしなくて結構です。

制限事項

  • 使用可能な型は、文字列(S)、数字(N)、真偽値(BOOL)、マップ(M)だけです。 リスト(L)はできれば対応したいと思っています。

  • 表示時のカラムの順序は指定できません。一見、projectionExpressionで指定した順番でデータを取得すればよいように思えるのですが、AWSから得られるデータの並びが、この順になっているわけではないからです。とはいえ、なんとか順序を指定できるようにしたいとは思っています。

リポジトリ

その他

同モジュールでは、他にも雑多なコマンドがたくさん含まれていますが、ドキュメントだけでなく動作確認等、まったく追いついていません。

不具合、御要望、改善案などございましたらGitHubのissueでご指摘ください。もちろん他の方法でも構いません。

また、個人的な取り組みとして最近ドキュメントは全て英文でチャレンジしていますので、妙な表現、文法間違い、Typoなど、山ほどあるかと思います。 こちらについても、おかしなところがあれば、ご指摘くださいヨロシクお願いいたします。

AWSへの接続について

※ 以下、~はホームディレクトリを表します。Windowsなら、C:\Users\<ユーザー名>などに読み替えてください。

aws-sdkでは、AWSへの接続のため、以下のAWS CLIで作成される認証情報を使用しているようです。 しかし、同じくAWS CLIが生成するデフォルトリージョンは利用してくれないため、このコマンド独自に読み込んでいます。

認証情報 ~/.aws/credential

[default]
aws_access_key_id = <アクセスキー>
aws_secret_access_key = <シークレットアクセスキー>

コンフィグ ~/.aws/configure

[default]
output = json
region = ap-northeast-1

DynamoDBのプレースホルダーについての基本

DynamoDBのテーブル操作の「式」の中で、プレースホルダ―を使用しなければならないケースがある。プレースホルダ―は以下2種類。

  1. 「属性名のプレースホルダ―」 - 式の中の属性名を置き換える。式の中には予約済みキーワードを表記できないので、属性名が予約済みキーワードとかぶった場合に使用。
  2. 「属性値のプレースホルダ―」 - 式の中の値を置き換えるためのもの。式の中には値を直接表記できないから、全ての値を置き換える必要がある。

予約済みのキーワードが多く、また一般的な単語も多く含まれている。 属性名に関して、予約済みキーワードがどうかにかかわらず全部置き換えても構わない。

npm「list-it」― コンソールへ列を揃えてデータを表示

コンソールへの表形式でのデータ表示を支援するNode.jsのモジュール(npm)「list-it」のご紹介。

2次元配列的なデータの列幅を揃えてキレイに表示。

文字列は左寄せ、数値は右寄せ。同じ列内の数値の小数点の位置も揃えます。

npmは、便利なツールが揃っていて、気楽にコードが書けるのがヨロシイですね。

f:id:takamints:20160501161451p:plain



駆け足でご説明するざっくりした使い方

  1. require("list-it")する。
  2. buffer()メソッドで空のバッファを作成。
  3. d()メソッドで、現在の行へ列(セル)データを追加。複数指定も可。
  4. nl()メソッドで現在行への列の追加を終了し次の行へ。
  5. 追加できるデータの型は文字列か数値。配列は行の追加になる(行追加時はnl()不要)
  6. 複数の配列を与えると複数の行が出来上がります。2次元配列でも可。
  7. toString()で文字列化してconsole.log()

機能の概要

表形式のデータを放り込んでコンソールへそのまま表示できる文字列を生成します。列ごとに数値の小数点位置を揃えられます。なんとなく便利でしょ?

  • autoAlign(自動整列)モードON(デフォルト)で、数値は小数点位置を揃えて右寄せ、文字列は普通に左寄せ。
  • 文字列の色や表示スタイルにANSIエスケープシーケンスが使用できます。カーソル移動とかは無理ですけどね。エスケープシーケンスのリセットは自動では行わないので、追加文字列の最後にリセットシーケンスを入れておいてください。

サンプルコードと出力例

japanese-foods.js

const ListIt = require("list-it");//①
const buf = new ListIt();      //②
console.log(
    buf
        .d("1").d("Sushi")      //③
            .d("vinegared rice combined raw seafood")
            .d("Healthy").nl()  //④
        .d("2").d("Yakiniku")
            .d("Grilled meat on Japanese")
            .d("Juicy").nl()
        .d("3").d("Ramen")
            .d("Japanese noodle soup dish")
            .d("I like it").nl()
        .d("4").d("Tempura")
            .d("Deep fried seafood or vegetables")
            .d("Delicious").nl()
        .d("5").d("Sashimi")
            .d("Very fresh sliced fish")
            .d("Try it now, It's good").nl()
        .toString());

出力: 文字列は左寄せです

$ node sample/japanese-food.js
1 Sushi    vinegared rice combined raw seafood Healthy
2 Yakiniku Grilled meat on Japanese            Juicy
3 Ramen    Japanese noodle soup dish           I like it
4 Tempura  Deep fried seafood or vegetables    Delicious
5 Sashimi  Very fresh sliced fish              Try it now, It's good

autoAlign

autoAlignオプションをtrueにすれば(デフォルトでtrueです)、データの型を考慮してセルの整形を行います。

planets.js

const ListIt = require("list-it");
const buf = new ListIt({ "autoAlign" : true });
var PLANETS = [
    ["NAME", "Mass(10^24kg)", "Dia(km)", "Dens(kg/m3)",
                        "Grav(m/s2)", "EscV(km/s)", "Rot(hours)" ],
    ["MERCURY", 0.33,   4879,   5427,   3.7,    4.3,    1407.6  ],
    ["VENUS",   4.87,   12104,  5243,   8.9,    10.4,   -5832.5 ],
    ["EARTH",   5.97,   12756,  5514,   9.8,    11.2,   23.9    ],
    ["MOON",    0.0073, 3475,   3340,   1.6,    2.4,    655.7   ],
    ["MARS",    0.642,  6792,   3933,   3.7,    5.0,    24.6    ],
    ["JUPITER", 1898,   142984, 1326,   23.1,   59.5,   9.9     ],
    ["SATURN",  568,    120536, 687,    9.0,    35.5,   10.7    ],
    ["URANUS",  86.8,   51118,  1271,   8.7,    21.3,   -17.2   ],
    ["NEPTUNE", 102,    49528,  1638,   11.0,   23.5,   16.1    ],
    ["PLUTO",   0.0146, 2370,   2095,   0.7,    1.3,    -153.3  ]
];
console.log( buf.d( PLANETS ).toString() ); //⑤、⑥

出力: 数値は小数点の位置を揃えて右寄せ

$ node sample/planets.js
NAME    Mass(10^24kg) Dia(km) Dens(kg/m3) Grav(m/s2) EscV(km/s) Rot(hours)
MERCURY        0.33      4879        5427        3.7        4.3     1407.6
VENUS          4.87     12104        5243        8.9       10.4    -5832.5
EARTH          5.97     12756        5514        9.8       11.2       23.9
MOON           0.0073    3475        3340        1.6        2.4      655.7
MARS           0.642     6792        3933        3.7        5.0       24.6
JUPITER     1898.0     142984        1326       23.1       59.5        9.9
SATURN       568.0     120536         687        9.0       35.5       10.7
URANUS        86.8      51118        1271        8.7       21.3      -17.2
NEPTUNE      102.0      49528        1638       11.0       23.5       16.1
PLUTO          0.0146    2370        2095        0.7        1.3     -153.3

日本語(ワイド文字)

japanese-foods-jp.js

const ListIt = require("list-it");
const buf = new ListIt();
console.log(
    buf
        .d("1").d("寿司")
            .d("酢とご飯とシーフード")
            .d("健康的だ").nl()
        .d("2").d("焼肉")
            .d("日本のグリルされたお肉")
            .d("ジューシー").nl()
        .d("3").d("ラーメン")
            .d("日本のスープに入った麺")
            .d("大好き").nl()
        .d("4").d("天ぷら")
            .d("シーフードや野菜に衣をつけて揚げたもの")
            .d("おいしー").nl()
        .d("5").d("刺身")
            .d("大変フレッシュな魚のスライス")
            .d("食べてみて!あご落ちるぜ").nl()
        .toString());

出力: HTMLでは何故か微妙にズレるけどコンソールではズレてません。

$ node sample/japanese-food-jp.js
1 寿司     酢とご飯とシーフード                   健康的だ
2 焼肉     日本のグリルされたお肉                 ジューシー
3 ラーメン 日本のスープに入った麺                 大好き
4 天ぷら   シーフードや野菜に衣をつけて揚げたもの おいしー
5 刺身     大変フレッシュな魚のスライス           食べてみて!あご落ちるぜ

未実装機能(将来追加する可能性はあり…ます…)

  • 文字列の折り返しができるようになればいいな。列幅指定してとか、コンソールの幅を判別して、自動的に列を折り返すとかできると超クール。
  • 見出し行とか見出しセルの概念を、我、欲す。行、列、セル単位でスタイル指定したい。
  • 表を転置(トランスポーズ:行列入れ替え)したいときがたまにある。
  • 演算機能があってもよいかなとか。あ、行列演算できてもよいか?いや、それはやりすぎか。

リポジトリ

メソッドの詳細などは、以下のリポジトリにあります。どう考えてもおかしな結果が得られたって時は、バンバンIssue入れてください。

GitHub

github.com

npm

www.npmjs.com

その他

これ、結構需要がある気がしていますが、プロジェクト単位でガチガチに力技で作ったりしがちですよね。 また、こういったモジュールは既にあるのかもしれませんが、軽く検索して見つけられなかったので作りました。

npmにはまる以前に作っていた別ソフトがベースになっています。 当時必要だと感じていた機能以上に、あれもこれもとドンドン実装したくなるから面白いもんですね。