OmniAICreator/Qiita-1.07M huggingface dataset:
OpenGoddard使い方２-非線形最適制御・軌道生成のためのpythonライブラリ

https://github.com/istellartech/OpenGoddard
https://istellartech.github.io/OpenGoddard/

[OpenGoddard使い方１](http://qiita.com/ina111/items/ec73bc77ad45dd65ac1e)
[OpenGoddard使い方２](http://qiita.com/ina111/items/20963133988c27d84748)←いまここ
[OpenGoddard使い方３](http://qiita.com/ina111/items/486aa2a24a1723081b91)
[OpenGoddard使い方４](http://qiita.com/ina111/items/60f75d90e5376d34a0ef)

## Goddard問題（大気中のロケット最適上昇制御問題）

ロケット工学の中では古典的な問題である、大気中のロケット最適上昇するための最適推力制御の問題である、ゴダード問題を解いていきます。
詳細は[example](https://github.com/istellartech/OpenGoddard)のファイルを見てください。

### 運動方程式
ロケットの運動を１次元（高さだけ）で考えます。ロケットエンジンでの推力と空気抵抗を考えて高度最大化を考えます。
T：推力
D：抗力（空気抵抗）
g：重力加速度

![2_rocket.png](https://qiita-image-store.s3.amazonaws.com/0/40132/d5d8feaa-ea40-a4a3-d3a3-571fdb261141.png)

```math
\begin{align}
\dot{h} &= v \\
\dot{v} &= \frac{T - D}{m} - g \\
\dot{m} &= - \frac{T}{c}
\end{align}
```

### 拘束条件

初期条件・終端値条件・状態変数と制御変数の上限下限を入力します。

### 評価関数
最小化したい値をreturnに入れる。ここでは、高度の最大化を目指したいので、符号に注意して下記の通りです。

```math
J = -h
```

### 結果

![2_0knot_.png](https://qiita-image-store.s3.amazonaws.com/0/40132/e424a026-000b-64df-1c94-e9efd005a9fb.png)


最初はフルスロットルで、途中で推力を絞ってあげるのが良いという結果になりました。
これは、現象的には重力による減速を小さくするために、推力はなるべく大きい方がいい、という性質と、空気抵抗は小さいほうがいいから空気濃いところでは加速しすぎないほうがいいという性質の兼ね合いの結果です。
専門用語では重力損失と空力損失の合計の最小化と言えます。
実際のロケットでも同じようなことを実際考えられていて、固体燃料ロケットでは、推力を途中で良い感じに調整しています。
ゴダード問題の解は実利用されています！
最適化問題は世の中の役に立つ！すごい！


## knotting method
OpenGoddardの中身である擬スペクトル法はすごいアルゴリズムですが、状態変数、制御変数が滑らかでない（微分可能ではない）ものは苦手です。制御変数が非連続に変わるものも若干苦手です。また絶対値なんかも得意じゃないです。
ゴダード問題で言うと、高度、速度、重量、推力が滑らかになるようにしか解いてくれません。
状態変数、制御変数をある特定の点で非連続でもで解を求める手法として、knotting methodというのを使います。
これは、非連続な部分で計算区間をわけてしまう方法です。
OpenGoddardでは簡単にknotting methodが使えるようになっています。
（世の中には自動的にknotting methodの区間を分けるアルゴリズムの最適化ソフトもあります・・・）

## Goddard問題（knotあり）

Problemクラスに入れる値をリストで並べていきます。

```python
time_init = [0.0, 0.1, 0.3]
n = [25, 25]
num_states = [3, 3]
num_controls = [1, 1]
```

また、区間ごとにどの運動方程式が適応されるのか指定し、状態変数が連続であるかどうかを指定します。
ここでは、制御変数だけが非連続に変化するという予測のもとにTrueを選択しています。ここのTrue/Falseと拘束条件は密接に関係するので注意して指定します。
Falseの場合は拘束条件(equality）にknot点で変数を固定しないと発散します。

```python
prob.dynamics = [dynamics, dynamics]
prob.knot_states_smooth = [True]
```

以上により、

![2_1knot_.png](https://qiita-image-store.s3.amazonaws.com/0/40132/5af018cd-dd29-c1de-6127-7d1adf174a7f.png)


knot有りは最高高度下がりました。。。あまり良い成果になりませんでした。
このようにknotting methodを使えば単純に良いということではありませんが、変数が非連続な問題も扱うことが出来るようになりました。
AnsibleでPostgreSQLの特定のデータベースに対してSELECTのみの権限のユーザを追加する

最初は[postgresql_userモジュール](http://docs.ansible.com/ansible/postgresql_user_module.html)のみで実現しようと思ったのですが、どうやら現状では `priv` オプションには、テーブルを指定しないといけないっぽいので、2つのモジュールに分けて実現しました。

```yaml
---
- name: DBユーザ my_read_only を追加
  postgresql_user:
    db: my_db
    name: my_read_only
    password: xxxXXXXxxxXX
- name: DBユーザ my_read_onlyにSELECTのみの権限を付与
  postgresql_privs:
    db: my_db
    type: table
    schema: public
    privs: SELECT
    objs: ALL_IN_SCHEMA
    role: my_read_only
```
误删除Innodb mysql后的恢复


使用的工具是percona-data-recovery-tool-for-innodb-0.5.tar.gz,测试的操作是delete from a;
然后将表里的数据恢复出来。虽然没有全部恢复，但是大部分有了。也就是说，我没有能全部恢复。

1.出现误删除后，尽快停掉mysql，然后拷贝删除表的ibd文件。然后再次启动mysql。
如果没有配置innodb_file_per_table，那就需要将ibdata1这个文件拿去恢复了。

>  After the “accidental” deletion of rows you should stop MySQL, take a copy of the salaries.ibd and start it again. 

2.查询表信息。
对于误删的表可以通过查询表信息，确认row_format和index信息。目的就是为了确认在使用page_parser命令的时候确定参数。

查询row_format信息：
**登陆到mysql里查询误删除表的信息**
如果informatino_schema这个库中，有innodb_sys的相关表，就可以直接查询出表的row_format以及index_id name

```sql
#database_name 就是数据库名,table_name是库里的表名，就是你误删除的那个库和那个表。
select i.index_id,i.name,t.row_format  from information_schema.innodb_sys_indexes as i inner join information_schema.innodb_sys_tables as t USING(TABLE_ID) where t.name='"${database_name}/""${table_name}"'"
```
样例如下：

![Kobito.zsUW5X.png](https://qiita-image-store.s3.amazonaws.com/0/163801/616669bc-3b33-2f4b-c6a1-79fd7e6a091b.png "Kobito.zsUW5X.png")

__如果没有这些表，可以查询tables表获取一些信息，剩下的就是自己根据情况判断了。__

3.获取了以上信息以后，就需要通过page_parser来导出page信息了

假设，拷贝出来的表叫a，文件就是a.ibd.

```shell
./page_parser -5 -f a.ibd

#这里的5表示row_format是Compact格式。
```
>The row format can be -4 (REDUNDANT) or -5 (COMPACT). From 5.0.3 the default format is COMPACT. 


当执行完毕后，会在当前目录生成一个pages-xxxxxxx的目录。这个目录里就是包含了导出的page信息。
例如：
pages-1489137771/FIL_PAGE_INDEX/

在这个目录下会有不同的目录，按上图的话就是0-2302,0-2303,0-2304。因为我们提前查询了index_id，所以知道 **0-2302是PRIMARY**,也就是起始的文件。我们一会就要使用这个文件来恢复。

4.通过perl脚本获取表信息，并创建数据恢复程序使用的表结构。

```
./create_defs.pl --host 127.0.0.1 --port 3306 --user root --password  xxxxx --db testaaa --table a >include/table_defs.h
```
include目录是解开工具包里自己就有的。直接按照命令输出到table_defs.h即可。

5.这一步是需要重新编译

```
make
```
完成这个步骤以后，会重新生成文件 **constraints_parser**，这个文件只适用于本次恢复的这个表。

6.恢复数据

```
./constraints_parser -5 -D -f pages-1489137771/FIL_PAGE_INDEX/0-2302/ >a.recovery
```

解释一下：
这个命令的参数5上边说过了，就是mysql的row_format格式。-D表示的只恢复程序认为已经删除的，-f表示需要读取的目录。最后是将能恢复的输出到以为文件，CSV格式的。

上边这个命令是从别的地方看到的。我实际实验的时候使用的是下边的命令

```
./constraints_parser -5 -f pages-1489137771/FIL_PAGE_INDEX/0-2302/ >a.recovery
```
也就是将所有记录全部导出来。

7.导入表中。

登陆到mysql中，使用以下命令导入表中。

```
load data infile 'a.recovery' replace into table `a` FIELDS TERMINATED BY '\t' OPTIONALLY ENCLOSED BY '"' LINES STARTING BY 'a\t' (id,username,testfield1,test3);
```

读取a.recovery文件导入到表a中，csv格式同时以'a’开头，后边括号里是字段名称。

具体根据需要修改。最好是查看以下恢复的文件。
バグのないソフトウェアの作れない理由

バグのないソフトウェアは作れないと言われますが、正しい命題はちょっと違います。「ソフトウェアにバグがないことは証明できない」です。
バグがないことが証明できない理由は、チューリングマシンの停止性問題が決定不能問題、有限時間内には答えの出ない問題だからです。
えっなんで停止性が有限時間内に判定できないとバグがなくせないの？

等価性判定問題
--
バグのないことが証明できない理由は、停止性問題の系である「与えられた2つのチューリングマシンが等価であるか否か」判定問題がやはり決定不能問題だからだと説明できます。

バグを定義しましょう。ごく簡単です。「プログラムの仕様と異なる動作」のことです。
バグがないことを証明するとは、仕様という（頭の中にある）チューリングマシンと実装されたプログラムというチューリングマシンの2つを等価判定する問題です。この判定作業には無限に時間がかかるよと証明されてしまっている、それが「バグがないことを証明できない」ことを意味しています。

だから「Hello worldプログラムにはバグがないことを証明できるではないか」という反論がなぜ成立しているのかも容易に理解できます。Hello Worldプログラムはチューリングマシンでなくとも有限オートマトンで記述できる複雑さだからです。つまり、この議論でいうソフトウェアとはチューリングマシンで記述する必要があるプログラム、もう少し具体的にはメモリ要求量が不定なプログラムのことであると理解してください。実用的なソフトウェアのほぼすべてが当てはまるはずです。

仕様と実装が比較し終えられない、だけでなく
--
実用的なソフトウェアにおいて仕様と実装を完全に比較する（つまり、テストする）のが有限時間内に終わらないと書きました。
で、その仕様というのは一体どんな形で頭の中に、もしくは紙の上にあるのでしょう。
仕様とは、プログラム開始後の入力列からその時点での出力列が得られる関数です。関数と言っても数式で（といいますか有限のルールで演繹的に）完全に表現できてしまうようなプログラムでない限り、入力列から出力列を引ける辞書です。そして、この辞書のサイズが有限ではありえないのです。有限だったらそれ全部試せば有限時間内でテストは終わることになるので。

なんということでしょう、仕様書という辞書はそもそも有限の長さの文書として書き下ろせるものではなかったのです。
完全な仕様書が書けないということは「バグがないこと」どころか「ある動作がバグがどうか判定できる」保証さえないということでもあります。

プログラマの自嘲的な替え歌、「バグは夜ふけ過ぎに　仕様へ変わるだろう」はこうしてみると味わい深い一節ですね。
巨大なヘッダ付きのファイルを指定行数で分割して処理する話

`split` コマンドに、

* 行数指定で分割する `-l` オプションと、
* 分割しつつstdinに流し込める `--filter` オプション

があるけど、これだと単純に指定行数ごとに分割するだけで、
1行目にヘッダがあるファイルとかの場合、分割２ファイル目以降はヘッダが落ちてしまって悲しいので、ちょっと工夫した話。

```bash:完成図
#!/bin/bash

function something_special() {
    cat
}

export -f something_special
tail -n +2 huge_file | split -l 10 --filter '(head -n 1 huge_file; cat) | tee $FILE | something_special'
```

# 追記＠2017/3/14

`--filter` に渡す文字列はシングルクォートにしないと、`$FILE` が**変数展開されてから**渡されてしまうので注意。

ファイル名ベタ書きの場合だと特に問題はないけど、
上記とのトレードオフで分割ファイル名に変数を使いたい場合はちょっとハマる。
`--filter` に渡す部分を一度コマンドを展開しておいて、シングルクォートで挟んで渡してやればOK。
書き方がちょっとトリッキーだけど。

```bash
cmd=$(printf '(head -n 1 %s; cat) >$FILE' $INPUTFILE)
tail -n +2 $INPUTFILE | split -a 4 -d --verbose -l 1000000 --filter ''"$cmd"''
```


# 余談的解説

## `export -f something_special`

`xargs` と同じで、これやっとかないとfilterの中から関数が見えない。
関数じゃなく外部のコマンドに流すとかなら不要。

## `tail -n +2 huge_file`

１行目を除外。

## `(head -n 1 huge_file; cat)`

`()`内でサブシェルを起動して出力を束ねて、後続のパイプに流す。
ちなみに `{}` だと駄目だった。

* `head -n 1 huge_file` で目的のファイルの１行目だけ拾って、
* サブシェルに流れてきた stdin を `cat` でバイパスして、

ヘッダ付き部分ファイルに束ねる。

## `tee $FILE`

`--filter` すると分割後の結果が残らないけど、
`＄FILE`環境変数に出力されるはずだったファイル名[^1]が入っているので、
teeでファイルに落としながらコマンドに繋いでやる。

分割したものを残す必要がなければここは削ってもOK。
分割後は、元のファイルと合わせて、容量が単純に２倍ちょいになるので、ストレージの容量ともご相談。

[^1]: デフォルトだと xaa, xab, xac, ...
ファイル名から拡張子とそうでない部分を分ける

ファイル名を拡張子とそうでない部分（名前ないのかな？）とに分離したいとき、Rubyなら

```rb
file_name = "test.txt"
name = File.basename(file_name, ".*") #=> "test"
ext = File.extname(file_name) #=> ".txt"
```

とできるわけですが、なんとなくDRYじゃない感じがして、一行で書いてみたので残しておきます。

```rb
file_name = "test.txt"
name, ext = /\A(.+?)((?:\.[^.]+)?)\z/.match(file_name, &:captures) #=> ["test", ".txt"]
```

正規表現の最初の括弧で`name`の部分をキャプチャします。
普通に`(.+)`だとgreedyにマッチするので、拡張子部分までマッチしてしまって上手くいきません。
また`(.*?)`だと、`filename = ".bashrc"`のとき、`[name, ext] == ["", ".bashrc"]`になってしまいます（上の`basename`と`extname`の例ではそうなりません）。

次の括弧で.とそれに続く.を含まない文字列をキャプチャします。`[^.]`としたのは、`file_name = "test.1.txt"`のようなときにtestと.1.txtに分かれてしまわないようにです。
また、`(\.[^.])?`でキャプチャしなかったのは、拡張子なしだった場合にextがnilではなく空文字列になるようにして、`File.extname`と同じ挙動にしたかったからです。

`Regexp#match`にブロックを渡すと、マッチが成功した時だけMatchDataオブジェクトを引数にブロックを実行してくれます。
なので、引数に`&:captures`を渡すとキャプチャした部分が配列で返ってきて変数に代入できるというわけです。
ちなみに`regexp.match(file_name).captures`でも良さそうにも見えますが、マッチに失敗した時に`nil.captures`になってNoMethodErrorになります。
Angular 2でサクッと週末開発をするための雛型兼サンプル（使い方追記）

# Angular
Angular2のオレオレアプリ向け雛型作りました。

# Angular2Bootstrap
[Angular2Bootstrap](https://github.com/YoshifumiShiiba/Angular2Bootstrap)

![Screen Shot 2017-03-10 at 6.50.47 PM.png](https://qiita-image-store.s3.amazonaws.com/0/9162/c1c644de-838c-9308-db37-7f9258dba8fd.png)

Angular2を使って素早くウィークエンドアプリを作るための雛型です。ほぼオフィシャルの機能を組み合わせただけなので、カスタマイズは簡単なはずです。
  
機能

- angular-cliを採用しています。Scaffold偉大。
- サンプルのルーティングとページ。追加も簡単です。
- サンプルのHTTPリクエストサービス（初期状態でHacker News APIを叩いています）とその利用例。
- アプリ全体で使い回す機能やデータを扱うためのAppServiceを定義しています。今はTitleタグを変更する仕事だけやっています。
- SassとBootstrapでそこそこ見た目が整っています。Material Design Liteはクラス名が長くて好きじゃない。スタティックファイルを突っ込んでいるだけなので、他の好みがあれば簡単に変えられるはず。
- GAタグとか細かいとこ。

## 依存ツール

[angular-cli](https://github.com/angular/angular-cli) 簡単にインストールできます。

## 使い方

1 レポジトリのクローン

```
git clone https://github.com/YoshifumiShiiba/Angular2Bootstrap.git
```

2 npm install

```
cd Angular2Bootstrap
npm install
```

3 ng serve

```
ng serve
```

4 ブラウザで指定されたURLを開く

## 使い方と詳細
### [angular-cli](https://github.com/angular/angular-cli)について
Angularプロジェクト謹製のオフィシャルコマンドラインツールです。各Scaffoldコマンド等詳細はリンク先のGitHubでどうぞ。

オフィシャルなので将来性的にも安心して使えるものの、生成した雛型がそのままでは何にも使えないくらい小さすぎたり、ルーティングが使われていなかったり、ロジックを実装し始めるまでのイニシャルがめんどくさいことこの上ない感じなので、今回これを製作した次第です。

### ルーティングとページ

ルーティング超大事。デフォルトでPage1とPage2を持っています。Routesオブジェクト自体は/app/app.module.ts の中に定義してあります。

##### ページ追加

まずはコンポーネントを追加します。

```
ng g component page3
```

コンポーネントはAppModuleから自動でロードされるので、Routesにオブジェクトを追加して、ルーティング情報を追加します。

```ts:src/app/app.module.ts
const appRoutes: Routes = [
  { path: '', component: Page1Component },
  { path: 'page1', component: Page1Component },
  { path: 'page2', component: Page2Component },
  // New!
  { path: 'page3', component: Page3Component },
];
```
これだけで localhost:4200/page3 にアクセスできるようになります。素晴らしい。

##### ハッシュベースのルーティング

デフォルトでハッシュではなくURLベースのルーティングを使っています。ハッシュベースのルーティングが好みなら、下記のように書き換えればOKです。

```ts:src/app/app.module.ts
    RouterModule.forRoot(appRoutes, { useHash: true })
```

### HTTPリクエストサービス
オフィシャルのドキュメントに従ってRxJSを採用しています。
/app/app-api.service.ts がサービス本体になっており、AppApiService内のgetHNTops()とgetHNItem()の2メソッドは挙動を確認するためのサンプルなので、基本的に消す必要があるかと思います。また、page1.component.ts のコントローラにてこのサービスを利用しているコードが入っているので、削除する必要があるかと思います。

ここではちょっとオリジナリティのあるコードを書いています。HTTPリクエスト周りとか外部リソースに依存するコードは、ちゃんと動いているやつを修正していった方が楽なんじゃないかと思ったのでカッとなってやった。

### AppService
デフォルトでTitleタグを変更してくれているAppService。
/app/app.service.ts が本体です。Angular(1)にはデフォルトであったいわゆるrootScope的な、全体に関わる状態保持やメソッドを持たせようと思って作っています。

### BootstrapとSass
そもそもプロジェクトがSassを使うように設定されているので、Scssとか他を使うのはちょっとめんどくさいことになるかもしれないです。Sass書けばいいんじゃないかな。
Bootstrapに深いこだわりがあるわけではないです。ないからBootstrapを使う。Material Design Liteはクラス名が長くて好きじゃない。
/styles.sass に一般的によく使うbootstrapのsass変数を置いてあります。いじるだけで結構戦えると思う。

### GAタグとか細かいとこ
どうせやるんだから準備しておきました。

### デプロイ

```
ng build
```
で、生成されたdistディレクトリの中身をアップロードしましょう。

デプロイの際には、存在しないリソースにアクセスした際に404ではなくindex.htmlを返すようにサーバを設定するといいでしょう。
TODOマークを使って実装忘れ防止

# はじめに
　個人的に一旦中身が空のメソッドだけを作って実装を後回しにしようということがよくあり、コメントでその旨を書いて残したりはするのですが、そのことすら忘れてしまったりすることがあります。

　そこでXcodeを用いた開発において**TODO**や、**FIXME**など書いたところがあると警告が出るように設定し、常に見える化する方法を実践します。

# 方法
1. プロジェクトナビゲーターの中からプロジェクトを選択します。
2. **TARGETS**の中の**Build Phases**を選択し、**+**を選択します。
3. **New Run Script Phase**を選択し、

<img width="720" alt="buildphaze.png" src="https://qiita-image-store.s3.amazonaws.com/0/104400/90fbaf1e-6635-c6cd-acb1-e37b059bde54.png">


```
TAGS="TODO:|FIXME:"
echo "searching ${SRCROOT} for ${TAGS}"
find "${SRCROOT}" \( -name "*.swift" \) -print0 | xargs -0 egrep --with-filename --line-number --only-matching "($TAGS).*\$" | perl -p -e "s/($TAGS)/ warning: \$1/"

```
例えば、`TODO:`と`FIXME:`を対象とするためには上のような**build script**を貼り付けます。

<img width="533" alt="buildscript.png" src="https://qiita-image-store.s3.amazonaws.com/0/104400/8e98fd34-7a4f-2bcc-5cf9-c68bc56bdc1b.png">
のようになります。

例えば、
<img width="620" alt="スクリーンショット 2017-03-10 19.01.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/104400/b0416796-8a43-9f9d-1ab0-e8e85a72eb7b.png">

というコードがあれば、
<img width="1433" alt="スクリーンショット 2017-03-10 19.05.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/104400/01de079d-79a7-56bd-d779-8def12f7eb12.png">

というように`TODO:`のあとに続く文字列が題名となって警告を出すことに成功しました。
(ただし、１度ビルドする必要がある。)
cakephp3 updateを禁止したい(insert限定)

## 課題

CakePHPは ```save()``` でインサートもアップデートも行います。
エンティティのidがあれば、インサート、なければアップデートが行われます。

~~ログ~~やプロセス、ステータスなどを記録する機能で、インサートのみを期待するDB:テーブルに対して、例えばボタンの連打などによる、"連続save"でアップデートが発生していました。

[03/11 追記]
例えばアクセスログなどの場合、重複したデータのログをとることは出来ないので、適していないというご指摘をうけました。その通りです。ご注意くださいませ。

## 解決策

1.　DB側で制約を設ける([ARCHIVEストレージエンジン](https://dev.mysql.com/doc/refman/5.6/ja/archive-storage-engine.html)/複合ユニークキー)

- ARCHIVEストレージエンジン良いけどインデックス欲しいしなー。使ったこと無いし心配...。
- cakeの仕様にあわせるためにDB構造いじるって...!?
- かなりレコードがたまるテーブルでidとcreatedの複合ユニークって大丈夫？

2.　save時に$entity->idがあるかどうか確かめる

- saveしている全箇所修正か...。

3.　cakeのテーブル or エンティティで共通で処理する 

- :point_up:これができればベスト

## テーブル or エンティティで共通で処理する

### アプリケーションルール

cakeのテーブルファイルで実装できる [buildRules](https://book.cakephp.org/3.0/ja/orm/validation.html) メソッドは、save前にバリデーションをかけることができます。

アップデート処理時のバリデートを常にfalseを返すようにしてみる

```php
    /*
     * @param \Cake\ORM\RulesChecker $rules The rules object to be modified.
     * @return \Cake\ORM\RulesChecker
     */
    public function buildRules(RulesChecker $rules)
    {
        $rules->addUpdate(function($entity, $options) {
            return false;
        }, 'ruleName');
        return $rules;
    }
```

うまくいきました！



※下記失敗例

```php
    /*
     * @param \Cake\ORM\RulesChecker $rules The rules object to be modified.
     * @return \Cake\ORM\RulesChecker
     */
    public function buildRules(RulesChecker $rules)
    {
        $rules->add($rules->isUnique(['id']));
        return $rules;
    }
```

:point_up:これはうまくいきませんでした。そもそもidはprimary_keyとしてユニークがかかっているわけだし...

## 謝辞

本件は、 slack の cakephp公式チームの japaneseチャンネルにて、
相談させて頂いたものをまとめたものです。
この場を借りて改めてお礼申し上げます。
@chinpei215 さん、@icchii さんありがとうございます！！

[CakePHP公式の日本語話者向けSlackチャンネル開設のご案内]
http://qiita.com/chinpei215/items/3c116171c5308365c314
Google Cloud FunctionsでPythonを使ってみる

Public Betaになりましたが、Pythonのサポートはまだのようなので無理やり使ってみます。

# 準備

Node.jsは書いたことないのですが、ググってこんな感じに書いてみました。

```js:index.js
const spawnSync = require('child_process').spawnSync;

exports.helloWorld = function helloWorld(req, res) {
  
  result = spawnSync('python', ['./inspect.py'], {
    stdio: 'pipe',
  });
  
  if (result.stdout){
    res.status(200).send(result.stdout);
  }else if (result.stderr){
    res.status(200).send(result.stderr);
  }
};
```

```py:inspect.py
print('hello functions!')
```

この２つのファイルをZipで圧縮し、Cloud FunctionsのConsole画面でアップロードします。

<img width="506" alt="Cloud_Functions_-_Test_fx_lab.png" src="https://qiita-image-store.s3.amazonaws.com/0/162369/ee612941-d4e6-2d8e-741c-1bb8c44af6f3.png">

これでdeployは完了、HTTP Triggerなので記載のURLをブラウザで開けばPythonが出力 'hello functions!'が表示されます。

# Python環境
Pythonを使えることがわかったので、もうちょっと詳細を調べてみます。

```py:inspect.py
try:
    import tensorflow as tf
    print('tensorflow %s' % tf.__version__)
except:
    print('tensorflow n/a')

try:
    import sklearn
    print('sklearn %s' % sklearn.__version__)
except:
    print('sklearn n/a')

try:
    import numpy as np
    print('numpy %s' % np.__version__)
except:
    print('numpy n/a')

try:
    import scipy as sp
    print('scipy %s' % sp.__version__)
except:
    print('scipy n/a')
```
とりあえず気になったライブラリの有無を列挙。　・・・**全滅でした**
3rd-party libは準備されていないようです。

他ざっと調べた内容

|||
|---|---|
| **Python version** | 2.7.9 |
| **OS** | Debian系 8.7 |
| **pip** | N/A |
| **easy_install** | N/A |
| **File System** | read only |

File Systemがread onlyなので、実行時に何かをインストールして使うのは無理そうです。
ですがdeploy時のZipに含まれるファイル形式に制限はなさそうなので、
バイナリなど予め入れておけば実行できそうです。

## 参考
GooglerがGoで同じことをやっています。そちらの方が参考になるかも。
https://github.com/kelseyhightower/google-cloud-functions-go

# 最後に
Pythonを使うのは現状かなり手間ですが、通常通りNode.jsを使うぶんには非常に簡便に機能を実行できる環境だと思います。Console上でサクッと書いて、すぐにdeployできるのはとても魅力です。
Grails 3.2でプロキシーごしにcreate-appする

# 事象 

Grails 2.3以来、久々にGrailsをダウンロードして使ってみようとしたら、create-appしたときにjava.net.UnknownHostExceptionが出てしまいました。

```
C:\Users\YOURNAME\Git\sample>grails create-app sample --stacktrace
| Error Error occurred running Grails CLI: repo.grails.org
 (NOTE: Stack trace has been filtered. Use --verbose to see entire trace.)
java.net.UnknownHostException: repo.grails.org
        at org.apache.http.impl.conn.SystemDefaultDnsResolver.resolve(SystemDefaultDnsResolver.java:45)
        ・・・・
```

# 対処

Grails 3あたりから、プロキシーの設定やら扱いがいろいろ変わったっぽい。

とりあえず、Windowsの環境変数の設定にて、システム環境変数 JAVA_OPTSに

```
-D"proxyHost=proxy.sample.example.co.jp" -D"proxyPort=8080"
```

を追加すれば解決しました。

別解としては、mavenの設定で `MAVEN_HOME/.m2/settings.xml` に設定追加したりとか `GRAILS_HOME/bin/grails.bat` に環境変数入れるとか、いろいろあるとは思いますが、上記が一番楽な気がします。
Jupyterで複数カーネルを簡単に選択するための設定

# はじめに
　最近になって，Anacondaで仮想環境を作成して用途に合わせた環境でコーディングするようになりました。その中で、所有しているPCのうち、なぜか一台だけは何の設定をしなくてもJupyter Notebookからカーネルを選択できたのですが、それ以外のPCでは設定無しではカーネルを選択することができませんでした。（おそらくAnacondaのバージョンの問題。）
　そこで、カーネルをJupyter Notebookから選択することができるようにするために、ネット上で色々と調べてみました。しかしながら、私の環境では、（Windowsだからか）[追加のパッケージ](http://github.com/Cadair/jupyter_environment_kernels)を入れてもうまくいかなかったり、コマンドの情報が古かったりしたので、自分用にまとめておきます。
　この設定をすることで、次のように一瞬でカーネルを変更できるようになります！
![jupyter_disp.png](https://qiita-image-store.s3.amazonaws.com/0/146858/7f5ec125-e285-d435-9ad2-5031e2141dc8.png)

# 実行環境
- Windows 10（64bit）
- Anaconda 4.3.0（64bit）

# 設定手順
## 仮想環境の作成
　condaを使うことで、簡単に仮想環境を作成することができます。今回は、jupyterを使うことを前提としているので、この仮想環境の作成時に同時にjupyterもインストールしておきます。

```shell-session:create_env
# 仮想環境の作成、jupyterもインストール
$ conda create --name=test python=python3.6 jupyter
# 仮想環境ができたかの確認、リストに表示されていれば成功
$ conda info -e
```

pythonのバージョンや--name=<名前>は、自分の環境に合わせて適当なものを入力してください。

## 仮想環境のカーネルをjupyterに追加
　この段階では、まだカーネルは追加されていないと思います。ここで、次のコマンドを実行してみてください。

```shell-session:check_kernel
# 利用可能なカーネルの表示
$ jupyter kernelspec list
```

ここに、先ほど追加した仮想環境のカーネルを追加します。仮想環境をアクティベートした状態で次のコマンドを実行します。

```shell-session:install_kernel
# 仮想環境をアクティベート
$ activate test
# カーネルを追加
$ ipython kernel install --user --name=test --display-name=test
```

以上で、Jupyter Notebook上でカーネルの切り替えや選択をすることができるようになっています。

最後に、カーネルを追加するときの主要なオプションについて、まとめておきます。

| オプション | 役割 |
|:-:|:-:|
| -h, --help | オプションに関するヘルプを表示  |
| --user | 現在ログイン中のユーザーにインストール  |
| --name NAME | カーネルスペックの名前を指定<br>複数のIPythonカーネルを指定するときには**必須** |
| --display-name DISPLAY_NAME | 表示されるカーネルの名前を指定  |

# 追加したカーネルを削除する方法
　追加したカーネルの情報は、--userオプションを付けていた場合、~\AppData\Roaming\jupyter\kernelsの中に置かれています。ここにある--nameで指定した名前のフォルダを削除することで追加したカーネルを削除することができます。

また、以下のコマンドでカーネルを削除することができます。

```shell-session:uninstall_kernel
# カーネルを削除
$ jupyter kernelspec uninstall test
```

# 参考
1. [stack overflow - Using both Python 2.x and Python 3.x in IPython Notebook
](http://stackoverflow.com/questions/30492623/using-both-python-2-x-and-python-3-x-in-ipython-notebook)
2. [Jupyter で、Anaconda 2 と Anaconda 3 を共存 + おまけ(Julia)](http://qiita.com/utahkaA/items/ae14623ae81f85bea4f5)
3. [Condaで作ってる仮想環境の切り替えをJupyter上で簡単に行う方法](http://qiita.com/yoppe/items/38005f415a5b8b884c7d)
DockerイメージをGitLab CI上で作るまでに困った話

# 悩み
ある日、DockerイメージをGitLab CIで作ろうとしました。
よーし、こうしよう(以下に示す`.gitlab-ci.yml`は例です。<strike>いつもの癖で`""`が多いのは許して下さい。</strike>)

```yaml
stages:
  - build
  - docker
build:
  image: ubuntu
  stage: build
  script:
    - echo some build tasks here
  artifacts:
    paths:
      - "result.file"
docker:
  image: docker
  stage: docker
  script:
    - "sh -c \"$DOCKER_LOGIN_COMMAND\" > /dev/null"
    - "docker build -t a-docker-image ."
    - "docker push a-docker-image"
```

失敗しちゃうんですね
じゃあこうだ

```yaml
stages:
  - build
  - docker
build:
  image: ubuntu
  stage: build
  script:
    - echo some build tasks here
  artifacts:
    paths:
      - "result.file"
docker:
  image: docker
  stage: docker
  script:
    - service docker start
    - "sh -c \"$DOCKER_LOGIN_COMMAND\" > /dev/null"
    - "docker build -t a-docker-image ."
    - "docker push a-docker-image"
```

これでも駄目
あれれー?
じゃあこうだろ?

```yaml
stages:
  - build
  - docker
build:
  image: ubuntu
  stage: build
  script:
    - echo some build tasks here
  artifacts:
    paths:
      - "result.file"
docker:
  image: ubuntu
  stage: docker
  script:
    - "apt update ; apt -y install apt-transport-https ca-certificates curl"
    - "curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -"
    - "sudo add-apt-repository \"deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable\""
    - "apt update ; apt-get -y install docker-ce"
    - service docker start
    - "sh -c \"$DOCKER_LOGIN_COMMAND\" > /dev/null"
    - "docker build -t a-docker-image ."
    - "docker push a-docker-image"
```

違うんですね。
じゃあ[StackOverflow](http://ja.stackoverflow.com)で聞いてこよう

![image](https://qiita-image-store.s3.amazonaws.com/0/111609/b94722a3-4753-bcbf-536a-804407bb0b11.png)

ここまで来ました。もう投稿ボタンポチで終わりです。
でも、一応ググってみよう、と。

# あった

**あ　っ　た**
しかも`docs.gitlab.com`にあったじゃないですかーヤーダー

そう、[これ](https://docs.gitlab.com/ce/ci/docker/using_docker_build.html)。
じゃあどうするのか

# じゃあどうするの?
先に答えを示します。

```yaml
stages:
  - build
  - docker
# 追加行 始め
variables:
  DOCKER_DRIVER: overlay
services:
  - docker:dind
# 追加行 終わり
build:
  image: ubuntu
  stage: build
  script:
    - echo some build tasks here
  artifacts:
    paths:
      - "result.file"
docker:
  image: docker
  stage: docker
  script:
    - "sh -c \"$DOCKER_LOGIN_COMMAND\" > /dev/null"
    - "docker build -t a-docker-image ."
    - "docker push a-docker-image"
```

あーやっとできた

コメント除いて4行で良いんです。
`DOCKER_DRIVER=overlay`の環境変数と、`docker:dind`というDockerイメージが提供しているサービスを使うよう宣言すれば`docker build`できる、という訳です。

# 最後に
このやり方に到達するまで数時間かかりました。
ググるって大事ですね
print()やNSLogを書かずにconsoleにメッセージを出力する方法

## はじめに

　デバッグ時に変数の中身を確認するなどよく`print()`や`NSLog()`を使っていましたが、大量に書くことによってコードがぐちゃぐちゃになってしまったり、あとで消し忘れてしまうことがよくありました。

　どうやらBreakpointの設定によって起動したアプリを一時させることなく、表示したいものを**console**に流し込める方法を知ったのでここに書きます。

## 手順

1. Consoleにメッセージを出したいところの行にBreakpointを置きます。
2. Breakpointにおいて右クリックし、**Edit Breakpoint**を選びます。
    <img width="345" alt="スクリーンショット 2017-03-10 17.52.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/104400/6c629452-0507-8a7c-61ed-ec83c092f171.png">

3. 次のように設定します。
    4. Actionの欄で**Log Message**を選びます。
    5. text fieldに出力したい文字列を入力します。
    6. **Log message to console**を選択します。
    7. アプリをstopさせないために**Automatically continue after evaluating actions**にチェックします。

<img width="497" alt="スクリーンショット 2017-03-10 17.53.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/104400/418fdc4f-17f0-0698-a536-643224aa4bda.png">

このような文字列が結果として表示されます。

<img width="905" alt="スクリーンショット 2017-03-10 17.54.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/104400/0e9efd9c-94e2-456e-653e-cb7105057a23.png">

- **%B**はBreakpointが置かれているメソッド
- **%H**はそのBreakpointを通った回数

### 動的な値をLogに出力

しかし、この方法では、静的な値しか表示できません。
変数を表示したい場合などでは大変不便です。

そのような時は次のように設定します。
1. Actionの欄で**Debugger Command**を選びます。
2. text fieldに`expression`キーワードを入れてから`print()`や`NSLog()`が後に続く形で書きます。
    ※右にある**+**をクリックすることで複数のアクションを追加可能です。
<img width="457" alt="スクリーンショット 2017-03-10 18.18.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/104400/6bd6e49c-511c-d58f-aa42-701f61820f34.png">

結果はこうなります。
<img width="604" alt="スクリーンショット 2017-03-10 18.24.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/104400/c838f330-c9a6-77a4-8dda-7a337fd130ae.png">

動的な値が表示されていますね。

## まとめ
今回の方法は逆に面倒くさく感じるといる方もいるかもしれません。
しかし、`print()`、`NSLog()`の消し忘れやコードの見通しを考えると作業効率を上げてくれると考えられます。

まだまだXcodeには知らないでいると損する機能があって、Xcodeのポテンシャルを発揮できていないような気がします。
また何か発見できればシェアできればと思います。
TensorFlowのiOSデモをビルドする


この記事を参考にインストールを進めたのですが、途中でハマってしまったので、微妙に手順を変えてみました。前半部分は参考記事と同じです。

http://qiita.com/shu223/items/ce190ea6669b2636a8a7

まずはbrewで必要なものを追加しときます。

```
brew instal automake libtools
```

続けて参考記事の通りに実行。

```
cd tensorflow/tensorflow/contrib/makefile
./download_dependencies.sh
cd downloads/protobuf/
./autogen.sh
./configure
make
sudo make install
```

compile_ios_tensorflow.shでどうしてもエラーが出るので、代わりにこちらを実行（ほとんど当てずっぽうです…）。ものすごく時間がかかりましたが、無事に終わった模様。

```
cd ../../
./build_all_ios.sh 
```

学習済みのモデルをゲットします。

```
cd ../ios_examples/camera/data/
curl -O https://storage.googleapis.com/download.tensorflow.org/models/inception5h.zip
unzip inception5h.zip
```

あとはXcodeを起動して、ビルド（インストール）するだけ。


![IMG_2069.jpg](https://qiita-image-store.s3.amazonaws.com/0/50780/f0aa7f68-d8c7-b818-9b88-ef4787e52b5b.jpeg "IMG_2069.jpg")

考察とかも元の記事の方が充実してますので、再びこちらをどうぞ。

http://qiita.com/shu223/items/ce190ea6669b2636a8a7
プロセス置換とファイルディスクリプタのリダイレクトでコマンドに逐次入力を流す話

たとえば [`jo`](https://github.com/jpmens/jo)で。

```bash:a.sh
#!/bin/bash

exec {fd}> >(jo > a.json)
trap 'exec {fd}>&-' EXIT

echo a=1 >&${fd}
sleep 1
echo b=2 >&${fd}

echo hoge
echo c=3 >&${fd}

whoami
```

実行すると、１秒sleepしたあとこんな感じで出力される。

```txt:stdout
hoge
kuryu
```

```json:a.json
{"a":1,"b":2,"c":3}
```

# 参考

プロセス置換
http://sechiro.hatenablog.com/entry/2013/08/15/bash%E3%81%AE%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9%E7%BD%AE%E6%8F%9B%E6%A9%9F%E8%83%BD%E3%82%92%E6%B4%BB%E7%94%A8%E3%81%97%E3%81%A6%E3%80%81%E3%82%B7%E3%82%A7%E3%83%AB%E4%BD%9C%E6%A5%AD%E3%82%84%E3%82%B9

リダイレクト
http://d.hatena.ne.jp/atneck/20120727/1343386906
UIAlertControllerのActionSheetの上にビューを追加する

完成イメージは以下の通り。

![ope.gif](https://qiita-image-store.s3.amazonaws.com/0/84917/e84091f8-054a-876e-6efb-ef91042c670a.gif)

参考: http://stackoverflow.com/questions/32790207/uialertcontroller-add-custom-views-to-actionsheet

# 実現方法
`UIAlertController`は`UIViewController`を継承しているので、`view`プロパティを持っています。
そのため、`view`に任意のビューを追加することができます。
今回は以下のような`UIAlertController`を継承したクラスを作りました。

```swift
import Foundation
import UIKit

class MyAlertController: UIAlertController {
    
    public var customView: UIView?
    public var customViewMarginBottom: CGFloat = 16
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        guard let customView = self.customView else {
            return
        }
        
        customView.frame.origin.y = -customView.frame.height - self.customViewMarginBottom
        self.view.addSubview(customView)
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        
        guard let customView = self.customView else {
            return
        }
        
        UIView.animate(withDuration: 0.1) {
            customView.alpha = 0
        }
    }
}
```

## ポイント1: `customView`の`frame.origin.y`をマイナスにする
`UIAlertController`の`view`のフレームは、タイトルが表示されているブロックの左上が(0, 0)となっています。今回はもっと上にビューを表示したいので、追加するビューのy座標をマイナスにしたうえで追加します。
`view`の`clipsToBounds`は`false`のままにしておいてください。

## ポイント2: `viewWillDisappear`に`customView`のアニメーションを追加する
`view`にビューを追加するだけで、表示されるときはいい感じにアニメーションしてくれます。
しかし、y座標をマイナスにしているため、消えるときは`customView`だけが取り残されたようなアニメーションになってしまいます。
そのため、`customView`を透明にするアニメーションを`viewWillDisappear`に書いてやります。

# 使う
追加したいビューを用意し、`MyAlertController`の`customView`に突っ込んでやるだけです。
ビューの幅をActionSheetと同じくらいにしたいときは、試した限りでは`x`を`0`、`width`を`self.view.frame.width-20`にしたらいい感じになりました。

```swift
...
    @IBAction func showSheet(_ sender: Any) {
        
        let view = UIView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width-20, height: 100))
        view.backgroundColor = .green
        
        let label = UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 30))
        label.backgroundColor = .orange
        label.text = "custom view"
        label.textColor = .white
        label.textAlignment = .center
        view.addSubview(label)
        
        let alert = MyAlertController(
            title          : "ほげ",
            message        : "ふが",
            preferredStyle : .actionSheet
        )
        alert.addAction(UIAlertAction(
            title   : "へい",
            style   : .default,
            handler : nil
        ))
        alert.addAction(UIAlertAction(
            title   : "へい",
            style   : .destructive,
            handler : nil
        ))
        alert.addAction(UIAlertAction(
            title   : "へい",
            style   : .cancel,
            handler : nil
        ))
        alert.customView = view
        self.present(alert, animated: true, completion: nil)
    }
...
```
docker toolboxのバージョンを17にするためにやったこと

どうやら、dockerのバージョンが17になったらしくそれに伴い、docker-toolboxも17が出たみたい。


17は色々変わった関係でdocker-machineのVMも入れ直した。

# インストールする

https://github.com/docker/toolbox/releases
からDLして入れる。virtualboxも入れ直したほうが良さそうなので、インストール時にはチェックを入れた。

# いま起動しているdocker-machine VMを消す

```
$ docker-machine stop default
$ docker-machine rm default
```

これでdefaultのVMが消える。

# docker-machine VMを新しく作る

```
$ docker-machine create default
```

怒られた。どうやらネットワークの設定がvirtualboxに残っているからエラーになる。
再起動することに。

再起動しても上手く行かなかったので、一度VirtualBoxのアンインストールし、現時点で最新だった5.1.16を入れました。

```
docker-machine create default
Running pre-create checks...
Creating machine...
(default) Copying C:\Users\username\.docker\machine\cache\boot2docker.iso to C:\Users\username\.docker\machine\machines\default\boot2docker.iso...
(default) Creating VirtualBox VM...
(default) Creating SSH key...
(default) Starting the VM...
(default) Check network to re-create if needed...
(default) Windows might ask for the permission to create a network adapter. Sometimes, such confirmation window is minimized in the taskbar.
(default) Found a new host-only adapter: "VirtualBox Host-Only Ethernet Adapter #2"
(default) Windows might ask for the permission to configure a network adapter. Sometimes, such confirmation window is minimized in the taskbar.
(default) Waiting for an IP...
Waiting for machine to be running, this may take a few minutes...
Detecting operating system of created instance...
Waiting for SSH to be available...
Detecting the provisioner...
Provisioning with boot2docker...
Copying certs to the local machine directory...
Copying certs to the remote machine...
Setting Docker configuration on the remote daemon...
Checking connection to Docker...
Docker is up and running!
To see how to connect your Docker Client to the Docker Engine running on this virtual machine, run: docker-machine env default
```

どうやらうまくいきました。

# docker-composeが動くか確認

```
$ @FOR /f "tokens=*" %i IN ('docker-machine env') DO @%i
$ docker-compose up -d
```

やってみると、docker-compose.ymlの書き方によってはエラーになるみたいです。
特にマウントで失敗します。マウント先がうまくいかないみたいです。

対象の問題はこのissueが建てられています。
https://github.com/docker/compose/issues/4039


# 再挑戦する

「docker toolbox 再インストール」でぐぐったら以下のサイトが出てきたので以下のサイトにある程度従うことにした。

http://acchi-muite-hoi.hatenablog.com/entry/2016/06/20/042002

geekで消して、`.virtualbox`フォルダや`.docker`フォルダも削除した。system32/driverのほうも削除した。

ただレジストリまでは消さなかった。

そして再起動して、再インストールしたら上手くいった。インストール編はNDIS5のチェックボックス以外は通常インストールした。細々したことはやってない。
どうやらdocker toolboxのアップデートは大変みたい。
Excelでセルに入力した条件でデータを検索する

業務でよく使うのでシェア。
1行目を検索欄として、入力した条件に一致したデータを抽出します。
一覧表やクエリテーブルでもアレンジ可能です。

VBAエディタ→シートに以下を貼り付け

```テストデータ.xlsx
'セル変更時
Private Sub Worksheet_Change(ByVal Target As Range)
    '1行目に入力された内容を元にオートフィルタをかける
    '複数セルが編集されている1行目のＡ～Ｋ列以外は対象外
        If Target.Count > 1 Then Exit Sub
        If Target.Row <> 1 Or Target.Column > 11 Then Exit Sub
        
        If Target.Value = "" Then
            '空白だったらその列の条件を"すべて"にする
            Range("A5").AutoFilter Field:=Target.Column
            
            ElseIf VarType(Target.Value) = vbString Then
                '空白じゃなかったら部分一致（文字の場合）
                Range("A5").AutoFilter Field:=Target.Column, Criteria1:="=*" & Target.Value & "*"
            ElseIf VarType(Target.Value) = vbDouble Then
                '空白じゃなかったら完全一致(数値の場合)
                Range("A5").AutoFilter Field:=Target.Column, Criteria1:="=" & Target.Value
            Else
        End If
End Sub

```

こんな表があったとして、
※架空の個人情報です
![1.PNG](https://qiita-image-store.s3.amazonaws.com/0/54890/c6666c4d-3eb6-245d-1cb5-74ab32072212.png)

１行目に文字を入力すると一瞬で抽出します。
![キャプチャ2.PNG](https://qiita-image-store.s3.amazonaws.com/0/54890/af62c6f7-48be-dbae-c156-a5e66a672fc6.png)

もちろん複数条件にも対応しています。
![キャプチャ3.PNG](https://qiita-image-store.s3.amazonaws.com/0/54890/b5edfeb5-6d19-dcf0-3f25-0527fa1b93b6.png)
Azure を利用するときに気をつけること

# 概要

個人的にいくつか気になったのでまとめておく

# まとめ

## shutdown と、仮想マシンの停止

仮想マシン上で

```
shutdown -h now
```

しただけでは、まだ課金対象。

仮想マシンの「停止」を行う必要がある

## azure vm stop と deallocate

```
azure vm stop
```

だけだと、マシンは、まだリソースを専有している状態のようなので

```
azure vm deallocate
```

して、はじめて、料金がかからないようになるようだ。

## portalのウェブについて

* 選択肢が表示されない
* 突然なにかの操作ができなくなる。ボタンがおせないとか

### 3rd party クッキーを使っている？

途中までうまくいくが、途中からメニューがでてこない。気づきにくい

#### 対処方法

ブラウザを変える

### Javascriptのエラーがでているときがある

Javascriptのエラーがでても、わかりにくいときがある。通知で、できない操作があることがわかることもあるが、突然何かができなくなる。

#### 対処方法

リロード

## portalから仮想マシンを削除しても、ディスクは残る

portal から、仮想マシンを消しても
ディスクは残る。

これは改めて、
* ストレージアカウント->コンテナ->対象のディスク
を削除する必要がある
[EXCEL]絞り込み中のテーブルを行削除をしようとしたら実行時エラー1004が出たので対策

## やりたいこと
テーブルをフィルタして表示されているレコードを削除する。
これをVBAで実行する。

■サンプルのテーブル
![1.png](https://qiita-image-store.s3.amazonaws.com/0/97601/3caf2232-3ade-28ac-188c-1c262e7a7cf1.png)

このテーブルを鈴木で絞り込んで行削除したい。

![2.png](https://qiita-image-store.s3.amazonaws.com/0/97601/68a8f63a-56ff-aa73-a263-f5ea1e84ad14.png)




## やったこと
下記コードを実行してみた。※エラー処理は除いてます。

```js:sample
Sub sample()
    Dim tb As ListObject
    Set tb = ListObjects("テーブル1")
    tb.Range.AutoFilter Field:=2, Criteria1:="鈴木"
    tb.DataBodyRange.SpecialCells(xlCellTypeVisible).EntireRow.Delete
End Sub
```


そうしたところ、Delete時に1004実行時エラーが発生することがあった。
発生する条件を調べたところ、鈴木で絞り込んで実行するとエラーが出て、佐藤で絞り込んで実行するとエラーが出ないことが分かったのでそこから原因を探った。

## 原因（たぶん）
削除する範囲が離れているとエラーが出るっぽい。
`tb.DataBodyRange.SpecialCells(xlCellTypeVisible).EntireRow`のAddressを見てみると鈴木の場合は`"$2:$2,$4:$4,$7:$7"`になっていた。
佐藤の場合は`"$5:$6"`になっていた。

手で行削除するときにもこの挙動が見られるのでそういうことなんだろうなと解釈。

↓鈴木の行を複数選択すると削除できない。
![4.png](https://qiita-image-store.s3.amazonaws.com/0/97601/bb8c8592-7a99-55e2-3cce-fcec188a16b8.png)

↓佐藤の行をまとめて複数選択すると削除できる。
![5.png](https://qiita-image-store.s3.amazonaws.com/0/97601/f41c3bb9-9baa-8d74-179c-1079bb7cf1d6.png)


## 対応
行を指定すると失敗するが、セルを選択すると範囲が離れていても削除できるみたい。

↓鈴木のセルだけ選択。
![6.png](https://qiita-image-store.s3.amazonaws.com/0/97601/6c9279f3-3d03-1b5a-b9a7-4d663807538b.png)


というこで、セル選択にするためEntireRowを除外。
また「行全体を削除しますか」というダイアログがでるので表示されないように前後でApplication.DisplayAlertsを変更させる。

これで落ち着いた。

```js:sample
Sub sample()
    Dim tb As ListObject
    Set tb = ListObjects("テーブル1")
    tb.Range.AutoFilter Field:=2, Criteria1:="鈴木"
    Application.DisplayAlerts = False
    tb.DataBodyRange.SpecialCells(xlCellTypeVisible).Delete
    Application.DisplayAlerts = True
End Sub
```
シェルスクリプトで、現状の標準入力を全て受け取ってから再度標準入力受付状態に戻す

シェルスクリプトで、標準入力を開きっぱなしにしていると、標準入力を取得するところで停止してしまい次のコードへ進まない。標準入力を閉じれば進むが、閉じたくない。
readを使用すると、改行コードなどがない場合にデータが取れない。
そんな状況になったので、解決方法を探してみた。

## テスト実行

```bash:入力待ち１
nc -l 6666 | while read -r line  ; do cat - ; echo next ;done
```

```bash:入力待ち２
nc -l 6666 | while read -r line  ; do echo "${line}" test ;done
```

```bash:データ送信
curl 'http://127.0.0.1:6666' --data 'aaa&bbb'
```

```bash:結果１
Host: 127.0.0.1:6666
User-Agent: curl/7.51.0
Accept: */*
Content-Length: 7
Content-Type: application/x-www-form-urlencoded

aaa&bbb
```

```bash:結果２
 test/ HTTP/1.1
 test 127.0.0.1:6666
 testAgent: curl/7.51.0
 testt: */*
 testnt-Length: 7
 testnt-Type: application/x-www-form-urlencoded
 test
```

## 解決案

標準入力を閉じれば、全部のデータが取れて、次のコードへ進める。
しかし閉じたくないのであれば、標準入力を差し替えて止めれば、あるいは。。
それならば、下記のことをすればできるはず。

1. 標準入力を一旦逃して、今ある分を`cat`で標準入力させる
1. `cat`を`kill`する
1. 標準入力を取得すると、最初に`cat`されたものが取得でき、入力が閉じているので、次のコードへ進む
1. 最初に逃した標準入力を標準入力に戻す

### コード

```bash:in.sh
#!/bin/bash

while read -r line
do
    exec 5>&0 < <(cat -) 2>/dev/null
    while true
    do
        pid=$(ps -o pid --ppid $! --no-header)
        [ "${pid}" ] || continue
        kill ${pid}
        break
    done
    data+=$(cat)
    exec <&5
    echo "##### output #####"
    echo "${data}"
    echo "##### next #####"
done

echo "###### END ########"
```

### 実行と結果

```bash:入力待ち
$ nc -l 6666 | bash in.sh                                                               
```

```bash:データ送信
curl 'http://127.0.0.1:6666' --data 'aaa&bbb'
```

```bash:結果
aa.sh: 5 行:  1266 Terminated              cat -
##### output #####
Host: 127.0.0.1:6666
User-Agent: curl/7.51.0
Accept: */*
Content-Length: 7
Content-Type: application/x-www-form-urlencoded

aaa&bbb
##### next #####
```

なんか動いた！ が、なんだこれｗ
一行目が抜けているけど、これは、最初のexecの直前で別途取ればいいだけ。
あと、一行目のエラーメッセージの消し方は分からなかった。

。。。力技すぎるので、正規のやり方や良いやり方を知ってる方がいたら、教えてください。
この解決策については、ググり方が分からない。。
【VMware】vMotionとvSphere HA, vSphere FTの違い

# vMotionの特徴
- 稼働中の仮想マシンを停止せずに、別の物理サーバーに移行させる機能  
→**計画的なサーバー停止（メンテナンス等）に対応する機能**
- 設定対象：仮想マシン単位
- ダウンタイム：ゼロ  

![vmotion.png](https://qiita-image-store.s3.amazonaws.com/0/168635/63a6fe19-4513-058d-5db2-dc6f5393c114.png)


# vSphere HAの特徴
- 物理サーバーで障害があった時に、自動的に別の物理サーバーで稼働させる機能  
→**非計画的な障害に対して、可用性を確保する機能**
- 障害が発生し、別の物理サーバーで起動するまでに数分時間がかかる（＝数分サービスが停止）
- 物理マシンに障害が発生した際に、クラスタ内の別ホスト（別の物理マシン）に仮想マシンが移動します（※再起動発生）！（安全地帯へ避難）
- 設定対象：クラスタ単位
- ダウンタイム：数分  

![vm_ha.png](https://qiita-image-store.s3.amazonaws.com/0/168635/40dbca0e-fc5d-3279-8240-f19c2e06f030.png)



# vSphere FTの特徴
- HAに対して、FTは障害が発生しても**サービスの停止をさせず**に、別の物理サーバーで稼働させる機能  
→クラスタ機能を利用して実現（※後述）
- FTを有効にすると、稼働中の仮想マシンがプライマリ、と別の物理サーバーのセカンダリに分けられる  
- クラスタ内の別の物理マシンに、仮想マシンンのセカンダリ（常に同期）を作成し、障害時にはセカンダリに切り替える（影分身の術）
- 設定対象：仮想マシン単位
- ダウンタイム：ゼロ
![vm_ft.png](https://qiita-image-store.s3.amazonaws.com/0/168635/f2118708-4533-5775-d574-bdd0f58c2316.png)


# クラスタとは
- **複数の物理サーバーを論理的にまとめたもの**  
→10台の物理マシンを1台として扱う！など
- クラスタ内での**リソースの共有**が可能  
→リソースが足りない物理サーバーに、リソースが余っている物理サーバーが力を貸す！（チームプレイですね）
![クラスタ.png](https://qiita-image-store.s3.amazonaws.com/0/168635/0c0314e6-146f-af3b-81e4-979ae152c73b.png)


# おわりに
提供するサービスによって、使う機能を検討しましょう！  
似ているようで、異なる3つの機能の紹介でしたー！
上記で使用した画像は、下記URLからいただきました・・・！
https://communities.vmware.com/thread/400678
AWS CLIワンライナー集

#これは何？
よく書式を忘れるのでメモがてらよく使うAWC CLIの書式を纏めています。

#前提条件
下記の権限を持つIAMユーザーのクレデンシャル情報を設定済み、もしくはIAMロールを設定済み

`ec2:DescribeTags`
`ec2:DescribeInstances`

#EC2上で自分の存在するリージョン名を取得

AWS CLIではないけど、以降のコマンドで基本、リージョン情報は必須なので。

## コマンド
```bash
$ curl -s --connect-timeout 2 http://169.254.169.254/latest/meta-data/local-hostname | cut -d'.' -f2
```

## 結果
```
ap-northeast-1
```

# タグで自分のリージョンのプライベートIPの一覧を取得
## コマンド
例：Envタグのバリューがproductionで検索

```bash
$ aws --region $(curl -s --connect-timeout 2 http://169.254.169.254/latest/meta-data/local-hostname | cut -d'.' -f2) ec2 describe-instances --output text --filters "Name=tag:Env,Values=production" --query "Reservations[].Instances[].PrivateIpAddress"
```

## 結果
```
192.0.2.0 192.0.2.1 192.0.2.5 192.0.2.10
```

# 自分のインスタンス名を取得
## コマンド
```bash
$ aws --region ap-northeast-1 ec2 describe-tags --output text --query "Tags[?ResourceId==\`$(curl -s http://169.254.169.254/latest/meta-data/instance-id)\` && Key==\`Name\`].Value" --region $(curl -s --connect-timeout 2 http://169.254.169.254/latest/meta-data/local-hostname | cut -d'.' -f2)
```

## 結果
```
web001
```

# hostsファイル生成
## コマンド
```bash
$ aws --region ap-northeast-1 ec2 describe-instances --output text --query 'Reservations[].Instances[].{Address:PrivateIpAddress, Tags:Tags[?Key==`Name`]}[].{a:Address, h:Tags[0].Value}'
```

# 複数のタグでインスタンスIDの一覧を取得
## コマンド
```bash
$ aws --region ap-northeast-1 --output text  ec2 describe-instances --filter "Name=tag:Group,Values=web" "Name=tag:Env,Values=production" --query "Reservations[].Instances[].InstanceId"
```

## 結果
```
i-11111111111111111111 i-22222222222222222
```
VAIO Z (2016年モデル) にLinux環境を構築したメモ

最近購入したVAIO Z(VJZ131A11N, 2016年モデル)にLinux環境を入れたのでメモ。
VAIO Zは巷ではLinuxインストールでコケることが多いとの噂で、しかもこのモデルはストレージがNVMeになっているので余計にややこしいらしい。

## まず最初にやること

* プリインストールされているWindows10を起動して適当に最低限の設定を済ませ、Windowsアップデートで更新する
* USB回復ドライブを作成する
* [VMWare vCenter Converter](http://www.vmware.com/jp/products/converter.html) でP2V変換をかけて仮想マシンイメージ化しておく（あとからホストのLinux上でゲストとして使うため）

## UEFI設定

* UEFI設定画面を開くにはF3 or F4を押しながら電源on
    * 再起動時にF3 or F4 を押していても成功しないので、一旦電源を落とす必要あり？
* USB Device boot をenable
* Secure Boot をdisable

## ディストリビューション選び

とりあえず Ubuntu 16.04

* あとで動くか試してみる候補
    * Arch Linux
    * Fedora Workstation

## Ubuntu 16.04 LTS をインストール

LiLi USB CreatorでisoからUSBスティックを作成してインストール。
一節には、このVAIO Zではgrubが/dev/nvmeからの起動に対応していないので、systemd-bootを使う必要があるとの説明だったが、Ubuntuのインストーラに言われるがままにインストールしてgrubが使われている状態で、今のところ問題なく起動できている様子。

## GNOME設定

### Caps Lock → Ctrl

[ UbuntuTips/Desktop/HowToSetCapsLockAsCtrl](https://wiki.ubuntulinux.jp/UbuntuTips/Desktop/HowToSetCapsLockAsCtrl) にしたがって下記のコマンドを叩く。

~~~
dconf reset /org/gnome/settings-daemon/plugins/keyboard/active
dconf write /org/gnome/desktop/input-sources/xkb-options "['ctrl:nocaps']"
~~~

## 参考にしたところ

* http://qiita.com/mopp/items/f1912433abbed69f5f99
* https://wiki.archlinuxjp.org/index.php/HiDPI
* https://wiki.ubuntulinux.jp/UbuntuTips/Desktop/HowToSetCapsLockAsCtrl
__getattr__を使ったメソッド呼び出し

### 背景
Twitter APIのライブラリとして https://pypi.python.org/pypi/twitter を使ってるんだけど、メソッド呼び出しが変わってたのでメモ

### Twitterライブラリについて
このライブラリはAPIのURLを直接渡す形式にはなってなくて、APIに対応したメソッドをコールするスタイルになってる。例えば [users/show](https://dev.twitter.com/rest/reference/get/users/show) というAPIであれば、 `twitter.users.show()`というメソッドを使う。  
ちなみに users/show のURLは https://api.twitter.com/1.1/users/show.json?screen_name=twitterdev こんな感じ。 

ただ、このライブラリのTwitterクラス、TwitterCallクラスにはこのメソッドは実装されてなくて、`__getattr__`を駆使してメソッド名からURLを組み立てて、APIを呼び出してる。

### サンプルコード
コード例としてはこんな感じ

```py3
class A(object):
    def __init__(self, cls, urlparts):
        self.callable_cls = cls
        self.urlparts = urlparts 

    def __getattr__(self, k):
        print('called {}'.format(k))
        try:
            return object.__getattr__(self, k)
        except AttributeError:
            def extend_call(args):
                return self.callable_cls(self.callable_cls, self.urlparts + (args,))
            return  extend_call(k)

    def __call__(self, **kwargs):
        return self.urlparts

a = A(A, ())
res = a.users.show()
print(res)
```

これを実行するとタプル`('users', 'show')`が結果として返る。
これからURL https://api.twitter.com/1.1/users/show.json?screen_name=twitterdev を作って、コールしている。

解説をとしては、`a.users`が呼ばれたときに`users`というフィールドもメソッドもないので、`__getattr__`が呼ばれる。その中で`extend_call(users)`が呼ばれて、`self.urlparts`にタプルとして追加される。続いて、a.users.showが呼ばれる、`show`というメソッドはないので、`__getattr__`が呼ばれる。これも`self.urlparts`にタプルとして入る。最終的にメソッドとしてコールされると`__call__`が呼ばれて、`self.urlparts`の中身を返す。

### まとめ
自分ではこういう実装方法を使うことはないと思うけど、メモとして
UnrealEngine スクリーンショットの格納先

# スクリーンショットの格納先
## エディタでスクリーンショットを撮影した際のデフォルトの保存場所

Execute Console Commnadのshotコマンド or F9でスクリーンショットを撮影することができる。
デフォルトでは、全てのスクリーンショットはプロジェクト フォルダの次の場所に保存されます。

Saved\Screenshots\Windows

## パッケージ(Development)化した際の保存場所
Execute Console Commnadのshotコマンド or F9でスクリーンショットを撮影することができる。
＠キーを押すとコマンド入力ができるので、shotを入力すればスクリーンショットを撮影することが出来る
![image](https://qiita-image-store.s3.amazonaws.com/0/111261/ad6315b7-a064-5c79-af34-1c6bc3ddca07.png)

保存先は
実行ファイルのパス/PackScreenshot\Saved\Screenshots\WindowsNoEditor
![image](https://qiita-image-store.s3.amazonaws.com/0/111261/7e9c379f-e1d0-2b50-7196-d7d609433bc0.png)


## パッケージ(Shipping)化した際の保存場所

Execute Console Command のshotコマンドが効かない
Win10のゲームバー機能を利用して、[Windowキー + Alt + PRT SCR]でスクリーンショットを撮影することは出来る
/マイドキュメント/video/キャプチャにスクリーンショットが保存される
![image](https://qiita-image-store.s3.amazonaws.com/0/111261/873d0e8c-b018-5e88-7d79-d3f4f1e8445b.png)


## 参照URL
スクリーンショットの撮り方
https://docs.unrealengine.com/latest/JPN/Engine/Basics/Screenshots/index.html

Unreal Engine 4: save rendered frame to memory
http://stackoverflow.com/questions/33554586/unreal-engine-4-save-rendered-frame-to-memory
既存のAWS IoTアーキテクチャを「大規模なIoTデータ基盤を支えるアーキテクチャ」に変更した結果

# 目次
- ローンチ当初のインフラ構成
- 大規模なデータ基盤を支えるために
- 最後に

## ローンチ当初のインフラ構成

![image.png](https://qiita-image-store.s3.amazonaws.com/0/159589/09fd6b5f-4398-91e6-acb3-1ba6644a28e1.png)

- お客様環境からセンサーデータを秒間数千件送信し、RDBに登録。
- その結果をリアルタイム分析し、お客様PCにてモニタリング
- IoTデバイスのメンテナンスもAWS側から実行(IoTデバイスが定期的にAWS側の更新情報を見に行く)
- 中長期分析にはNoSQLのEC2に分析データを蓄積

--------------------------------------------
## 稼働後の問題
以下のような問題が生じました。

- 秒間数千件以上のリクエストを捌くことが困難になってきた。
- 複数のアプリケーションが同じRDBへのRead/Writeで密結合
- NoSQLサーバのクラスタ構成の運用が難しい


# 大規模なデータ基盤を支えるために
- 以下のような構成に変更しました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/159589/299dde0c-955f-76e1-9377-a3e6a42e5f3b.png)


変更した点は以下になります。
- **センサーデータはRDSではなく、DynamoDBに格納**
- **リアルタイム分析はDBを直接参照せずCacheを参照**(試してはいませんが、DynamoDB Streams x lambdaも使えるかもしれない)
- **統計分析はKinesisCLを入れたEC2が定期的にセンサーデータをS3に送り、S３経由でRedshiftに格納、分析処理を行う。**

--------------------------------------------
## 実際に変更した結果
- 秒間数千件の処理には耐えうることができました。(アプリケーションの制約とはいえ、最初からRDBをチョイスしたことが誤っていました)
- 統計分析のデータ基盤で使用していたNoSQLサーバのクラスタ構成のメンテナンスが非常に難しく、Redshiftに置き換えたことにより、運用負荷が大幅に軽減できそうです。

--------------------------------------------
# 最後に
- 既存のアーキテクチャを変更することはローンチ後は本当に厳しいと思います。(フットワークが軽い開発部隊だと別ですが)
- 要件定義、設計段階で本当にそのアーキテクチャの選択はあっているのか？を早い時点で問いかけてみることが重要だと感じました。
 - 自分たちのスキルセットだけでアーキテクチャを選んでいないか？
 - お客様の(漠然とした構成案に対して)言うがままに作っていないか？など
timestamp is justice! ～サマータイムなんて大嫌い！～


# せっかちな方への結論

サマータイムがある地域の時間計算は、
**タイムスタンプ上で計算した方が安全確実！**

# 問題点と解決案

```php
$pdt = new DateTime('2017-03-12 02:00:00', $timeZone);
$pdtMod = clone $pdt;
$pdtMod->modify("-1 second");
$out = "{$pdtMod->format(DateTime::ISO8601)} : {$pdtMod->getTimestamp()} : {$pdtMod->format('I')}";
var_dump($out);		// -> string(41) "2017-03-12T03:59:59-0700 : 1489316399 : 1"
```

PDTに切り替わった直後に、
DateTime::modify() で1秒引くと、
2017-03-12T01:59:59-0800 になってくれると思いきや、
**2017-03-12T03:59:59-0700 といった感じで、
2017-03-12T04:00:00-0700 から1秒引いた結果になっている！**


…じゃ、どうすんのよ？ってことで↓こうする

```php
$pdtSub = new DateTime("now", $timeZone);        // <- あとでsetTimestamp()をするから、この時点での時間はどうでもいい
$pdtSub->setTimestamp((int)($pdt->getTimestamp() - 1));
$out = "{$pdtSub->format(DateTime::ISO8601)} : {$pdtSub->getTimestamp()} : {$pdtSub->format('I')}";
var_dump($out);		// -> string(41) "2017-03-12T01:59:59-0800 : 1489312799 : 0"
```

( ´ー｀)ﾌｩｰ．．．

# （おまけ）上記を含めたテストコード

```php
$timeZone = new DateTimeZone('America/Los_Angeles');
$pst = new DateTime('2017-03-12 01:59:59', $timeZone);
$out = "{$pst->format(DateTime::ISO8601)} : {$pst->getTimestamp()} : {$pst->format('I')}";
var_dump($out);		// -> string(41) "2017-03-12T01:59:59-0800 : 1489312799 : 0"

$pdt = new DateTime('2017-03-12 02:00:00', $timeZone);
$out = "{$pdt->format(DateTime::ISO8601)} : {$pdt->getTimestamp()} : {$pdt->format('I')}";
var_dump($out);		// -> string(41) "2017-03-12T03:00:00-0700 : 1489312800 : 1"

// modify
$pdtMod = clone $pdt;
$pdtMod->modify("-1 second");
$out = "{$pdtMod->format(DateTime::ISO8601)} : {$pdtMod->getTimestamp()} : {$pdtMod->format('I')}";
var_dump($out);		// -> string(41) "2017-03-12T03:59:59-0700 : 1489316399 : 1"

// sub Timestamp
$pdtSub = new DateTime("now", $timeZone);
$pdtSub->setTimestamp((int)($pdt->getTimestamp() - 1));
$out = "{$pdtSub->format(DateTime::ISO8601)} : {$pdtSub->getTimestamp()} : {$pdtSub->format('I')}";
var_dump($out);		// -> string(41) "2017-03-12T01:59:59-0800 : 1489312799 : 0"

// re modify
$pstMod = clone $pst;
$pstMod->modify("-1 second");
$out = "{$pstMod->format(DateTime::ISO8601)} : {$pstMod->getTimestamp()} : {$pstMod->format('I')}";
var_dump($out);		// -> string(41) "2017-03-12T01:59:58-0800 : 1489312798 : 0"
```