OmniAICreator/Qiita-1.07M huggingface dataset:
ITの知識0で応用情報技術者試験に独学で受かった話

※この記事のせいで落ちたなど言われても責任はとれないのでそこはすいません。
##高専に入って５日
高専に入って5日くらいたったときに実践技術単位という話を聞いた。
資格、試験、学校のお手伝いをするとたくさん単位がもらえて、多ければ多いほど研究室選びが優遇されるよというもの。
もちろんその種類によってもらえる単位の数が違う。
その中で一番単位数が大きかったのが応用情報技術者試験だった。
ちなみに
Tパスポート試験 （情報処理推進機構） [経済産業大臣] ｛１｝ 
基本情報技術者試験 （情報処理推進機構）  [経済産業大臣] ｛５｝ 
応用情報技術者試験 （情報処理推進機構）[経済産業大臣] ｛８｝ 
こんな感じ。
他にも英検数検漢検や危険物、無線とかがある。
これを見た瞬間、応用情報をとろうと思った。
題名の通り、この時のぼくのIT知識は0。
データベースやブラウザの意味もわからないレベルだった。
##基本情報技術者試験を受ける
さすがに一発目で応用情報技術者試験を受けるのは無謀だと思い、一年生の秋に基本情報技術者試験を受けた。
知らない方の為に説明しておくと簡単な順に
ITパスポート
基本情報技術者試験
応用情報技術者試験
がある。（基本情報と応用情報は範囲が異なるため上位関係にはない）
それぞれ4月の第三日曜日、10月の第三日曜日に試験がある。
本題に戻るが、結果をいうと不合格だった。
勉強時間は合計で20時間くらいだったと思う。
勉強内容は有名な参考書（過去問じゃなくて教科書のようなもの）を一冊、それも一周しただけだった。
勉強サボったのもそうだけど全然解けなくて悔しかった。
この時は対して知識もないくせに無謀に基本情報受けてるなんて思われたくなくて、一人で辛さを抱え込んでいた。
##応用情報技術者試験を受ける
高専2年生の春。
基本情報落ちたけど応用情報受かったらチャラになるよねと思い、基本情報は諦めた。
だけどこのとき全然勉強がはかどらなくて、受ける前から落ちることに自分で悟っていた。
やっぱり落ちた。
##応用情報技術者試験二回目
高専3年生の春。
今までは受験費を親からもらっていたけど、受けすぎやと言われて今回からは実費。
しかし、不合格。
このときは周りの人にも話していて、割とネタにしていた。
##応用情報技術者試験三回目
高専3年生の秋。
前回の反省を生かして教科書のような参考書は全くなしに受験。
その代わりにWebサイトとこのとき購入した本一冊だけ勉強した。
結果合格した。
##独学でいけるか
最初から最後まで、過去問や参考書は学校の図書館から借りたので僕は受験費以外お金をかけていない。
と言いたいとこだけど応用情報３回目の時に一冊だけ本を買った。
でも講座とかは行ってないし独学っちゃ独学。
高専に通学する内に知識をつけるのでは、という意見があるかもしれないが、僕の学科では情報を勉強することは少なかった。
再三いうが、本当にITの知識が全くなく、二進数の概念から勉強を始めた。
終わってから思うと、一日3時間勉強ができる方ならば一ヶ月で合格できるレベルだった。
４回も受けたから説得力ないかな笑
所詮試験だから最短で合格できる道筋があるので、僕が思うその道を紹介する。
##勉強法
応用情報は午前試験と午後試験の二つ試験があり、どちらも6割を取れれば晴れて合格となる。
####午前試験
午前試験の対策は過去問の本を使ってもいいが、とてもオススメのサイトがある。
応用情報技術者ドットコムといって、過去28回の午前試験の問題を一問一答形式で答えることができる。
ユーザ登録をすれば自分が間違えた問題だけ解くこともできるし、何より解説が素晴らしい。
午前試験の対策はマジにこのサイトで十分。
28回分あるが、最新10回分の過去問を8割解けるようになれば大丈夫。
応用情報技術者試験ドットコム
https://www.ap-siken.com/apkakomon.php
####午後試験
次は午後試験の対策だが、午後試験の勉強は午前試験の勉強をある程度進めてからがいい。
午後試験は午前試験の知識が土台となって解くことができるからだ。
が、午後試験は『国語』の問題とよく言われ、あの長ーい文章を理解できれば解ける問題が多いというのも事実。
午前が通ってもここを通らない人は8割ほどしかいないので午前ができるようになればもうすぐだ。
午後問題は唯一僕が本を購入したのだが、小口達夫さんのものがオススメ。
午後問題だけを取り上げているので洗練されてるし、また解説が素晴らしい。
午後は閃き問題みたいなとこあるのでこれは一周すれば十分だと思う。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/367062/855e73ca-3885-238e-b7a7-c652c77ac0ff.png)
##最後に
応用情報のような資格は自分のスキルをたった10文字ほどで証明できるので持っているとすごくいいと思う。
だけど応用情報で勉強した知識を使うことは今のところなく、もちろん受かったからといってエンジニアにはなれない。
TOEIC900点代でもビジネス英語喋れない人がいるのと同じで、資格って外から見たらすごいけど本当のスキル証明にならないきがるする。
いやもしかしたらスキル証明に特化した資格があるのかなーあったら教えてほしい。
【メモ】ローカルからAWSのEC2にフォルダを転送する際に詰まったところ

## 背景
AWSのEC2にファイル転送するときに少し詰まったのでメモ


## フォルダ転送コマンド
キーのあるディレクトリに移動し以下のコマンドを実行すればローカルフォルダを転送できる

```
$ scp -i [.pemファイルの場所].pem -r [転送元のローカルフォルダの場所]　[ユーザー名]@[パブリックDNSかパブリックIP]:[転送先の場所]
```
・オプションの意味
-i :接続に使用する公開鍵ファイルを指定する
-r :ディレクトリ内を再帰的にコピーする

## エラー
以下のようなエラーが出た

```
Permission denied (publickey). 
```

## 解決策
AWSで作成したインスタンスのオーナーは”ec2-user”（Amazon Linux の場合）しかし、デフォルトではアクセス権限がないため、”ec2-user”(オーナー)に書き込み権限を与えることで解決した

awsインスタンスにssh接続して以下のコマンドを実行し書き込み権限を与える

```
sudo chown -R ec2-user [転送先]
```

## 参考文献
[エラー「Permission denied.」と「No such file or directory.」の判別方法](https://support.sugutsukaeru.jp/ja/troubleshooting/installation/146.html)
Homebrew で Composer をインストール

# 環境
- macOS Siera 10.12.6

# インストール

```bash
$ brew install composer
==> Downloading https://getcomposer.org/download/1.8.4/composer.phar
######################################################################## 100.0%
🍺  /usr/local/Cellar/composer/1.8.4: 3 files, 1.8MB, built in 21 seconds
```

# 確認

```bash
$ composer -v
   ______
  / ____/___  ____ ___  ____  ____  ________  _____
 / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
                    /_/
Composer version 1.8.4 2019-02-11 10:52:10
```
Homebrew で PHP7.2 をインストール

# 環境
- macOS Siera 10.12.6

## インストール済みのPHPバージョン
```bash
$ php -v
PHP 5.6.30 (cli) (built: Oct 29 2017 20:30:32) 
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
```

# インストール

Formulaを探す。

```bash
$ brew search php72
==> Formulae
php@7.2
```


```bash
$ brew install php@7.2
==> Installing dependencies for php@7.2: apr, openssl, apr-util, argon2, aspell, autoconf, brotli, c-ares, libidn, libmetalink, libssh2, jansson, jemalloc, libev, libevent, nghttp2, openldap, rtmpdump, curl-openssl, libtool, unixodbc, freetds, libpng, freetype, gettext, libffi, pcre, glib, gmp, icu4c, jpeg, libpq, libsodium, libzip, readline, sqlite, tidy-html5 and webp
==> Installing php@7.2 dependency: apr
==> Downloading https://homebrew.bintray.com/bottles/apr-1.6.5.sierra.bottle.tar
######################################################################## 100.0%
==> Pouring apr-1.6.5.sierra.bottle.tar.gz
==> Caveats
```
略

# 確認

```bash
$ php -v
PHP 5.6.30 (cli) (built: Oct 29 2017 20:30:32) 
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
```

ターミナルを再起動後、改めて確認するも変化なし。

## シンボリックリンクの作成

```bash
$ brew link php72 --force
Linking /usr/local/Cellar/php@7.2/7.2.15... 25 symlinks created

If you need to have this software first in your PATH instead consider running:
  echo 'export PATH="/usr/local/opt/php@7.2/bin:$PATH"' >> ~/.bash_profile
  echo 'export PATH="/usr/local/opt/php@7.2/sbin:$PATH"' >> ~/.bash_profile
```

## パスを通す
```bash
$ echo 'export PATH="/usr/local/opt/php@7.2/bin:$PATH"' >> ~/.bash_profile
$ echo 'export PATH="/usr/local/opt/php@7.2/sbin:$PATH"' >> ~/.bash_profile
```

## 再び確認

ターミナルを再起動後、確認。

```bash
$ php -v
PHP 7.2.15 (cli) (built: Feb 26 2019 10:47:19) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.2.15, Copyright (c) 1999-2018, by Zend Technologies
```

おしまい。
Homebrew をインストール

# 環境
- macOS Siera 10.12.6

# インストール

https://brew.sh/index_ja

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

上記、公式サイトに記載されていたインストール用のスクリプトをターミナルで実行。

```bash
==> This script will install:
/usr/local/bin/brew
/usr/local/share/doc/homebrew
/usr/local/share/man/man1/brew.1
/usr/local/share/zsh/site-functions/_brew
/usr/local/etc/bash_completion.d/brew
/usr/local/Homebrew
==> The following new directories will be created:
/usr/local/Caskroom

Press RETURN to continue or any other key to abort
==> /usr/bin/sudo /bin/mkdir -p /usr/local/Caskroom
Password:
```
中略

```bash
==> Installation successful!

==> Homebrew has enabled anonymous aggregate formulae and cask analytics.
Read the analytics documentation (and how to opt-out) here:
  https://docs.brew.sh/Analytics

==> Homebrew is run entirely by unpaid volunteers. Please consider donating:
  https://github.com/Homebrew/brew#donations
==> Next steps:
- Run `brew help` to get started
- Further documentation: 
    https://docs.brew.sh
```

途中、パスワードの入力を求められたりしながら数分で終了。

# 確認

## バージョン確認

```bash
$ brew -v
Homebrew 2.0.2
Homebrew/homebrew-core (git revision 46be2; last commit 2019-02-27)
```

## 環境診断

```bash
$ brew doctor
Your system is ready to brew.
```

# メモ
Homebrewのインストールを説明する記事では
事前にXcode（Command Line Tools）のインストールを行なっているものが多い。

今回、Homebrewを直接インストールしたが特に問題はなさそう。

https://sutepulu.com/homebrew-about-command-line-tools-installation/
>Command Line Toolsがインストールされていない場合は、以下のように、Homebrewのインストール中にCommand Line Toolsが自動でダウンロードされ、インストールされました。
Telemetry入門

Telemetryに入門したので、まとめる。

# Telemetryとは
超ざっくり言ってしまうと、SNMPの後継とされる技術
SNMPではサーバ側からデータ送信を要求（Pull）していたが、Telemetryではノード側から自動的にデータ送信を行う（Push）。またデータはGPB（Google Protocol Buffer）形式やJSON形式で出力され、今どきのDBや可視化ツールを用いて処理することができる。

# Telemetry＝新しいプロトコル？ → No!
Telemetryはプロトコルの名前ではない。
Push型で様々なデータを出力し、それを活用するソリューション全体を指す言葉と考えた方がよい。

# Telemetryシステムのコンポーネント
Telemetryを利用するには、システムに以下の要素が存在しなくてはならない。
（これが全てではなく、最低限。他の要素も存在しうる）

### ノード
当然のことだが、データを送信するノードがTelemetryに対応しなくてはならない。
ノードが「Telemetryに対応」とは、以下の全てを実装していることを示す。

- **データモデル**<br>出力可能なデータはYANGモデルで定義されている必要がある。業界標準を目指すOpenConfigに準拠したデータモデルと、ベンダ依存のデータモデルが存在する。<br>当然OpenConfigの方が便利に思えるが、各ベンダのH/Wに依存したデータ等はベンダモデルでしか表現できないため、全てをOpenConfigだけで賄えるわけではない

- **トランスポート**<br>データの送信には以下のいずれかのプロトコルを用いる。Cisco開発者曰く、UDPは送信は早いがdatagramサイズに制限があるため、TCPかgRPCがよいとのこと。
    - TCP
    - UDP
    - gRPC

- **エンコーディング**<br>送信するデータのフォーマット。GPBを用いる場合は、受信側（コレクタ）でデコードが必要。
    - GPB：データはバイナリで送信
    - GPB-KV：key-value形式のテキストで送信
    - JSON：全てテキストで送信

### コレクタ
ノードとトランスポートセッションを確立し、データを受信・デコードし、データストアに送信する。現時点（2019年3月）では、ベンダ毎に異なるコレクタを用いるのが一般的。

### データストア
コレクタから受信したデータを格納する。Telemetry専用のソフトウェアがあるわけではなく、InfluxDBやElasticsearchといった時系列DBが用いられる。

### ダッシュボード
データストアのデータを図表にするなど人間が見やすい形に表現する。Grafana、Kinaba等が用いられる。
あるブックの任意の範囲を別のブックの指定した箇所にコピペする　その2

今回は、前回作成したマクロ
『同じフォルダ内にある「○○一覧.xlsx」の任意のシート内容をそれぞれ別のファイルに転記する』
を配列と繰り返し構文を使用して改修しました。

```vb
Sub tenki1()
 
'○○一覧を開く
    Workbooks.Open ThisWorkbook.Path & "\◯◯一覧.xlsx"
    
'シート名を配列に入れる　※ブック名は「シート名YYMMDD」とする
    Dim sheetName(1) As String
    sheetName(0) = "商品マスタ"
    sheetName(1) = "顧客マスタ"
       
'繰り返し変数の宣言
    Dim i As Long
    For i = 0 To 1
        
'シート内容を転記することを繰り返す
    For i = 0 To 1
    Worksheets(sheetName(i)).Activate
    Cells(1, 1).Activate
    Worksheets(sheetName(i)).UsedRange.Copy
    Workbooks.Open ThisWorkbook.Path & "\" & sheetName(i) & "YYMMDD.xlsx"
    Worksheets("データ").Range("A1").Select
    ActiveSheet.Paste
    Range("A1").Select
    ActiveWorkbook.Save
    ActiveWindow.Close
   Next i
    
'○○一覧を閉じる
    ActiveWindow.Close
End Sub
```
繰り返し構文を使用したので、乱雑な感じは少し減りました。
でも、ブックに転記するシートの名前・数が変わると対応できないので、それを解決して汎用性を高くしたいです。
セルにシート名を記載してそれを参照するようなコードに改修したら解決する気がするので、
まずは、それを目標に頑張りたいと思います。
あと、ブック名とシート名に相違があった時などにメッセージ表記もしたいですね！
#PowerApps レスポンシブレイアウトの紹介 (Preview)

Power Platformのリリース予定に記載されていた中でも、アプリのデザインの点で注目されていたレスポンシブデザインへの対応が、プレビュー環境向けに配信されていましたので、ご紹介します。

# アプリの設定 (App Settings)

これまではアプリの設定のうち、画面サイズに関する設定が２つ存在していました。
- アスペクト比の固定
- スクリーン回転の固定
アスペクト比は、固定を外すことで、画面回転時に横幅/高さが調整されるような挙動になりましたが、レスポンシブレイアウトを実現するための「現在のスクリーンサイズ」が取得できないという問題がありました。

今回のアップデートにより、アプリの設定に、新たに**"Scale to fit"**という項目が追加されています。この設定をOFFにすることにより、アプリがレスポンシブレイアウトに対応します。
![AppSetting.png](https://qiita-image-store.s3.amazonaws.com/0/202779/34319070-6518-f42e-85f8-ab3e354d418e.png)
繰り返しですが、レスポンシブにする際はトグルをOFFにしてください。

# アプリのプロパティ

アプリのプロパティにも追加がありました。
追加されたプロパティは
- App.DesignHeight
- App.DesignWidth
の２つです。
![AppProperty.png](https://qiita-image-store.s3.amazonaws.com/0/202779/a6446f8e-947a-7553-1455-459bd9b645e3.png)
これらのプロパティは、**"アプリの既定のサイズ" (≠ 現在のスクリーンのサイズ)**を表しています。
今までのHeight/Widthが置き換えられたと言えます。
一方で、これまでに存在していた
- App.Height
- App.Width
は、~~レスポンシブレイアウトに必要だった**"現在のスクリーンのサイズ"**を表すプロパティに変更されています。~~
アプリを表示している画面の大きさを表すプロパティに変更されています。

また、スクリーン側のプロパティも変更されています。
- Screen.Height
- Screen.Width
これらのプロパティはいままで固定の数値が取得できるだけでした。（App.Height/Widthと同じ値）
ですがアップデートによって、既定では以下の関数で指定される量に置き換わっています。
- Max(App.Height, App.DesignHeight)  ※for Height
- Max(App.Width, App.DesignWidth) ※for Width
この関数によって、スクリーンサイズもApp.Height/Widthと同様に変更されます。
![ScreenProperty.png](https://qiita-image-store.s3.amazonaws.com/0/202779/31f9a5d6-bb3d-689c-292b-596b8170243b.png)

# サンプル
実際にアプリを作成してテストしてみました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/202779/f9d702d2-1238-75e5-a867-e0302ac146ce.png)
ラベルを追加して、App.WidthとApp.Heightの大小関係で色を変えるようにしています。
また、参考のために、App.HeightとApp.Widthを表示しています。
動作は以下のTweetをご覧ください。
<blockquote class="twitter-tweet" data-lang="ja"><p lang="en" dir="ltr">Sample App <a href="https://t.co/aywe9YJR8d">pic.twitter.com/aywe9YJR8d</a></p>&mdash; Hiro #🅿𝕠𝕨𝕖𝕣🅰𝕕𝕕𝕚𝕔𝕥 (@mofumofu_dance) <a href="https://twitter.com/mofumofu_dance/status/1100772916289925120?ref_src=twsrc%5Etfw">2019年2月27日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

ご覧のように、App.HeightとApp.Widthが画面の回転によってひっくり返っています。
あとはCSSのmediaクエリのように、オブジェクトの表示非表示を、```If(App.Width>XXX, )``` のような形で与えてあげれば、通常みるようなレスポンシブ対応アプリのように動作します。


# 注意事項
レスポンシブに対応させるにあたっては、原則的に各オブジェクトの配置、サイズをスクリーンのサイズに対して相対的に指定することをお勧めします。
絶対座標で指定した場合、スクリーンのサイズ（回転方向）によっては、画面外に表示されてしまうためです。
例えばオブジェクトの横幅は ```icon.Width : App.Width/8```のように、Widthからのスケールで、X,Yについても相対で定義すると見切れることなく表示されます。


# 最後に
2019/02/28の0:00現在でもテナントによっては反映に差があるようです。少し待てば、プレビュー環境向けには配信されると思いますので、今しばらくお待ちください。
angular.jsよりもAngularを推奨してもらったので、さっそく勉強してみた。

#Angular.jsよりもAngularを推奨してもらったので、さっそく勉強してみた。

#今日の勉強時間
一通り実行してみた結果、実際にかかった時間は３０分ぐらいかも。
Angular.jsよりサンプルプログラムをインストールして実行するまでの時間は短く感じました！

#前提
・npmがインストールされていること
・Node.jsのバージョン8.xまたは10.xがインストールされていること

僕は昨日の記事の中でインストール済みなので飛ばします。

参考:ANGULAR.JS公式チュートリアルのPhoneCat Tutorial Appはじめました。
https://qiita.com/ryuutamaehara/items/4f095b264f5e688ef1c1#comment-54fb8b28131e1bbf3996

#なぜAngular？昨日はAngular.jsだったじゃん。

昨日の記事を見ていただいた方にコメントをいただきました。

「angularJS はもう古くなってしまっている」


ﾅﾝﾄ(´･ω･｀)

WEB開発って時代の流れが速いっていうけど本当なんですね。

いままで顧シス担当やらメインフレームの運用とか〇〇みたいな現場しか回ったことなかった私はこの事に感動を覚えました。いいね。web系。
これからちょこっとずつ頑張っていきたいと思います('ω')ノ

では、今日から実際にオススメをいただいた「Angular」を勉強してみたいと思います。

#さっそく公式サイトをチェック！
まずは公式サイトから！
驚くなかれ！な、なんと日本語だァァァァァァァ！('ω')ﾜｰｲ

参考:https://angular.jp/


トップページに「モバイルとデスクトップ、ひとつのフレームワーク」なんてオシャンなキャッチフレーズを見てわかる通り、Angularでは今の主要なデバイスのシステムを１つのフレームワークで構築可能な事が強みのようです。

#では、まずはじめに
Angular.jsと同じくNode.jsとnpmを使うみたいですね。
この二つはこの記事の頭にも書きましたが、すでにインストール済みなので飛ばします。

#Angular CLIをインストールする
ここも記事通りに進めてみます。
Angularは主にCLI(コマンドラインインタフェース)で操作を進めるみたいですね。
CUI嫌いだからwindows使っているんだけどなぁ...。

文句言っちゃダメですよね。はい。

コマンドプロンプトから以下のコマンドを実行します。

```
npm install -g @angular/cli
```

#ワークスペースと初期アプリケーションを作成の作成

ワークスペースと初期アプリケーションを作成します。
次のコマンドを実行する前に作成したいディレクトリに移動しておいてくださいね。

```
ng new my-app
```

ng newコマンドでアプリケーションのひな型を作成されるようです。
my-appが作成されるアプリケーション名になります。

作成されるひな型プロジェクトは以下の構成を含むようです。
・my-appという名前のルートフォルダをもつ新しいワークスペース
・my-appと呼ばれる最初のスケルトンアプリケーションプロジェクト（srcサブフォルダ内）
・エンドツーエンドのテストプロジェクト（e2eサブフォルダ内）
・関連する設定ファイル

このアプリの中にはすぐに実行できるアプリが入ってるみたいですね。

#サーバを起動する

作成したひな型の中にはサーバも含まれるみたいですね！
さっそく起動してアプリの動作を確認してみます。

```
cd my-app
ng serve --open
```

serverではなくserveですよ。（笑）
成功するとhttp://localhost:4200/が自動的にブラウザで開かれます。

Angularのアイコンとともに「Welcome to my-app! 」といった表記が画面が表示されていたら成功です。


#Angularコンポーネントを編集してみる

./src/app/app.component.tsのファイルがAngularの構成管理ファイルらしいです。
画面上のデータ表示からユーザからの入力に基づいたアクションなどもここに記載するっぽいです。

この中に「my-app」という記載があるので、「My First Angular App」という文字列に変更してみます。
この状態で先ほど起動したアプリ画面を更新すると、「Welcome to my-app! 」といった表記が、「Welcome to My First Angular App! 」に変わったことが確認できます。

次にcssの設定をしてみます。

```./src/app/app.component.css
h1 {
  color: #369;
  font-family: Arial, Helvetica, sans-serif;
  font-size: 250%;
}
```

元のブラウザに戻ると、cssが適用されたことが確認できます。


ここまでで今日の分のチュートリアルは完了です。

#明日のおはなし
次のステップとして公式サイトには次のように記載されています。


・Tour of Heroesチュートリアルでは、実践的な追加学習が提供されています。それは、人材派遣会社がスーパーヒーローの従業員のグループを管理するのに役立つアプリを構築する手順を順を追って説明します。

なんか聞き覚えがあるような無いような…
タイバニ？なんだ？記憶が…ｗ

・アーキテクチャガイドでは、モジュール、コンポーネント、サービス、依存性の注入（DI）などの重要な概念について説明します。特定のAngularの概念と機能に関する詳細なガイドの基礎を提供します。

今日は以上です！！眠い！_(:3 」∠)_
graphiql-railsでクエリをお気に入り登録する方法

前々から、`graphiql`で『実行したクエリを名前つけて保存できる機能』があればいいのに、と思っていました。
今日たまたま発見したので、Qiitaでメモしておきます。
（みなさんには、当たり前のことかもしれませんが。。。）

### お気に入り登録する方法

- `History`ボタンをクリックして、実行したクエリの履歴を表示します。

<img width="623" alt="スクリーンショット 2019-02-27 19.27.40.png" src="https://qiita-image-store.s3.amazonaws.com/0/161900/8fe7af73-a9f9-8f88-7a32-72bc4aeeaa85.png">

- 保存したいクエリにフォーカスを当てて、:star:アイコンをクリックします。

<img width="683" alt="スクリーンショット 2019-02-27 19.28.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/161900/0650068a-6238-6bb8-6950-08ee7a8c90b1.png">

- リロードすると、お気に入りのクエリとして追加されます :star2: 

<img width="618" alt="スクリーンショット 2019-02-27 19.28.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/161900/3a7de808-38cc-4d3f-040a-199263080bdc.png">


### お気に入り登録したクエリのラベリング方法

- お気に入り登録したクエリにフォーカスを当てて、:pencil2:アイコンをクリックします。  
ラベルが編集できるようになるので、好きな名前を付けます。

<img width="636" alt="スクリーンショット 2019-02-27 19.28.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/161900/e26c261e-32b6-9499-df03-0cf1b538b586.png">

- どういうクエリか一発で分かるようになりました :raised_hands_tone1:

<img width="646" alt="スクリーンショット 2019-02-27 19.29.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/161900/413763f3-afbb-fc74-1d0b-2f7d1ead4b78.png">

### さいごに

これまでは残しておきたいクエリは、全てコメントアウトして残していました。
1つ2つならいいですが、大量に残しすぎて、何が何かさっぱり分からなくなっていました。
これからは、お気に入り登録できるようになったので、クエリの再利用がスムーズに行えます。:tada:
ローカルからnode.jsを削除する

## node.jsをインストーラからインストールしてしまった
node.js１日目です。

何も考えずnode.jsをインストーラ経由でインストールしてしまいました。
 [がいぽい(Twitterアカウントはこちら)](https://twitter.com/gaipoi_?lang=ja) です。 (本業はiOSエンジニアをやっています。)

node.jsのローカルからの削除ですが、非常に簡単です。
node.jsの削除は５秒で終わったのですが、当記事の作成には1時間かけております。はい。

この度node.jsを使う事になりまして、「とりあえずnode.js入れといたらいいんやろ」 みたいな感じで適当に[インストーラ](https://nodejs.org/ja/)からインストールしてみました。
しかし様々な記事で、 *「node.jsのバージョン管理は面倒だから、今すぐnodebrewに変えたほうがいいよ」* と言われました。

「そんなに言うなら、一旦ローカルのnode.js消してnodebrew経由にするか」

## という事で、ローカルのnode.jsを削除する
### 検索して沢山出てきたこのコマンド
```console
$ lsbom -f -l -s -pf /var/db/receipts/org.nodejs.pkg.bom \
| while read i; do
  sudo rm /usr/local/${i}
done
sudo rm -rf /usr/local/lib/node \
     /usr/local/lib/node_modules \
     /var/db/receipts/org.nodejs.*
```
(参考資料)How do I uninstall nodejs installed from pkg (Mac OS X)?
  https://stackoverflow.com/questions/9044788/how-do-i-uninstall-nodejs-installed-from-pkg-mac-os-x

これで本当に消せた人いるんですか？
コピペしましたが

```
can't open /var/db/receipts/org.nodejs.pkg.bom: No such file or directory
**** Can't open /var/db/receipts/org.nodejs.pkg.bom.
```
と言われました。コマンドの意味を理解せずに実行するのは絶対に辞めましょう(自戒)


## node.jsの削除
### node.jsの実行時のフルパス取得

```console
$ which node
→ /usr/local/bin/node
```
### 実際の削除

```console
$ sudo rm -rf /usr/local/bin/node
```

### 削除できたかどうかの確認
```console
$ node -v
bash: command not found: node
```
### ついでにnpmも削除

```console
$ sudo rm -rf ~/.npm
```
### 削除できたかどうかの確認
```console
$ npm -v
bash: command not found: npm
```

消えてた。　終わり。
フォルダの最新ファイルを取得する

####目的
特定のフォルダの中にある、更新日が最も新しいファイルを取得する

#####全体図
![image.png](https://qiita-image-store.s3.amazonaws.com/0/298686/adcb6522-efbe-1234-b2ec-b5deccf0a30c.png)



####内容
1.system.IO.Directory.GetFiles(“フォルダ”)
で特定のフォルダに入っているファイル名を取得します。変数arrayへ。

2.ファイルの更新日時を入れる変数[Modified]の初期値を設定。
DateTime型にします。とりあえず01/01/2001。

3.For Each
arrayに入っているものから取り出します。

3-1. if 
Modified < IO.File.GetLastWriteTime(item)
・変数[Modified]はファイルの更新日時
・IO.File.GetLastWriteTime(item)で　
　　item(※フォルダに入っている各ファイル）の更新日時
この2つを比較し、item側が大きければその値を[LatestFile][Modified]へ代入します。

ループが終われば最新のファイル名は[LatestFile]に入っているので、それを利用すればOK
GeoTag(GPS情報)をjpgファイルに設定/取得する

**もくじ**
→https://qiita.com/tera1707/items/4fda73d86eded283ec4f

**GeoTag関連**
- [GeoTag(GPS情報)をjpgファイルに設定/取得する](https://qiita.com/tera1707/items/0322a22517dfacee4133)
- [GeoTag(GPS情報)をjpgファイルに設定/取得するときのハマったメモ](https://qiita.com/tera1707/items/b245c4a264ed2bf50746)

# 準備
- WPFアプリでUWPのAPIを使用するため、プロジェクトの参照に下記の追加必要

    - C:\Program Files (x86)\Windows Kits\10\UnionMetadata\Windows.winmd

    - C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETCore\v4.5\System.Runtime.WindowsRuntime.dll

- usingを追加
    - using Windows.Devices.Geolocation;      // BasicGeoposition、Geopointのため
    - using Windows.Storage.FileProperties;   // GeotagHelperのため

# コード

jpgファイルからGPS情報読み出し

```C#:

            var filepath = FilePathBox.Text;
            var file = await Windows.Storage.StorageFile.GetFileFromPathAsync(filepath);
            if (file != null)
            {
                var gps = await GeotagHelper.GetGeotagAsync(file);

                if (gps != null)
                {
                    MessageBox.Show("latitude : " + gps.Position.Latitude + "\r\nLongitude : " + gps.Position.Longitude);
                }
                else
                {
                    // gpsデータなし
                }
            }
```

jpgファイルにgps情報を書き込み

```C#:
            var filepath = FilePathBox.Text;
            var file = await Windows.Storage.StorageFile.GetFileFromPathAsync(filepath);
            if (file != null)
            {
                // GPS値作成
                BasicGeoposition bgps = new BasicGeoposition();
                bgps.Latitude = 48.0;
                bgps.Longitude = 2.0;
                bgps.Altitude = 1.0;

                // GPS値をGeopointにセット
                Geopoint gps = new Geopoint(bgps);

                // GPS値をjpgファイルに書き込み
                await GeotagHelper.SetGeotagAsync(file, gps);
            }
```

## 置き場所
https://github.com/tera1707/WPF-/tree/master/014_jpg_GeoTag

## 参照
まず、WPFからUWPのAPIを使えるようにする
https://blog.okazuki.jp/entry/2018/03/29/101601

GEotagHelperクラス
https://docs.microsoft.com/en-us/uwp/api/windows.storage.fileproperties.geotaghelper
source ~/.zsh_historyは絶対に実行してはいけない(戒め

#あるある
```zsh
# ivm .zshrc
# dlssjksdklsdfkjlllklld
```
打ち損じたり、考え事をしていて不意に意味不明な文字をターミナルに叩いてしまう。
ついやってしまうが、上キーでコマンド履歴を漁る度にこいつらが出てくる。ううむ。
#どうすりゃいいんだ...
みた感じ~/.zshrc_historyを直接編集して該当部分を消せばいいらしい。
vimで編集して保存する。
#あれ？
反映されない。なんで？(殺意
#じゃあ...
source ~/.zshrc_historyで反映っと...

```zsh
# source ~/.zshrc_history
```

#！？
```zsh
# source ~/.zsh_history                                                                                                                 
/bin/zsh
root のログインシェルを変更中
新しい値を入力してください。標準設定値を使うならリターンを押してください
	ログインシェル [/bin/zsh]: n
chsh: 警告: n は存在しません
/root/.zsh_history:source:4: そのようなファイルやディレクトリはありません: ./.zshrc
/root/.zsh_history:source:5: そのようなファイルやディレクトリはありません: ./.vimrc
E: 不正な操作 ibus-anthy
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています                
状態情報を読み取っています... 完了
以下のパッケージはアップグレードされます:
  ibus-anthy
アップグレード: 1 個、新規インストール: 0 個、削除: 0 個、保留: 1514 個。
739 kB 中 0 B のアーカイブを取得する必要があります。
この操作後に追加で 0 B のディスク容量が消費されます。
/usr/share/apt-listchanges/apt_listchanges.py:540: FutureWarning: Possible nested set at position 25
  email_re = re.compile(r'([a-zA-Z0-9_\+\-\.]+)@(([[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)')
changelog を読み込んでいます... 完了
^CE: 子プロセス /usr/sbin/dpkg-preconfigure --apt || true がシグナル 2 を受け取りました。
E: Failure running script /usr/sbin/dpkg-preconfigure --apt || true
/root/.zsh_history:cd:9: そのようなファイルやディレクトリはありません: etc/apt
Loading internal logger. Log::Log4perl recommended for better logging
Reading '/root/.cpan/Metadata'
^C^C
```
！？？！！？？？？！？？！？？！？！？？？！？！？？！？！！？？
次々と身に覚えのないコマンドが勝手に実行されます。恐怖です。祈るような気持ちでctrl-Cを連打します。

#原因
よく考えなくても当然です。
sourceは.zsh_historyに記録されているコマンドを頭から読み込んでかたっぱしから実行しているのです。

```zsh
# head .zsh_history                                                                                                                            
chsh -s /bin/zsh
echo $SHELL
chsh
source ./.zshrc
source ./.vimrc
vim 
apt ibus-anthy
apt install --fix-missing ibus-anthy
cd etc/apt
vim apt.conf.d
```

なんて恐ろしいんだ...

#教訓
当時、齢15の少年だった僕はsourceコマンドを勝手に「設定を更新/反映してくれるコマンド」だと勘違いしていました。zshrcを更新するノリでうっかり実行してしまったのです。
僕みたいなうっかりが、もしかしたらいるかもしれないので教訓としてここに残しておきます。

＿人人人人人人人人人人人人人人人人人人人人人人人人人人人人＿
＞ **source ~/.zshrc_historyは絶対に実行してはいけない** ＜
￣Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y￣ 


(もしかしてLinuxあるあるじゃないのか...?)
はじめてのC++【3日目】

#はじめに
昨日はrand関数の取扱の重要性がわかりました。
rand関数を取り扱う上で注意すべき点
・乱数の質が悪い
・質は悪いが処理速度は早い
正確な乱数を取得したいときの方法をコメントにて教えてもらったので紹介します。
現在の C++ (C++11 以降) では random ヘッダにある std::mt19937 と std::uniform_int_distribution を組み合わせて使う。
ネットで調べたところこのようなコードを発見した。
<img width="454" alt="スクリーンショット 2019-02-27 23.23.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/298612/e17a512f-c5c2-3450-f7c8-1c32246d6c22.png">


それでは、ポインタ天国に行こうと思います。
##メモリ町1番地
メモリとは？
メモリとは、使用中のデータを一時的に記憶する領域のこと。電源を切ると内容が消える可能性もある
・関数や変数もメモリのどこかにある
・プログラム使用中のデータの殆どがメモリに存在する
アドレスとは？
アドレスとはメモリの中にある住所である。

アドレスを表示させるプログラム
<img width="506" alt="スクリーンショット 2019-02-27 23.52.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/298612/af68e26a-42ed-a334-3f80-867eea6ddf65.png">
実行結果
<img width="218" alt="スクリーンショット 2019-02-27 23.52.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/298612/40c96a19-2a64-4bea-7fce-f8595dee42ab.png">

bのアドレスが表示されないのは環境のせいなのか。
Fooのアドレスも1になっているのが少し怪しい。

##終わりに
今日は体調が悪いので少しだけしか進めなかった。
明日は昼から自由なのでたくさん進めようと思う。
Python3でナノ秒の計測をする方法

#コード#
Pytho処理時間をナノ秒で計測する方法です。
python3.7で追加された、time.clock_gettime_ns()を利用することで実現しています。[^1]

```python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import sys
import time

def main():
    start = time.clock_gettime_ns(time.CLOCK_MONOTONIC)
    <処理内容を記載>
    end = time.clock_gettime_ns(time.CLOCK_MONOTONIC)

    print('time: {}'.format(end - start))

if __name__ == "__main__":
    sys.exit(main())
```

- 結果の単位は、ナノ秒(10^-9)"です。
- time.CLOCK_MONOTONIC"は、単調増加の時間で 表現されるクロックを取得するオプションです。[^2]

#補足#
##"end - start"のオーバーフローが気になる
time.clock_gettime_ns()は、int型を返します(なので上記コードのstart, endはint型)。

int型の場合overflowが気になりますが、python3のint型は仕様上上限なしでメモリサイズに空きがある限り拡大できるようです(python2のlong型がint型になった)
なので、python3の場合はオーバーフロー気にしなくて良さそうですね
>https://docs.python.org/3.1/whatsnew/3.0.html#integers
Integers
    PEP 0237: Essentially, long renamed to int. That is, there is only one built-in integral type, named int; but it behaves mostly like the old long type.
    PEP 0238: An expression like 1/2 returns a float. Use 1//2 to get the truncating behavior. (The latter syntax has existed for years, at least since Python 2.2.)
    The sys.maxint constant was removed, since there is no longer a limit to the value of integers. However, sys.maxsize can be used as an integer larger than any practical list or string index. It conforms to the implementation’s “natural” integer size and is typically the same as sys.maxint in previous releases on the same platform (assuming the same build options).
    The repr() of a long integer doesn’t include the trailing L anymore, so code that unconditionally strips that character will chop off the last digit instead. (Use str() instead.)
    Octal literals are no longer of the form 0720; use 0o720 instead.


[^1]: [time — Time access and conversions — Python 3.7.2 documentation](https://docs.python.org/3/library/time.html:title)
[^2]: [time — Time access and conversions — Python 3.7.2 documentation](https://docs.python.org/3/library/time.html)や、[Man page of CLOCK_GETRES](http://linuxjm.osdn.jp/html/LDP_man-pages/man2/clock_gettime.2.html)を参照
RubyでArrayから重複した値を取り出す方法

今回はRubyでArrayから重複した値を取り出す方法を紹介します。

## RubyでArrayから重複した値を取り出す方法
```ruby
a = [1, 1, 2, 3, 4, 4, 5]
a.select{|v| a.count(v) > 1}.uniq # [1, 4]
```
selectとuniqを組み合わせるのがポイントです。
以上になります。
## 終わりに
私は現在、Web3のサービスの開発をしています。詳しくはこちらの記事をご覧下さい。
        [無料でイーサリアムが当たる、Web3時代の寄付サイトを作った話](https://note.com/kenroda/n/n814347fbdcd7)
水上ドローン 作りたい 1

#自己紹介
趣味ベースで水上ドローンを作りたいと思い立ち、作ってみることにしました。誰かの役に立つ部分もあるかとおもうのでここでレポートします。
##私のスペック
- 年齢 アラフォー
- ソフトウエア制作には8年程前まで関わっていましたが、今はしてません。
- 電子工作の経験 全くなし
- 大阪出身の東京在住

#ドローン面白そうですよね
今更ですけどドローン、面白そうです。今迄見ることの出来なかった空の景色を手軽に届けてくれるのは本当に素晴らしい。さて、そんなにいい物なら作ってみたくなりますよね。

現在ドローンと言えば航空ドローンですが、さすがにこれは厳しい。何せ物を浮かす訳でですから。軽量なボディーに、強力なモーター＆バッテリー、姿勢制御も難しそう。これを片手間で作れるとはさすがに思えないです。

#妥協案 ボートならいけるのでは？
水上ドローンであれば素人でも手を出せそうな気がします。具体的にいうと
- 市販のラジコンが豊富に有り、改造元として利用できる。
- 浮力さえ確保できれば、取り敢えず浮いている事が出来る。航空ドローンに比べて遥かに楽。
- 浮力が足りなければ、ペットボトルでもくくりつけておけば良い。
- モーターパワーが不足していても、スクリューさえ廻っていればちょっとづつでも進む。

なんとかなりそうな気がします。というわけで、駄目元で制作を開始してみました。
#最低限実現しておきたいこと
- 池や川にボートを浮かべ、そこからの映像、音声をリアルタイムで受信して楽しみたい。航空ドローンのように今迄見ることの出来なかった景色を見ることが出来たら最高。
- 遠隔のボートを自在にコントロ－ルして楽しみたい。ボートに乗っているような臨場感があれば最高！

#改造元のラジコン
Amazonで探しました。

[非充電式　高速リモートコントロール　ヨット2モーター高速ボート　おもちゃ　包装付く　グリーン](https://www.amazon.co.jp/dp/B07CRJF1JT)
ざっと 1500円。完全に値段で決めました。
![20181110132633_IMG_0551.JPG](https://qiita-image-store.s3.amazonaws.com/0/359316/e08d9c05-24ba-7924-f8bf-1865ac42b9de.jpeg)
この値段ですけど、なかなかの作りです。
#動作
購入前のイメージと違っていたのが舵が無いこと。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/359316/c7027af8-a04e-fc38-44cc-f01e132a4423.png)
後部にモーターが2つ有るのみで、舵が有りません。方向転換は左右モータの出力差で行います。

#内部の構造
大きく分けて3つのパーツで構成されています。船底、甲板、屋根のみっつです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/359316/c415918f-0f33-7673-9bcb-036642544822.png)
#配線
それ程複雑ではありません。船底からモーターの配線が伸びていますのでこの線だけ流用して他は全て外してしまうつもりです。
#改造方針
ボートを分解して眺めていると、今回の改造作業がどの様な物になるか有ると程度イメージできてきました。する事自体はシンプルです。
モータ用の配線は船底から這い出ているので、ここに適切な直流電流を流せばよい。電流のコントロールルはRasberry Piに任せる。

大雑把ですがする事を列挙してみる。

- ボートコントロール
 - 既存の制御基板を外し、Rasberry PIをボートに搭載
 - Rasberry PIより、左右モーターに適切な電流を流す
 - コントロール用PCから命令を受け取り、実行する
- 映像、音声の転送
 - カメラ、マイクモジュールを搭載して、Rasberry PIに取り込む
 - 取り込んだデータをエンコードしてコントロール用PCに転送する
- ネットワーク関連
 - 3G、4G回線を経由してコントロール用PCとデータをやり取りする
- ラジコンボートの改造
 - 浮力不足の対策
 - 各種コンポーネントを本体に押し込んで、配線する。
- コントロールPC
 - ボートへアクセル開度、左右のステアリング情報を取得して送信
 - ボートから送られて来た映像、音声の表示

###制作期間
プライベートの空き時間を使い、3ヶ月の期間を目処に制作を行います。とにかく動作する事を最優先させます。
【小ネタ】Xavier Developer KitのUSB3.0 Type Aポートの使い方

#要約
"Hybrid eSATA/USB port"なる物の存在を知らなかった私が無知を晒す記事です。
なお、このポートはNVIDIAの文書でも"USB 3.0"と"USB 3.1 Gen1"と表記が混在してるので本記事では"USB 3.0"で統一します。同じものだし。

#Xavier Dev KitにUSB3.0 Type Aポート？
って思う方、いるんじゃないでしょうか。
私はそうでした。ぱっと見、USB Type-Cが2つとMicro-Aが1つしか見当たらないし。
でも、[NVIDIAのサイト](https://developer.nvidia.com/embedded/buy/jetson-agx-xavier-devkit)には書いてあるし、
<img width="576" alt="eSATA.png" src="https://qiita-image-store.s3.amazonaws.com/0/168480/af2d3aee-d67e-9b07-ceee-f50201f12f61.png">
Quick Guide読むとEtherとHDMIに挟まれたポートが**eSATA+USB3.0**と表記してあります。
<img width="576" src="https://qiita-image-store.s3.amazonaws.com/0/168480/87e60a11-c37b-e2f7-f3bc-f75a05cb1722.jpeg">

#どうやって使うの？
結論から言ってしまうと、ここにUSB Type-Aがそのまま刺さります。
こうして、、、
<img width="576" src="https://qiita-image-store.s3.amazonaws.com/0/168480/dbde6351-1b4d-574b-40b7-b289a9f3301a.jpeg">
こうなる。
<img width="576" src="https://qiita-image-store.s3.amazonaws.com/0/168480/b7f13f4c-63fe-bd26-af98-87f1d1555686.jpeg">

なんだこのポート？って思って、eSATA-USB変換ケーブルとかいうマイナー商品を数千円も出して買った私は一体。。。orz
[Hybrid eSATA/USB port](https://www.cnet.com/forums/discussions/what-is-esata-usb-port-506251/)というポートらしいです。

一つ勉強になりました。
プラグインインストール済のJenkins 構築 Docker編 その1

#モチベーション
パッとローカルのwin10 PCによく使うPlugin入りのJenkinsを構築したい。
みんなで使うJenkinsさんはあるんだけど、ちょっと周りに迷惑かけずに試したいことがある時に、その時だけ使ってあとは捨てる前提。
手段は大きく分けると2つ。
1.Docker Image作っておいて、必要な時だけコンテナ起動
2.Ansibleなどの構成管理ツールで、自動で構築
机上で考えても両者の優越つけられなかったので、両方やってみましょう。
今回は1.のDocker編です。

#環境や前提条件
windows10 pro 1803
PowerShell
Docker 18.09.0

##まず素のJenkinsを動かしてみよう
Dockerfileの準備

```dockerfile:dockerfile
FROM jenkins:2.19.4
#COPY plugins.txt /usr/share/jenkins/ref/
#RUN /usr/local/bin/install-plugins.sh $(cat /usr/share/jenkins/ref/plugins.txt)
```


Dockerfileからdocker imageを作成

``` powershell:powershell
# cd C:\docker\jenkins
# docker build -t myjenkins:1 .
# docker images

REPOSITORY   TAG   IMAGE ID       CREATED         SIZE
myjenkins    1     f61635651954   2 years ago     714MB
```

jenkinsフォルダをwindows10から見れるように -v でマウントするオプション付きで、コンテナの起動する。

``` powershell:powershell
# docker run -it -d -v /c/docker/jenkins/home:/var/jenkins_home/ --name myjenkins-1 -p 8080:8080 myjenkins:1
```

コンテナに入り、Administrator passwordを確認

``` powershell:powershell
PS C:\docker\jenkins> docker exec -i -t myjenkins-1 bash
jenkins@b7fe956826b7:/usr/share/jenkins$ cat /var/jenkins_home/secrets/initialAdminPassword
42d3091b11634def8d58589b93102269
```
Administrator passwordを入力
![image.png](https://qiita-image-store.s3.amazonaws.com/0/29032/34b40463-8153-c7df-6925-031b2bbc3920.png)

Pluginのinstallは自動化したいので、Select Pluginsを選択し、
![image.png](https://qiita-image-store.s3.amazonaws.com/0/29032/1cd6362a-5038-44a7-1c26-77d648c9176f.png)

Install
![image.png](https://qiita-image-store.s3.amazonaws.com/0/29032/4214522f-8aa0-7897-2191-a26a9236db19.png)

PluginsのDownloadでエラーがでるけど、気にしないことに。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/29032/70864e3f-28c7-f931-eb0a-907f6275cd8f.png)

Continue
![image.png](https://qiita-image-store.s3.amazonaws.com/0/29032/7e018079-a28f-c05d-e44e-95f510db2561.png)

Save and Finish
![image.png](https://qiita-image-store.s3.amazonaws.com/0/29032/82acdbe8-35c6-78e4-241f-ed7801fcb71e.png)

Start using Jenkins
![image.png](https://qiita-image-store.s3.amazonaws.com/0/29032/d6e1457a-220d-817d-13d3-46eef3501eae.png)


「jobb」というjobを作って一回起動してみた。（画面は省略）
windowsフォルダを確認すると、jobbのworkspaceが作れていることがわかる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/29032/e4c91c1f-efec-9ce0-b328-60f841b895fa.png)

試しにコンテナを削除してみる

``` powershell:powershell
# docker rm -f xxxx(コンテナ名)
```
windowsフォルダにはファイルは保持されてるので、
同じイメージを使って別のコンテナを起動しても、

``` powershell:powershell
# docker run -it -d -v /c/docker/jenkins/home:/var/jenkins_home/ --name myjenkins-1 -p 8080:8080 myjenkins:1
```
データが消えてないので、先ほど設定した情報はそのままでJenkinsが使える。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/29032/257a2917-30ce-14ec-b64e-f57e13b2060e.png)

#次回予告
Plugin Installの自動化
セットアップウィザードの無効化
を実施したい。

#関連投稿
[プラグインインストール済のJenkins 構築 Docker編 番外編](https://qiita.com/atmaru/items/eba33a407d12cb40f079)
Ruby on RailsのIDEをどれにしようかなぁと軽く調べた

## Cloud9で開発するの、地味に疲れる

今までAWSのクラウド開発環境であるCloud9を利用してきたわけですが、それをやめようかなぁと思い始めています。
理由は単純で、**Command+W 暴発問題**があるから。

ファイルを閉じたくてうっかりCommand+Wを叩くと、Safariのタブが閉じてしまい、開発環境そのものが閉じてしまいます。
そんなの気をつけれてば済む話じゃんって言われるとそこまでなのですが、ロジックを書くことに集中しているといつの間にか頭から飛んでしまうのだ…つらぁ…。

## Macに入れるIDEを考え始める

元々Java屋でEclipseを使っていたので、とりあえずイマドキなIDEを入れればいいかって考えに至り、探してみることに。
パッと検索した限り、以下の3つが良いっぽい。

- Eclipse (+RadRails)
- RubyMine
- VS Code

## Eclipse (+RadRails)

<img width="1521" alt="スクリーンショット 2019-02-27 23.17.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/304374/f57603c3-4003-08b7-082e-f3b2d2a1da3f.png">

Javaをやってる方で(使用有無はさておき、)Eclipseを知らない方はいないでしょう。
Pleiadesでフル日本語化されたAll in Oneを落としてくればささっと開発に取りかかれる簡単さがあります。
元々使っていたところにプラグインを入れれば使えるというのは学習コストをかなり抑えられそうです。

良さそうなところ：

- 学習コスト低め

ちょっとなーってところ：

- Javaやってた時と代わり映えしないので飽きが…

## RubyMine

<img width="1520" alt="スクリーンショット 2019-02-27 23.01.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/304374/b482c626-4443-19ff-0581-3bcb05d36f75.png">

使いやすいIDEを出してくることに定評のある(と伝え聞いている)JetBrains社製IDE。
ちょっと前までデファクトスタンダードだったとどこかで見ました。

良さそうなところ：

- 情報量が豊富、何かあっても検索してどうにかなりそう

ちょっとなーってところ：

- 有料か…

## VS Code

<img width="1518" alt="スクリーンショット 2019-02-27 23.00.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/304374/1cfefd37-fff6-6022-f2bc-94e6a037f51f.png">

プロプライエタリ製品の名称だったVisual Studioの名を冠して登場した無料版だと思ってたら、あっという間にWeb業界へ浸透している感のあるIDE。
色んなところから「VS Codeはいいぞ」と聞こえてきます。

良さそうなところ：

- 今超絶ホット。使ってるだけで最前線感バリバリ。

ちょっとなーってところ：

- まだ情報が蓄積されていなさそう(& バージョン依存のトラブルシュートが引っかかる)

## とりあえずVS Codeからかじってみようかなー

ローカルでRailsの開発をするのはこれからなので、切り替えの手間を考えなくていい分、新しいやつをやってみようという安直な理由でVS Code。
ダメだったらEclipseに転ぶことにしよう。

## IDE？テキストエディタ使えよ
わかる、わかるよ、その方が軽いし環境選ばないしハッカーっぽいしで良いってのはわかるよ。
でもこちとらRailsに関してはホビープログラマ、楽なやり方で開発したいのだ…本当にすまない…。

## おすすめあったら教えてくださいなんでもしますから！

「(なんでもするとは言ってない)」の文脈。
「RailsでこのIDEいいよ！」って意見、お待ちしております。
ConditionalAttributeのメソッドの引数に副作用のある式を書くとどうなるか

## 概要
最近C#に入門していて、`ConditionalAttribute`なるものの存在を知りました。
例えば、`[Conditional("AAA")]`という属性をメソッドに与えている場合において、シンボルのAAAが定義されていなければ、その**メソッドを呼び出している箇所がコンパイルされなくなる**というものです(メソッド自体はコンパイルされます)。

```csharp:Program.cs
using System;
using System.Diagnostics;

namespace ConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            // シンボルAAAが定義されていないため、下のHello()の呼び出しはコンパイルされない
            Hello();
            Console.WriteLine("Main()");
        }

        [Conditional("AAA")]
        static void Hello()
        {
            Console.WriteLine("Hello()");
        }
    }
}
```

実行結果

```
Main()
```

シンボルのAAAが定義されていないため、`Hello()`メソッドが呼び出されてないことが確認できます。

そこで、1つ疑問が浮かびました。
`ConditionalAttribute`のメソッドの引数に副作用のある式を書いたらどうなるのでしょうか。これは、C/C++の`assert()`において、意図せず副作用のある式を書いてしまい、挙動がDebugとReleaseのときで異なりバグが発生することがよくある？ことであり気になったからです。

例えば、C++でassert()に副作用のある式を書いてしまったソースコードは下記です。

```cpp:main.cpp
#include <iostream>
#include <cassert>

using namespace std;

int main()
{
    int a = 10;

    assert(++a);

    cout << a << endl;

    return 0;
}
```

NDEBUGを定義するかしないかで、`a`の値が変化してしまいます。

```
$ clang++ main.cpp && ./a.out
11
$ clang++ -DNDEBUG main.cpp && ./a.out
10
```

## 検証

検証用のソースコードは下記です。

```csharp:Program.cs
using System;
using System.Diagnostics;

namespace ConsoleApplication
{
    class Program
    {
        static int a = 10;

        static void Main(string[] args)
        {
            Hello(++a);

            Console.WriteLine("Main():{0}", a);
        }

        [Conditional("AAA")]
        static void Hello(int x)
        {
            Console.WriteLine("Hello():{0}", x);
        }
    }
}
```

実行結果

```
Main():10
```

というわけで、`Hello(++a);`がコンパイルされなくなっているので、`++a`は実行されず、aが11になることはありませんでした。
結論としては、`ConditionalAttribute`のメソッドの引数に副作用のある式を書くのは、あまり良いことでは無いかもしれません。

## 参考文献
[ConditionalAttribute Class (System.Diagnostics) | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/api/system.diagnostics.conditionalattribute?view=netframework-4.7.2)
sympy,wolframalphaで定積分 「京大数学2019年度第1問2」をやってみたい

~~読売新聞~~
~~https://www.yomiuri.co.jp/nyushi/sokuho/k_mondaitokaitou/kyoto/mondai/img/kyoto_zenki_sugaku_ri_mon.pdf~~
~~https://www.yomiuri.co.jp/nyushi/sokuho/k_mondaitokaitou/kyoto/kaitou/img/kyoto_zenki_sugaku_ri_kai.pdf~~
~~毎年同じurlみたい。~~


京大数学 過去問ライブラリ＞2019年度解答例＋引用題理系＞第1問2
https://www.densu.jp/kyoto/19kyotospass.pdf

#wolframalphaでやってみた
(1)
https://www.wolframalpha.com/input/?i=Integrate%5Bx%2Fcos(x)**2,%7Bx,0,pi%2F4%7D%5D
Integrate[x/cos(x)**2,{x,0,pi/4}]
(Pi - Log[4])/4
(2)
https://www.wolframalpha.com/input/?i=Integrate%5B1%2Fcos(x),%7Bx,0,pi%2F4%7D%5D
Integrate[1/cos(x),{x,0,pi/4}]
integral_0^(π/4) 1/cos(x) dx = 2 tanh^(-1)(tan(π/8))?0.8814
#SymPy Liveでやってみた
print(integrate(x/cos(x)**2,(x, 0, pi/4)))
結果:よくわからないので.....(省略)
print(integrate(1/cos(x)**2,(x, 0, pi/4)))
結果:1
#pythonでやってみた

```fullscript.py
from sympy import *
x = Symbol('x')

f=x/cos(x)**2
print(f)
print(integrate(f,(x, 0, pi/4)))

f=1/cos(x)
print(f)
print(integrate(f,(x, 0, pi/4)))

# x/cos(x)**2
# log(2*(-sqrt(2)/2 + 1)**2 + 1)/(-1 + 2*(-sqrt(2)/2 + 1)**2) + 2*(-sqrt(2)/2 + 1)**2*log(sqrt(2)*(-sqrt(2)/2 + 1) + 1)/(-1 + 2*(-sqrt(2)/2 + 1)**2) - 2*(-sqrt(2)/2 + 1)**2*log(2*(-sqrt(2)/2 + 1)**2 + 1)/(-1 + 2*(-sqrt(2)/2 + 1)**2) - log(sqrt(2)*(-sqrt(2)/2 + 1) + 1)/(-1 + 2*(-sqrt(2)/2 + 1)**2) - sqrt(2)*pi*(-sqrt(2)/2 + 1)/(2*(-1 + 2*(-sqrt(2)/2 + 1)**2)) - I*pi + 2*(-sqrt(2)/2 + 1)**2*(log(-sqrt(2)*(-sqrt(2)/2 + 1) + 1) + I*pi)/(-1 + 2*(-sqrt(2)/2 + 1)**2) - (log(-sqrt(2)*(-sqrt(2)/2 + 1) + 1) + I*pi)/(-1 + 2*(-sqrt(2)/2 + 1)**2)
# 1/cos(x)
# log(sqrt(2)/2 + 1)/2 - log(-sqrt(2)/2 + 1)/2
```
sadf コマンド

# 概要
sadf コマンドを利用することで、sar の結果を別フォーマットで取得できる。

# 手順
## インストール
```
[vagrant@localhost ~]$ yum -y install sysstat
```

## コマンド実行
```
[vagrant@localhost ~]$ sadf -T -j
{"sysstat": {
	"sysdata-version": 2.16,
	"hosts": [
		{
			"nodename": "localhost.localdomain",
			"sysname": "Linux",
			"release": "3.10.0-229.el7.x86_64",
			"machine": "x86_64",
			"number-of-cpus": 1,
			"file-date": "2019-02-27",
			"statistics": [
				{
					"timestamp": {"date": "2019-02-27", "time": "14:30:01", "utc": 0, "interval": 599},
					"cpu-load": [
						{"cpu": "all", "user": 0.01, "nice": 0.00, "system": 0.03, "iowait": 0.01, "steal": 0.00, "idle": 99.96}
					]
				},
				{
					"timestamp": {"date": "2019-02-27", "time": "14:40:01", "utc": 0, "interval": 599},
					"cpu-load": [
						{"cpu": "all", "user": 0.01, "nice": 0.00, "system": 0.04, "iowait": 0.00, "steal": 0.00, "idle": 99.96}
					]
				},
				{
					"timestamp": {"date": "2019-02-27", "time": "14:50:01", "utc": 0, "interval": 599},
					"cpu-load": [
						{"cpu": "all", "user": 0.01, "nice": 0.00, "system": 0.03, "iowait": 0.00, "steal": 0.00, "idle": 99.96}
					]
				}
			],
			"restarts": [
			]
		}
	]
}}

## jq と併用
[vagrant@localhost ~]$ sadf -T -j | jq -c
{"sysstat":{"sysdata-version":2.16,"hosts":[{"nodename":"localhost.localdomain","sysname":"Linux","release":"3.10.0-229.el7.x86_64","machine":"x86_64","number-of-cpus":1,"file-date":"2019-02-27","statistics":[{"timestamp":{"date":"2019-02-27","time":"14:30:01","utc":0,"interval":599},"cpu-load":[{"cpu":"all","user":0.01,"nice":0,"system":0.03,"iowait":0.01,"steal":0,"idle":99.96}]},{"timestamp":{"date":"2019-02-27","time":"14:40:01","utc":0,"interval":599},"cpu-load":[{"cpu":"all","user":0.01,"nice":0,"system":0.04,"iowait":0,"steal":0,"idle":99.96}]},{"timestamp":{"date":"2019-02-27","time":"14:50:01","utc":0,"interval":599},"cpu-load":[{"cpu":"all","user":0.01,"nice":0,"system":0.03,"iowait":0,"steal":0,"idle":99.96}]},{"timestamp":{"date":"2019-02-27","time":"15:00:01","utc":0,"interval":599},"cpu-load":[{"cpu":"all","user":0.44,"nice":0,"system":0.17,"iowait":0.02,"steal":0,"idle":99.36}]}],"restarts":[]}]}}
```
複数台のsar の結果を扱いやすい形で取得できて便利！

性能試験等で、複数台サーバのsar 結果をsummarize したりする際にとてもやくにたちそう。
【SwiftChaining】 UIとバインディングする

[SwiftChaining](https://github.com/objective-audio/SwiftChaining)の解説記事その2です。
前回の記事はこちら -> [Swiftでデータバインディングするライブラリを作った](https://qiita.com/yasos/items/4d8dd0d1aa63605dc63b)

iOSアプリでデータバインディングをするからには、UIと値を同期できないと始まりません。

今回は例として、`UISwitch`とバインディングする例を紹介します。

## UISwitchとバインディングする

`UISwitch`のスイッチのON・OFFの状態である`isOn`と、[前回の記事](https://qiita.com/yasos/items/4d8dd0d1aa63605dc63b)で紹介した`ValueHolder`の値をバインディングしてみます。コードは以下の通りです。

```swift
import UIKit
import Chaining

class ExampleViewController: UIViewController {
    @IBOutlet weak var mySwitch: UISwitch!
    
    lazy var isOnAdapter = { KVOAdapter(self.mySwitch, keyPath: \UISwitch.isOn )}()
    lazy var valueChangedAdapter = { UIControlAdapter(self.mySwitch, events: .valueChanged) }()
    
    let isOnHolder = ValueHolder(true)
    let pool = ObserverPool()
    
    override func viewDidLoad() {
        super.viewDidLoad()

        self.isOnHolder.chain().sendTo(self.isOnAdapter).sync().addTo(self.pool)
        self.valueChangedAdapter.chain().map { $0.isOn }.sendTo(self.isOnHolder).end().addTo(self.pool)
    }
}
```

### 解説

KVOに対応したプロパティを`SwiftChaining`で扱えるようにするためのクラスが`KVOAdapter`です。

```swift
KVOAdapter(self.mySwitch, keyPath: \UISwitch.isOn )
```

対象となるオブジェクトとプロパティの`keyPath`を渡して生成し、値を監視したり更新したりできます。

`ValueHolder`同士の場合と同じく、以下のように`sendTo`に`KVOAdapter`を渡すことで`ValueHolder`からの値を受け取ることができます。

```swift
self.isOnHolder.chain().sendTo(self.isOnAdapter).sync()
```

逆に`KVOAdapter`から`isOn`の変更を受け取るのには、以下のように逆方向に繋げれば良いのですが、今回の場合、残念ながらうまくいきません。

```swift
// うまくいかない
self.isOnAdapter.chain().sendTo(self.isOnHolder).sync()
```

`UISwitch`をタップしてON・OFFの状態を変更したときはKVOでは通知されないので、`UIControl`のイベントを監視するようにします。

`UIControl`のイベントを監視するクラスとして`UIControlAdapter`を用意しています。

```swift
UIControlAdapter(self.mySwitch, events: .valueChanged)
```

`events`で監視したい`UIControl`のイベントを指定します。

`UIControlAdapter`からイベントを監視して`ValueHolder`に値を反映させるには以下のように書きます。

```swift
self.valueChangedAdapter.chain().map { $0.isOn }.sendTo(self.isOnHolder).end()
```

`UIControlAdapter`から送られる値は`UIControl`（ここでは`UISwitch`）なので途中で`map`関数を使って`isOn`の値に変換して`ValueHolder`が受け取れるようにしています。

このように、それぞれ変更があった時に双方向に値を送り合うことで、値を同期することができるという感じになります

`SwiftChaining`では値の送信が循環しても延々とループにならないように内部でロックしているので、それこそ`chain`したオブジェクトを`sendTo`にそのまま渡すようなことをしてもハングアップしたりはしません。

## ObserverPool

ちなみに、今回のコードで出てきたクラスに`ObserverPool`というものがあります。

```swift
let pool = ObserverPool()
...
self.isOnHolder.chain().sendTo(self.isOnAdapter).sync().addTo(self.pool)
```

複数のObserverを保持しておかないといけない時に別々に管理するのは面倒なので、Observerをまとめて保持しておけるものとして用意しています。`ObserverPool`を破棄したり`invalidate()`を呼んだら、保持しているObserverがまとめて無効になります。

Observerの追加を`ObserverPool`側の関数でやると書きにくかったので、`sync`や`end`の後にそのまま`addTo()`をつなげて書いて追加できるようにしています。

## 補足

なお今回紹介したコードだと、`ValueHolder`から`UISwitch`へ値を反映させる時にアニメーションをしなかったり、`UISwitch`の`isOn`をコードで直接変更した時に`ValueHolder`へ値が反映されません。それらが必要であれば、さらにコードを追加・変更することになるでしょう。

`SwiftChaining`は`UIKit`をラップして簡単にするものではないので、このような`UIKit`の対応は通常と変わらず考える必要があります。
Unity2018のStandardAssetsの場所

# メモ

Unity2018以降あたりからStandardAssetsをUnityインストール時にインポート出来なくなっているようです。
AssetStoreを開いてインポートすればいいのですが、毎度やるのも面倒なのでURLをメモ。
Unityがインストールされた環境で適当なブラウザで開いてOpeninUnityボタンを押せばUnityが立ち上がる気がします。

[Standard Assets \- Asset Store](https://assetstore.unity.com/packages/essentials/asset-packs/standard-assets-32351)
https://assetstore.unity.com/packages/essentials/asset-packs/standard-assets-32351

![{EB31C3EB-1CDC-4673-9457-D8EFABA2FF9E}.png.jpg](https://qiita-image-store.s3.amazonaws.com/0/116607/dd89ea18-fd43-9ad3-4bbe-be3182213c55.jpeg)


# 参考

[Unity 2018で標準アセットを使用する \- Qiita](https://qiita.com/tomato_sugar/items/58c1d0a846c0361ac22a)
[【Unity】ImportPackage（StandardAssets）が無い時の対処 \- テラシュールブログ](http://tsubakit1.hateblo.jp/entry/2015/06/26/232958)
div要素全体にリンクをつける方法

div要素全体にリンクをつけたい時の方法メモ
自分用に簡潔にまとめる。

<p class="codepen" data-height="279" data-theme-id="0" data-default-tab="html,result" data-user="iwato" data-slug-hash="moJwZV" style="height: 279px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid black; margin: 1em 0; padding: 1em;" data-pen-title="div要素全体にリンクをつける方法">
  <span>See the Pen <a href="https://codepen.io/iwato/pen/moJwZV/">
  div要素全体にリンクをつける方法</a> by iwato (<a href="https://codepen.io/iwato">@iwato</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
数理最適化:線形計画問題【Pythonの数値計算】

#まえがき
太郎さんは八百屋に行きました。
そこでは
Aセット:みかん4個とりんご1個で400円、
Bセット:みかん2個とりんご3個で500円
の二種類のセット販売がありました。
太郎さんはお母さんに「たくさん買ってきてね」と言われていました。
可能な限りお金を使う買い方を考えましょう。
ただし八百屋さんの在庫にはみかん100個、りんご70個しかありません。
# 数式にしてみましょう
これは線形計画問題と言われる問題です。
Aセットをx個、
Bセットをy個買うとします。

最大化したい関数は値段なので、
$$ 400 x + 500 y  $$
という式になります。

さらにみかん100個、りんご70個という在庫の制約があるため

```math
4x + 2y \leq 100 \\
 x + 3y \leq 70 
```
が条件に加わります。
ついでに$x,y \geq 0$も条件。
まとめてこう書きます。


```math
\mathrm{Maximize}~~~400 x + 500 y\\
\mathrm{Subject~to} ~~~ 4x + 2y \geq 100\\
~~~~~~~~~~~~~~~~~~x + 3 y \geq 70\\
~~~~~~~x \leq 0 \\
~~~~~~~y \leq 0 
```
(整数じゃなきゃダメじゃね？みたいなツッコミは禁止とします。)
#Pythonで解いてみよう
`scipy.optimize.linprog`という関数を利用します。
以下の形を標準形とします。

```math
\mathrm{Minimize}~~~c^Tx\\
\mathrm{Subject~to} ~~~ Gx \geq h\\
~~~~~~~~~~~~~~~~~~Ax = b\\
```
$c,G,h,A,b$の5つを引数に設定できます。これは最小化の関数ということに注意。
問題の式を一般形に当てはめると

```math
\mathrm{Minimize}~~~    \left(
    \begin{array}{ccc}
      -400  \\
      -500 
    \end{array}
  \right)^T 
\left(
    \begin{array}{ccc}
      x  \\
      y 
    \end{array}
  \right)\\
\mathrm{Subject~to} ~~~    \left(
    \begin{array}{ccc}
      4 & 2  \\
      1 & 3 \\
      -1 & 0\\
      0 & -1
    \end{array}
  \right)
\left(
    \begin{array}{ccc}
      x  \\
      y 
    \end{array}
  \right)\leq
    \left(
    \begin{array}{ccc}
      100  \\
      70 \\
      0\\
      0
    \end{array}
  \right)

```
「最小化」の関数にするために、値段をひっくり返してます。
ここから

```math
c = \left(
    \begin{array}{ccc}
      -400  \\
      -500 
    \end{array}
  \right),G = \left(
    \begin{array}{ccc}
      4 & 2  \\
      1 & 3 \\
      -1 & 0\\
      0 & -1
    \end{array}
  \right) ,h =     \left(
    \begin{array}{ccc}
      100  \\
      70 \\
      0\\
      0
    \end{array}
  \right)
```
この三つの引数を入れて関数を使ってみましょう。

```python
import numpy as np # npという名前でimportする慣習。
from scipy import optimize

c = np.array([-400,-500])
G = np.array([[4,2],[1,3],[-1,0],[0,-1]])
h = np.array([[100,70, 0, 0]])
sol = optimize.linprog(c, G, h)
print(sol.x)
print(sol.fun)
# [16. 18.]
# -15400.0
```
つまりAセットを16個、Bセットを18個買って15400円。
これが最大となります。

# まとめ
数理最適化問題は、関数に一般化して入れればいい。
線形計画問題を解くための関数は色々あるらしいですが、その一例を示しました。
この関数だって上限下限の設定とかデータ型とかもうちょっと行儀のいい書き方あるけど無視。

『機械学習のエッセンス』という本を参考にしました。
この本についてまとめていきます。
前回:数値範囲に気をつけよう:
https://qiita.com/NNNiNiNNN/items/2f17f874f8a234bd10ad
次回:最小二乗法 $y = ax$型
https://qiita.com/NNNiNiNNN/items/4fd5367f9ead6e5905a9
Ruby｜RSpecでメソッド呼び出しのテスト（ブロック付き）

いつものように「これ、誰がつかうん？」という小ネタです。

たまーにRSpecでメソッドってちゃんと呼び出されてるよね？というテストを書くと思います。`with`を使うと引数に狙った値が渡っているかを検証できますが、ブロック付きはどうするか調べたのでそのメモです。

先に言ってしまうと検証は「&手続きオブジェクト」の場合のみ出来ます。

# 前段階

検証に使うプログラムは`Deck`クラスを利用します。これは何枚かのカードを持っていてシャッフルしたり偶数と奇数を分けてくれます。今回の検証は`Deck#split_even_numbers`で`Enumerable#partition`にブロックを渡していますが、それをRSpecでテストする方法です。

本来であればメソッドを呼び出した結果を検証すべきですので、メソッド呼び出しのみのテストはいいと言ってはいません。用法用量を守るのはお兄さんとのお約束だぞ:wink: 

```ruby
class Deck
  def initialize(cards)
    @cards = cards
  end

  def shuffle
    @cards.shuffle
  end

  def split_even_numbers
    @cards.partition { |card| card.even? }
  end

  def split_odd_numbers
    @cards.partition(&:odd?)
  end
end
```

# RSpec

## ブロックの検証

`with`にブロックを指定すると`{ |card| card.even? }`を受け取ることができるようです。`&block`としているので`Proc`クラスのオブジェクトになっています。

`Proc`クラスのオブジェクトをつくって比較すればいいか！と思っていたのですが、メソッドに渡してるブロックとは異なるようでテストはうまくいきませんでした:sweat_smile:

```ruby
describe Deck do
  describe '#split_even_numbers' do
    let(:deck) { Deck.new(cards) }
    let(:cards) { [5, 4, 3, 2, 1] }

    it do
      expect(cards).to receive(:partition).with(no_args) do |&block|
        # この検証はうまくいかない
        expect(block).to eq(Proc.new{ |card| card.even? })
      end
      deck.split_even_numbers
    end
  end
end
```

## &手続きオブジェクト
「&手続きオブジェクト」といっていますが検証したい`Proc`クラスのオブジェクトとテストでの期待値が同じオブジェクトであれば今回のやりたいことは実現することが出来ます。

`:odd?.to_proc`は常に同じオブジェクトを返すので検証で利用して期待した結果を得ることが出来ます。

```ruby
describe Deck do
  describe '#split_odd_numbers' do
    let(:deck) { Deck.new(cards) }
    let(:cards) { [5, 4, 3, 2, 1] }

    it do
      expect(cards).to receive(:partition).with(no_args) do |&block|
        expect(block).to eq(:odd?.to_proc)
      end
      deck.split_odd_numbers
    end
  end
end
```