OmniAICreator/Qiita-1.07M huggingface dataset:
TabPageViewControllerでスワイプを無効にしたい時

#1. 概要
ニュースアプリ的なレイアウトのアプリを作りたい時に便利な、Endou Mariさんの[TabPageViewController](https://github.com/EndouMari/TabPageViewController)というライブラリ。
しかし、 UITableViewのセルをスワイプする動作を実装しようとすると、タブメニューのスクロールとして感知されてしまいます。

#2. 環境
swift5
Xcode10.2.1

#2. 解決策
TabPageViewControllerを継承したクラスのdataSourceを無効化します。
ただし、タイミング的にはviewDidAppearで行わなければなりません。

```swift:CarouselViewController
override func viewDidAppear(_ animated: Bool) {
    self.dataSource = nil
}
```

TableViewのスワイプ処理は以下を参考にして作りました。
[【Xcode】iOS11からUITableViewのSwipe Actionが新しくなった](http://an.hatenablog.jp/entry/2017/10/23/225424)

これでタブメニューのスクロールは認識されず、セルのスワイプが可能になると思います。

#3. 最後に
Swift初心者なので詳細なことはわかりませんが、「[UIViewControllerのライフサイクル](https://qiita.com/motokiee/items/0ca628b4cc74c8c5599d)」の記事を見る限り、レイアウト処理（TabPageViewControllerのスワイプ認識実装）が終わった後にdataSourceを無効化することで、スクロールを無効化しているのでしょうか…？
訂正・質問などあればコメントお願いします。

#4. 参考
 - [TabPageViewController](https://github.com/EndouMari/TabPageViewController) - 今回使ったライブラリのリポジトリ
 - [【Xcode】iOS11からUITableViewのSwipe Actionが新しくなった](http://an.hatenablog.jp/entry/2017/10/23/225424) - 最新版のスワイプ実装方法が解説されている
 - [UIViewControllerのライフサイクル](https://qiita.com/motokiee/items/0ca628b4cc74c8c5599d) - viewDidLoadやViewDidAppearなどのメソッドが実行されるタイミングが解説されている
良い統計モデルとは？

#はじめに
統計モデルの精度はどのように評価されるのかをまとめました。

参考文献：「データ解析のための統計モデリング入門」

#AICとは
モデル選択規準の一つに、「AIC (Akaike's information criterion)」があります。これは、**良い予測をするモデルが良いモデルである**という考えに基づいて設計された規準です。

※ 観測データにあてはまりが良いモデルが、良い統計モデルであるという考え方は正しくありません。複雑なモデルほど観測データへのあてはまりが良くなるからです。

###数式的定義

最尤推定したパラメーターの個数が*k*であるとき、AICは

```math
\begin{align}
AIC &= -2(\log L^*-k)\\
&= D+2k
\end{align}
```
と定義されます。(逸脱度：$D=-2\log L^*$)

**このAICが一番小さいモデルが良いモデルとなります。**

#なぜAICで「予測の良い」モデルが選ばれるのか
以下の二点について検討していきたいと思います。

・AICで選ばれたモデルは何が「良い」のか
・$AIC=-2(\log L^*-k)$となるのはなぜか
<br>

これには、「最大対数尤度」と「平均対数尤度」の違いを理解することが重要です。

###最大対数尤度
パラメーター推定に使った観測データ自身に対するあてはまりの良さのこと

推定された統計モデルが真の統計モデルに似ているかどうかではなく、**たまたま得られた観測データへのあてはまりの良さ**です。

###平均対数尤度
平均対数尤度は統計モデルの予測の良さを表す量のこと

**真の統計モデルから**予測の良さを評価するデータを生成して、すでに推定された統計モデルに対してあてはまりの良さを対数尤度で評価した平均です。

※ 「真の統計モデル」：単純な真のモデルがあって、そこからデータが生成されると措定した考え方

したがって、統計モデリングの目的が現象の背後にあるメカニズムの予測であるとすると、
**この平均対数尤度が統計モデルの良さの指標となります。**

###AICの定義
最尤推定するパラメーターを *k* 個もつモデルの平均対数尤度の推定量は$\log L^*-k$であることが解析的に導出できるため、これに-2をかけたものがAICとなります。

平均対数尤度は統計モデルの予測の良さでしたから、その推定量である$\log L^*-k$にマイナスをかけたAICは「予測の悪さ」と解釈できます。

**したがって、AICのモデル選択とは、
「予測の悪さ」が小さいモデルを選ぶことになります。**

#まとめ
AICは「あてはまりの良いモデル」を選ぶ規準ではなく、「良い予測をするモデル」を選ぶ規準です。
シンボルのススメ

#目次
1. はじめに
2. シンボルとは
3. シンボルのメリット
4. シンボルの注意点
4. 参考にしたwebサイト

#はじめに
私は、プログラミングをの勉強を初めてまだ2ヶ月の初心者であります。自分のアウトプットも兼ねてまだまだ技術は未熟ではありますが、私以外の初めて間もない方々の役に立つようなことができればと思いまして、投稿をさせていただきます。不備等ございましたら、恐れ入りますがコメントにてご指摘いただければ幸いでございます。

#シンボルとは
文字列の前(後に置くこともできます)にコロン記号":"を書くことで定義されるオブジェクトです。
シンボルと比較されるものとして、文字列があります。
文字列と比較して、説明致します。

###中身は数値である
シンボル生成の際に振り分けられる数値(オブジェクトID)は一つの名前のシンボルに対して、１つです。これに対し文字列は、中身のオブジェクトを確認してみると毎回同じ文字列のものを定義していたとしても、毎回新たな数値のオブジェクトを生成します。同じ名前のシンボル、文字列を2つづつ生成し、２つのオブジェクトの数値を確認すると違いがわかります。さらにこの部分がシンボルの利点につながっていきます。

````ruby
string1 = "kintarou"
string2 = "kintarou"
string1.object_id                #70290363282580
string2.object_id                #70290363219840

--------------------

string1 = :kintarou
string2 = :kintarou
string1.object_id                #10278748
string2.object_id                #10278748
````

#シンボルのメリット
3つに分けて説明していきます。
###メモリ消費が少ない
先程の通り同じオブジェクトとして参照されるので、毎回異なるオブジェクトを参照する文字列オブジェクトに比べ、メモリ消費が少なくなります。

###処理が高速になる
メモリ消費が少なくなることと同じ理由で、文字列に比べ処理が高速になります。

###読みやすい、わかりやすい
可読性が上がるという表現がよく使われます。つまりは読みやすい、ぱっと見ただけで理解しやすく、誤解されにくいということです。

#シンボルの注意点
シンボルの名前に関して、"-"使うとエラーになってしまいます。必要な場合は"_"を利用するとエラーが出ることなく定義できます。ただし、こういった記述をすることで、-を使うことは可能です。

````
:'kin-tarou'
````
この際、定義したハッシュを呼び出す際もがクオーテーション('')が必要となりますので、注意が必要です。

#参考にしたwebサイト
[【Ruby入門】コロン記号の意味とシンボルのやさしいまとめ！](https://www.sejuku.net/blog/13094#i)
[Rubyの文字列とシンボルの違いをキッチリ説明できる人になりたい](https://qiita.com/Kta-M/items/53a13ef60e14fcb41193)
[Rubyのハッシュとシンボル](https://qiita.com/ryosuketter/items/257d672eb83210b5f8dc)
[Rubyのややこしい配列とハッシュとシンボルについて整理してみた](https://blog.isao.co.jp/organize-array-and-hash-and-symbol-of-ruby/)
[Rails チュートリアル](https://railstutorial.jp/chapters/rails_flavored_ruby?version=5.1#sec-hashes_and_symbols)
[配列とハッシュとシンボルは紛らわしいので整理！！](https://qiita.com/iron-breaker/items/32710004f0bb2e2babb6)
[[Ruby]シンボルとは](http://snagimo.com/what-is-symbol-on-ruby)
[Rubyで便利なシンボルとは？使い方とメリットを解説](https://magazine.tech-boost.jp/Programming-languages/ruby/1073520)
WordPressメモ: ページ内リンク

# やりたいこと
**CSSを使ってWordPressのページ内リンクを貼りたい**
[Sample Page](https://ggcs.io/library/japan/constitution-memo/tax/)の目次項目をクリックすると記事本体に飛ぶようにしたい（普通にHTMLでやるとイマイチなので、CSSを使って華麗にキメたい）。

## 概要
**Step 1:** [CSSを追加する](#step-1-cssを追加する)
**Step 2:** [リンク先にタグを付ける](#step-2-リンク先にタグを付ける)
**Step 3:** [リンク元にタグを付ける](#step-3-リンク元にタグを付ける)

## やり方
###Step 1: CSSを追加する
外観 > カスタマイズ > 追加CSS を開き、以下（Fig 1）を追記。こんな感じ（Fig 2）で書き込んで「公開」ボタンを押しておく[^1]。

[^1]: [WordPress 日本語サポート](https://ja.support.wordpress.com/custom-design/editing-css/)

*Fig 1*

```css:CSS
a.anchor{
    display: block;
    padding-top: 110px; /*数値は結果を見ながら適当に*/
    margin-top: -110px; /*上の値とプラマイ打ち消すようにすれば良いみたい*/
}
```

*Fig 2* 外観 > カスタマイズ > 追加CSS を開いて Fig 1のコードを貼り付ける。
<img width="320" alt="fig-02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480830/2cc275db-a8fb-ede2-b31b-4978d642cff4.png">

### Step 2: リンク先にタグを付ける
本文タイトル「**サラリーマン税金訴訟（大島訴訟）**」（Fig 3）に飛ばしたいので、ここにリンク先を設定する。

- まずはターゲットの名前を決める。ここでは、*a002* と名付けた。
- ブロックを「HTMLで編集」（Fig 4）で開き、リンク先文字列の頭にアンカタグ`<a id="a002" class="anchor">`を貼り付ける。
- こんな感じ（Fig 5）（最後の`<a href="#a000">目次</a>`は目次に戻るためのタグ）。

*Fig 3* リンク先（ビジュアル編集）
<img width="320" alt="fig-03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480830/920e5572-2ef5-1e31-0bde-bed6ee2ccf79.png">

*Fig 4* リンク先（HTMLとして編集）
<img width="320" alt="fig-04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480830/0956606b-2445-e2fb-8396-64f9b3e5fdd9.png">

*Fig 5*

```html:HTML
<p class="has-background has-luminous-vivid-amber-background-color"><a id="a002" class="anchor"></a><strong>サラリーマン税金訴訟（大島訴訟）</strong> [<a href="#a000">目次</a>]</p>
```

### Step 3: リンク元にタグを付ける
**リンク元の文字列に普通にリンクを設定する。**
- リンク先指定は `#ナントカ` だけでOK。今回は `id="a002"` に飛ばしたいので、頭に `#` を付けて `#a002`だけ書き入れておけば良い。
- もちろん、`https://example.com/foo/bar/#a002` みたいにフルパスを入れても良い（他のページのアンカに飛ばすときはパスを入れてやればOK）。

<img width="320" alt="fig-06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480830/6e43c34a-0577-62bd-3f95-5a04bd964bb7.png">
【2019年9月版】Cloud Functions のバージョンアップに負けない！Go開発環境の構築方法

前回の記事([【2019年9月版】Cloud FunctionsでGoをデプロイをする際のエラーメッセージが「go: finding ・・・」だった時の対処方法](https://qiita.com/koinori/items/cf381675eb8ac596dfe0))のほぼ焼き直しになりますが、個人的に**この間デプロイしたばっかりのプログラムが今日デプロイするとエラーになる**というのは**トラウマ**レベルのショックな事件でしたので、再度、事前の対策としてどうしておけばよかったのか？というのをまとめておきたいと思いました。
というわけで、改めてこちらの記事とさせていただきます。

とはいえ、キモは以下の一点です。

# Goのバージョンに依存しすぎない、開発環境の構築方法

今回は Go言語での事件でしたが、node.js や python、Java、その他の言語でもありますよね？**バージョンの依存**。。。
プログラム側の依存は一筋縄ではいきませんが、せめて環境だけでも git clone しなおせばOKなようにしておきたいものです。

そんなわけで、以下では`バージョンに依存しすぎない`Go言語の開発環境の構築手順となります。
尚、対象は Ubuntu となります。また、Cloud Functionsを対象とするため、Goのバージョンは1.11.6、とします。(ちょっと古いですがすいません。)

今回、必要なツールは以下の2つです。

- [goenv](https://github.com/syndbg/goenv)
- [direnv](https://github.com/direnv/direnv)

なんと、たったこれだけ。この２つでフレキシブルにイケてしまします。

まずは goenv で go言語ツールキットの切り替えを容易にします。
また同時に GOPATHなどのパスの参照先を楽に切り替えるために、direnvを使用いたします。

## goenv のインストール

こちらのページを参考に・・・

https://github.com/syndbg/goenv/blob/master/INSTALL.md

といっても clone して `goenv init` してパスを通すだけでOKです！
サクッと入れてしまいましょう。

## direnv のインストール

direnvも難しいことはありません。https://github.com/direnv/direnv/blob/master/docs/installation.md

インストールして、`~/.bashrc` で `eval "$(direnv hook bash)"` するだけでございます。
こちらもサクッとインストールしてしまいましょう。

### goenv で go のインストール

まずは goenvから`1.11.6` をインストールしてみましょう。

```
$ goenv install 1.11.6
```

このままでは有効になりませんが・・・まだです！1.11.6を有効にするのはしばらくお待ちください。
続いてGoはビルドするために GOPATHが必要ですが、1.11.6用の GOPATHディレクトリを作成します。
例えば、以下のようにします。

```
$ mkdir -p ~/go_prj/1.11.6

$ cd ~/go_prj/1.11.6
```

で、**ここでdirenvを有効にします**。

まず、以下の .envrcを上記の1.11.6用のディレクトリ直下に作成します。

```bash:.envrc
goenv local 1.11.6

EXPORT GOPATH=~/go_prj/1.11.6
GOROOT ~/.goenv/1.11.6

EXPORT GO111MODULE=on
```

そして、以下のコマンドでdirenvを有効にします。

```
$ direnv allow
```

以上で準備はOKです！

`direnv` でトリガーされた `.envrc`が勝手に `1.11.6` を有効にしてくれます！

この手順で `~/go_prj/1.11.6` 以下のディレクトリでは go 1.11.6 が有効になりました。

## goenv で go のバージョンを追加してみる

例えば Cloud Functions が 1.11.7 をターゲットにする日が来るかもしれません。
ご安心ください。上記の手順を 1.11.7 として行えばよいのです。


```
$ goenv install 1.11.7
...
$ mkdir -p ~/go_prj/1.11.7

$ cd ~/go_prj/1.11.7
```

で `1.11.7`をインストールしたらGOPATH用のディレクトリを作成し、direnv 用のリソースファイルを作成して・・・

```bash:.envrc
goenv local 1.11.7

EXPORT GOPATH=~/go_prj/1.11.7
GOROOT ~/.goenv/1.11.7

EXPORT GO111MODULE=on
```

direnv を有効にすればOKです！

```
$ direnv allow
```

これで`~/go_prj/1.11.7`以下では go 1.11.7が有効になります！

ついでに `~/go_prj/1.11.6`に移動してみると・・・

```
$ cd ~/go_prj/1.11.6
$ goenv loccal
1.11.6
```
はい、即座に1.11.6の環境に切り替わります！


もう、いつCloud FunctionsのGoランタイムのバージョンが上がっても怖くありませんね？！

以上とります。

今後、XX言語バージョンの記事を起こすかもしれませんが・・・
xxenvとdirenvを組み合わせるとバージョンの切り替えが楽ちんになりますよ～、ということでした。
【Android】TelephonyManager#get 系で情報を取得するには READ_PHONE_STATE が必要な理由

# 言いたいこと
Telephonymanager#get 系のメソッド（例えば getSimOperatorName)で情報を取得するには、READ_PHONE_STATE パーミッションが必要です。

# 経緯
業務で TelephonyManager#getSimOperatorName メソッドから通信キャリアの情報を取得する必要がありコードを書いたところ、プルリクエストで

「これ READ_PHONE_STATE パーミッションって必要？ドキュメントに required って書いてないけど？」

と言われました。

https://developer.android.com/reference/android/telephony/TelephonyManager.html#getSimOperatorName()

> getSimOperatorName
>Added in API level 1
>public String getSimOperatorName ()
>Returns the Service Provider Name (SPN).
>
>Availability: SIM state must be SIM_STATE_READY
>
>Returns
>String	
>See also:
>
>getSimState()

確かにドキュメントには書いてないです。

が、実際にこのパーミッションを許可したりしなかったりして調べてみた結果、
**メソッドのアクセスには READ_PHONE_STATE は必要ないが、これを許可せずにアクセスしても空文字しか返ってこない**
ということが分かりました。

 　　　　|パーミッションあり（許可）|パーミッションなし（許可なし）|
-------|-----------------|--------------------|
SIMあり|キャリア情報が取得される|空文字が取得される
SIMなし|空文字が取得される|空文字が取得される

TelephonyManager でググるといろいろ記事は出ますが、みんな当然のように READ_PHONE_STATE を許可していて、**なぜ必要なのか？** ということに言及した記事がなかなか見つからなかったのでここに書きました。
Cool UI - CSSアニメーションボタン 001

## Cool UI - CSS Animation Button 001

暇だったので以下のサイトのボタンを再現しました。

> 日本気象協会
> https://www.jwa.or.jp/

元のサイトにあった余分なHTMLを削り、なるべく最小限なマークアップで再現してみました。
また、蛇足ですが丸を大きくする挙動も足してみました。

## DEMO
<p class="codepen" data-height="265" data-theme-id="dark" data-default-tab="html,result" data-user="loki__codepen" data-slug-hash="OJLomoz" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Cool UI - CSS Animation Button 01">
  <span>See the Pen <a href="https://codepen.io/loki__codepen/pen/OJLomoz/">
  Cool UI - CSS Animation Button 01</a> by Loki (<a href="https://codepen.io/loki__codepen">@loki__codepen</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

---
Twitterのフォロワーを募集しております！
すでにWeb業界にいらっしゃる方や、業界未経験の方、どんな方でも募集しておりますので、どうぞよろしくお願いいたします(\*^^\*)

Twitter - https://twitter.com/loki__tweet
プロキシを通さないと外に出れないネットワーク上にあるWindowsに、DOOM Emacsをインストールした

# 諸注意

[DOOM Emacs](https://github.com/hlissner/doom-emacs)はMacやLinux向けに設計されています。

つまり自己責任で導入お願いいたします。

# 事の発端 tl;dr

Visal Studio2015は地味に画面分割が思い通りにならないなとか思って、本腰入れてDOOM Emacsを職場のWindowsにインストールしてしまった。

ということで、誰かの役に立つかもしれないのでメモ。

# 用意するもの

+ [Emacs本体](https://www.gnu.org/software/emacs/)
+ [Git](https://git-scm.com/)

Emacsの為のWindowsの環境変数設定については省く。

# 手順

## まずGitの設定

### Gitへのプロキシ設定

Gitにプロキシ設定を行う。

```shell-session
$ git config --global http.proxy "http://your.proxy.jp:1234"
$ git config --global https.proxy "https://your.proxy.jp:1234"
```

後でLAN内Gitリポジトリにプロキシを介さずにフェッチなどを行いたいときに、以下の様なシェルスクリプトを組んで保存しておいてもいいかもしれない。

```toggle-proxy.sh
proxy="http://your.proxy.jp:1234"

git config --global --list | grep -sq "http.proxy" 
if [ $? -eq 0 ] ; then
    git config --global --unset http.proxy
    git config --global --unset https.proxy
else
    git config --global http.proxy $proxy
    git config --global https.proxy $proxy
fi
```

### straight.el用の設定もGitに追加。

更にこのDOOM Emacsで使用しているパッケージマネージャー（straight.el）の[issue 347](https://github.com/raxod502/straight.el/issues/347)の情報も参考に下記設定をGitに追加。

```shell-session
$ git config --global url."https://".insteadOf "git://"
```

## すわ、DOOMをインストール。

あとは通常通りのDOOM Emacsのインストール方法である。

```shell-session
$ git clone --depth 1 --branch develop https://github.com/hlissner/doom-emacs ~/.emacs.d
$ ~/.emacs.d/bin doom install
```

Yay! Evil!

あとはお好みで `~/.doom.d` の `init.el` を編集。

あ、アイコン関係のフォントはWindowsにしっかりインストールしておきましょう。

# おまけ mastodon-modeでQiitadon

Qiitaで運営しているmastodonサーバー（インスタンスとも言う）[Qiitadon](https://qiitadon.com)にEmacsから投稿できるようにしてしまったので、それもメモ。

## `.doom.d/` 配下のファイル編集。

```.doom.d/packages.el
(package! mastodon)
```

```.doom.d/config.el
(setq mastodon-instance-url "https://qiitadon.com")
```

それぞれのファイルにそれぞれ上記追記。

## 正直ドキドキの `doom update`

```shell-session
$ ~/.emacs.d/bin/doom update
$ ~/.emacs.d/bin/doom refresh
```

もしくはDOOM Emacsで、`M-x doom update`
した後で `M-x doom refresh`

## 念のためQiitadonのアカウントにパスワード設定

「おまっ、パスワードの無いアカウントなんて許されるわけないだろ！」

と[mastodon.el](https://github.com/jdenen/mastodon.el)から怒られそうなので。

## `M-x mastodon`

あとは大体わかるはずだ。

### Emacs自体のプロキシ

ふとQiitadonへの投稿に成功してしまったのは、Emacsのプロキシ設定もチャッカリしていたからではと思ったので加筆。

```.doom.d/config.el
(setq url-proxy-services '(("http" . "your.proxy.jp:1234")
                           ("https" . "your.proxy.jp:1234")))
```

---

これで皆さんも[ErgoDash](https://github.com/omkbd/ErgoDash)とかで両腕を広げて、
DOOM Emacsを全画面表示にしてどやりながらコーディングできますよ。

# P.S.
gitのプロキシ設定がわかると、上手く行けばVimのプラグインの導入や、[Spacemacs](http://spacemacs.org/)の導入も行けるかと。

おまけ記事ができました。
[で、DOOM Emacsでソースコードリーディングってどうやるんだ？](https://qiita.com/manzyun/items/a145df9902e0765e451b)
「mount: /dev/sdx: can't read superblock」エラーが出た時の対処

# はじめに
何度かディスクを消去したりパーティションを切ったりを繰り返すと不意にマウントができなくなる事が多々ある。

```
# mount -a
mount: /dev/sda1: can't read superblock
```

## どうするか
ネットで同様の事象を調べると、*xfs_repair*コマンドで修復してやると良いと出てくるが
私の場合はうまくいかなかった

```
# xfs_repair /dev/sda1
Phase 1 - find and verify superblock...
xfs_repair: error - read only 0 of 4096 bytes
```

superblock含めディスクを初期化してやることにした。


### partedコマンドでパーティションを削除
```
# parted /dev/sda
GNU Parted 3.1
/dev/sda を使用
GNU Parted へようこそ！ コマンド一覧を見るには 'help' と入力してください。
(parted) p
モデル: FTS PRAID EP420i (scsi)
ディスク /dev/sda: 199GB
セクタサイズ (論理/物理): 512B/4096B

パーティションテーブル: gpt
ディスクフラグ:

番号  開始    終了   サイズ  ファイルシステム  名前     フラグ
 1    1049kB  199GB  199GB                     primary

(parted)
(parted) rm 1
(parted)
(parted) p
モデル: FTS PRAID EP420i (scsi)
ディスク /dev/sda: 199GB
セクタサイズ (論理/物理): 512B/4096B
パーティションテーブル: gpt
ディスクフラグ:

番号  開始  終了  サイズ  ファイルシステム  名前  フラグ


(parted) q
通知: 必要であれば /etc/fstab を更新するのを忘れないようにしてください。
```

### ディスクを初期化
```
# wipefs -a /dev/sda
/dev/sda: 8 bytes were erased at offset 0x00000200 (gpt): 45 46 49 20 50 41 52 54
/dev/sda: 8 bytes were erased at offset 0x2e71fffe00 (gpt): 45 46 49 20 50 41 52 54
/dev/sda: 2 bytes were erased at offset 0x000001fe (PMBR): 55 aa
/dev/sda: calling ioclt to re-read partition table: 成功です
```


再度パーティションを作成し、問題なくマウントできた。
Rのデータセットをcsvファイルにエクスポートする

読み込むデータとしては，psychパッケージのbfiデータを使います。

data(bfi, package="psych")

で読み込んだら，



```ruby:qiita.rb
write.table(bfi, "bfi.csv", sep=",", row.names=F)

```

上記のコマンドを打ち込むだけ

参照サイト
https://researchmap.jp/jojkqcenn-1781589/
【paiza】swiftで文字列の部分一致を確かめる為にcontains()を使ったがうまく動かなかったがxcodeでは動く(自分用メモ)

Swiftはバージョンで書き方が大きく変わっている.
ググった情報がpaizaのバージョン（swift3.0.1）で動かない時がある.
最新のXcodeでplaygroundを開き、そこで動けばOKとして無視する.

# 文字列の部分一致を試したがうまくいかない.
ググったらこんなの方法が出てきたがpaizaでは動かなかった.

```paiza.swift
/* 例
入力値に"ero"を含む文字列を検索したい。
*/

let checker: String = "ero"
let input = "hero"
if input.contains(checker) == true {
    print(input)
} else {
    print("none")
}
// 結果 -> hero

```

# ご指導ご鞭撻お待ちしております
paizaで動かなかったが、Xcodeでは動いたので良しとして、その問題は諦めた。
バージョンに寄る差異がすぐにわかれば直せば良いと思うが、ググってもすぐに見つけられなかったので諦めることにした。(ググり力がないということだとは思います。)
こんな時の対処法、勉強法があれば教えて欲しいです。
(コネタ) extract + contract / extract + partition + customize の差

# osrm-contractがおそい

osrmで地図をビルドする方法には二通りあるわけですが、
俺々lua w/ ラスタデータ にしてから
osrm-contractの方が非常に時間がかかるようになりました。

# 差分は？

公式のQ&Aサイトでも contract が遅いと言っている人がいます。

@wieringen OSRM contains two "acceleration algorithms":
https://github.com/Project-OSRM/osrm-backend/issues/4584#issuecomment-340217359

で、差分はなんだろうと思い調べてみました。

```
osrm-extract+osrm-contract = CH (Contraction Hierarchies). Slow to pre-process, but queries are very fast on the generated data.
osrm-extract+osrm-partition+osrm-customize = MLD (Multi-Level Dijkstra). Faster to pre-process, but queries are slower than CH (perhaps 2x or 3x slower)
After data processing, the routing results should be identical, except for query speed.
```

検索アルゴリズムの違い
* CH(Contraction Hierarchies)はデータ作成時(pre-process)に多くのことをやるので、検索(query)が早い
* Multi-Level Dijkstra は検索がやや遅い


#まとめると

* extract + contract              --> データ作成遅い、ランタイム検索早い
* extract + partition + customize --> データ作成速い、ランタイム検索遅い

以上です
Internet ExplorerとAdobe Acrobat Reader DCを組み合わせるとPDFがダウンロードできないときの緊急対処

#現象
Internet ExplorerとAdobe Acrobat Reader DCを組み合わせるとPDFがダウンロードできない。
PDFはInternet Explorerで表示されるが、保存関係のボタンが無効になっている。

#原因
Internet ExplorerとAdobe Acrobat Reader DCの相性が悪い

#暫定対応
Google Chromeなど、他のブラウザを利用する。

特定のWEBシステムを使っているのであれば、ショートカットを作成し、項目の場所を以下のようにする。
（例としてhttps://www.google.com/）

**"～インストールフォルダ～\chrome.exe" https://www.google.com/**

～インストールフォルダ～については、実際にchrome.exeまでのパスを入れてください。
URLの前に半角スペースが入っているのは、実行時の引数だからです。実行時の引数のURLが表示されます。
なので、実行時の引数に特定のWEBシステムのURLを入れてください。

#本来するべき対応
Internet Explorerの利用を禁止する。

以上
vbsの作法 その31

#概要

vbsの作法調べてみた。
base64encodeしてみた。

#サンプルコード

```

Function base64enc(PlainText)
	Dim st
	Dim dom
	Dim tmp
	Dim bin
	Set st = CreateObject("ADODB.Stream")
	st.Type = adTypeText
	st.Charset = "Shift-JIS"
	st.Open
	st.WriteText PlainText
	st.Position = 0
	st.Type = adTypeBinary
	bin = st.Read
	st.Close
	Set dom = CreateObject("Microsoft.XMLDOM")
	Set tmp = dom.CreateElement("tmp")
	tmp.DataType = "bin.base64"
	tmp.NodeTypedValue = bin
	base64enc = tmp.Text
End Function

Const adTypeBinary = 1
Const adTypeText = 2 
Dim str0, str1
str0 = "あ"
str1 = base64enc(str0)
MsgBox str1

```

以上。
Windowsシミュレータで学ぶuITRON (3) - メールボックス

# はじめに

**uITRON（FreeRTOSベース）Windowsシミュレータ - Qiita**
https://qiita.com/imagou/items/42c687402e6e58fccddb

今回のお題は、何かあったことに加え、追加情報を伝える**メールボックス**です。
（「何かあったこと」のみであれば、[イベントフラグ](https://qiita.com/imagou/items/80ec6e4970de31540524)でOK）

# 本編

## 1. 環境

[こちらの記事](https://qiita.com/imagou/items/42c687402e6e58fccddb#1-1-%E7%92%B0%E5%A2%83)を参照ください。

## 2. 動かしてみる

こちらは[初回記事](https://qiita.com/imagou/items/de102b81d0049b819532#2-%E5%8B%95%E3%81%8B%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B)を参照。

### 2-1. タスクでのメール送受信

改めて[**「2-2. 送信タスク・受信タスク」**](https://qiita.com/imagou/items/de102b81d0049b819532#2-2-%E9%80%81%E4%BF%A1%E3%82%BF%E3%82%B9%E3%82%AF%E5%8F%97%E4%BF%A1%E3%82%BF%E3%82%B9%E3%82%AF)の動作を確認してください。

## 3. 解説

### 3-1. 概要

メールボックスとは、前述したように**「何かが発生したことに加え、情報を伝える仕組み」**です。
（「メール」って名称からお察しではありますが・・・）

メールの型（メッセージという呼び方をします）はユーザーで自由に決められます。
若干面倒なポイントは以下です：

- **ユーザーがメッセージ領域を確保する必要あり**
- **メッセージの取得・解放もユーザーの責務**


### 3-2. コードによる説明

以降は、プログラムコード - `main.c`を引用して説明します。

#### 3-2-1. メッセージ定義・領域確保

メッセージの型と、領域（64個分）の確保箇所は以下です。

```C
/*--- Message ---*/
typedef struct {
    T_MSG       msg;
    ID          id;
    uint32_t    params[1];
} MESSAGE_ENTITY;

#define MESSAGE_SIZE    (64)
static MESSAGE_ENTITY   g_Messages[MESSAGE_SIZE];
static uint16_t         g_MessageIndex = 0;
```

注意事項として、構造体先頭の`T_MSG msg;`は必ず含めてください。RTOSの予約領域です。

#### 3-2-2. メッセージ取得・解放

以下を参照ください。

```C
/* メッセージ取得 */
static MESSAGE_ENTITY* GetUserMessage(void) {
    uint16_t index = g_MessageIndex++;
    index %= MESSAGE_SIZE;
    return &(g_Messages[index]);
}
/* 解放はまだ用意していない */
```

`GetUserMessage()`は、リングバッファとして領域を扱い、返しているだけです。

解放は色々あって未実装ですが、メッセージを同時に64個以上送信することがなければ、なくてもいいかなーと思っています（面倒くさいわけではないですよ！笑）。

#### 3-2-3. メールボックス生成

`cre_mbx()`で生成します。

```C
    T_CMBX cmbx;
    cmbx.mbxatr = TA_TFIFO;
    cre_mbx(MAILBOX_ID(RECV), &cmbx);
```

`cre_mbx()`のパラメータは下表：

|パラメータ番号|名称|説明|
|---|---|---|
|第1パラメータ|メールボックスID|単なるID。<br>以降はこのIDでもってメールボックス送信・受信を実施。|
|第2パラメータ|T_CMBX構造体変数|以下で説明|

T_CMBXのメンバは下表：

|名称|指定可能な値|説明|
|---|---|---|
|mbxatr|TA_TFIFO &#124; TA_TPRI|メールボックス属性。<br>それぞれ、待ちキューの順序をFIFO順とするか、優先度順とするか。|

**※なお、mbxatrはこれ以外の値も指定可能（だが、上記のみで必要十分と考える）。**

#### 3-2-4. メールボックスへの送信

`snd_mbx()`を使います。
`id`にはイベントを数値に変換したもの、`params[0]`にはカウンタを渡して送信しています。

```C
        MESSAGE_ENTITY* ent;
        ent = GetUserMessage();
        /* Numeric Event */
        /* メッセージIDはイベントを（数値に戻して）設定 */
        /* パラメータにカウンタを渡す */
        int32_t num = 0;
        for (num = 0; !((flgptn >> num) & 1) ; num++) ;
        ent->id = (ID)num;
        ent->params[0] = ++count;

        snd_mbx(MAILBOX_ID(RECV), (T_MSG *)ent);
```

#### 3-2-5. メールボックスからの受信

`rcv_mbx()`を使用します。

```C
        T_MSG *msg;
        rcv_mbx(MAILBOX_ID(RECV), &msg);
        MESSAGE_ENTITY* ent = (MESSAGE_ENTITY*)(msg);
        DEBUG_PRINT("[%s]: RECV MESSAGE (%d,%d)", __func__, ent->id, ent->params[0]);
```

### 3-3. TBD

TBD（今後追加していく予定）

# おわりに

メールボックスは、メッセージ領域の確保が若干面倒なので、
**イベントフラグ＋外部変数**
という使い方をする方も多いように思います（やってることは変わりませんからね）。
が、一応解説してみました。笑

# 参考

**Micro-ITRON4.0 Specification (in Japanese)**
http://www.ertl.jp/ITRON/SPEC/mitron4-j.html
【PowerApps】重複の無い連番のID番号の振り方

#何をしたいのか？
ソースデータにはID列を作ってPatch関数やSubmitForm関数で外部保存をする時に重複の無いID番号を振っておくと、その後にレコードの編集や削除をする時に便利です。

しかし、簡単そうでしたが、意外と情報が無く、実現するのに苦労したのでここに備忘録しておきます。

#Max関数を使う。
Max関数は指定の列の最大値を出す関数なので、それで今現在ID列にある最大値をだしてそれに１を足す。

```
Max(Database,ID) + 1
```
良い感じなんですが、Max関数は委任が出来ないのでデータ数が2000を超えたら使えません。ですから使わない方が良いです。

#Last関数を使う。
Last関数はそのテーブルの最後のレコードを返します。要は最後に保存されたレコードです。
https://docs.microsoft.com/ja-jp/powerapps/maker/canvas-apps/functions/function-first-last

レコードですので、どの列かを指定する必要があります。前回のレコードのIDに１足した数が今回のIDです。

```
Last(Database).ID + 1
```
~~この関数は委任されるので結構使えます。~~(2019/10/08修正：すみません、Last関数は委任されません。）さらに、厳密に言うとこの関数でID番号を取得し、実際に外部保存が完了するまでに若干タイムラグがあるので、同じアプリを複数の人で使う場合で、ほとんど同時に外部保存がされた場合は同じID番号が振られてしまう可能性はあります。

#GUID関数を使う。
英語圏ではこの関数を使っている人がいます。この関数は連番ではないですが、重複の無い文字列を取得出来ます。
https://docs.microsoft.com/ja-jp/powerapps/maker/canvas-apps/functions/function-guid

```
GUID()
```
数式は簡単なのですが、出てくる文字列が長すぎて使い物になりません。

#SharePointのID列を使う。
これが僕の結論です。SharePointのリストをデータベースに使う場合ですが、一番シンプルで簡単だと思います。英語ですが、参考リンクを貼っておきます。

https://sharepointmaven.com/how-to-add-a-unique-identifier-to-a-sharepoint-list-or-library/

SharePointのリストには実はID列が自動で生成されていて、データを保存すると整数の１から順番に連番が振られていきます。これをそのまま利用するのです。

しかし、その列は通常は非表示です。次の手順で表示できます。

対象SharePointリストを表示して画面右の「Add column」、「Show/Hide columns」の順にクリックする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403091/a4081dae-7e1a-61ff-232b-aabddedae377.png)

次の画面で「ID」にチェックを入れて、そのIDをドラッグして一番上まで持っていきます。ちなみに僕は「Title」列は使い難いので使いません。ですので、ここでチェックを外して非表示にします。

そして上の「Apply」をクリックしますが、これだけでは保存されません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403091/8e87ee8d-8341-41eb-4a4a-23629a6d3a4e.png)

そのちょっと上にある「All Items」、「Save view as」をクリックしてちゃんと保存ができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403091/665b1736-172f-094e-6792-c4837a0dcac8.png)

これでID列が表示されてちゃんと連番が作られていきます。これはSharePointの機能ですので確実に重複なしの連番が自動で割当てられていきます。

このIDの名前も変更できますが、PowerApps内では変わらず「ID」で参照することになりますのでご注意ください。ちなみにこのIDは数値型です。
Spreadsheetで管理しているTODOをGASを使ってslackにリマインドする

# 概要
毎月1本くらいは記事書こうねとか、有給が上手に取れなくて期限が来る前にまとめてバタバタ取ると大変なので毎月１回は取ろうねーとか
定期的にやらないとダメだけど忘れがちなものとか、アンケートとか
リマインドしててもリマインドしてることすら忘れちゃうので、チームみんなまとめてリマインドするスクリプトを作りました。

スプレッドシートで管理することで、自分だけじゃなくて他の誰かが気づいて追加できて運用できるってのがなかなかいいと思ってる。
あと個人的に○○さんはもう終わってるのかっていう追い込みが効いてる。

# TODO管理するSpreadsheetのフォーマット
以下のフォーマットで`TODO`って名前で作ってスクリプトエディタにソースコードを貼ると多分動きます。
![スクリーンショット 2019-09-13 18.15.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30928/865bd323-c0b2-7076-ee60-cd77ba82d16e.png)


# ソースコード
```javascript:gas
var SPREADSHEET = SpreadsheetApp.getActiveSpreadsheet();
var SHEET = SPREADSHEET.getSheetByName('TODO');
var SLACK_WEB_HOOK_URL = 'ここにウェブフックのURL';
var TODO_SHEET = 'TODOが管理されてるシートのURL';

function main() {
  const today = new Date();
  // 営業日以外はおとなしくしとく。
  if (!isBusinessDay(today)) {
    return;
  }

  const message = getReminderMessage()
  if (message.length) {
    message += "\n\n対応お願いします。"
    message += "\n" + TODO_SHEET
    postSlack(message)
  }
}

function getReminderMessage() {
  const range = SHEET.getRange('3:1001');
  const today = new Date();
    
  var message = []
  range.getValues().forEach(function(row, rowIndex){
    const notCompatible = []
        if (typeof(row[1]) == 'object' && row[1].getTime() < today.getTime()) {
          row.forEach(function(e, index) {
            if (e == '未対応') {
              notCompatible.push(getName(index+1))
            }
          })
          
          if (notCompatible.length) {
            message.push(row[0] + "の期日です。")
            message.push(notCompatible.map(function(e) { return "<@" + e + ">" }).join(" "))
          }
      }
  })
  
  if (message.length) {
    message.push("\n\n対応お願いします。")
    message.push("\n" + TODO_SHEET)
  }
  return message.join("\n")
}

// ２行目に書いてるslackID取得するやつ
function getName(index) {
  const slackIdRow = '2'
  const range = SHEET.getRange(wmap_column_convert(index) + slackIdRow);
  return range.getValue()
}

//列番号のアルファベット列名変換
function wmap_column_convert(colmun_number) {
  var result = SHEET.getRange(1, colmun_number);
  result = result.getA1Notation();
  result = result.replace(/\d/,'');
  
  return result;
}

// 営業日かどうか
function isBusinessDay(date){
  if (date.getDay() == 0 || date.getDay() == 6) {
    return false;
  }
  var calJa = CalendarApp.getCalendarById('ja.japanese#holiday@group.v.calendar.google.com');
  return calJa.getEventsForDay(date).length === 0
}

function postSlack(message) {
  var jsonData =
  {
    "link_names" : 1,
    "text" : message
  };
  var payload = JSON.stringify(jsonData);

  var options =
  {
    "method" : "post",
    "contentType" : "application/json",
    "payload" : payload
  };

  UrlFetchApp.fetch(SLACK_WEB_HOOK_URL, options);  
}
```

# slackのユーザーIDの取得方法
ユーザの詳細画面出してメニューっぽいところ押したらコピーできるみたい
![スクリーンショット 2019-09-13 17.59.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30928/4dffc709-3d47-85eb-05a7-00001ac3541b.png)


# 参考
[Google Apps Scriptで営業日を判定してトリガーを作成する方法](https://tonari-it.com/gas-trigger-businessday/)
[スプレッドシートで管理しているタスクをSlackにリマインドする方法](https://qiita.com/n11sh1/items/a9609eddce91662ce592)
vbsの作法 その30

#概要

vbsの作法調べてみた。
urlencodeしてみた。

#サンプルコード


```
Function Urlencode(strSource)
    Dim sc
    Dim js
    Dim str
    Set sc = CreateObject("ScriptControl")
    sc.Language = "JScript"
    Set js = sc.CodeObject
    str = js.encodeURI(strSource)
    Urlencode = str
End Function


Msgbox Urlencode("あ")
```

以上。
Nuxt(Vue) + TypeScriptでの$refsの参照エラー


## 概要
子コンポーネントで定義したメソッドを親コンポーネントから直接呼び出したい！
そうだ$refsを使おう！

```
Property '子コンポーネントのメソッドないしはプロパティ名' does not exist on type 'Element | Element[] | Vue | Vue[]'.
Property '子コンポーネントのメソッドないしはプロパティ名' does not exist on type 'Element'.
```
そんなプロパティないって言われてるやんけぇ_:(´ཀ`」 ∠):


## 解決策
```vue
<template>
    <children-component ref="children"></children-component>
</template>

<script lang="ts">
import { Component, Vue } from 'nuxt-property-decorator'
import ChildrenComponent from '@/components/organisms/ChildrenComponent.vue'

@Component({
  name: 'ParentComponent',
  components: {
    ChildrenComponent,
  }
})
export default class ParentComponent extends Vue {
    $refs!: {
        children: ChildrenComponent
    }

    // ChildrenComponentにあるfugaメソッドを直接ParentComponentで呼びたい場合
    private hoge(): void {
        this.$refs.children.fuga()
    }
}

</script>
```

## 詳細
importした子のコンポーネントを型として呼び出せば、その子のコンポーネントにあるpublicのプロパティやメソッドは直接呼び出せる！

```vue
<script lang="ts">
import { Component, Vue } from 'nuxt-property-decorator'

@Component({
  name: 'ChildrenComponent'
})
export default class ChildrenComponent extends Vue {
    // アクセスできない
    private murimeProperty: string
    // アクセスできる
    public fugaProperty: string

    // できない
    private murimeMethod(): void {}
    // できる
    public fuga(): void {}
}
</script>
```

## 余談
ちゃんと型定義すると補完で出てくるの気持ちよすですよねー
今回の場合はVueクラスの$refsをオーバーライドしてるんかな・・
もっとTypeScriptの深淵にゆきたい今日この頃
DBから取得したものをcsv化。ブラウザでダウンロードできるようにする。(Microsoft Excelでも見れるようにする)。

# 環境
## サーバーサイド
* フレームワーク： goa
* ORM：gorm
* DB： MySQL

## フロントエンド
* Vue.js(単一ファイルコンポーネント)
* axios(Vue内で利用)
* file-saver(Vue内で利用)

# 決まっている要件

* csvをダウンロードするAPIを作成。
* ブラウザ上でボタンをクリックすると、APIが叩かれ、csvがダウンロードできるようにする。
* Microsoft Excelでも文字化けせず、見れるようにする。

# 前置き
今回、`goa`のcontrollerの一つをcsvダウンロード用にしています。
`goa`でcontrollerを作るなどには言及しません。

# サンプルコード

## サーバーサイド(golang)

``` golang
package controller

import (
        "bytes"
        "encoding/csv"
        "strconv"

        "github.com/jinzhu/gorm"
        "github.com/goadesign/goa"
)

// 色々他のコントローラがあることを想定...
// ...

// GetCsv runs the get csv action.
func (c *MyAppController) GetCsv(ctx *app.GetCsvMyAppContext) error {
        // MyAppController_GetCsv: start_implement

        // ...DBから値を得るなどしていることを想定
        // ...

        b := &bytes.Buffer{}
        w := csv.NewWriter(b)
        headers := []string{"id", "名前", "猫種"}
        w.Write(headers)
        w.Flush()

        catDB := models.NewCatsDB(c.db)
        cats, _ := catDB.List(ctx.Context)
        for _, cat := range cats {
                record := []string{}
                record = append(record, strconv.Itoa(cat.ID))
                record = append(record, cat.Name)
                record = append(record, cat.Breed)
                
                w.Write(record)
                w.Flush()
        }

        rw := ctx.ResponseWriter
        rw.Header().Set("Content-Type", "text/csv")
        rw.Header().Set("Content-Disposition", "cat_list.csv")

        csvLength := strconv.Itoa(b.Len())
        rw.Header().Set("Content-Length", csvLength)

        rw.Write(b.Bytes())

        return ctx.NoContent()
        // MyAppController_GetCsv: end_implement
}
// 色々他のコントローラがあることを想定...
// ...
```

## フロントエンド(Vue.js)

``` vue.js
<template lang="pug">
div
  // ...
  // ...
  button(@click="csvDownLoad()") CSVダウンロード

</template>
<script>
import saveAs from 'file-saver'

export default {
  ...
  ...
  methods: {
    csvDownLoad () {
      // axiosは、main.jsなどにグローバルで登録をしておき、this.$axiosで呼び出せるようにしてあります。
      this.$axios
        .get(`${process.env.API_URL}/api/cats/csv`) // getで呼び出すAPIは、今回はgoaで生成したものに合わせているという前提になります。
        .then(response => {
          let mimeType = response.headers['content-type']
          const name = response.headers['content-disposition']
          const data = response.data // サーバーサイド(goa)からのレスポンスに合わせている。
          const bom = new Uint8Array([0xEF, 0xBB, 0xBF]) // Microsoft Excelでも見れるように
、BOMを付与。
          const blob = new Blob([bom, data], {type: mimeType})
          saveAs(blob, name)
        })
    },
    ...
    ...
  }
}
</script>
```

# 個人的ポイント
## axiosでサーバーサイドからのレスポンスを取得してから、BOM付与処理をする。
サーバー内にのどこかのディレクトリ(例えば`/tmp`とか)に、そのまま書き込むのであれば、サーバサイドで、SJIS変換処理(BOMをつけるなど)をすれば良いと思います。

しかし、golangの`ResponseWriter`を噛ませて、ブラウザ側でファイル取得をすると、サーバーサイド側でSJIS化の処理していても、UTF-8フラグがついてしまうのか、文字化けしました。

なので、Vue.js側でBOMを付与して、BOM付きのutf-8にすることによって、Microsoft Excelでも文字化けせずに表示できるようにしました。


goaを使っていて、さらに`ResponseWriter`を噛ませたりするのは、どうなのか？みたいな気持ちはあるのですが、この辺もし良い方法が他にあったら、教えてください。
【Java】スタックトレースをフィルタリングする

# やること
`SpringBoot`等のフレームワークで`Exception`を自作して、既知の挙動としてエラーを吐く場合であっても、スタックトレースはそのままログに表示されてしまいます。
つまり、エラーが起きている原因がアプリケーション内なのは明白なのに、単純に無駄な情報が表示されているということになります。

スタックトレースが長ければ読解の邪魔になりますし、ログ容量が増えすぎて問題を起こすこともあるため、余計な情報は無い方がよいです。

そこで、スタックトレースをフィルタリングします。

# やり方
以下のようにフィルタリング関数を用意し、コンストラクタで`setStackTrace`することでできます。
パッケージ名は`com.wrongwrong.example`のような文字列で、ルートパッケージを指定します。

```java
public class MyException extends RuntimeException {
    static StackTraceElement[] filteringStackTrace(StackTraceElement[] elements) {
        return Arrays.stream(elements)
                .filter(it -> it.getClassName().startsWith("${パッケージ名}"))
                .toArray(StackTraceElement[]::new);
    }

    public MyException(String msg) {
        super(msg);
        setStackTrace(filteringStackTrace(getStackTrace()));
    }
}
```
UnityでのOculus Touch入力まとめ

Oculus Rift、Rift S、QuestのコントローラーのOculus Touchのよく使いそうな入力をまとめておきました。
RiftとRift S、Questのコントローラーは形状は違いますが、両方ともOculus Touchと言うらしいです。

前提として、Assetである、[Oculus Integration](https://assetstore.unity.com/packages/tools/integration/oculus-integration-82022)が必要です。

#ボタン、トリガー入力

ボタンを押したときにTrue

```
OVRInput.GetDown()
```

ボタンが押しっぱなしの時にTrue

```
OVRInput.Get()
```

ボタンが離されたときにTrue

```
OVRInput.GetUp()
```

右手のOculusボタンは入力ができないです。

Aボタン入力

```
if(OVRInput.GetDown(OVRInput.RawButton.A))
{
}
```
Bボタン入力

```
if(OVRInput.GetDown(OVRInput.RawButton.B))
{
}
```
Xボタン入力

```
if(OVRInput.GetDown(OVRInput.RawButton.X))
{
}
```
Yボタン入力

```
if(OVRInput.GetDown(OVRInput.RawButton.Y))
{
}
```
メニューボタン入力

```
if(OVRInput.GetDown(OVRInput.RawButton.Start))
{
}
```
右人差し指トリガー入力

```
if(OVRInput.GetDown(OVRInput.RawButton.RIndexTrigger))
{
}
```
右中指トリガー入力

```
if(OVRInput.GetDown(OVRInput.RawButton.RHandTrigger))
{
}
```
左人差し指トリガー入力

```
if(OVRInput.GetDown(OVRInput.RawButton.LIndexTrigger))
{
}
```
左中指トリガー入力

```
if(OVRInput.GetDown(OVRInput.RawButton.LHandTrigger))
{
}
```
右スティックボタン入力

```
if(OVRInput.GetDown(OVRInput.RawButton.RThumbstick))
{
}
```
左スティックボタン入力

```
if(OVRInput.GetDown(OVRInput.RawButton.LThumbstick))
{
}
```

#トリガーの押し込みを取得する
Oculus Touchのトリガーは押し込みを調整する事が出来ます。その値を0～1までfloat型で取得出来ます。

右中指トリガーの取得

```
float tmp = OVRInput.Get(OVRInput.RawAxis1D.RHandTrigger);
```

右人差し指トリガーの取得

```
float tmp = OVRInput.Get(OVRInput.RawAxis1D.RIndexTrigger);
```

左中指トリガーの取得

```
float tmp = OVRInput.Get(OVRInput.RawAxis1D.LHandTrigger);
```

左人差し指トリガーの取得

```
float tmp = OVRInput.Get(OVRInput.RawAxis1D.LIndexTrigger);
```

#スティックの動きを取得する
Vextor2でX軸、Y軸は-1～1で取得出来ます。

右スティックの取得

```
Vector2 tmp = OVRInput.Get(OVRInput.RawAxis2D.RThumbstick);
```
左スティックの取得

```
Vector2 tmp = OVRInput.Get(OVRInput.RawAxis2D.LThumbstick);
```

#スティックをデジタル入力する
アナログのスティックですが、上下左右の押し込みをbool型で取得できます。

右スティックを上に倒した

```
if (OVRInput.GetDown(OVRInput.RawButton.RThumbstickUp)) {
}
```
右スティックを下に倒した

```
if (OVRInput.GetDown(OVRInput.RawButton.RThumbstickDown)) {
}
```
右スティックを左に倒した

```
if (OVRInput.GetDown(OVRInput.RawButton.RThumbstickLeft)) {
}
```
右スティックを右に倒した

```
if (OVRInput.GetDown(OVRInput.RawButton.RThumbstickRight)) {
}
```
左スティックを上に倒した

```
if (OVRInput.GetDown(OVRInput.RawButton.LThumbstickUp)) {
}
```
左スティックを下に倒した

```
if (OVRInput.GetDown(OVRInput.RawButton.LThumbstickDown)) {
}
```
左スティックを左に倒した

```
if (OVRInput.GetDown(OVRInput.RawButton.LThumbstickLeft)) {
}
```
左スティックを右に倒した

```
if (OVRInput.GetDown(OVRInput.RawButton.LThumbstickRight)) {
}
```
visualStudio 参照マネージャー　COM　ない

プロジェクト作成の時に(.NET Framework)がついてるプロジェクトにしないと参照マネージャーでCOMオブジェクトが表示されません！

![com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255687/6fd69e9a-807d-3929-61d9-9ac61dcc21bf.png)
【CSRF】Railsの持つ対策機能

久々にブログ更新。

 

スクールではチーム開発が始まり、なんか知らんけどスクラムマスターになりました。

他メンバーよりもコードを書く時間がないっていうのがちょっと辛いところですが、インフラからフロントまで広く勉強していけるのはいいですね。

 

いいです。いい・・かなぁ？器用貧乏さが増すような・・。まぁいいや。

 

<h2>CSRFとは</h2>
クロスサイトリクエストフォージェリと呼ばれる。
この攻撃により、掲示板や問い合わせフォームなどを処理するWebアプリケーションが、本来拒否すべき他サイトからのリクエストを受信し処理してしまいます。

具体的な手順はこんな感じ

１：攻撃者は攻撃用Webページを準備し、ユーザがアクセスするよう誘導する。

２：ユーザが攻撃用Webページにアクセスすると、攻撃用Webページ内にあらかじめ用意されていた不正なリクエストが攻撃対象サーバに送られる。

３：攻撃対象サーバ上のWebアプリケーションは不正なリクエストを処理し、ユーザが意図していない処理が行われる。

フィッシングサイトとか、詐欺メールとかよく言われるやつかなと思います。


<h2>Railsで行われているCSRF対策</h2>
application controllerにprotect_from_forgery with: :exceptionの記述がある。

この記述により、Railsが生成する全てのフォームやAjaxリクエストで自動的にセキュリティトークンを含めることができる



application.html.erbにcsrf_meta_tagsというメソッドも埋め込まれている

RailsのjQueryはPOST送信時にこのメソッドで追加されるHTMLタグの情報を自動的に使用するため、このメソッドがあれば特に何もせずともCSRF対策がなされる

こんな感じで、コントローラ及びビューそれぞれで脆弱性対策を行なっているようです。
CI/CDとは

# はじめに
最近、仕事でCI/CDを担当することになったため、備忘録を残そうとこの記事を書きました。CI/CDについて名前を聞いたことがあるレベルだったので、まずは概念の理解から。

# CI/CDとは
CI/CDとは、開発のステージに自動化を取り入れて、アプリケーションを提供する頻度を高める手法です。
CI/CDのコンセプトは継続的インテグレーション、継続的デリバリー、継続的デプロイメントです。
ちょっと何言ってるのか分からないので各コンセプトの説明をします。
ちなみに「CI」が継続的インテグレーション、「CD」が継続的デリバリー、継続的デプロイメントを指します。

# 継続的インテグレーション
今どきのアプリケーションはgitを用いて複数人のメンバで開発します。当然各機能に対して、同時に開発を進め、ブランチにマージしますよね。
マージ後も問題なくアプリケーションが動作することを確認して、マージを許可するという作業に時間が取られ、開発のペースダウンにつながります。
そこで、継続的インテグレーション(CI)は、開発者による変更がアプリケーションにマージされると、自動的にビルドし、テストを実行し、変更を検証します。
ビルド～単体テスト、結合テストを自動化します。
このような自動サイクルを回すことにより、バグを素早く容易に発見し、修正することができます。

# 継続的デリバリー
継続的デリバリーでは、検証されたコードのリポジトリへのリリースを自動化します。
簡単に言うと、本番環境にデプロイできるコードベースを常に保持します。
コード変更のマージから本番環境対応のビルドのデリバリーまで、すべてのステージでテストの自動化とコードリリースの自動化が実施され、プロセスの終了時には、本番環境に素早く簡単にデプロイできます。

# 継続的デプロイメント
本番環境対応のビルドをコードリポジトリへ自動的にリリースして、継続的デリバリーの延長として、継続的デプロイメントはアプリケーションを本番環境に自動的にリリースします。
簡単に言うと、上記フェーズでの自動テストをクリアしたら、自動的に本番環境にデプロイするよってことです。

# 最後に
自分のお勉強がてら、メモベースでまとめただけですので、分かりづらくて、すいません。
参考にしたサイトのリンクを載せておきます。
[CI/CD とは(redhat)](https://www.redhat.com/ja/topics/devops/what-is-ci-cd)
mysqlでメールアドレスのドメイン部分だけを取得するor書き換える方法

# ドメイン部分を取得する

以下のSQLでメールアドレスのドメイン部分だけの一覧を取得することが出来ます。

```sql
select right(email, char_length(email) - instr(email, '@')) from users;
```

# 解説

## right
文字列を右から指定した文字数だけ取得します。

## char_length
文字列の長さを取得します。

## instr
最初に指定の文字が出現する位置を返します。

## 全体で　
メールアドレスを(文字数の全体 - @が表示される位置)の文字数右から取る。というロジックです。

# メールアドレスを書き換える場合

以下のようにすることでメールアドレスのドメインを特定のドメインに一括で書き換えることが出来ます。

```sql
update users set email = concat(left(email, INSTR(email, '@')), 'macloud.jp') where 'email' not like '%@macloud.jp'
```
Ruby on Railsで使うコマンド

# 概要

割と毎回ググっていて効率悪いなと思ったのでここにまとめる。
随時更新予定。

## railsを起動する

```
rails s -b 0.0.0.0 -p 3000 RAILS_ENV=development
```

## db/schema.rbを更新する

```
rake db:schema:dump RAILS_ENV=development
```

## DBマイグレーション実行

```
rails db:migrate
```

## DBマイグレーションロールバック

```
rails db:rollback STEP=1
```

## DBマイグレーションリセット(リセット後にseedを実行する)

```
rails db:reset
```

## DBマイグレーションリセット(リセット後にseedを実行しない)

```
rails db:migrate:reset
```

## DB作成

```
rails db:create
```

## シードデータを作成

```
rake db:seed
```
vbsの作法 その29

#概要

vbsの作法調べてみた。
formをpostしてみた。

#サンプルコード

```
Dim url
Dim param
Dim xhr
Dim res
url = "http://hohe.com/dump.php"
param = "param1=1.2&param2=3.4&param3=5.6"
Set xhr = CreateObject("MSXML2.XMLHTTP.3.0")
xhr.Open "POST", url, False
xhr.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
xhr.send param
res = xhr.Status
If res <> 200 Then
	msgbox "error!"
Else
	msgbox xhr.responseText
End If
```

以上。
【Python】ABC - 107 - Grid Compression【set型】

# 問題
黒を表す'#'と白を表す'.'で構成されたマス目において、'.'しか存在しない行（または列）を削除して出力するという問題。
# 方針
以下の方針でAC。

1. 行方向の探索
行方向に'.'の数をカウントして、列数と一致するとすべて白マスだと判定し、その行を削除する。

2. 列方向の探索
それぞれの行で見たときにすべての行で'.'であるインデックスが存在すれば、その列の要素すべてが白マスだと判定して、その列を削除する。
pythonのset型の積集合を用いて、すべての行のインデックスの要素で共通するインデックスを特定する。

3. 上記の行と列を削除したものを出力する。

```python
H, W = map(int, input().split())
a_list = [list(input()) for _ in range(H)]
# 白マスを表す'.'の数をカウント
dot_cnt = [sum([a == '.' for a in a_col]) for a_col in a_list]
# すべてが'.'とならない行のインデックスを取得
exist_idx = [i for i, num in enumerate(dot_cnt) if num != W]

# set型で表現する集合の初期化（今回は積集合をとるため、すべてのインデックスを含む集合を定義）
st = set(range(W))

for i in exist_idx:
    # それぞれの行における'.'のインデックスを取得
    dot_idx = [i for i, a in enumerate(a_list[i]) if a == '.']
    # 積集合を取得（すべての行を探索した後に生き残ったインデックスがすべて白マスの列を表現）
    st = st & set(dot_idx)

for i in exist_idx:
    # 出力の整形（リストをjoinすることで文字列の連結を実現）
    print(''.join([a for i, a in enumerate(a_list[i]) if i not in st]))
```

# 別解
自分では思いつかなかったが、配列を転置させる解法も存在。
これも知らなかったが、ndarrayではなくリストでもzipを用いて転置できるらしい。
【参考】
[AtCoder Beginner Contest の B 問題全部やったので詰まったやつや面白かったやつを紹介する【Python3】](https://www.planeta.tokyo/entry/3984/)
[Python標準で転置行列](https://qiita.com/mas9612/items/821fbb4c881b7a836451)
vbsの作法 その28

#概要

vbsの作法調べてみた。
excel使わないで、xls読んで、みた。

#インストール

```
Microsoft Access データベース エンジン 2010 再頒布可能コンポーネント
```

#サンプルコード

```
Dim sh
Dim cd
Dim xls
Dim str
Dim db
Dim sql
Dim rs

adClipString = 2
Set sh = CreateObject("WScript.Shell")
cd = sh.CurrentDirectory
xls = cd & "\Book1.xls"
Properties="Excel 8.0;HDR=YES";
str = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & xls & ";Extended Properties=""Excel 8.0;HDR=YES"""
Set db = CreateObject("ADODB.Connection")
db.Mode = 1
db.Open str
sql = "SELECT * FROM [Sheet1$]"
Set rs = db.Execute(sql)
msgbox rs.GetString(adClipString, , ",", vbCrLf, "")
db.Close
```

以上。
mongoシェルのfindコマンドのprojectionで計算などが出来るようにaggregateを使って新たなfindを作る

# 概要
Mongoシェルの**db.collection.find()**で`projection`はフィールドの出力可否しかできない。**Aggregation**の`$project`ようにもっといろいろなことが出来たら良いと思います。そこで、**db.collection.aggregate()**を使って新しい`db.collection.agfind(query, projection, others)`を作ってみます。

コマンドの追加の詳細は「[mongoシェルのdb,collectionにコマンドの追加](https://qiita.com/h6591/items/be96f41cc5d9ebf151cc)」を参照してください。

# 実装例

```javascript
DBCollection.prototype.agfind = function(query, proj, others) {
   let pipeline = []
   if (query!= undefined && Object.keys(query).length > 0) {
      pipeline.push({$match: query})
   }
   if (proj != undefined && Object.keys(proj).length > 0) {
      pipeline.push({$project: proj})
   }
   if (others != undefined && Object.keys(others).length > 0) {
      Object.keys(others).forEach(key => {
         let doc={}
         doc["$"+key] = others[key]
         pipeline.push(doc)
      })
   }
  return this.aggregate(pipeline)
}
```

`Object.keys(match).length > 0`は空ドキュメントのときはPipelineに入れないため。

`others`は追加のPipeline Stageを配列でなくドキュメントで記述し、Stage名の`$`は付けない。例として次のように記述します。
`[{$sort:{field1:1}}, {$limit:1}]`は
`{sort:{field1:1}, limit:1}`とする。


# 実行例


データの作成

```javascript

db.col.insert([
{a:1, b:11, c:"abc"},
{a:2, b:22, c:"opqr"},
{a:3, b:33, c:"xyz"}
])
```


まずは通常の`find`と同じ使い方

```javascript

> db.col.agfind()
{ "_id" : ObjectId("5d8035a3047fb359c5337c0a"), "a" : 1, "b" : 11, "c" : "abc" }
{ "_id" : ObjectId("5d8035a3047fb359c5337c0b"), "a" : 2, "b" : 22, "c" : "opqr" }
{ "_id" : ObjectId("5d8035a3047fb359c5337c0c"), "a" : 3, "b" : 33, "c" : "xyz" }
```

```javascript
> db.col.agfind({a:{$gt:1}},{_id:0,a:1,b:1})
{ "a" : 2, "b" : 22 }
{ "a" : 3, "b" : 33 }
```

`a,b,c`を別名で出力します。

```javascript
> db.col.agfind({},{_id:0,数量:"$a", 金額:"$b", メモ:"$c"})
{ "数量" : 1, "金額" : 11, "メモ" : "abc" }
{ "数量" : 2, "金額" : 22, "メモ" : "opqr" }
{ "数量" : 3, "金額" : 33, "メモ" : "xyz" }
```

`a+b`を`total`として出力します。

```javascript
> db.col.agfind({},{_id:0, total:{$add:["$a","$b"]}})
{ "total" : 12 }
{ "total" : 24 }
{ "total" : 36 }
```


`others`を使ってみます。

```javascript
> db.col.agfind({},{_id:0, total:{$add:["$a","$b"]}, c:1}, {sort:{total:-1}, limit:2})
{ "c" : "xyz", "total" : 36 }
{ "c" : "opqr", "total" : 24 }
```
RealSenseライブラリについて【雑文】【Python】

# 内容

　python 3.6以下でないと動作しない。

　Realsenseには、デプスカメラver.(D435)とトラッキングカメラver.(T265)がある。ライブラリは共通しているが、それぞれ使用できる関数／設定値が異なるため、注意すること。姿勢推定はトラッキングカメラver.の方でのみの提供らしい。サンプルコードの説明にて、「a T265 is required.」とかなんとか書いてある。

　デプスカメラの方はOpenNIを使用すると良いはず。デプスカメラの方で姿勢推定などの機能が提供されていないのは、こういった有名どころのライブラリとの互換性を持たせるため？　真意は分からない。結局変数の受け渡し時にはnumpyを使用するだろうから、型さえ意識してれば使えるのだろうか。

# 参考
- RealSenseサンプルコード：[https://dev.intelrealsense.com/docs/code-samples?_ga=2.129005705.407926829.1568688964-592016067.1563410396](https://dev.intelrealsense.com/docs/code-samples?_ga=2.129005705.407926829.1568688964-592016067.1563410396)
【資格試験】  スケジュールと記録等まとめ

今年度は転職活動してたこともあり、ベンダ資格を取れるだけ取ろうとしてるので、そのスケジュールと記録のまとめ。

####１．受験スケジュール
#####2019年
######8月
・Python3エンジニア認定基礎試験（8.30/<font color="red">合格</font>）
######9月
・なし
######10月
・HTML5プロフェッショナル認定試験(レベル1)（10.5/<font color="red">合格</font>）
・ネットワークスペシャリスト認定試験(10.20/<font color="red">午前Ⅰ免除獲得</font>)
######11月
・ディープラーニングG検定(11.9/<font color="blue">不合格</font>)
　※やっぱり、当日頑張って調べようくらいの気持ちじゃ合格できない。。
######12月
・ウェブデザイン技能検定２級(12.1/<font color="red">12/27合格発表、午前の問題なさそう</font>)
<font color="red">・LinuC レベル1(101)</font>
#####2020年
######1月
<font color="red">・Oracle認定Javaプログラマ(silver)</font>
<font color="red">・Ruby技術者認定試験(silver)</font>
######2月
・AWS認定デベロッパー(アソシエイツ) ※検討中

####２．受験結果、感想
#####(1)Python3エンジニア認定基礎試験
https://qiita.com/ydzum1123/items/e586ca6fc9ddfc83b343
#####(2)HTML5プロフェッショナル　レベル１認定試験
https://qiita.com/ydzum1123/items/05f233ff6589f03971ed

####３．その他、気になってる資格
#####
(1)ACiT(Appleが認定するiOS技術者の資格)

　
【概要】
　　お店でApple社製品を扱ったり、Apple社に就職してAppleStoreのスタッフになるために必要な認定資格(？)
　【動機】
　　アプリ開発経験はあるけどBtoB向けでポートフォリオにおおっぴらにかけないし、製品とかアプリのこと知ってるよ、って証明になる資格が何かあればなぁ、という感じ
　　(ちょっと動機と位置づけにギャップがありそう。あんまり情報無くて分からない)

　シラバスをちょっと見た感じ、製品より業務に寄った内容っぽかったのでスルー。

#####(2)アジャイルソフトウェア開発技術者検定
　【概要】
　　アジャイル開発のこと知ってるよ、の検定
　　レベル１、２があるらしい。
　【動機】
　　SIerでのキャリアしかないので、こういう検定持ってると、小規模でアジャイルメインなデベロッパでも転職しやすいかな、と。
　　(チラッと見かけただけなので、どれくらい「つぶしがきく」かは不明。。
　　　新しい上にかなりマイナっぽいので、市場価値は微妙。)

#####(3)Python3エンジニア認定試験(データ分析)
Pythonエンジニアになりたいわけじゃないけど。
せっかく基礎試験のほうは取得したので、どうせなら発展的な内容にも挑戦したい。

#####(4)CCNA, CCNP
ネットワーク系の人には知名度が高そうな資格。
ネットワークはいつまで経っても概念を理解しきれないので、こういう資格を取れば、その勉強をする過程で理解も深まるかなぁ、と。
Webで問題集を使った勉強ができるサイトがあったり、(単純に自分のタイミングで受験できる、って意味でも)IPAのネスペよりは取りやすいかなぁ、と思ったけど、受験料が高い。

#####(5)Webデザイン技能検定(2級)
Webデザイン系の国家資格、ということもあり、
ベンダー資格より普遍的な価値があるかな、と。
実技でAdobeのイラレ、フォトショも使えないといけないらしいことも聞いてるので、
そのあたりのスキルを身に着ける意味でも勉強してみたい。

#####(6)AWS認定資格(アソシエイトレベル３種)
今後、個人としても業務としても、Webサービスの開発をしていく上では、
どこかでぶつかりそうな気がするので、ある意味では一番「使える知識」が身につきそうな気がする資格。

#####(7)App Development with Swift(Apple認定)
Rubyによるデザインパターンを読んだメモ

:warning: この記事は私が本を読み進めるたびに追記されます

## メタ設計パターン

以下のような問が発生したときの回答となるような**メタ設計パターン**がGoFによって述べられている。

### 問

- どのように他のオブジェクトと関連するのか
- それらはどのように結びつくべきなのか
- それらは互いに何を知るべきなのか
- 頻繁に変わりそうな部品を入れ替えるにはどうすればいいか

### メタ設計パターン

- 変わるものを変わらないものから分離する
- インターフェイスに対してプログラミングし、実装に対して行わない
- 継承より集約
- 委譲、委譲、委譲

また、ラス・オルセンのアイディアとして

- 必要になるまで作るな

## Template Method

[Github](https://github.com/bino98/design-patterns-in-ruby/tree/master/template-methods)

> あなたのコードは44行目を除いて全く同じことをさせたいのかもしれません。44行目はこっちをしたいときもあるし、あっちをしたいこともあります。そのような時は **Template Method** が使えます。

基底クラスに普遍の部分を記述し、変わる部分はサブクラスに定義するメソッドにカプセル化します。基底クラスはメソッドを未定義にしておくことができます。ただしその場合はサブクラスでそのメソッドを提供しなければなりません。

### 用語

- フックメソッド
    - Template Methodの具象クラスによってオーバーライドできる非抽象メソッドのこと
    - サブクラスが使うことができるメソッド。具体的な意味を持つので、非抽象と言えるのかな。
- ダックタイピング
    - JavaやC#ではインタフェースが決められていて、**このクラスはどのインタフェースを持つか。それらの型はなにか。**が定義される。Rubyの場合は、**クライアントが呼び出そうとしているメソッドをオブジェクトが実装している**ことだけをチェックする。これをダックタイプと呼ぶ

### ダックタイピングできることは危険なことか？

静的型付けのほうが安心に思えるかもしれない。

現実的に、周りに出てきた言語は静的型付けを行うことができる言語も多い。当たり前のように静的型付け言語を使用しているが、見逃している点がある。それは「静的型付けのコスト」である。馬鹿にならないはず。

Rubyによって書かれたRuby on RailsやRubyの標準ライブラリは現実に存在し、それが問題なく動いていることが動的型付け言語でも問題が起きないことを示している。

### 実例

- `Webrick::GenericServer` を継承する `HelloServer`
- `initialize` メソッド

## Strategy

[Github](https://github.com/bino98/design-patterns-in-ruby/tree/master/strategy)

> ひょっとすると変わるのは44行目ではなくてアルゴリズム全体なのかもしれません。ちゃんと仕事は定義されていて、完了させる必要があるのですが、方法が沢山あるのです。猫を檻から出す仕事があったとき、それには1つ以上のテクニックがあるかもしれません。それらのテクニックやアルゴリズムをラップするのが、 **Strategy** オブジェクトです。

### Template Method と解決したいことは同じ...？

Template Methodは問題解決のために、継承の上に成り立っている。そのため、たとえどんなに注意深くコードを設計しても、サブクラスはそのスーパークラスに依存してしまいます。一度、アルゴリズムを選択すると方針を変えるのが困難になり、レポートフォーマットを変更する必要がある場合、わざわざ具象クラスを作る必要がある。単に *出力形式を切り替えたいために*...

GoFのメタ設計パターンでは 継承より集約 と述べている。サブクラスをたくさん作る代わりに、たくさんの変化に富んだコードの塊をすべて引き剥がしてクラスに閉じ込めてしまうのはどうだろう。

### GoFではコンテキストと呼ばれる

> クラスの外部からはストラテジオブジェクトが同じように見えることから、ストラテジの利用者（GoFでは**コンテキスト（Context）**と呼んでいます）はそれらを取替可能なパーツとして扱うことができるようになります。

*ストラテジオブジェクト*を使う側を、**コンテキスト**と呼ぶ。なぜなら、ストラテジオブジェクトは同じ仕事をこなすだけではなく、正確に同じインタフェースを提供するため、外側から見た場合、どんなストラテジオブジェクトがDIされても、気にしない。

### Strategyパターンの現実的なメリット

> 関心の分離をとてもうまく達成することができます。Strategyパターンを使うことで、一切の責務と知識を、`Report`クラスから取り除くことができるのです。

### Template Methodと共通すること

バリエーションの決定を1箇所ないしは数箇所に集中できるという点。

- Template Methodの場合は、具象サブクラスを選択するとき
- Strategyの場合は、実行時に注入するストラテジオブジェクトの選択するとき

### コンテキストとストラテジ間でのデータを共有する方法

2つある

- ストラテジオブジェクトにメッセージを送るときに、ストラテジ内部で必要なデータを引数として設定して送る方法
- ストラテジオブジェクトにコンテキストオブジェクト自身を送る方法

### ダックタイプ

> 「抽象」Formatter基底クラスと、HTMLFormatterとPlainTextFormatterの2つの派生クラスから構成していました。しかしながら、この方法はかなり「Ruby的ではない」手法です。

どちらの派生クラスも、同じインタフェースを共有していれば、それは同じである...というダックタイプの哲学で言えば、別に*基底クラスを保つ必要はない*。一般にRubist達は基底クラスをすっ飛ばすやり方を好みがち