OmniAICreator/Qiita-1.07M huggingface dataset:
python setup.py bdist_egg --exclude-source-files が動かないPython3と対処法

# 背景

egg配布でPythonのソースコードを「含めない」という方法として、`bdist_egg --exclude-source-files`と指定する方法があります。ありました。

例えば次のプロジェクトを例に。

https://github.com/dmiyakawa/python_greeting

`python setup.py bdist_egg --exclude-source-files` を実行するとeggが出来ます。
ただしPython 3系でこのeggをeasy_installしても動作しないのです。
`--exclude-source-files`を指定しなければGreeting!という文字を出すだけのgreetingコマンドが手に入ります。

# 何故

要するに`__pycache__`下のpycだけではPython3のコードは動作しないのです。

以下の、特にPEP 3147と図を御覧ください。

http://stackoverflow.com/questions/11648440/python-does-not-detect-pyc-files/11648547

![image](https://qiita-image-store.s3.amazonaws.com/0/14365/fc949b22-ce56-2a32-3c34-5738865d4dbd.png)

図によれば.pyがあった上で`__pycache__`を引きます。
一方`--exclude-source-files`を指定すると.pyだけ抜けるので、PEP 3147のフローから見ると`ImportError`一直線です。
`__init__.py`相当のものもないのでモジュールとして認識しない( ｰ`дｰ´)

これを理解した上で、setuptoolsのbdist_egg実装をさっと読んでみますと、distutilsのバイトコンパイル機能を使ってるのです。が、これがlegacyオプション対応してない。固定で`__pycache__`にバイトコンパイル結果を突っ込んでしまうようです。`compileall.compile_dir`とか使ってくれてれば簡単な修正で済むんですががが

http://docs.python.jp/3/library/compileall.html

# ワークアラウンド

`bdist_egg --exclude-source-files`によって壊れた状態のeggファイルをzipファイルとして読みこんで、`__pycache__/` 下にいるキャッシュとしてのpycを、レガシーな位置にむりやり引きずり出せば動作するようになります。

以下はPython 3.5.2上での実装例。importは省略。

```py3:tweak_egg.py
RE_PYCACHE_FILE = re.compile('(.+/)__pycache__/(.+)\.cpython-3\d(.pyc)$')

with tempfile.TemporaryDirectory() as tmpdir:
    names_lst = []
    tmpdir_abs_path = os.path.abspath(tmpdir)
    with ZipFile(egg_path, 'r') as zf:
        for name in zf.namelist():
            m = RE_PYCACHE_FILE.match(name)
            if m:
                w_name = m.group(1) + m.group(2) + m.group(3)
            else:
                w_name = name
            w_path = os.path.join(tmpdir_abs_path, w_name)
            dir_path = os.path.dirname(w_path)
            if not os.path.exists(dir_path):
                os.makedirs(dir_path)
            with open(w_path, 'wb') as file_to_write:
                with zf.open(name) as file_to_read:
                    file_to_write.write(file_to_read.read())
            names_lst.append(w_name)
    with ZipFile(egg_path, 'w', compression=ZIP_DEFLATED) as zf:
        for name in names_lst:
            r_path = os.path.join(tmpdir_abs_path, name)
            zf.write(r_path, arcname=name)
```

# おまけ

上のような事実に気づく前に果敢にバグ報告したら、意外なクローズのされ方をされてむしろ驚きました。

https://bugs.python.org/issue28630

setuptoolsはここで報告しても意味ないのか。そっちかよ。

＃ しかし前回もそうだったけど、初動がめっちゃ早いなぁ……偉大だ。

出来れば上記を取りまとめて再度setuptools本家に報告する予定ですが、とりあえずそういうことがあったということで。

追記(2016-11-09 16:50): 報告しました。 https://github.com/pypa/setuptools/issues/844
viewで`each`すると、変な文字が表示されてしまう


```
<p>
  <%= @tags.each do |tag| %>
  <a href="#"><%= tag %></a>
  <% end %>
</p>
```

こうすると、展開されたデータだけじゃなく`@tags`が画面に表示されてしまう。

```
test test test test
[test,test,test,test] # これが表示される
```

原因が分からず苦しんでいたのですが、`each`の所に`=`が付いてはいけないのではないかと思って消してみると表示されなくなった！！

irbで調べてみたのだが、

```
irb(main):020:0> a
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
irb(main):021:0> 
irb(main):022:0* 
irb(main):023:0* a.each do |x|
irb(main):024:1* x
irb(main):025:1> end
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
irb(main):026:0> a.each do |x|
irb(main):027:1* puts x
irb(main):028:1> end
1
2
3
4
5
6
7
8
9
10
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # こいつが表示される
```

`each`の所で、`=`を書いちゃうと変数展開されて、`@tags`が表示されてしまったってことかな。

また、はまりそうなのでメモとして残しておく。
iOSのバージョン判定をする方法

いつも忘れてしまうので、防備録として。
iOSのバージョン判定するには以下の方法で行う。

```objc:Objective-C
if ( floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_9_x_Max )
{
    // iOS10以降の場合
} else {
    // iOS9以前の場合
}
```

```swift:Swift
if floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_9_x_Max {
    // iOS10以降の場合
} else {
    // iOS9以前の場合
}
```

＜追記＞
なお、Swiftだとこういう書き方もできるとコメントをいただきました。
こちらの方がかなり直感的ですね。

```swift:Swift
if #available(iOS 10.0, *) {
    // iOS10以降の場合
} else {
    // iOS9以前の場合
}
```

iOSのバージョンによって異なるデザイン（iOS7以前）やiOS10から変わったウィジェットの背景色などを調整したりする際にこの判定処理が使えます。

以下の方法でもiOSのバージョン判定ができますが、直接値が書かれていたりするので、上記の方法が個人的には好きです。

```objc:Objective-C
float iOSVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
if (iOSVersion > 9.9f) {
    // iOS10以降の場合
} else {
    // iOS9以前の場合
}
```

参考：[iOS 7 UI Transition Guide](https://developer.apple.com/jp/documentation/UserExperience/Conceptual/TransitionGuide/SupportingEarlieriOS/SupportingEarlieriOS.html#//apple_ref/doc/uid/TP40013174-CH14-SW3)

＜追記＞
コメントでいただいたのだが、こんな方法でも判定ができるとのこと。
判定方法はいろいろとあるようですね。

[iOS のバージョンを簡単にマイナーバージョン等を加味して判定する
](http://qiita.com/ktysne/items/31bbcb9cd0508e29a7aa
)
[Homebrew] brew updateでエラーが出た時の対処法

#はじめに
Android Studio 2.2.2のVCS(Version Control System)でgitを使おうと、軽い気持ちで、最初にbrew upgradeを行おうとした矢先。下記、brewお作法中。

+ brew doctor
+ brew update <--- ここでエラー
+ brew upgrade

になってしまった・・・。
色々なサイトを参考にして解決したのでメモしておく。

#環境
+ Mac OS X El Capitan 10.11.6

#brew updateのエラー内容
```rudy:ターミナル
$ sudo brew update
error: Your local changes to the following files would be overwritten by merge:
	Library/Contributions/example-formula.rb
	Library/ENV/4.3/cc
	Library/ENV/4.3/git ...(省略)

Please commit your changes or stash them before you merge.
error: The following untracked working tree files would be overwritten by merge:
	Library/Homebrew/formula_assertions.rb
	Library/Homebrew/language/go.rb
	Library/Homebrew/requirements/maximum_macos_requirement.rb
Please move or remove them before you merge.

Aborting
Error: Failure while executing: git pull -q origin refs/heads/master:refs/remotes/origin/master
```

沢山ある……。＼(^o^)／
基本的に悪さをしているのは、gitのよう…（長い間、放置していたのが祟ったか…）

と思いつつ、同じようなエラーで対応策を出してくださっていた方々が沢山いたので、それに習って対処。

#対処コマンド
実際のコマンドは、以下。

```rudy:ターミナル
$ cd $(brew --prefix)
$ git fetch origin
$ sudo git reset --hard origin/master
```

*git reset --hard origin/master*
というのは、gitの「HEADの位置・インデックス・ワーキングツリー」全てリセットするってことのよう。

これでイケるっしょ！と思い、brew updateを実行。

```ruby:ターミナル
$ brew update
Error: /usr/local must be writable!
```

いけませんでした...（遠い目）
エラー内容は、書き込みできなきゃダメ！ってことなので、/usr/localの権限を変更。

```rudy:ターミナル
$ sudo chown -R $(whoami):admin /usr/local
```

今度こそ、ということでbrew updateを再度実行。

```rudy:ターミナル
$ brew update
$ brew upgrade
```

どちらも成功！
良かった、よかった。

#参考元
[ヾ(oﾟωﾟo)ﾉﾞbrew updateでエラーでたった[Homebrew]](http://qiita.com/harapeko_wktk/items/f4f44ddb5d3912e15ea2)
[brew updateでエラーが出た話](http://iganari.hatenablog.com/entry/2016/05/17/091132)
[[git reset (--hard/--soft)]ワーキングツリー、インデックス、HEADを使いこなす方法](http://qiita.com/shuntaro_tamura/items/db1aef9cf9d78db50ffe)
RubyとSeleniumとFirefoxを使ってWebスクレイピングをする時のtips

今までに作ったスクレイピングシステムで得られたノウハウを書く。たまにしかやらないし、目的を達成したらもういじらないし、すぐ忘れるので備忘録として。

# 使うツール

* Ruby
    * 楽だし慣れてるから。
    * しかし、Selenium bindingsの対応具合からするとPythonの方がいいような気がする。
* Selenium
    * Webブラウザをプログラムから操作するためのアイツ。
    * 本来はテスト用のツールのような気がするが、細かいことは気にしない。
    * MechanizeとかPhantomJSとかの、プログラム制御専用の実装もあるが、人様の作ったWebサイトを読み込む場合は、普通のブラウザでないとまともに動かないことが懸念される。特にログインが必要で、かつ限られた人向けのサイトは。
    * 3.0がリリースされてたけど、なんか動かなかったので2.x系を使った。
* Firefox
    * ESR版を使った。 https://www.mozilla.jp/business/
    * ブラウザとSeleniumとの間でバージョン不整合により動かなくなることがよく起きるので、あまり頻繁に更新したくない。
* Debian 8
    * Firefox ESR版のパッケージが含まれているメジャーなdistroが他になかった。
    * rpm系は普段使わないので調べてない。
* docker
    * 時代はコンテナらしいのでがんばってついていきたい。

## Implicit Wait と Explicit Wait

昨今のWebサイトはやたらと非同期処理があるので、適切にwaitを入れてやらないと目的のDOMが構築される前に探しに行って、例外が発生してしまう。

今までは適当にsleepとか入れていた(ひどい)のだが、正しい方法がちゃんとあった。

### Implicit Wait

これをやっておくと `find_element` を実行した時、目的の要素が現れるまで「探す→待つ」を繰り返してくれる。指定した秒数を超えるとtimeoutして例外が発生する。 `Selenium::WebDriver` インスタンス生成時に指定する。

```
driver = Selenium::WebDriver.for :firefox, :profile => Selenium::WebDriver::Firefox::Profile.new
      browser.manage.timeouts.implicit_wait = 10
```

### Explicit Wait

特定のリクエストについて、特別に長く待ちたい時などに使う。

```
# まずインスタンスを作る
wait = Selenium::WebDriver::Wait.new(:timeout => 30)
```

#### 特定の要素が現れるのを待って取得する

```
e = wait.until { driver.find_element(:xpath, "//input[@name='sometext']") }
```

#### 要素が clickable になるのを待つ

```
e = wait.until { e.displayed? && e.enabled? }
```

Seleniumには `ExpectedConditions` というクラスがあるらしいのだが、Ruby Selenium bindingsには無いらしい。また `clickable` というのは要するに `displayed? && enabled?` のことらしい。 https://stackoverflow.com/a/29903931

## テキストボックス(`<input type="text" />`)に入力する

```
driver.find_element(:xpath, "//input[@name='sometext']").clear
driver.find_element(:xpath, "//input[@name='sometext']").send_keys("hogehoge")
```

`clear` しておいた方が、続けて検索する時とかにハマらなくて済む。

## 特定の文字列がページ内にあるかチェックする

```
driver.page_source.match(/ほげほげ/u)

# これは思ったより重い
driver.find_element(:xpath, "//body").innerHTML.match(/ほげほげ/u)
```

# あとがき

なんかあったら追記していく。
`¥ git reset --hard` を元に戻す方法


本番環境に反映されているPGを検証環境で再現させたい時に、`git reset`することが良くある。
そんな時は、本番環境で`git log`してコミットIDを確認して`git reset`する。

```
¥ git reset --hard コミットID
```

次に検証したいPGがコミットIDより新しい時、どうすれば良いか悩んでいたのだけど元に戻す方法があるのでメモ

```
¥ git reflog # これで直近変更したコミットログが表示される
¥ git reset --hard "HEAD@{1}" # 戻したいコミットを探して数字を入れてやる
```

`git log` `git reflog`の違いが分かってないが、今度調べよう。
ソースコードの無思慮なコピペを生むGithubというアーキテクチャについて

https://github.com/search?q=%22%23define+RUBY_VERSION+%22+filename%3Aversion.h&type=Code

まずは上記の検索結果を見てくれ。これは

- ファイル名が`version.h`
- 内容に"`#define RUBY_VERSION`"

という検索クエリで、もちろん、そのようなコードはプログラミング言語Rubyの本体に由来することはいうまでもないわけだが、自分からは7,918件の検索結果が見える。これにはforkやリビジョン違いを含んでいない。

なぜこんなに多いのか? これは、Rubyがコピペを助長するような製品だからか?

どうもそうでもないらしい。たとえば同様のことをCPythonでやると
https://github.com/search?q=%22%23define+PY_VERSION+%22+filename%3Apatchlevel.h&type=Code
自分からは6,079件ヒットしているように見えるし、同様のことをPerlでやると
https://github.com/search?q=%22%23define+PERL_REVISION+%22+filename%3Apatchlevel.h&type=Code
自分からは695件ヒットしているように見える。

なんなんだ? これは。

## コピペすんなボケが。

そもそもコピペがよくないという話は、Githubとしても分かりきったことのはずだ。Githubにはわざわざforkという仕組みがそなわっている。これはコピペではなく彼らの言葉で言うと「シェア」する仕組みだし、見え方としても親があって、子があるという見え方で、完全にすっきりしている。べつに無限にコピペ増殖することを意図して設計されているわけではないことは観測からも推測される。

にもかかわらずのこの検索結果であるから、やはり根本的に使い方を間違ってコピペする輩が後を絶たないのだろうということが強く示唆されるわけである。

これは、個人の努力とかそういう問題じゃない。デザインだ。誤った設計が誤った運用を生んでいるんだ。

## なにがいけないのか

Pythonの例をよく見るとヒットしてきている大多数は、どうやらvenvの中のヘッダファイルのようだ。`pyvenv`がコピペを誘発するアーキテクチャになっている是非にはここでは触れない(よく知らないけど、たぶん何か考えがあってのことなんだろう)。問題はこういうコピペされたコードがGithub側に無思慮にコピペされてきていることのほうにある、と思う。

思うに、ユーザーのローカル環境とか、あるいはデプロイ先とか、そういうところにコピペされたファイルがあるのは、RubyだのPythonだのの場合はある意味で不可避なわけだけれども、だからといってGithubにまでそれをそのまま無思慮にコピペしてくる輩がいるのが問題なのではないか。もちろん`.gitignore`を適切に書けという話はあるかもしれない。が、ユーザーが無思慮なところに向かって「ちゃんとしろ」と言ってみたところで。そこはコントロールしようとしても不毛なだけ。

## ただのホスティングサービスに成り下がってるのが問題
ようはユーザーの **書いた** コードじゃなくて、ユーザーの手元にあるコードが全部アップロードされてくるのが間違いだったと言わざるをえない。「デプロイの都合を考えると全部のファイルがgitで落とせる方が…」いや、問題はGithubからデプロイするところにあるんだよ。Githubをただのファイル置き場として使ってるでしょ? そうなってると、そりゃ自分の著作じゃなくてもとりあえず突っ込むって思想が出てくるわ。でも本来違うことを意図していたはずなんだよ。

本来Githubはプログラムの「開発」をする場であって、便利なうpろだじゃないはずなんだよ。目指してたのはね。でも現状ではそう使われちゃってるわけ。なので検索とかにただのうpろだ的な用途が引っかかってきててSN比が低下しているんだ。

べつにうpろだの必要性を否定したいわけではないが、わざわざGithubに担わせるべき役割だったのかというと疑問だ。少なくとも当初は違ったんだろう。でも今やGithub Pagesとかあるから、ある時期にそういう、コピペのファイルを突っ込んどく用途を許容するように方向転換があった(意識的になのかは知らん)。その結果としてコミュニティ部分が弱まって、なんかよくわからん、いかにもメンテされてないコピペの残滓みたいのが跋扈するようになってしまった。ということなんだとおもう。

## まとめ
コミュニティ機能とホスティング機能があっていい。その両方ともを別に否定したいわけじゃない。ただ混ざってるのは良くない。コミュニティ機能の側にコピペ不要。SN比の低下を防ぐように分離することを考えるべきだと思う。
pandasデータ読み込み



### method

- デフォ

```python
import pandas as pd
pd.read_csv("hoge.csv")
```

- ヘッダーなし  
`pd.read_csv("hoge.csv",header=None)`
- 名前をつける  
`pd.read_csv("hoge.csv",names=["a","b","c"])`
- タブなど区切りで分ける  
`pd.read_csv("hoge.csv",sep="\t")`

### ちなみに
拡張子が`csv`でなくても読み込める？
(tsv, dat, csvはできた)
git commitの取り消し方

状況に応じて使い分ける
- `git commit --amend`
前回のコミットログに上書き。取り消すほどでないちょっとした修正に

- `git reset --soft <hash>`
消えるが、staging areaに変更が残る(再度commit可能)

- `git reset <hash>`
修正したfileはstaging areaに残る。追加したfileはworking directoryに残る

- `git reset --hard <hash>`
修正履歴は消える
untracked files(まだaddしていない、新しく追加されたファイル)は残る

- `git clean -df`
untracked files(追加したファイル)も消える
macOS: parityのインストール方法



macOS向けで、brewでインストールする方法


## セットアップ

[Setup · ethcore/parity Wiki](https://github.com/ethcore/parity/wiki/Setup)

バイナリのインストール: 公式ドキュメントによるとUbuntuでもHomebrewの入っているMacでも以下をやるだけでいいらしい。

```
bash <(curl https://raw.githubusercontent.com/ethcore/scripts/master/install-deps.sh -L)
```

が、自分は以下のようにbrewだけでやった。

## brewでparityをインストール

* [ethcore/homebrew-ethcore: Homebrew tap for ethcore](https://github.com/ethcore/homebrew-ethcore)


### tapする

```
brew tap ethcore/ethcore
```

### brew インストールする

```
brew install parity
```

### brew updateする

```
brew update && brew upgrade parity
brew reinstall parity
```



## ブロックチェーンの同期

早く同期する方法

[Getting Synced · ethcore/parity Wiki](https://github.com/ethcore/parity/wiki/Getting-Synced)

以下のアドレスをbittorrentクライアント(Transmission等)に貼り付けてファイルをダウンロード
余談) bittorrentとuTorrentは、Sophosがアドウェアが入っていると警告出してきた。


```
 magnet:?xt=urn:btih:E9B318B15016AAD261E925FF19AE14B30D1BACA3&dn=mainnet-2021235.snapshot
```


その後、以下のようにリストア

```
$ parity restore mainnet-2021235.snapshot
2016-11-01 17:13:08  Configured for Frontier/Homestead using Ethash engine
2016-11-01 17:13:08  Snapshot restoration is experimental and the format may be subject to change.
2016-11-01 00:13:08  Restoring state
2016-11-01 00:13:08  Processed 0/51 state chunks and 0/30 block chunks.
2016-11-01 00:13:13  Processed 8/51 state chunks and 0/30 block chunks.
2016-11-01 00:13:18  Processed 14/51 state chunks and 0/30 block chunks.
2016-11-01 00:13:23  Processed 16/51 state chunks and 0/30 block chunks.
2016-11-01 00:13:28  Processed 19/51 state chunks and 0/30 block chunks.
2016-11-01 00:13:33  Processed 21/51 state chunks and 0/30 block chunks.
2016-11-01 00:13:38  Processed 25/51 state chunks and 0/30 block chunks.
2016-11-01 00:13:43  Processed 30/51 state chunks and 0/30 block chunks.
2016-11-01 00:13:48  Processed 35/51 state chunks and 0/30 block chunks.
2016-11-01 00:13:53  Processed 38/51 state chunks and 0/30 block chunks.
2016-11-01 00:13:58  Processed 42/51 state chunks and 0/30 block chunks.
2016-11-01 00:14:03  Processed 42/51 state chunks and 0/30 block chunks.
2016-11-01 00:14:08  Processed 42/51 state chunks and 0/30 block chunks.
2016-11-01 00:14:13  Processed 45/51 state chunks and 0/30 block chunks.
2016-11-01 00:14:18  Processed 49/51 state chunks and 0/30 block chunks.
2016-11-01 00:14:20  Restoring blocks
2016-11-01 00:14:23  Processed 51/51 state chunks and 6/30 block chunks.
2016-11-01 00:14:28  Processed 51/51 state chunks and 19/30 block chunks.
2016-11-01 00:14:33  Restoration complete.
```


## 起動

あとは、普通にparityを起動。


## Mistを使うためにgethモードで起動

--gethオプションを付ける


```
$ parity --geth
2016-11-01 00:00:34  Starting Parity/v1.3.10-stable-7972c27-20161104/x86_64-macos/rustc1.12.1
2016-11-01 00:00:34  Using state DB journalling strategy fast
2016-11-01 00:00:35  Configured for Frontier/Homestead using Ethash engine
```


## 関連用語

* Ethereum, イーサリアム, エセリウム
* Blockchain, ブロックチェーン, ブロックチェイン
* geth, parity, EthereumJ
Shinyでreq()とmodalDialogを使ってエラーハンドリングを実装する

[Shinyでユーザーがすぐ使えるダッシュボードが作れる](http://qiita.com/komde/items/0f7a8f01ae6366055f47)のは皆さんご存知の通りですが、不正な処理が起こった時のエラー表示がやや目障り、という問題があります。

**真っ赤っか～**
<img width="607" alt="スクリーンショット 2016-11-08 16.10.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/103775/17d0f9f4-ee8a-bdb8-38ca-fc188d942627.png">

UX全盛の世の中で、このようなユーザーアンフレンドリーなUIは許されませんので、RESTでデータをやり取りする実装をサンプルにエラーハンドリングを行ってみたいと思います。

Shinyでエラーハンドリングを行うには2種類方法があります。
[validate/need](http://shiny.rstudio.com/articles/validation.html)
[req](http://shiny.rstudio.com/articles/req.html)
validate/needのほうがフローのコントロールやエラーメッセージなどより柔軟な対応が取れるのですが、やや実装が複雑になります。ここではより簡単な(コード全体をいじらなくてもよい)、req()について解説させていただこうと思います。req()は評価結果がFALSE/NULLなどだった場合に内部でstop()を呼び出すので、これ以降のコードが実行されなくなります。validate/needよりも簡単と記述したのは上記のようなreqの乱暴かつ効果的な機能によるところがあり、関数型主義の人には邪道に映るかもしれませんが、シーンを選べばとにかく便利なので個人的にはおススメです。
一方reqはすべての処理を止めるだけなので、ユーザーとしてはなぜエラーになったのかが分かりません。なので、ダイアログを使用してreqで処理を止める前に止める理由をユーザーに教えてあげるのが親切でしょう。以下サンプルで処理の流れを説明させていただきます。
※ちなみにreqはShiny version 0.13以上、ダイアログ(modalDialog)はversion 0.14以上が必要ですのでライブラリ更新してない方はアップデートしてください。

##サンプルソースの全体像
こんな感じのフローを想定してみます。
(1)id/passをもとに、RESTでtokenを取得しにいく
(2)token取得後特定idのデータを取得する
(3)取得したデータを描画する

####ui.R
id/passをテキストボックス・パスワードボックスで入力、session_loadというボタンを配置し、押すとdata_textにデータが返る構造です。

####server.R抜粋
```
library(shiny)
library(httr)

p_client_id <- "123456789"
p_client_secret <- "qwertyuiop1234567890asdfghjkl"
ca_url <- "https://api.example.com/ep/login"
get_url <- "https://api.example.com/ep/events"

#session_loadボタンを押すとログイン→データを取得する関数
reload_data <- eventReactive(input$session_load, {
  #ログイン認証
  body <- list(grant_type = "password", username=input$id, password = input$pass, client_id = p_client_id, client_secret = p_client_secret)
  #verbose()を入れるとこちらが渡した値と返ってきた値の詳細が見えます
  r <- POST(ca_url, body = body, encode = "multipart", content_type = "application/x-www-form-urlencoded", verbose())
  #トークンなどの返りをリストに格納
  li <- content(r, "parsed")
  #セッション情報を破棄
  handle_reset(ca_url)

  #データの取得
  query <- list(type = "app_data", id = "1234567890")
  r <- GET(ze_url, query = query, add_headers(Accept = ""), add_headers(Authorization = paste("Token",li$token),"Accept-Language" = "ja", Accept = "application/json", verbose()))
  handle_reset(get_url)
  el <- content(r, "parsed") #データ部分を格納します
  return(list(li=li,el=el))

  #本当はここにrevoke必要
}

output$data_text <- renderText({
  el<- reload_data()[["el"]]
  el$data
})
```

####問題
さて、ここでid/passに不正値がセットされた場合、output$data_textはデータが取得できないため、例の赤のエラー画面になってしまいます。このコードのエラーハンドリングをするにはどうしたら良いでしょうか？

####答え
トークンを取得した後(handle_reset(ca_url)の後)に以下のコードを挟みます。トークンを取得できなかった場合li$tokenがNULLになるので、まずエラーダイアログを表示し、その後req()を使用して後ろの処理を全て止めます。

```
if(is.null(li$access_token)){
  showModal(modalDialog(title = "エラー", "検索条件に該当するデータがありません", easyClose = TRUE, footer = modalButton("OK")))
}
req(li$access_token) #ログイン失敗時はここで止めてしまう
```
<img width="179" alt="Screenshot_20161111-151600.png" src="https://qiita-image-store.s3.amazonaws.com/0/103775/defbf9c7-8985-61e7-a980-b825fa2a57e9.png">

以上。簡単ですね！
あまり多用しすぎるとスパゲッティになると思うので、ここぞという時にreq()を使ってみてください。
JavaScriptでテキストをカラフルにシャッフルするやつを作った

## こんなやつです

![shuffle-colorful-chars in action](https://raw.githubusercontent.com/kozo002/shuffle-colorful-chars/master/demo.gif)

よかったら試してみてください
[https://www.npmjs.com/package/shuffle-colorful-chars](https://www.npmjs.com/package/shuffle-colorful-chars)
Mac SierraにHomebrew + Cask + Versionsを導入する方法


> ちょっと訳あってbrew周りを整理したく、一旦まっさらな状態にしたかった時の備忘録。

## Homebrewインストール

### アンインストール & インストール

- 既にHomebrewを入れてある場合、一旦アンインストール。

    > 先にrubyをunlinkしているが、これをやらずに無邪気にアンインストールを行うと、brewで入れたrubyへのシンボリックリンク先が存在せず、インストール実行時に困ってしまう。

    ```bash:console
    brew unlink --force ruby
    sudo ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/uninstall)"
    ```

- homebrewをインストール。

    > 先述の通り、無邪気に既存のbrewを消してしまった場合も考慮し、rubyはMacに標準で入っているrubyをフルパスで指定。

    ```bash:console
    /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
    ```

### 確認

- version

    ```bash:console
    brew --version
    (結果)
    Homebrew 1.1.0
    Homebrew/homebrew-core (git revision 1a39; last commit 2016-11-07)
    ```

- help

    ```bash:console
    brew help

    (結果)
    Example usage:
      brew search [TEXT|/REGEX/]
      brew (info|home|options) [FORMULA...]
      brew install FORMULA...
      brew update
      brew upgrade [FORMULA...]
      brew uninstall FORMULA...
      brew list [FORMULA...]

    Troubleshooting:
      brew config
      brew doctor
      brew install -vd FORMULA

    Developers:
      brew create [URL [--no-fetch]]
      brew edit [FORMULA...]
      https://github.com/Homebrew/brew/blob/master/docs/Formula-Cookbook.md

    Further help:
      man brew
      brew help [COMMAND]
      brew home
    ```

## Homebrew Caskをインストール

> Homebrewでインストールできるパッケージを拡張する。
> yum repositoryみたいなもの?

### インストール

- 以下のコマンドを実行してインストール

    ```bash:console
    brew install caskroom/cask/brew-cask
    ```

    > Xcode can be updated from the App Store.っておこられたら、xcodeアップデート&起動してライセンス承認しましょう。
    > 30分くらいかかるかも…。

- 確認

    ```bash:console
    brew cask --version

    (結果)
    Homebrew-Cask 1.1.0
    caskroom/homebrew-cask (git revision 84d2; last commit 2016-11-08)
    ```

## Homebrew Versionsを導入

> Cask上には複数のバージョンのパッケージが登録されていることがあるため、バージョンを指定してインストールすることが可能になるhomebrew-versionsを導入する。

### 導入

- brew tapでインストール

    ```bash:console
    brew tap caskroom/versions
    ```

### 確認

- tap内容を確認

    ```bash console
    ls /usr/local/Homebrew/Library/Taps/caskroom

    (結果)
    homebrew-cask		homebrew-versions
    ```
behatでhttps://localhostをテストする

参考：http://stackoverflow.com/questions/34977817/behat-curl-ssl-certificate-error-on-localhost

##問題
HTTPSなサイトをローカルでテストしようとすると、cURLエラーを喰らう。

###実行結果
```
$ ./bin/behat
Feature: Can show Installer

  Scenario: redirect to wp-admin/install.php # features/00_installer.feature:3
    Given I am on the homepage               # Behat\MinkExtension\Context\MinkContext::iAmOnHomepage()
      cURL error 60: SSL certificate problem: Invalid certificate chain (see http://curl.haxx.se/libcurl/c/libcurl-errors.html) (GuzzleHttp\Exce
ption\RequestException)
    Then print current URL                   # Behat\MinkExtension\Context\MinkContext::printCurrentUrl()

--- Failed scenarios:

    features/00_installer.feature:3


1 scenario (1 failed)
2 steps (1 failed, 1 skipped)
0m0.12s (13.21Mb)

```

##対応
behat.ymlでverifyをfalseにすればつながる。

```behat.yml
default:
  extensions:
    Behat\MinkExtension:
      base_url: https://localhost:8443/
      goutte:
        guzzle_parameters:
          verify: false
  suites:
    default:
      contexts:
        - 'Behat\MinkExtension\Context\MinkContext'
paths:
  features: features
  bootstrap: %behat.paths.features%/bootstrap
```
###実行結果
```
$ ./bin/behat

Feature: Can show Installer

  Scenario: redirect to wp-admin/install.php # features/00_installer.feature:3
    Given I am on the homepage               # Behat\MinkExtension\Context\MinkContext::iAmOnHomepage()
    Then print current URL                   # Behat\MinkExtension\Context\MinkContext::printCurrentUrl()
      │ https://localhost:8443/wp-admin/install.php

1 scenario (1 passed)
2 steps (2 passed)
0m1.30s (13.48Mb)
```
systemdを使用しないで起動するスクリプトを作る

#前提
CentOS7からsystemdがプロセスの実行に関わっているようで、`/etc/init.d`に作成した起動用スクリプトが思った通りの動きをしてくれない時の覚え書き。

#今回ぶつかった壁
とある事情からyumで入れられるSamba4ではなくSamba3をソースからコンパイルした際に、起動・終了のスクリプトを作ったのに何故かsystemctlにviaしてしまって涙目に。

#環境
| OS | Samba |
|:---------:|:----------:|
| CentOS 7.2 | Samba 3.6.24 |

#やったこと
[samba 3.6.24 のinstallと、自動起動](http://d.hatena.ne.jp/end0tknr/20150210/1423495771)
上記サイトを参考に、Samba3.6.24を起動するためのスクリプトを作成。
そして実行。

```html
# /etc/init.d/samba start
Starting samba (via systemctl):
```
うーん…。なんか違う。

##スクリプトをデバッグしてみる
先人が作ったものを丸コピでは進歩できないので、中身を見てみることに。

```html
# sh -x /etc/init.d/samba start
```

```bash
(中略)
++ action 'Starting samba (via systemctl): ' /bin/systemctl start samba.service
++ local STRING rc
++ STRING='Starting samba (via systemctl): '
++ echo -n 'Starting samba (via systemctl):  '
Starting samba (via systemctl):  ++ shift
++ /bin/systemctl start samba.service
```

うーん…。systemctlを起動しちゃってる。
けどよく分かんない。

##おとなしくググる

[【CentOS7】起動スクリプトを実行すると勝手にsystemctlを使う件](http://zacodesign.net/blog/?p=1976)

>\$\_use_systemctl変数が”1″である場合、systemctl_redirectという関数を実行し、exitするようになっています。
(中略)このように、$SYSTEMCTL_SKIP_REDIRECT 変数が空文字であった場合、勝手にsystemctlを使ってしまうということがわかりました。

この先に答えも書いてありました。素晴らしいサイトです。

##SYSTEMCTL_SKIP_REDIRECT変数を使用する

もう↑のサイトのまんまですが

```html
# SYSTEMCTL_SKIP_REDIRECT=1 /etc/init.d/samba start
Starting SMB services:                          [  OK  ]
```

ｷﾏｼﾀﾜｧ・゜ﾟ・:.｡..｡.:・゜(n'∀')ηﾟ・:.｡..｡.:・゜ﾟ・

#応用

毎回頭に`SYSTEMCTL_SKIP_REDIRECT=1`とつけてスクリプトを実行するのはあまり美しくないのでスクリプトの中に直接ぶっこんでみます。

```bash:/etc/init.d/samba
#!/bin/sh
SYSTEMCTL_SKIP_REDIRECT=1
SMB_HOME=/usr/local/samba
# Source function library.
if [ -f /etc/init.d/functions ] ; then

　　　　　(中略)

        echo $"Usage: $0 {start|stop|restart|reload|status|condrestart}"
        exit 2
esac

exit $?
```

これで`/etc/init.d/samba`を実行してみる。

```html
# /etc/init.d/samba stop
Shutting down SMB services:                        [  OK  ]
```

うん、いい感じです。
[CentOS 7][KVM] virt-installの典型的（？）な使用例

# 典型的（？）な使い方

## CentOS 7仮想マシンの作成

こんな条件で作成する場合のコマンド例です。

 - CPU: ホストそのままを使う
 - メモリ: 1024MB
 - 画面: 外部からSPICEで接続、コンソールへ自動接続しない(virt-viewerを起動しない)
 - ネットワーク: ホストのIPアドレスを使ってNAT接続、準仮想化
 - ISOファイルからインストール
 - OSの種類はCentOS 7.0
 - ディスク: ストレージプールから割り当て、容量10GB、準仮想化、ファイル形式はraw

```
virt-install --name guest1\
 --cpu host\
 --memory 1024\
 --graphics spice,listen=0.0.0.0\
 --noautoconsole
 --network network=default,model=virtio
 --location /var/lib/libvirt/images/CentOS-7-x86_64-DVD-1511.iso\
 --os-variant centos7.0\
 --disk pool=default,size=10,bus=virtio,format=raw
```

## Windows仮想ディスクをインポート

 - CPU: Core2Duoをエミュレート(Windows 10だとこれがよいみたい)
 - メモリ: 1024MB
 - 画面: 外部からSPICEで接続、コンソールへ自動接続しない(virt-viewerを起動しない)
 - ネットワーク: macvtapを使ってホストデバイスへ直接続
 - ディスク: 既存ディスクイメージファイルを使用
 - OSの種類はWindwos 8.1

```
virt-install --name guest1\
 --cpu core2duo\
 --memory 1024\
 --graphics spice,listen=0.0.0.0\
 --network type=direct,source=ens32\
 --disk path=/var/lib/libvirt/tmp/cpa647ss.raw,bus=sata\
 --import\
 --os-variant win8.1\
 --noautoconsole
```

# 各オプションの説明

## --name NAME

仮想マシン名です。

## --memory 数字

メモリ容量です。単位はMiBです。

## --cpu MODEL[,+feature][,-feature][,match=MATCH][,vendor=VENDOR]

CPUモデルと機能の使用可/不可を指定します。ホストをそのまま見せるときは`host`にします。

## --graphics TYPE,opt1=arg1,opt2=arg2,...

TYPEはvnc、spice、noneを指定できます。

オプションの主なところはこんなんがあります。

|オプション | 説明 |
|:-----------|:------------|
|port|ポート番号|
|listen|リッスンするIPアドレスです。未指定だとlocalhostになります。|
|password|VNCのパスワードです。|


## --os-variant

OSの種類です。

`osinfo-query os`コマンドで使用できるOSが一覧できます。

## --graphics

|オプション | 説明 |
|:-----------|:------------|
| listen | |

## --network

|オプション | 説明 |
|:-----------|:------------|
| model ||

## --location

## --disk

|オプション | 説明 |
|:-----------|:------------|
| model ||

## --noautoconsole

コンソールを開始しません。
WebRTC入門者の会（勉強会）に参加しました

# 勉強会の基本情報

* 【日　時】2016年11月02日 19:00~22:00
* 【会　場】レバレジーズ株式会社
* 【参加費】無料
* 【主　催】@afroscript, @n0bisuke
* 【申し込み】http://connpass.com/event/39679/

# 概要

* WebRTCに使うデバイスを選択するには（＋おまけ）
    * @massie_g
* WebRTCデバッグ入門
    * @yusuke84

# 内容

## WebRTCに使うデバイスを選択するには（＋おまけ）

### ディバス一覧の取得
* 取得できるディバス
    * オーディオ入力ディバス（マイク）
    * ビデオ入力ディバス（カメラ）
    * オーディオ出力ディバス（スピーカー）　ー　chromeのみ(53~)

* ディバス情報の内容
    * deviceId - ディバスID
    * kind - audiooutput(chromeのみ) videoinput audioinput
    * label - 名称
    * groupId - 同じハード機器内のディバスは同じなる仕様

### labelを取得できるケース
* Chrome - https://〜
* Firefox - ユーザーがアクセスを許可している間(https://〜で「常に許可」したら、その後ずっと)

### Andriodでフロント/バックカメラを指定
```
  
  var constraints = {
    audio: true
    video: { 
     facingMode: "user" // フロントカメラ（ユーザ側カメラ） ※デフォルトはこちら
     // facingMode: "environment" // バックカメラ（環境側カメラ）
    }
  };
```

### Firefox ではFakeカメラ、Fakeオーディオが使える
```
 var constraints = {video: true, fake: true, audio: false};
```

## WebRTCデバッグ入門

### ケース1
* 現象
    * ネットワーク的に接続されているか(chrome場合)
* 対策
    * アドレスバーに、chrome://webrtc-internalsを入力して
    * Conn-xxxx-x-x という項目がある（有効なTransport/輸送路）
* 確認
    * 存在しなければネットワーク的に接続されているか
    * ある場合でもタイムスタンプが更新されていない場合はその時点で利用されていない

###  ケース2
* 現象
    * 音声、映像ストリームが流れているかを確認する
* 対策
    * アドレスバーに、chrome://webrtc-internalsを入力して
    * AudioTrackとVideoTrack情報を確認する
* 確認
    * 送受信バイト数がカウントアップしていればストリームは流れている

### ケース3
* 現象
    * カメラの映像やマイクの音声が取得できない
* 対策
    * プルダウンで選択しブラウザをリロードすることで有効になる
    * navigator.mediaDevices.getUserMedia のAPIでエラー返すfunctionに、ログを出力
* 確認
    * navigator.mediaDevices.getUserMediaで指定するキャプチャサイズ（widthとheight）の映像をWebカメラから取得できない
    * PC側のマスターボリュームが0になっているなど

### メディアを解釈する サーバを介するもの
* MCU(Multipoint Control Unit)
    * MCUはメディアを集約し、ミキシングし、各デバイスに流す。かなり、クライアントの処理負荷が軽いのがメリットだ。
    * サーバー側がデコードやエンコード処理必要であるので、負荷が高くなる
    * 代表例：Skype

* SFU(Selective Forwarding Unit)
    * このアーキテクチャでは、まずクライアントは1つのストリームをSFUに送信する。SFUはエンドポイントが希望するストリームのみをリダイレクトする。
    * サーバー側に負荷が高くない
    * 代表例：Google Hangout



# 感想
* 初めてWebRTCに関する勉強会に参加した
* いろいろな情報をもらえることが良かった
* 情報が大体的にクライアント側に集中しているが、サーバー側の情報が少ない
* 参加者が３０人ぐらいが、WebRTCに趣味ある方少ない感じ

# メモ
* [WebRTCに使うデバイスを選択するには（＋おまけ） \- Qiita](http://qiita.com/massie_g/items/b9863e4366cfed339528)
* [WebRTCデバッグ入門 \- Qiita](http://qiita.com/yusuke84/items/8d232c8d24156f16e8ba)
* [WebRTCのシグナリングサーバーにMilkcocoaを使って見るメモ \#webrtcjp \#mlkcca \- Qiita](http://qiita.com/n0bisuke/items/2d88d5b31b9bb7e7ac1e)
* http://qiita.com/oh_rusty_nail/items/f93a080e95961c902f6b#_reference-f76f66a27fa31cc0352f
Google App Engine Custom Runtimesで不要ファイルを消すとCOPYが早くなるか

規模によりますが、不要なファイルをCOPYしなければ処理が早くなるのではと思いました。

まずは、そのまま実行します。

```bash
$ time gcloud -q app deploy app.yaml --promote

real	8m20.526s
user	0m17.927s
sys	0m2.334s
```

次に、不要なファイルを削除してみます。

```bash
$ rm -rf .git tmp log
$ time gcloud -q app deploy app.yaml --promote

real	6m32.573s
user	0m13.282s
sys	0m1.194s
```

ちょっと早くなったかも
CakePHP3にて複数のDBを使う場合

# 経緯と概要
CakePHP3において、複数DBにまたがってデータ参照をする場合の設定方法を記します。
特に、テストのときに狙ったtest用DBを向かなくてはまりました。
2016/11/8現在, わかりやすい位置に本エントリに該当する説明がなかったので何かの助けになればと思います。
# configの設定
例えばdefaultでとあるDB「hoge」, 別でDB「fuga」を参照したい場合
http://book.cakephp.org/3.0/ja/development/testing.html#id13
公式のこの辺りを参照してconfigに記述します。

```php:config/app.php
(中略)
'Datasources' => [
    /* デフォルト設定 */
    'default' => [
        'className' => 'Cake\Database\Connection'
        'driver' => 'Cake\Database\Driver\Mysql',
        'persistent' => false,
        'host' => XXX.XXX.XXX.XXX,
        //'port' => 'non_standard_port_number',
        'username' => 'username',
        'password' => 'passwd',
        'database' => 'hoge',
        'encoding' => 'utf8mb4',
        'timezone' => 'Asia/Tokyo',
        'flags' => [],
        'cacheMetadata' => true,
        'log' => false,
　　　　　　　　　　　　　　　　'url' => env('DATABASE_TEST_URL', null),
　　　　　　　],
    /* fuga */
   'fuga' => [
       'className' => 'Cake\Database\Connection',
       'driver' => 'Cake\Database\Driver\Mysql',
       'persistent' => false,
       'host' => XXX.XXX.XXX.XXX,
       'username' => 'username',
       'password' => 'passwd',
       'database' => 'fuga',
       'encoding' => 'utf8mb4',
       'timezone' => 'Asia/Tokyo',
       'cacheMetadata' => true,
       'quoteIdentifiers' => false,
       'log' => false,
       'url' => env('DATABASE_TEST_URL', null),
   ],
   /* defaultのテスト */
   'test' => [
        'className' => 'Cake\Database\Connection'
        'driver' => 'Cake\Database\Driver\Mysql',
        'persistent' => false,
        'host' => XXX.XXX.XXX.XXX,
        //'port' => 'non_standard_port_number',
        'username' => 'username',
        'password' => 'passwd',
        'database' => 'test',
        'encoding' => 'utf8mb4',
        'timezone' => 'Asia/Tokyo',
        'flags' => [],
        'cacheMetadata' => true,
        'log' => false,
　　　　　　　　　　　　　　　　'url' => env('DATABASE_TEST_URL', null),
　　　　　　　],
    /* fugaのテスト */
   'test_fuga' => [
       'className' => 'Cake\Database\Connection',
       'driver' => 'Cake\Database\Driver\Mysql',
       'persistent' => false,
       'host' => XXX.XXX.XXX.XXX,
       'username' => 'username',
       'password' => 'passwd',
       'database' => 'test',
       'encoding' => 'utf8mb4',
       'timezone' => 'Asia/Tokyo',
       'cacheMetadata' => true,
       'quoteIdentifiers' => false,
       'log' => false,
       'url' => env('DATABASE_TEST_URL', null),
   ],
```

# テスト時に必要な設定
今回のハマリポイント。fixtureにも向き先を指定してやる必要がありました。
https://github.com/cakephp/cakephp/blob/master/src/TestSuite/Fixture/TestFixture.php#L39
冒頭の公式Doc3回位見つめたけど発見できず...

```php:tests/Fixture/PiyosFixture.php
<?php
namespace App\Test\Fixture;

use Cake\TestSuite\Fixture\TestFixture;

class PiyosFixture extends TestFixture
{

    public $table = 'piyo';
    public $connection = 'test_fuga';

    (略)
}
```

# 最後に
ぐぐっていたときにCakePHP2には$useDbConfigがあり、fixtureで明示的に指定してあげるという記述を見かけました。
3系では上記の操作に値したようです。
やっぱりDocumentに頼ってばかりじゃなくてちゃんとソースコード読まないとだめですね。
これさえ知っていればOK、クラウド用語

#前書き
[これさえ知っていればOK、ICT基本用語](http://qiita.com/yagi21/items/dfba7aef5fb8588d37f5)からクラウドについて独立させたものです。
丁寧に解説しているわけではないので、詳細はググってください。

#用語一覧
クラウドは主にSaaS、PaaS、IaaSの3つに分類できる。
それぞれネットワーク越しに提供する範囲が異なる。

###SaaS
Software as a Serviceの略。
**ソフトウェア**を提供する。

例)Gmailなど

###PaaS
Platform as a Serviceの略。
**ハードウェア・OSなどのプラットフォーム**(開発環境)を提供する。
開発環境を提供することにより、開発準備の手間が省けてコストカット・開発作業に専念できる。
レンタルサーバと違い、スケールアップ/アウトが容易に行える。

例)MicroSoft Azureなど

###IaaS
Infrastructure as a Serviceの略。
サーバなどのコンピュータシステムの基盤となる部分を提供する。
OSやDB、プログラミング言語は自分で準備する。
サーバを自前で準備する手間が省ける。

###PaaSとIaaSの違い
![](http://image.gihyo.co.jp/assets/images/admin/serial/01/cloud_career/0004/thumb/TH400_001.jpg)

画像引用元：
[雲を駆け抜けろ　第4回　プラットフォームを作るPaaSを理解する――PaaSとIaaS，SaaSの違い
](http://gihyo.jp/admin/serial/01/cloud_career/0004)

###パブリッククラウド
企業や組織をはじめとした不特定多数のユーザにインターネットを通じて提供するクラウドサービス。

###プライベートクラウド
一つの企業のためだけに構築するコンピューティング環境を提供するクラウドサービス。

###パブリッククラウドとプライベートクラウドの違い
参考ﾘﾝｸ：
[プライベートクラウドとパブリッククラウドの違いとは](https://www.cloud-ace.jp/report/detail05/)


#クラウド業界の動向
- これからはハイブリットクラウド（オンプレミス＋クラウド）。最終的にはクラウドに集約される。
- IoTや人工知能の基盤に使われる。
- IaaSはコモディティ化による価格競争が進んでいる。

##各クラウド事業者の強み・機会
![](http://cloud.watch.impress.co.jp/img/clw/docs/688/718/845_s.jpg)

画像引用元：
[過去のISPのようにクラウド事業者も淘汰されるか？　NTT Comがクラウド市場動向を説明](http://cloud.watch.impress.co.jp/docs/news/688718.html)
PHOTOSHOP JSX開発メモ

# 概要
jsxを書く機会があり、調査した内容を残しておきます。
自分用なので、簡単なメモと参考リンクを貼る程度です。

# 実行方法
1. jsxファイルを次のディレクトリに配置する（mac環境）　→　```Applications/Adobe Photoshop C XXX/Presets/Scripts/```
2. photoshopから　```ファイル　→　スクリプト　→　参照　→　1で作成したファイル```　で実行 ※

※１で正常に配置できた場合は、２の　```ファイル　→　スクリプト```　のリストの中に表示されているが、これはphotoshopが起動した状態のものがキャッシュされていると思われる。
開発中は保存した内容を即チェックしたいので、```ファイル　→　スクリプト　→　参照　→　1で作成したファイル```とすることで即反映される。

# デバッグ方法
あまりいい方法がない・・・
- 変数の中身や計算結果はalertで表示する
- オブジェクトの中身はkey、valueをセットで表示する関数を定義しておく（参考：http://stocker.jp/diary/photoshop-jsx/）

# Photoshopで使えるAPI
http://www.openspc2.org/book/PhotoshopCS6/
OpenCVで出力したaviファイルが再生できない

Pythonを用いたOpenCVで撮影した動画のフレーム間の差分を白黒の動画として出力し、その白黒の動画のファイルは生成されたのですが、再生することができない状況です。 
デフォルトのOpenCVでは無圧縮のaviファイルしか再生できないと書いてあるのを見たことがあるのですがどう対処していいかわからないので教えて頂きたいです。




# -*- codig: utf-8 -*-

import cv2

import time

import numpy as np



def flame_sub(im1,im2,im3,th,blur):

d1 = cv2.absdiff(im3, im2)
d2 = cv2.absdiff(im2, im1)
diff = cv2.bitwise_and(d1, d2)

# 差分が閾値より小さければTrue

mask = diff < th

# 背景画像と同じサイズの配列生成

im_mask = np.empty((im1.shape[0],im1.shape[1]),np.uint8)
im_mask[:][:]=255

# Trueの部分（背景）は黒塗り

im_mask[mask]=0

# ゴマ塩ノイズ除去

im_mask = cv2.medianBlur(im_mask,blur)
return im_mask


if __name__ == '__main__':

cam = cv2.VideoCapture("toukasoku_movie.mp4")

im1 = cv2.cvtColor(cam.read()[1], cv2.COLOR_RGB2GRAY)
im2 = cv2.cvtColor(cam.read()[1], cv2.COLOR_RGB2GRAY)
im3 = cv2.cvtColor(cam.read()[1], cv2.COLOR_RGB2GRAY)


out = cv2.VideoWriter('output_toukasoku.avi',-1, 20.0, (640,480))

while True:

ret,frame = cam.read()
# フレーム間差分計算
im_fs = flame_sub(im1,im2,im3,5,7)
im1 = im2
im2 = im3
im3 = cv2.cvtColor(cam.read()[1], cv2.COLOR_RGB2GRAY)
out.write(frame)
cv2.imshow("Motion Mask2",im_fs)

# フレーム間差分終了

if cv2.waitKey(100) & 0xFF == ord('q'):
cam.release()
out.release()
cv2.destroyAllWindows()
break


def flame_sub2(im4,im5,im6,th2,blur2):

d3 = cv2.absdiff(im6, im5)
d4 = cv2.absdiff(im5, im4)
diff2 = cv2.bitwise_and(d3, d4)

# 差分が閾値より小さければTrue

mask2 = diff2 < th2

# 背景画像と同じサイズの配列生成

im_mask2 = np.empty((im4.shape[0],im4.shape[1]),np.uint8)
im_mask2[:][:]=255

# Trueの部分（背景）は黒塗り

im_mask2[mask]=0

# ゴマ塩ノイズ除去

im_mask2 = cv2.medianBlur(im_mask2,blur2)
return im_mask2


if __name__ == '__main__':

cam2 = cv2.VideoCapture("Frame_detection.MP4")
im4 = cv2.cvtColor(cam2.read()[1], cv2.COLOR_RGB2GRAY)
im5 = cv2.cvtColor(cam2.read()[1], cv2.COLOR_RGB2GRAY)
im6 = cv2.cvtColor(cam2.read()[1], cv2.COLOR_RGB2GRAY)

while True:


#フレーム間差分の差分計算

cv2.imshow("Motion Mask3",cam2)
im4 = im5
im5 = im6
im6 = cv2.cvtColor(cam2.read()[1], cv2.COLOR_RGB2GRAY)
key2 = cv2.waitKey(1)

#フレーム間差分の差分計算終了






if cam == True:
frame = cv2.flip(frame,0)
out.write(out)

# qキーが押されたら

if cv2.waitKey(100) & 0xFF == ord('q'):
cam.release()
out.release()
cv2.destroyAllWindows()
break


if __name__ == '__main__':
main()
CentOS7,firewalldでhttpとsshだけ許可する設定

#CentOS7,firewalldでhttpとsshだけ許可する設定
インフラエンジニアインターンが実際にやってみて、苦戦したところ、理解したところまでまとめます。

#仕様環境
PCのOS:Windows10
使用したソフト:VMware(仮想環境にCentOS7をインストール)、Tera Term

#苦戦したところ

・Firewalldを起動します。その後、次回以降サーバ起動時に自動でfirewalldが起動するよう設定します。

```
[root@localhost ~]# systemctl start firewalld　#サービスを起動するコマンド
[root@localhost ~]# systemctl enable firewalld　#自動起動設定
[root@localhost ~]# firewall-cmd --get-default-zone　#firewalldのコマンド
FirewallD is not running #firewalldが起動してない！！？？
```
firewalldのコマンドを実行すると、何故だか出来ませんでした。

・firewalldが起動してるか確認しました。

```
[root@localhost ~]# systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon
  Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled)
  Active: inactive (dead) since 水 2016-11-02 17:59:18 JST; 4min 23s ago
  Process: 768 ExecStart=/usr/sbin/firewalld --nofork --nopid $FIREWALLD_ARGS (code=exited, status=0/SUCCESS)
 Main PID: 768 (code=exited, status=0/SUCCESS)
```

中程にあるActive: inactive (dead)に注目してほしいのですが、もし起動して
いた場合はActive: active (running)となるはずなので、死んでます。悲しい。

原因は調べてもわからなくてとても長いこと苦戦していましたが、アドバイスを頂き解決出来ました。
```
[root@localhost ~]# yum update 
```

をサーバ構築してから一回もやっていなかったために、出来なかったようです。
yumはiPhoneでいうApple Storeのようなアプリやサービスを管理するもので、
インストールアンインストールアップデート等ができます
サーバを新しく構築する際は、最初に忘れずにyum updateしましょう。


#firewalldの設定
では、気を取り直して再起動して作業再開です。

###firewalldの起動確認
firewalldの起動確認をしてみると

```
[root@localhost ~]# systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled)
   Active: active (running) since 水 2016-11-02 18:46:02 JST; 1min 49s ago
 Main PID: 762 (firewalld)
   CGroup: /system.slice/firewalld.service
           mq762 /usr/bin/python -Es /usr/sbin/firewalld --nofork --nopid
```

Active: active (running)とありましたので、無事起動しています。

###デフォルトゾーンの設定
CentOS7からはfirewalldの設定で、firewalld-cmdというfirewalld専用コマンドを用います。
興味がある方は、今回使った他にもいろいろありますので、調べてみて下さい。
firewalldにはゾーンが9つあり、それに振り分けることでサービスを許可したり拒否したり出来るようですね。
今回はhttpとsshだけ許可し、それ以外は拒否する設定をします。
まずデフォルトゾーンをpublicからdropにして、デフォルトでサービスを拒否するようにします。


```
[root@localhost ~]# firewall-cmd --get-default-zone　#今のデフォルトゾーンを表示
public
[root@localhost ~]# firewall-cmd --set-default-zone=drop　#デフォルトゾーンの設定
success
```

###httpとsshの許可設定

その後、httpとsshだけ許可のゾーンに入れてあげます。
＊＊注意＊＊--permanentを入れないと再起動したときに設定が戻ってしまうので注意してください。

```
[root@localhost ~]# firewall-cmd --add-service=http --permanent　#httpを許可
success
[root@localhost ~]# firewall-cmd --add-service=ssh --permanent　#sshを許可
success
[root@localhost ~]# firewall-cmd --list-all-zones　#どのゾーンに何が入ってるか確認
長いので省略
[root@localhost ~]# firewall-cmd --reload　#設定を適用するために再起動
```

これで設定は終わりです。
httpとsshが許可されているか実際に接続して試してみましょう。

読んで頂きありがとうございました。

firewalldのコマンドやゾーン、基本設定で参考にしたサイトも載せておきます。
http://www.unix-power.net/centos7/firewalld.html
https://www.server-world.info/query?os=CentOS_7&p=firewalld
Behatを使いたいので、GherkinのContextをいろいろ走らせてみる（その１）


覚書です。
とりあえず簡単なfeatureを書いては実行して、どういう動きするのかを確認してみました。

##初期設定
https://blog.hanhans.net/2015/06/26/behat-15minutes/
この記事の内容をほぼそのままやりました。
ここで紹介するContextは大体このやり方で使えます。

##Contextを試してみる

### `Then /^print current URL$/`
今いるぺーじのURLを出力する。
どのページをテストしているかとかを確認する時に利用するっぽい。

###コード

```
Feature: test Gherkin context
  Scenario: check Then print current URL
    Given I am on the homepage
    Then print current URL
```

####実行結果

```
Feature: test Gherkin context
  Scenario: check Then print current URL # features/test.feature:3
    Given I am on the homepage           # Behat\MinkExtension\Context\MinkContext::iAmOnHomepage()
    Then print current URL               # Behat\MinkExtension\Context\MinkContext::printCurrentUrl()
      │ http://www.yahoo.co.jp/
```

### `Then /^print last response$/`
最後のレスポンス内容を出力する。
HTML返されると出力エライことになるから、JSON APIのテスト時とかに使うような気がする。

####コード

```
Feature: test Gherkin context
  Scenario: check Then print last response
    Given I am on "https://wp-kyoto.net/wp-json/wp/v2/hoge"
    Then print last response

```
####実行結果
```
Feature: test Gherkin context
  Scenario: check Then print last response                  # features/test.feature:7
    Given I am on "https://wp-kyoto.net/wp-json/wp/v2/hoge" # Behat\MinkExtension\Context\MinkContext::visit()
    Then print last response                                # Behat\MinkExtension\Context\MinkContext::printLastResponse()
      │ https://wp-kyoto.net/wp-json/wp/v2/hoge
      │ 
      │ {"code":"rest_no_route","message":"URL\u3068\u30ea\u30af\u30a8\u30b9\u30c8\u30e1\u30bd\u30c3\u30c9\uff08request method\uff09\u306b\u5408\u3063\u305f\u30eb\u30fc\u30c8\u304c\u3042\u308a\u307e\u305b\u3093","data":{"status":404}}
```   

### `Then the response status code should be (?P<code>\d+)$/`
レスポンスステータスコードを確認する。
`Then the response status code should not be (?P<code>\d+)$/`もあるので、「レスポンスが500エラーを返していないか？」とか「APIが200を返しているか？」などのテストができる。

####サンプルコード
```
Feature: test Gherkin context
  Scenario: check Then response status code should be
    Given I am on "https://wp-kyoto.net/wp-json/wp/v2/hoge"
    Then the response status code should be 404
    
  Scenario: check Then response status code should not be
    Given I am on "https://wp-kyoto.net/wp-json/wp/v2/posts"
    Then the response status code should not be 404
```

####実行結果

```
Feature: test Gherkin context
  Scenario: check Then response status code shold be        # features/test.feature:11
    Given I am on "https://wp-kyoto.net/wp-json/wp/v2/hoge" # Behat\MinkExtension\Context\MinkContext::visit()
    Then the response status code should be 404             # Behat\MinkExtension\Context\MinkContext::assertResponseStatus()

  Scenario: check Then response status code shold not be     # features/test.feature:15
    Given I am on "https://wp-kyoto.net/wp-json/wp/v2/posts" # Behat\MinkExtension\Context\MinkContext::visit()
    Then the response status code should not be 404 
```

##まとめ
今回試したContextでできそうなこと。

- APIが正しいレスポンスを返しているかのテスト
- webアプリのプロビジョンが正しく機能しているか
- APIのレスポンス内容確認
linux / gv > フォルダ内にあるpsファイルをすべて連結してpdfファイルにする > gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sPAPERSIZE=a4 -dNOPLATFONTS -sOutputFile=tmp.pdf $(ls *.ps)

```txt:動作環境
Xeon E5-2620 v4 (8コア) x 2
32GB RAM
CentOS 6.8 (64bit)
openmpi-1.8.x86_64 とその-devel
mpich.x86_64 3.1-5.el6とその-devel
gcc version 4.4.7 (とgfortran)
NCAR Command Language Version 6.3.0
```

1024個のpsファイルを作成した。
それを別処理したpsファイルと比較したい。

とりあえず連結してpdfファイルとすることにした。

2つのpsファイルを連結する方法は以下で見つけた。情報感謝です。
http://vikslinuxtips.blogspot.jp/2007/08/pspdf.html

それを流用して、以下を実行した。

```
$ gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sPAPERSIZE=a4 -dNOPLATFONTS -sOutputFile=tmp.pdf $(ls *.ps)
```

これですべてのpsファイルが連結したものがtmp.pdfとして作成される。
【AWS- IAM】絶対王政におけるIAMの運用について

## 絶対王政におけるIAMの運用について

AWS運用をやってくなかでちょこちょこ出てくるんだけど、IAMよくわかんね。
って思ったので以下の資料を参考にさせていただいてまとめてみました。

ただまとめるのもつまんないので絶対王政風味。

---
### 参考：

http://www.slideshare.net/AmazonWebServicesJapan/20150617-aws-blackbeltiam?qid=a93c7f89-bf69-44da-b07b-08ef7c9ca706&v=&b=&from_search=1
※ 下記ベストプラクティスはこちらからお借りしました。

---

## そもそもIAMってなんじゃらほい？

### → AWS Identity and Access Management

### Identity : 身元/同一性(この場合ユーザアカウントが対象) → 身分
### Access Manegement : アクセス管理 → 権限管理/委任

### AWSの中で、ユーザとそのアクセス権を管理するためのツールだね。

---


## 絶対王政的なIAMの権限階層(えらい順)

### (1)AWSアカウント(王様)
　→ 万能かつ最強かつ唯一絶対の王者。キング。えらい。
　→ 王権（アカウント）を簒奪されると、全資産を(クレカ情報とか)国ごと持って行かれるため、
　　基本的に権限だけ与えて王座の間に引きこもって働かせないほうがいい。

### (2)IAMユーザーアカウント(領主、騎士、平民)
　→ 王様から割り当てられた権限(Policy)を実行可能なナイト。
　→ 王様から許された範囲でしか活動できないが、割当て次第では王様並になんでもできる。
　　王様から「権限を委任してやるぞよ(administratoraccess)」と言われたやつは、
　　他ユーザー（あと自分にも）権限割り振りが可能。当然こいつも盗まれると危険。

### (3)一時ユーザー：Temporary Securyty Credentials(傭兵)
　→ 戦争や小競り合いのために一時的な許可(SessionToken)を貰って暴れる傭兵。
　→ 雇う側と雇用期間契約(Expiration)を結ぶ。
　　契約は絶対にして不滅のため、期間の延長や途中解雇はできない。

---

## 絶対王政的なIAM政権(ベストプラクティス) 

#### 1. AWS アカウント（ルート）のアクセスキーをロックする
   → 王様が即位したらとっとと玉座の間に引きこもる。

#### 2. 個々の IAM ユーザーを作成する 
   → 騎士叙勲および領地の授与。
#### 3. IAM ユーザーへのアクセス権限を割り当てるためにグループを使う 
   → 公爵、伯爵、子爵、貧乏貴族、平民など、身分制度(roll)を厳格に。
   → 貧乏貴族に資産管理(View Billing)させたり、平民に国庫管理（S3FullAccess)させたりしちゃだめ。

#### 4. 最小限の特権を認める 
   → たまに全ユーザーに権限委任(administratoraccess)しちゃう雑な王様もいる。
　　  その場合、ならずものが城を崩壊（EC2インスタンスを落とす)させたり、
　　  おっちょこちょいが書物に火を（RDSのインスタンスを削除）放ったり、
　　  城壁のゆるいところ(Security Group)を突破して隣国が攻めてきたりするので、
　　  権限委任はかなり慎重に。

#### 5. ユーザーのために強度の高いパスワードを設定する
   → 門番の頭が悪いからといって、間違っても王様の誕生日を数字4文字で合言葉に指定とかしない。
   
#### 6. 特権ユーザーに対して、MFA を有効化する 
   → パスワードがバレても最後の鍵(MFA)を設定することでなんとかなる。
   → ただし、物理MFA紛失したり仮想MFAのアプリを間違って消したりすると
   　 王様本人が玉座の間に入れなくなるから注意。
   
#### 7. EC2で作動するアプリケーションに対し、ロールを使用する 
   → お城(EC2)に配備する騎士や兵士にはちゃんと個々の役割をあたえてあげる。
   　 よそのお城に対する権限与えたりすると喧嘩が起きるので注意。
   
#### 8. 認証情報を共有するのではなく、ロールを使って委託する
   → 身分制度(roll)にちゃんと権限をつけるように。
   　袖の下をもらったからといって通行手形（アクセスキー）を共有したりしちゃいけません。

#### 9. 認証情報を定期的にローテーションする 
   → 通行手形は顔パスにならないように定期的に変えましょう。

#### 10. 不要な認証情報の削除 
   → 通わなくなった行商人、降格された貴族なんかの通行手形は無効にすること。

#### 11. 追加セキュリティに対するポリシー条件を使用する 
   → 出入り口の無い城壁はただの負債(課金されます)なので適切な抜け道をつくること。
   
#### 12. AWSアカウントのアクティビティの履歴の保持 
   → どんな通行人が通ったか、手形番号は控えておきましょう。


以上。
### 各位、平和な国家を築いてください。
これさえ知っていればOK、ICT基本用語

#前書き
私が就活の時に調べたものをまとめたものです。

- ICT業界を受ける就活生。
- ICT業界にいるけどICTとかよくわかんない、でも今のICTのトレンドについて知っておきたい。
- ICT業界の人と仕事してるけど、あいつら何言ってるかよくわからない。

のようなICTにあまりなじみのない方対象です。
最低限のICT知識がないと意味わかんないのもあるかも。そのときはググってください。
細かいこともググってください。

#用語一覧
##☆☆☆
###IoT
パソコンやスマートフォンだけでなく、あらゆるモノがインターネットやクラウドに接続され、相互にやり取りできるようになる仕組みのこと。

後日別記事作成予定。

###AI
コンピュータで人間と同様の知能を再現させようという試み。
この試み自体はコンピュータが誕生した当初からあったが、DeepLearning等の誕生を機に爆発的な盛り上がりを見せている。

###ビッグデータ
たくさんのデータの集まり。
膨大なデータを収集して分析することで、事業の繁栄に役立てたりできる。

###クラウド
インターネット越しにサービスを受けるコンピュータの利用形態。
クラウドを利用すると自社にサーバを立てずに済む。そのため設備費用がかからない。
便利なサービスが気軽に受けられる。

長くなるので[別記事](http://qiita.com/yagi21/items/c8b73510803e44168d3c)にしました。

###VR
Virtual Reality(仮想現実)の略。
ユーザはゴーグル・HMD(ヘッドマウントディスプレイ)を着用することで、360°映像をみたり、仮想空間にいるかのように感じたりすることができる。
PSVRなどゲームや映像業界を中心に盛り上がっているが、手術や危険を伴う作業のシミュレーションなどへの応用も期待されている。

###アジャイル開発
短期間での開発を繰り返して優先度の高いものからつくっていく手法。
現在の主流であるウォーターフォール開発よりも機転が利きやすい。

##☆☆
###AR
Argumented Reality(拡張現実)の略。
ポケモンGOみたいなやつ。

###MR
Mixed Reality(複合現実)の略。
3Dホログラムを現実世界に投影する。リンク先の動画の方がわかりやすい。
[マイクロソフトの「HoloLens」に感じた期待と課題。現実と仮想が混じりあうMRゴーグル](http://japanese.engadget.com/2016/04/29/hololens-jal/)

###仮想化
プロセッサやメモリ、ディスク、通信回線など、コンピュータシステムを構成する資源（および、それらの組み合わせ）を、物理的構成に拠らず柔軟に分割したり統合したりすること。

###ムーアの法則
18か月ごとに集積回路(CPU)の性能が２倍になるという法則。
現在は3年ごとになっている。

###2045年問題(シンギュラリティ)
2045年にコンピュータの知能が全人類を超えるという予測。ムーアの法則に基づいている。
人工知能が自分より優れた人工知能を作り続けるため、人類のコントロールを超え、人間が想像もつかないレベルに達するらしい。

###リスティング広告
GoogleやYahooなどの検索結果画面に広告を表示できるサービス。

###要件定義と設計の違い
要件定義は何を作るか。
設計はどのように作るか。

###RDB
Relational Data Baseの略。
従来のDB。

- 膨大なデータが格納でき、効率的に処理可能。
- データの一貫性を保証するのが大前提。

↑の実現のため、数々の機構を組み込んでおり、処理時間を増やしている。

###NoSQL
Not Only SQLの略。

- データの一貫性はないが、高速処理にフォーカス。
- 単純なデータ構造を処理対象としている。

Cassandraなどがある。

##☆
###ソフトウェアとアプリケーションの違い
「ソフトウェア」は、ウィンドウズ(Windows)やiOSに代表されるオペレーティングシステム(OS)、すなわち基本ソフトウェアに当たる「システムソフトウェア」と、
ワード(Word)やエクセル(Excel)など特定の作業や業務を目的として基本ソフトウェア上で動作する「アプリケーションソフトウェア」に大別される。

###ミドルウェア
ソフトウェアの一種。
OSとアプリケーションソフトの中間に位置し、様々なソフトウェアから共通して利用される機能を提供する。

###サーバ
コンピュータネットワークにおいて、他のコンピュータに対し、自身の持っている機能やサービス、データなどを提供するコンピュータ。

###ホスティング
企業が自社内にあるインターネットに接続されたサーバの機能を、遠隔から顧客に利用させるサービス。

###Open Stack
オープンソースで開発されているクラウド環境構築用のソフトウェア群。IaaS系（後述）。

###SDN
「管理が簡単で個別の機器設定が不要」で、「ハードウェアに依存せず自由に構成変更やリソース追加が可能」なネットワークをソフトウェアで実現する概念。

###シームレス
サービスやシステム、ソフトウェアなどが複数の要素や複数の異なる提供主体の組み合わせで構成されているとき、利用者側から見てそれぞれの違いを認識・意識せずに一体的に利用できる状態。

###SIEM
Security Information and Event Managementの略。
サーバーやネットワーク機器、セキュリティ関連機器、各種アプリケーションから集められたログ情報に基づいて、異常があった場合に管理者に通知したりその対策方法を知らせたりする仕組み。

###HEMS, BEMS
Home/Building Energy Management Systemの略。
gcloud compute ssh でのSSH認証鍵の自動配置を無効化する

## 動機

gcloud compute ssh は自動でSSH認証鍵が配置されてログインできるようにしてくれて非常に便利なツールであるが、逆に言うと、gcloud の OAuth2 認証さえ通っていれば、誰にでもなりすましてログインできるようになってしまうようだ。

```
$ gcloud compute ssh "foo.bar@ホスト名"
```

で foo.bar になりすましてログインできた。なんと。。。

## 対応 

無効化するには、デフォルトで動いている google accounts daemon を止めれば良い。

**Ubuntu14.04**

```
$ ps -ef | grep google | grep accounts
root      1663     1  0 Nov07 ?        00:00:00 /usr/bin/python /usr/share/google/google_daemon/manage_accounts.py
root     14096  1663  0 01:47 ?        00:00:00 /usr/bin/python /usr/share/google/google_daemon/manage_accounts.py
$ sudo initctl list  | grep google | grep accounts
google-accounts-manager-service running
google-accounts-manager-task stop/waiting
$ sudo initctl stop google-accounts-manager-service
$ sudo rm /etc/init/google-accounts-manager-{service,task}.conf
```

**Ubuntu18.04**

```
$ sudo systemctl stop google-accounts-daemon
$ sudo systemctl disable google-accounts-daemon
$ sudo rm /usr/bin/google_accounts_daemon # ねんのため
```

なお、内部動作としては、gcloud compute ssh を打つと、~/.ssh/google_compute_engine{,pub} がなければ生成して、public key を GCE インスタンスのメタデータに登録、ssh しようとするとこの google accounts manager がmetadata から公開鍵を持ってきて対象ユーザの `~/.ssh/authorized_keys` に登録しているっぽい。