OmniAICreator/Qiita-1.07M huggingface dataset:
【gitコマンド 】リポジトリのクローンからリモートへのpushまでする

## リモートのファイルを自分のPCに反映させる
リモートリポジトリをローカルにクローン
`git clone https://hogehoge…`

リモートにどんなブランチがあるか確かめる
`git branch -a`

リモートブランチをローカルにもってくる
例: developブランチ
`git checkout -b develop remotes/origin/develop`

自分が今いるブランチをかくにん
`git branch`

最新の情報をローカルに反映させる
`git pull` 

ログをかくにん（コミットが最新の情報か？確認しましょう）
`git log`

新しく自分の作業するブランチを作る（ローカルブランチの作成）
`git checkout -b feature/newbranch（任意のブランチ名をつける）`

ローカルでの作業　ファイルを追加したり変更したりする

## 更新したファイルをリモートリポジトリに反映させよう
更新したファイル全てをインデックスに追加する
`git add .`

個別にファイルをコミットしたいときは
`git add ファイルのパス`

インデックスに追加されたファイルをかくにん（コミットする予定のファイルを確認）
`git status`

コミットする
`git commit -m ‘任意のコミットメッセージ’`

コミットできたかかくにん
`git log` 

[※間違えてたら`git commit —amend`で修正できるよ]
(https://qiita.com/mochifuture/items/0cbc90d4867f314059e2)

問題なければリモートにプッシュする
`git push`

新しく作ったブランチの時は以下のコマンド
`git push —set-upstream origin feature/newbranch`

リモートリポジトリに、変更が反映されているか確認しましょう
AWS 認定ソリューションアーキテクト – アソシエイト受験を考えている人のための雑記

## はじめに

合格体験記でも書こうと思っていたが、既に多くの人が内容の濃い記事を書いていたので、
今回は合格体験記を交えながら、**受験を考えている・迷っている人** 向けに書いてみます。
試験の内容、形式等については公式または他記事をどうぞ。


## 試験について


### 暗記ゴリ押しで行ける？

60%くらいいけます。ただサービスの範囲が広いのでヤマを張るくらいなら、
ちゃんと手を動かすなりして網羅的に勉強したほうが良いです。
知識として定着させるためにも。


### どんなサービスが出題されるの？

時間が余ったのでサービス別に集計をしてみたんですが、
公開するとおそらくNDA違反のため何となくニュアンスだけ。
問題傾向は模擬試験を解くとだいぶわかるかと思うので割愛。

ストレージ系サービスはしっかりやっておくといいです。
各サービス毎の特長、相違点、ユースケースを説明できるようにしておく、
付随的な機能がある場合は最新の情報とともにチェックしておくことが必要です。

あとは、下のような視点をもって勉強すると提案/設計面でも役に立つと思われます。

- 何がしたい（解決したい）からこのサービスを使うのか
- このサービスを使うことによって何が嬉しいのか
- 他のサービスを使うことのデメリットは何か


### 試験合格までの距離感

[公式サイト](https://aws.amazon.com/jp/certification/certified-solutions-architect-associate/)にて受験者の概要が公表されていますが、
合格に焦点を当てるのであれば、 **数週間程度AWSを触った経験がある、理解している状態** で十分。

下に、受験者のレベル別に合格までの距離感がどのくらいか示してみます。
（個人的な主観に基づいています）

##### 1. EC2でLAMP相当の環境を構築できる

AWSの基本的なサービスは理解できていると思われるので、
後はストレージ系の暗記、知らないサービスのインプットを行えば問題なく合格できると思います。
個人差はありますが必要な勉強時間は10～20時間ほど、
試験対策本や公式の模擬試験を中心に進めるのが良いかと。

##### 2. AWS未経験だが、オンプレでガンガン構築運用してきた

オンプレでの業務経験があり、ネットワーク基礎知識などがある場合、
AWS未経験でもある程度アドバンテージが期待できるので短～中期的な目標とするのがおすすめ。
個人差はありますが必要な勉強時間は15～25時間ほど、
試験対策本や公式の模擬試験を中心に、ホワイトペーパーをリファレンスとして進めるのが良いかと。

##### 3. AWS未経験、アプリ開発、コーディング経験のみ

とりあえずサンプル問題を解いてみること。
何を問われているのかわからない場合、長期目標として試験の合格を掲げ、
時間をかけてサービスを調べるところから始めるのが良さそうです。
公式資料はほぼ文章のため、イメージ化するために画像検索なども活用しよう（出典は確認すること）。
30～50時間くらいは勉強時間が必要と思われます。


### DVAとSAAどちらを受けるべき？

AWSを一通り触っているのであればどちらでも問題ないです。
（気持ちSAAの方が楽かも。）
AWS歴が浅い場合はSAAから攻めたほうが良いかもしれません。というのも、
2018年の改訂前であればDVAの方が暗記割合も多く比較的楽でしたが、
改訂によってDVAで出題されるサービスがDevOps寄りに範囲変更となったため、取っつきにくい試験となってしまった印象です。


# 合格体験記

最後に少しだけ自分の合格した状況を。

#### 経歴

- WEB系エンジニア5年目
- 座学を受けてDVA取得（2017年）
- 業務では1ヶ月半ほどAWS使用

#### 勉強期間・内容

- 12時間（業務で触っていたので上記の「EC2でLAMP相当の環境を構築できる」に該当）
- 各種ホワイトペーパー、模擬試験、サンプル問題
- 市販の試験対策本・WEB問題集使用せず

#### テストセンター

- 歌舞伎座タワーのテストセンター
- 他所のように身分証読み取り、監視員とのやり取りがないので東京近郊であればおすすめ


# さいごに

言語系のベンダー試験に比べて実用的な知識が問われる部分も多く、
暗記で合格してサヨナラ、とするには惜しいので是非最初の一歩として目指してみてください。

あと試験の種類に限らずテストセンター選びは結構重要。
同じ試験でもメモ用紙が配布される会場と、そうでないところとかがあったりします。
[AWS:Lambda] Lambda用のnode.jsをローカル環境で開発しやすくする為のTips

今月お仕事でAWSのLambdaでバッチ処理を書きました。

今回は node.js(v8.10) でローカル開発する際の備忘録として書き残します。
ローカル環境はMacです。

## ローカル用の踏み台ファイル(proxy.js)の用意

https://symfoware.blog.fc2.com/blog-entry-2218.html

上のURLを参考にして、作業ディレクトリ内に`proxy.js`を用意します。
なぜ踏み台が必要かも説明されています。
今後はこのファイルを通して

``` bash
$ node proxy.js 
```

と実行すれば、ローカルで`index.js`の処理を実行する事ができるようになります。

## dotenvで環境変数を管理できるようにする

バッチ処理中にAPIを使用する事も多いです。
その際ファイル内にパスワード等を直書きするのはよろしくありません。
Lambdaは環境変数を専用の場所から設定できますのでそこで管理しましょう。
ローカルでは`dotenv`を使用して管理すると良いでしょう。

作業ディレクトリで以下を実行して`dotenv`を導入します。

``` bash
$ npm install dotenv
```

先ほど用意した `proxy.js` に下の行を追加します。

``` proxy.js

'use strict'
require('dotenv').config() //<- これを追加。.envから環境変数を取得
// ...
```

作業ディレクトリ内に`.env`を作成し、次のように記述すると環境変数を設定できます。

```
REDSHIFT_USER="user"
REDSHIFT_PASS="password"
```

`index.js`で次のように指定すれば`.env`の変数を使用できます。

``` index.js
//...
const REDSHIFT_USER = process.env.REDSHIFT_USER
const REDSHIFT_PASS = process.env.REDSHIFT_PASS
//...
```

git管理をしているなら`.gitignore`に`.env`を含めないようにするとベターです。

上でも書いたようにLambdaの環境変数は専用の場所から設定するので
`.env`はLambda環境までアップロードしません。

故に`dotenv`のようなローカルでのみ使うようなライブラリは
`proxy.js`で読み込めば`index.js`を汚さずに済むようになります。

## zip化の処理を書く

処理が完成したらLambdaにアップロードする為のzipファイルを作成しないといけません。
zipファイルは10MBを越えると`S3`経由からアップロードしなくてはいけなくなります。

zip化する際に軽くする為に不要なファイルや`node_module`の中のライブラリを除かないといけません。

特に気をつけなくてはいけないのは`aws-sdk`という
AWSのツールを簡単に操作する為のライブラリです。これが38MB近くあります。
これをzipに含めると圧縮しても10MB以下に抑えるのが難しくなります。

幸いな事に、Lambdaでは`aws-sdk`が最初からインストールされている為、
このライブラリを使う為に`node_modules`に含めておく必要はありません。

ですので、`zipForLambda.sh`を作業ディレクトリ内に作成し次のように記します。

``` zipForLambda.sh
cd `dirname ${BASH_SOURCE:-$0}`
zip -r lambda index.js node_modules/ -x "node_modules/aws-sdk/*" "node_modules/dotenv/*"
# 他にも含めたいファイルがあるなら追加していく↑　　　　　　　　　　　他に除きたいファイルがあるならここから追加していく↑
```

そして、次を実行すれば

```
$ bash zipForLambda.sh
```
Lambdaにアップロードする為のファイル`lambda.zip`が書き出されます。
入っているのは`index.js`と必要な`node_modules`だけです。
`dotenv`もLambdaで不要なのでzipに含めませんでした。

また、`proxy.js` `.git` `.gitignore`等も不要なので含めていません。
lambdaでは処理の実行前に`npm install`をしてくれません。
ですので`package.json`等も不要です。


## まとめ
これでローカルで開発する為の環境が整いました。

開発フローは次のようになります。
1. `index.js`に処理を書く。
2. 必要な環境変数が出てきたら`.env`に記述。`index.js`で受け取る。
3. `$ node proxy.js`を実行して動作確認。
4. 完成したら`$ bash zipForLambda.sh`を実行してzip化。
5. `lambda.zip`をAWS Lambdaにアップロードしてテスト。

となります。

必要なファイルが増えた際`zipForLambda.sh`を更新するのを忘れないようにしてください。
`zipForLambda.sh`内に`aws-cli`を使用したlambdaへのアップロードコマンドも含めるのもいいと思います。

### 参考
proxy.js
https://symfoware.blog.fc2.com/blog-entry-2218.html
bash zipコマンドの書き方の参考
https://qiita.com/yudoufu/items/48cb6fb71e5b498b2532
https://superuser.com/questions/312301/unix-zip-directory-but-excluded-specific-subdirectories-and-everything-within-t
AWS Lambdaへの環境変数の設定方法
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/env_variables.html
UIでEditTextに入れた値がMutableLiveDataに反映されない

# やりたかったこと
価格をEditTextで入力して、BindさせたMutableLiveDataへ値を反映させたかった。

# なぜ反映されなかったか
EditTextのandroid:textにMutableLiveDataを記載するがパターンが２つある。

* 一方通行
* 双方向

# どうしたか
以下のように記載を修正した。

```
android:text="@={MutableLiveData}"
```

以下のように記載すると一方通行(LiveData->EditText)。

```
android:text="@{MutableLiveData}"
```

"="の有無でだいぶ変わるんですね…
rubyインストールでtmpの容量不足

# どうした？
conohaにrubyをインストールしようとしところ`/tmp`が不足しているため(?)インストールできなかった。
このようなエラーがでた

```
compiling raddrinfo.c
/tmp/ccYYl90Y.s: Assembler messages:
/tmp/ccYYl90Y.s: Fatal error: can't close raddrinfo.o: No space left on device
```
ちなみに`/tmp`のサイズは`242M`
100%使われていることがわかる。

```
$ df -h
Filesystem      Size  Used Avail Use% Mounted on
dev             236M     0  236M   0% /dev
run             242M  368K  241M   1% /run
/dev/vda2        20G  5.5G   14G  30% /
tmpfs           242M     0  242M   0% /dev/shm
tmpfs           242M     0  242M   0% /sys/fs/cgroup
tmpfs           242M  240M  1.9M 100% /tmp
tmpfs            49M     0   49M   0% /run/user/1000
```

# こうする！

`TMPDIR`として大きな領域を指定してビルドしてあげる。
`TMPDIR="${PWD}/tmp" rbenv install 2.1.0`

# 参考
[/tmpがnoexec指定されていてrbenv installなどがコケるとき - Qiita](https://qiita.com/mazgi/items/2ea799d84f42f3071ddf)
DataBindingでNotFoundExceptionが起こる

# やりたかったこと
レイアウト(xml)ファイルのandroid:textに数をBindさせて表示させたかった。

# なぜ起こっていたのか
android:textにはStringを入れる必要があるのにIntのMutableLiveDataをそのまま入れてしまっていた。

# どうしたのか
以下のように記載

```
android:text="@{String.valueOf(<ここに出したい値を入れた>)}"
```
AlertDialogをshow()するとIllegalStateExceptionが起こる

# 個人的備忘録的記事
ダイアログ出すときにいろんなところで起こってしまってしばらくハマってしまっていた。
理由はAlertDialogをcreate()してshow()するという実装をしていた。
AlertDialogはcreate()を複数呼んではいけないのだが、create()した結果をメンバ変数に入れていて引っかかってしまっていた。
create()は初回だけ呼ぶようにして、show()だけを呼ぶようにしたら解決。
Linuxをターミナルで操作する時のショートカットキー

Linuxをターミナル（CUI）で操作する際に使用できるショートカットキーをまとめました。

# 01. コマンドの入力
### カーソル移動
矢印キーではなくショートカットキーを使用することで、ホームポジションを離れない操作が可能になります。

|コマンド|動作|
|---|---|
|Ctrl + b|左に1文字移動|
|Ctrl + f|右に1文字移動|
|Alt + b|左に1単語移動|
|Alt + f|右に1単語移動|
|Ctrl + a|行頭に移動|
|Ctrl + e|行末に移動|

### 文字の削除と貼り付け
入力した文字の削除もショートカットキーが使えます。
下記表の「※」がついている「単語削除」「行頭/行末までの削除」では、ヤンク（貼り付け）が可能です。

|コマンド|動作|
|---|---|
|Ctrl + h|カーソルの左1文字を削除(=BackSpace)|
|Ctrl + d|カーソル上の1文字を削除(=Delete)|
|Ctrl + w|カーソル左の単語を削除 ※|
|Ctrl + u|行頭からカーソル左の文字まで削除 ※|
|Ctrl + k|カーソル上の文字から行末までを削除 ※|
|Ctrl + y|「※」で削除した内容をヤンク|

### コマンド履歴の選択
「↑」「↓」で、そのユーザーが過去に使用したコマンドを呼び戻せますが、こちらもホームポジションから離れずできます。

|コマンド|動作|
|---|---|
|Ctrl + p|1つ前に実行したコマンドを表示する|
|Ctrl + n|1つ最新のコマンドを表示する|
|Ctrl + r|コマンド履歴のインクリメンタル検索|

### 「コマンド履歴のインクリメンタル検索」時の操作
コマンド履歴をインクリメンタル検索（1文字入力するたびに検索結果が更新される、逐次検索）することできます。「Ctrl + r」でインクリメンタル検索モードになるので、そこで下記操作を行えます。

|コマンド|動作|
|---|---|
|Ctrl + r|1つ過去の検索結果を表示|
|Enter|現在の検索結果を実行|
|Esc|現在の検索結果を保持したままコマンドラインへ戻る|
|Ctrl + g|検索を中止し、コマンドラインへ戻る|

# 02. ターミナル操作

### 画面ロック
「コマンドが入力できなくなった！！」というときは、画面ロックをしてしまった可能性を疑うとよいかもです。

|コマンド|動作|
|---|---|
|Ctrl + S|画面への出力をロックする ※１|
|Ctrl + Q|画面への出力のロックを解除する|

※1 入力自体は受け付けていて、ロック解除時にターミナルに入力内容を反映されます。例えばロック中にEnterを押していると、ロック解除と同時に、Enterまでに入力された文字列がコマンドとして実行されます。

###その他
画面の出力結果を消したいときはclearコマンドを使っていましたが、これもショートカットキーでできるんですね。コマンド入力中に「Ctrl + l」を使っても、入力中の内容は保持されたままなので便利です。

|コマンド|動作|
|---|---|
|Ctrl + C|実行中のコマンドを中止する|
|Ctrl + D|ログアウトする（何も入力していない時のみ）|
|Ctrl + l|画面に表示された内容を全消しする（=clearコマンド）|


#参考
- [新しいLinuxの教科書](https://www.amazon.co.jp/dp/4797380942/ref=cm_sw_r_tw_dp_U_x_bBwXCbMMGS21P)
新入社員が一ヶ月間、業務後にQiitaに記事を書き続けた話

#まずは自己紹介から
どうも初めまして、作道(さくどう)です。

黒と赤を偏愛する
ちょっと頭のおかしな
今年の4月から全く別の業界から転職し
新しくプログラマーとして働き始めた
福岡に住んでいる26歳男性です。

組める言語はJavascriptやPHPで
最近は様々なフレームワークを触ったり、バックエンド的な知識を業務で得ています。

##なんでQiitaに投稿しようと思ったの？
簡潔にまとめると

- 未経験でプログラマーとしてweb業界で働くので不安だった。
- 独学で学んできた雑魚なので不安だった。
- バズって人気者になりたかった。
- 業務でやることを予習したかった。
- 業務でわからなかった事を復習したかった。
- Twitterのフォロワーを増やしたかった。

まぁ不安を拭いたくて
あわよくば…
**あの、あわよくば、よ？**
Qiitaのランキングに載ってチヤホヤされたいな～なんて。

で業務が終わって家に帰った後Qiitaに記事を投稿していました。

##実際に書いた記事を紹介

01日目：[.htaccessを編集してリダイレクトする。](https://qiita.com/sakdor/items/6bd1e9b08a38150574b1)
02日目：[phpのデバッグの基本](https://qiita.com/sakdor/items/207f9267a8e54148cb08)
03日目：[phpのclassとinstanceと$this](https://qiita.com/sakdor/items/36f5ccfd614203d2c0b3)
04日目：弊社花見開催と地下鉄事故によって帰宅が遅かったので…サボった(素直
05日目：[.htaccessによるBasic認証](https://qiita.com/sakdor/items/5426d45e0d2e51f90879)
06日目：[SSLの更新手順の簡単な概要](https://qiita.com/sakdor/items/f705190739c28814497e)
07日目：[queryでNewbieがハマったポイント](https://qiita.com/sakdor/items/b926632571f07d0eb4bb)
08日目：[ダサくないデザインとは](https://qiita.com/sakdor/items/2c3fa535c5a372871649)
09日目：[印刷用のCSSでデザインがページで分断されてしまわない為に](https://qiita.com/sakdor/items/0bfb1dd52cfc07cad446)
10日目：[ターミナルのコマンド 初心者編](https://qiita.com/sakdor/items/7ebcb321dc70f908bf6e)
11日目：[Perlを初めて書いてみよう！](https://qiita.com/sakdor/items/5f536bd497b842cb90bc)
12日目：[令和へ対応せよ！元号のアルゴリズム](https://qiita.com/sakdor/items/e13421c60438408e0e5b)
13日目：[phpのpublic・private・protectを理解しよう！](https://qiita.com/sakdor/items/58de4f15bf1f4cdc6d56)
14日目：[phpで文章を整形せよ！](https://qiita.com/sakdor/items/69ac5329096b51013fdc)
15日目：[アナリティクスツールであるMatomoをサーバーにインストールする。](https://qiita.com/sakdor/items/b17d38e2dd26876af44c)
16日目：[JavaScriptでRSSを扱ってみよう！](https://qiita.com/sakdor/items/0d0f5da3b9a0832b3909)
17日目：[phpが動かない時にやったことメモ](https://qiita.com/sakdor/items/f0d9e36176910c490599)
18日目：[PHPでクエリパラメータから配列を受け取る物語](https://qiita.com/sakdor/items/8a11d88099008bb1e9dc)
19日目：[見たことなかったSQLコマンドを調べてみた。](https://qiita.com/sakdor/items/b3c29a15245009d2c8f9)
20日目：[WordPressのjetpackプラグインがセットアップできないエラーを解決する](https://qiita.com/sakdor/items/e6cd0a417b33dbfc2395)

注：記事中に上司っぽい人が出てきますが、かなりふざけて書いてるので実際とはかけ離れています。
弊社上司はかなり良い人です、聖人です。

##書いてみて気づいたこと

### 間違いなくレベルアップ出来る
当然ですが学問と同じく、予習復習すれば知識や実力は身につきます。
特に独学でやってきた僕にとって業務的な知識は身につけなければならなかった物なので
Qiita投稿を続けて良かったなと思います。

### 他の人からアドバイスを貰える
SNSなので当たり前ですが、他の人からレスポンスがあります。
「ココはこうしたほうが良い」と暖かくコメントを貰えるのでQiita凄いです。
正直炎上を覚悟した
[令和へ対応せよ！元号のアルゴリズム](https://qiita.com/sakdor/items/e13421c60438408e0e5b)
ではバグを指摘してもらえたり、アドバイス記事書いてもらったり…
優しい世界でした。

### バズらない
甘かった…
Twitterのフォロワーは3人増えただけでした…
[@sakdor_br](https://twitter.com/sakdor_br)
執筆時点でフォロワー50人…（露骨な宣伝
でも個人ブログに投稿するよりかは10倍くらい読まれます。
Qiitaの人口は結構多いと思います。

###何をユーザーが求めているのかがわかる
平日毎日記事を投稿していると
どの記事が読まれなくて、どの記事が読まれるのかが
露骨に浮き彫りになります。
このノウハウをnoteあたりで有料で売ってウハウハでも良いのですが
面倒なので簡単に教えます。

- タイムリーなネタで記事を書く
- メジャーなカテゴリでネタを書く
- 技術に寄りすぎない話を書く
- 面白い物語の流れで書く

上記の感じだと読まれやすい気がします。
あと僕の予想だとこの記事も読まれやすいと踏んでいます。
（これで全く読まれなかったら、それはそれでネタになるなぁ…）
 
###インプットが疎かになる
これはデメリットなのですが
Qiitaの記事を書く時間が必要となるので
インプット ＞ アウトプット
になります。
おかげで積読が増えて死にます。
それに段々とアウトプットの質が下がります。
なので週に2回ぐらいの投稿がベストな気がします。

#終わりに
総合して、まぁ記事を書き続けて**良かった**と思っています。
まぁでも5月からはペースを落とすかなぁ～って感じです。
なのでフォローしてください…笑
[@sakdor_br](https://twitter.com/sakdor_br)
一週間分のTweetをまとめてみたかった話


# きっかけ

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">RTした興味深い記事とかが流れて行ってしまって一か月後とかに振り返れないのはちょっともったいないな。。<br>一週間に一回ぐらいワードプレスとかにまとめておくといいんだろうか？</p>&mdash; なかまえ (@ryo_naka) <a href="https://twitter.com/ryo_naka/status/1119428739673149440?ref_src=twsrc%5Etfw">2019年4月20日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>




# なんか簡単な仕組みがないかな？
ある程度手動でもいいから、簡単にまとめられるものがないかと探してみるが、
TwitterのアナリティクスだとRTだけだとコメントしてないと取得できないし、
してたとしてもそれのURLが簡単に取れなさそう。
Twilogだと一見取得できそうなんだけど、整形したデータとしては取得できるがそこにはRT元のURLが入っていない。

# なさそう
ということで、せっかくなので処理を書いてみた。

とりあえずの仕様としては、
・自分の一週間分のTweetをたどってRTのものを取得
・日付ごとにまとめる
・ファイルに出力する
この三点である。

## 検索パラメータ
仕様
https://developer.twitter.com/en/docs/api-reference-index

上記仕様を参考に今回の取得のパラメータ的にはこんな感じにした。

```
var parm = new Dictionary<string, object>();
parm["screen_name"] = screen_name;
parm["since_id"] = start_id;
parm["include_rts"] = true;
parm["count"] = 200;
var tweets = tokens.Statuses.UserTimeline(parm);
```

で、いったん、指定ID以降のTweetを全部取得する（よほどのことが無い限り一週間で200Tweetもしていないはずだし）ようにして、ファイル出力する際にRetweetedStatusがNULLのものを省いた。

ただそれだと自分がRT＋コメントしたヤツが取れなかったのでQuotedStatusが入っているやつも残すようにしてみる処理も追加。


## できあがり

コードはこんな感じ。

https://github.com/RyoNakamae/GetRT



でファイル出力したものに、適当にコメントを追加しながら作ったのが以下。

http://www.riosnest.co.uk/2019/04/post-653/




でも、作ってから気が付いたけど、自分でサイトから共有したようなものはひっかからないな。。
その辺はまたそのうち考えるか。
iperfでマシン間の回線速度調査

マシン間の回線速度を調べる方法としてiperfを使うというのがあるけど、ググってみると古い情報だと「ver.2はもう更新終了してver.3に移行した」とか「ver.3はまだWindowsに対応していない」とか出てきたので、見つけた方法のうち2019/04/22時点で一番楽なのはこれだと思う。

# ダウンロードサイト
各種OS向けのiperf 3.1.3がダウンロードできる。
LinuxだけでなくWindows、Andoroid、iOS用のものもある。
https://iperf.fr/iperf-download.php

#使い方
Windowsでは解凍して出てきたiperf3.exeをコマンドプロンプトで各種オプションを付けて実行するだけ。
Linuxの場合はrpmをインストールして、Windowsと同様に各種オプションを付けて実行すれば良い。

```none:rpmインストール
[root@host ~]# rpm -ivh iperf3-3.1.3-1.fc24.x86_64.rpm
```

オプションについてはサーバ側として起動する「-s」、クライアント側として起動する「-c [ホスト名 or IPアドレス]」などがある。
オプションの使い方については他に説明している人がいるのでそちらを参照すればいいと思う。

[ネットワーク測定ツールiperfの使い方 - Qiita](https://qiita.com/takish/items/bff7a1df712d475432df)

[iperf3コマンド使い方、オプション一覧 - Qiita](https://qiita.com/yokoc1322/items/bfd8b6e69d6bdb3bb1c6)

サーバ側：Linux、クライアント側：Windows 10、というように異なるOS間でも使用できる。
またローカル内で2つ、サーバ側とクライアント側として起動するとローカルでのデータコピーが何Gbps相当なのかといった調べ方もできる。

# 所感
個人的な感想ではあるが、iperfで出る回線速度は体感よりも小さな値だと思う。
イントラネットなど高速で近いところだとほぼ期待どおりの値がでる。例えば1000BASE-Tでつないだイントラネットでは900Mbpsくらい。
一方でフレッツの1Gbpsベストエフォートで実測300～400Mbpsくらいと言われているところでもiperfで試してみると40Mbpsと表示されたりする。
ファイルサイズが大きいものを投げれば回線速度の値は大きくなるし、小さいものを投げれば小さくなる。
実測値として転送処理時間の計算に入れるのではなく、あくまで「目安として測ってみたら何Mbpsだった」と思った方がいいかもしれない。
回線は速いはずなのにマシンがぽんこつで処理速度が出ない、じゃあネックはどこだ、というように調べるのにも使える。
MacOSでsudoが遅くなったことの原因

#概要
[「Linuxでパスワードの入力なしでsudoを実行できる」](https://www.lapidem.pw/linux/110/debian-password-sudo-su-superuser/)ようにして、スクリプト実行中にパスワード入力をしなくても済むようにしていたので、MacOSでもと思い、トラブルが起きたマシン以外のMacでも設定を行い、うまく行っていた。当該マシンでもと考え、設定を行ったのだが、結果的には他のマシンではしなかった余計な設定をしたためにハマりました。
こんな事をする人は稀でしょうが、同じ状況になった方にお役に立てれば幸いです。

#環境
MacOS Mojave, Mac mini(2018)

#症状
/etc/sudoersで「パスワード入力なしでsudoを実行する」の設定後に、**sudoできるのですが、パスワード入力のプロンプト表示まで数分の時間を要する**ようになった。後から考えると、設定後の動作確認を行った後に更に変更を追加し、その時には問題ないと考えてチェックを怠たり、気が付いたのが後日だったことが原因だった。


#解決
##解決の糸口
検索したところ、[「mac で sudo時に非常に時間がかかるんだよね」](https://qiita.com/to_obara/items/1f5d7bc2068256636b25#)がヒットし、助かりました。/etc/sudoersで、存在しないグループの設定をしてはいけない、ということが書かれていました。macOSの/etc/sudoersは以下のようになっています（関係のある部分のみ抜粋）。

``` :/etc/sudoers
<略>
##
## User privilege specification
##
root ALL=(ALL) ALL
%admin  ALL=(ALL) ALL

## Uncomment to allow members of group wheel to execute any command
# %wheel ALL=(ALL) ALL

## Same thing without a password
#%wheel ALL=(ALL) NOPASSWD: ALL

## Uncomment to allow members of group sudo to execute any command
#%sudo  ALL=(ALL) ALL
<略>
```
##トラブルの原因
Debian系ではsudoグループ、RedHat系ではwheelグループがsudoできるグループとして設定されているようですが、MacOSではadminグループです。Debianな私は、当然、sudoというグループが存在すると考えて、不注意にも以下のようにしてしまいました。当然、sudoグループの存在を確認していませんでしたが、無くても問題ないだろうと考えたのが浅はかでした。

```
## Uncomment to allow members of group wheel to execute any command
%wheel ALL=(ALL) ALL

## Same thing without a password
%wheel ALL=(ALL) NOPASSWD: ALL

## Uncomment to allow members of group sudo to execute any command
%sudo  ALL=(ALL) ALL

```
MacOSでは、管理者はadminグループに設定されるようですので、本来は、以下のようにすべきです。（私は別な方法にしています。後述）

```
## Same thing without a password
#%wheel ALL=(ALL) NOPASSWD: ALL
%admin ALL=(ALL) NOPASSWD: ALL
```

#私の設定
私は、CentOSと同様に自分をwheelグループにしています。

```
%wheel ALL=(ALL) ALL
%wheel ALL=(ALL) NOPASSWD: ALL
```
しかし、この後でMacOSには、**usermod**がないことに気づきました。以下のように行います。
wheelグループへの追加


```
sudo dscl . append /Groups/wheel GroupMembership user_name
```
wheelグループからの削除は

```
sudo dscl . delete /Groups/wheel GroupMembership user_id
```

/etc/groupでも登録は確認できますが、wheelグループに登録されたユーザを表示は以下のようにします。

```
dscl . read /Groups/wheel
```

sudoに時間がかかるのは、死活問題であることを痛感しました。
take, call, put, select, fork, takeEveryの一言説明

忘れる、調べる、思い出す、を反復してる現状を踏まえる


## 忘れたら最初にここを読む

```js
import { put, call, take, select } from 'redux-saga/effects';
```

|なまえ|一言でいうと|
|---|---|
|`yield put({type: 'xxx', ...})`|actionをdispatchしたい|
|`yield call(fn, args)`|関数をコールして返す値をキャッチしたい。<br/>`axios.get(..)` する関数とかをコール|
|`yield take(actionType)`|特定のactionをキャッチしたい|
|`yield select(selector関数, args)`|storeからデータを取りたい|
|`fork`|sagaをコールしたい|
|`takeEvery`|このactionがdispatchされたらこのsagaを毎回コールしたい|

- 他人のコードを読む用
- ~~`yield fork(fn, args)` は読む機会が無いので現状はスルー~~takeEveryは`call`と`fork`を組み合わせて実装されてる

```js
// selector関数の例 storeからcartだけ取りたい
export const getCart = state => state.cart
```



## 次に読むページ

型定義ファイル（「`function put(` 」とかでページ内検索して、コメントを読む）

- https://github.com/redux-saga/redux-saga/blob/master/packages/core/types/effects.d.ts
安全なデータ削除方法

#CISSP自習memo
##Domain 3
###Sanitization
- sanitization  
hdd,ssd,cd,dvd,tapeなど利用後にデータを安全に消去もしくは破棄すること  
人の作業はもちろんのことツールなどを使って消去してもきちんと行われたかどうか確認することは難しい  
  よって多くの組織は消去後に除却するのではなく破壊によるデータ破棄を行っている。  
- erasing  
only the directory or catalog link消すだけ。  
データは数ヶ月に渉って残置することも
- clearing  
何らかの情報を媒体に上書きすること。
フォレンジックツールで取出せることもある.
残置磁気とかだろうか?
- pursing  
more intense than clearing  
deガウスとか  
消去の信頼性は低い  
再利用できない
- degaussing  
磁気的消去。  
オプティカルメディアcd,dvd,ssdには無効。  
あんまりオススメではないです。  
テープの破棄に使われる?
- destruction  
物理的破壊。  
最も信頼性が高いメディアの廃棄方法
Excelワークシート上でSplit(文字列を区切り文字で分割)関数を使用する

#手順
1 Excelを拡張子xlsm(マクロ有効ブック)で保存する
2 VBEを開き、標準モジュールを作成
<img width="665" alt="無題.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181210/2a9f3ad5-836c-1d4f-bac5-59e14979f775.png">
<img width="534" alt="無題.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181210/36eaf33a-034c-5b47-cffb-71d3b4191cee.png">

3 下記のコードを標準モジュールに記述し保存

```
Function split_on_worksheet(target_string As String, separater As String) As String()
    split_on_worksheet = Split(target_string, separater)
End Function
```
<img width="822" alt="無題.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181210/c8ea8e11-7c94-c558-0b18-a8cd468993d3.png">


4 分割した文字列を表示するセル範囲を指定する(画像の場合はB2:J2を選択している)

<img width="643" alt="無題.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181210/b7d6d5c7-2c78-b499-f906-35002aca207c.png">

5 **選択した状態のまま**、下記のように入力し **Ctrl + Shift + Enter**を押す(Enterだけではダメ)
`=split_on_worksheet(B1,",")`
※1つ目の引数には分割する文字列を、2つ目の引数には区切り文字を指定

<img width="638" alt="無題.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181210/c5790fdb-7e71-83c8-9ebd-a6f663cf8ae4.png">


すると、下記のように文字列が分割されます。
※D2~J2には入る値が無いので#N/Aになります。
<img width="633" alt="無題.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181210/05962784-54d2-40c5-4811-18040a9fc202.png">


6 もし横では無く縦に展開したい場合は、縦に選択した状態でTranspose関数と組み合わせて使用してください。
`=TRANSPOSE(split_on_worksheet(B1,","))`

<img width="427" alt="無題.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181210/f1288566-7223-23fe-8748-82177332e68b.png">
Redux単体で動作する環境を作る

Reduxのソースを読むために、まずはReduxだけを動かす環境を作ります。
Reduxのgithubには、[The Gist](https://github.com/reduxjs/redux#the-gist)として、Redux単体で動かすサンプルコードが載っています。このサンプルコードを動かすまでを目標とします。

基本的にはNode.jsのプロジェクトを作成して、そこにreduxをインストールします。ただ、[The Gist](https://github.com/reduxjs/redux#the-gist)がES6のimportの書き方をしているので、これを解釈できるようにbabel-cliとbabel-preset-envも一緒に入れて、babel-nodeで起動できるようにします。

まずは、空のディレクトリを作成して、redux babel-cli babel-preset-env をインストールします。

```shell:
$ mkdir redux-simple2 
$ cd redux-simple2
$ echo "{}" > package.json
$ npm install redux babel-cli babel-preset-env --save
```

次に、package.jsonにscript/startを追加します。

```json:package.json
{
  "dependencies": {
    "babel-cli": "^6.26.0",
    "babel-preset-env": "^1.7.0",
    "redux": "^4.0.1"
  },
  "scripts": {  // 以下3行を追加
    "start": "babel-node --presets babel-preset-env index.js" 
  }
}
```

最後に、index.jsに[The Gist](https://github.com/reduxjs/redux#the-gist)をコピペします。
この状態で npm start すると、babel-nodeがES6なindex.jsを解釈して起動します。

```shell
$ npm start

> @ start /Users/tak/proj/redux-simple2
> babel-node --presets babel-preset-env index.js

1
2
1
```

Ultimate版のIntelliJは、JavaScriptのデバッグ実行が可能です。babel-nodeの引数に$NODE_DEBUG_OPTION を追加する事で、IntelliJでのデバッグ実行ができるようになります。

```json:package.json
"start": "babel-node $NODE_DEBUG_OPTION --presets babel-preset-env index.js" 
```
Scala Playの学習方法【GW連投企画】

# 大前提
Scala Playはウェブアプリ入門者が最初に着手すべき組み合わせではないと考えています。

既にRuby(Rails)かPHP(Laravel)、またはJava(Play)等を学習された方々には向いてると思います。

## 優先すべきと事と関数型について
関数型という事を一旦置いてJavaの亜種を扱ってる感じ且つ、Railsっぽいなって感じでコードを見渡すと理解が早いです。

「暗黙のパラメータ」や「カリー化」等の言語自体に非常に魅力的な機能があるのですが、
「Scala Play」でウェブアプリを作る事ができる事を優先し関数型言語を深く身に付けるのは、
一旦Scala PlayでCRUDアプリを作れるようになってからでイイかなと思います。

関数型の文法を深くおって、仮に理解してもいったいどんな時に使うのかが想像もつかない事が
度々あります。

「暗黙のパラメータ」や「カリー化」等なんかまさにそうです。

## 進めかた
### ウェブサイト
[ドットインストール Scala入門](https://dotinstall.com/lessons/basic_scala)
まずは御馴染みのサイトで文法を！

[Play Framework Tutorial](https://www.youtube.com/watch?v=zQUZOiQPz_I&list=PLYPFxrXyK0Bx9SBkNhJr1e2-NlIq4E7ED)
Javaですが、Playの雰囲気を掴めます

[Play2 + Slick / ScalikeJDBCハンズオン](https://github.com/bizreach/play2-hands-on)
[Guide to Play2 Scala](https://www.amazon.co.jp/Guide-Play2-Scala-%E4%B8%AD%E6%9D%91%E4%BF%AE%E5%A4%AA-ebook/dp/B00L6TIW1S/ref=sr_1_4?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&keywords=play+scala&qid=1556438250&s=gateway&sr=8-4)
国内に置けるScala利用をゆうめいした会社の有名なチュートリアル。鉄板ですね。

### 書籍
[はじめての「Play Framework」](https://www.amazon.co.jp/%E3%81%AF%E3%81%98%E3%82%81%E3%81%A6%E3%81%AE%E3%80%8CPlay-Framework%E3%80%8D-I%E3%83%BB-BOOKS-%E6%B8%85%E6%B0%B4/dp/4777520633/ref=sr_1_3?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&keywords=play+scala&qid=1556438250&s=gateway&sr=8-3)
DBを使わず完結する事もあってシンプルな内容になってますが、一度に学習するちょうど良いボリュームなのでRuby On Rails等の経験者だとこの本が最初でもOKだと思います

[Java/Scalaフレームワーク PlayFramework入門]( https://www.amazon.co.jp/Java-Scala%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%83%AF%E3%83%BC%E3%82%AF-PlayFramework%E5%85%A5%E9%96%80-%E6%8E%8C%E7%94%B0-%E6%B4%A5%E8%80%B6%E4%B9%83/dp/479805707X/ref=la_B004L5AED8_1_22?s=books&ie=UTF8&qid=1556438345&sr=1-22)
前書はJavaよりでしたが大分構成が代わりScalaの情報も充実してます。

[Scala逆引きレシピ](https://www.amazon.co.jp/Scala%E9%80%86%E5%BC%95%E3%81%8D%E3%83%AC%E3%82%B7%E3%83%94-%E7%AB%B9%E6%B7%BB-%E7%9B%B4%E6%A8%B9/dp/4798125415/ref=sr_1_fkmrnull_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&keywords=%E9%80%86%E5%BC%95%E3%81%8D+scala&qid=1556438385&s=gateway&sr=8-1-fkmrnull)
復習とAkka等の学習に使いました

### N予備校について
良質なのですが、関数型の特性を活かす為に数学の問題と絡んで進むので只でさえ難解な言語をとっつきにくく感じてしまうことがあるので、最初には選ばない方が良いと考えています。

そこそこわかるようになってから関数型視点でScala Playを学ぶ時に使いましょう。
【20190607update】Watson Discovery リリースノート 超訳

# はじめに
[Watson Discoveryのリリースノート](https://cloud.ibm.com/docs/services/discovery?topic=discovery-release-notes)で、まだ日本語されていない部分をGoogle翻訳様などに頼って日本語化してちょっぴり感想を付け加えてみようという試みです。何度も何度も同じリリースノートを翻訳するのが不毛に思えてきたのです。あからさまに間違っているところがあれば、こっそり教えてくださいな。

# さっそく翻訳
2019年6月7日時点で、英語のリリースノートは6月4日更新、日本語化されているリリースノートは2月10日分まで。

## サービスAPIのバージョン管理
API 要求には、version=YYYY-MM-DD という形式で日付を設定する version パラメーターが必要です。 後方互換性のない方法で API が変更されると、API の新規マイナー・バージョンがリリースされます。

API 要求のたびに version パラメーターを送信してください。 本サービスでは、指定された日付の API バージョン、またはその日付より前の最新のバージョンが使用されます。 現在日付をデフォルトに設定しないでください。 代わりに、ご使用のアプリと互換性のあるバージョンに一致する日付を指定し、より新しいバージョン用にアプリの準備ができるまでその日付を変更しないでください。

現行バージョンは 2019-04-30 です。

**※日本語のリリースノートではAPIバージョンがまだ 2019-01-01 になっています**

## 4 June 2019
Preview APIは推奨されなくなり、2019年9月30日から使用できなくなります。
**Preview APIって、何があったっけ～。要確認。**


## 30 April 2019
ディスカバリーツールの検索設定画面を使用して、クエリー拡張リスト(シノニム)とストップワードリストをアップロードまたは削除できるようになりました。 以前は、これらのリストはAPIを使用してしか管理できませんでした。
**※シノニム、ストップワード設定ファイルのアップロードがツールからできるようになっている！便利～**

## 26 April 2019
2019年4月2日に発表されたIBM Watson Discoveryのアップデートが完了した。このアップグレードには、Discoveryで使用されているドキュメントとパッセージのランク付けアルゴリズムの精度を向上させるための変更が含まれていました。スコアと信頼度の変化は小さくなければならないし、順位も多少変わるかもしれない。アプリケーションでスコアまたは信頼度フィールドを直接使用する場合は、必要に応じてアプリケーションを更新する必要があります。

マルチトークン・クエリーの拡張がサポートされるようになりました。詳細は、[Query expansion](https://cloud.ibm.com/docs/services/discovery?topic=discovery-query-concepts#query-expansion)を参照してください。


## 17 April 2019
Data Crawlerはダウンロードできなくなり、サポートされなくなりました。その他の接続オプションについては、データ・ソースへの接続を参照してください。

## 2 April 2019
2019年4月9日より、IBM Watson Discoveryのアップグレードが提供されます。このアップグレードでは、Discoveryで使用されている、ドキュメントとパッセージのランク付けアルゴリズムが変更されます。つまり、アップグレード後にスコアと信頼性の結果が変わる可能性があります。アプリケーションでスコアまたは信頼度フィールドを直接使用する場合は、必要に応じてアプリケーションを更新する準備をしてください。詳細は、 [「Upgrading the infrastructure of the IBM WatsonTM Discovery External link icon」](https://www.ibm.com/blogs/bluemix/2019/03/announcement-for-the-ibm-watson-discovery-community/) を参照してください。

**※confidenceとscoreの値が変わるかもよ、順位もな！ということですね。**

## 25 March 2019
・すべてのAPIコールのバージョン文字列が、2019-01-01から2019-03-25に変更されました。

・変換時にタイトルフィールドがHTMLドキュメントからトップレベルフィールドとして抽出されるようになりました。HTML変換を参照してください。このタイトル・フィールドは、文書セグメンテーションを使用して分割された文書の各セグメントにも含まれます。例については、「文書セグメンテーションを使用した文書の分割」を参照してください。これにより、クエリー結果の信頼スコアが改善され、タイトルが一節の一部として戻される可能性があるため、戻される一節が変更される可能性があります。タイトルフィールドを抽出するには、既存のコレクションのインデックスを再作成する必要があります。

- Note:
・ディスカバリー・ツールは、現在のAPIバージョン2019-03-25(現在2018-08-01を使用しています。)をまだ使用していないため、ディスカバリー・ツールでWebクロール・コネクターをアップロードまたは使用してHTML文書を取り込むときに、タイトルが抽出されません。

**※2018-08-01利用ってことは、まだしばらくはタイトル抽出あきらめたほうが良さそう**

・配列をエンリッチできるようになりました(以前は、配列をエンリッチできなかった)。Smart Document Understandingを使用すると、デフォルト(例:answer、author、footer、header、question、subtitle、table_of_contents、text、およびtitle)フィールドとカスタムフィールドの両方をエンリッチすることができます。以前は、テキストフィールドのみをエンリッチするように限定されていました。

## 21 March 2019
2019年3月21日以降は、IBM Cloudアカウントに割り当てられた役割に関連付けられたサービス資格情報のみが表示されます。たとえば、リーダーの役割を割り当てた場合、ライター以上のレベルのサービス資格証明は表示されません。

この変更は、既存のサービスキー認証情報を持つユーザーまたはアプリケーションのAPIアクセスには影響しません。影響を受けるのは、IBM Cloudでのクレデンシャルの表示だけです。

サービスキーとユーザーロールの詳細については、「IAMサービスAPIキー」を参照してください。

# おわりに ＆ 更新履歴
ベストエフォートで随時更新していきます！
2019.05.02 … 30 April 2019の更新を追記
2019.06.07 … 4 June 2019の更新を追記
Azure に YAML をアップロードするだけで Growi を立てる

※本稿で紹介するのは運用に耐えうる構成ではなく、あくまで [Microsoft Azure Web App for Containers](https://azure.microsoft.com/ja-jp/services/app-service/containers/) の便利さを伝えるためのデモ用の内容です。また、Web App for Containers の Multi-Container 機能の2019年4月時点のプレビュー版の情報を元にしており、仕様変更の可能性があります。

## Azure Web App for Containers

Web App for Containers の Multi-Container 機能を使うと、複数コンテナからなるアプリケーションを簡単に Azure 上にデプロイできます。

ためしにオープンソースの wiki ツール [GROWI](https://growi.org/) を、3分で構築してみます。GROWI は Node.js アプリケーションと MongoDB のデーテベースの2つのコンテナがあれば最低限動作します。

## 構築手順
まず [Microsoft Azure ポータル](https://portal.azure.com/#home)に入り、「リソースの作成」→「Web」→「Azure Web App for Containers」と進みます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50391/f869db8b-1f19-c861-d2c8-3bb71fa406a6.png)

アプリ名がドメインになるので、好きな文字を入力します。
OS を Linux にして、「コンテナーの構成」をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50391/976ce390-19e6-d7a7-8369-c4beecac991a.png)

予め下記 `docker-compose.yml` ファイルをローカルに作成しておくか [筆者のgist](https://gist.github.com/s2terminal/9dc9a387c7d7fd552cc55138165ee66a) からダウンロードしておき、「Docker Compose (プレビュー)」をクリックし、「構成ファイル」からアップロードします。

```docker-compose.yml
version: '3'
services:
  growi:
    image: weseek/growi:3.4.4
    links:
      mongo: mongo
    depends_on:
      - mongo
    environment:
      MONGO_URI: mongodb://mongo:27017/growi
      PASSWORD_SEED: superstrongpassword012345678901234567890123456789012345678901234 # ※適当に
    volumes:
      growi_data: /data

  mongo:
    image: mongo:3.6
    ports:
      27017:27017
    volumes:
      mongo_configdb: /data/configdb
      mongo_db: /data/db
volumes:
  growi_data:
  mongo_configdb:
  mongo_db:
```

「作成」ボタンを押して3分ぐらい待って `https://(アプリ名).azurewebsites.net/` にアクセスすると、GROWIのトップページが映ると思います。

以上、YAML ファイルをアップロードするだけで GROWI を構築することができました。簡単ですね。

### 注意点
- 今回利用した `docker-compose.yml` は、一般的な記法と少々異なっています。
    - 例えば `environment:` が `PASSWORD_SEED=seed` というイコールで繋ぐのではなく `PASSWORD_SEED: seed` となっています。こうしないと Azure Web App ではうまく動かないようでした。
- elasticsearch をうまく動かす方法が不明だったため省略しています。この場合でも GROWI は起動するものの、検索が使えません。
- volumes の設定は効いていないようで、この構成だと**アプリを再起動するたびに全データが消失**します。
    - 実際に GROWI を運用する場合には [Azure Cosmos DB](https://azure.microsoft.com/ja-jp/services/cosmos-db/) 等を使って永続化する構成になるんじゃないかと思います。
- そもそも GROWI は Amazon Web Services の S3 に依存しているので、Azure に立てるのは...

まだ実用レベルでは厳しいですが、`docker-compose.yml` を(ほぼ)そのままアップロードするだけで3分待てば Web アプリケーションがクラウド上で動くというのは、かなり魅力的だと思います。

## 参考
- [Web App for Containers でマルチコンテナー アプリを作成する \- Azure App Service \| Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/app-service/containers/tutorial-multi-container-app)
- [Web App for ContainersのMulti\-Containerを試してみる \- Qiita](https://qiita.com/shingo_kawahara/items/7da5ff6f61a833e32076)
- [weseek/growi\-docker\-compose: growi\-docker\-compose \- The fastest way to boot All\-in\-One GROWI](https://github.com/weseek/growi-docker-compose)
Windows10でRails5.2.3を動かしてみる

# はじめに
Windows上でのRails開発は決して万人に勧められるものではありません。
Ruby開発においてWindowsがマイノリティであり
さらにRailsを実際に運用するとなると多くの場合Linuxを用いるので
WindowsでRailsを開発するための情報に需要がなくネットに情報を上げている人は限られ
自力でトラブルを解決する必要があり、それが出来ない初心者が手を出してはいけません。

Vagrantを用いてCentOS環境を作った方が数段楽です。
また、Win10ならば[WSLで動かす](https://qiita.com/stkdev/items/96f507f46276c4e782c0)方法もあるらしいです。

(正直ここでこの記事を終わりにしたい)

----


# 用意するもの
- Windows 10(x64版)  
  x32でもdlfcnを適切にインストールできればやれないことはない気はしますが  
  ここでは確かめていません。
- [Ruby 2.6.3](https://github.com/oneclick/rubyinstaller2/releases/download/RubyInstaller-2.6.3-1/rubyinstaller-devkit-2.6.3-1-x64.exe)  
  MSYS2を既にインストールしてあるのならばdevkit付き版でなくてもいいですが  
  MSYS2をインストールしたくないというのは無理です。  
  cloud9やpaiza cloudを用いてください

# インストール
#### Rubyをインストールします。
![rapture_20190427185644.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51874/b298c604-6730-221e-5ea8-130c0eca2311.png)
- [x] Add Ruby executable PATH (Ruby実行ファイルをPATHに登録する)
- [x] Associate .rb and .rbw files with this Ruby Installation (.rbおよび.rbwを関連付けする)

については、外したければ外してもいいです。
PATH登録しないと面倒だとは思いますが、関連付けについてはどうでもいいです。

![rapture_20190427185723.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51874/80a20b7d-eca6-1dfa-1f74-c15fabeaf9a1.png)
![rapture_20190427185926.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51874/bf879d40-40ba-ad17-85af-4637259def75.png)

この2箇所の☑については外しません。

![rapture_20190428130503.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51874/a528cea6-5e9f-9bc6-1990-f12eef75bdd9.png)
この画面がでるので、`1 2 3`と半角空白区切りで入力してください。

![rapture_20190428130523.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51874/578e5316-91f3-1211-b68d-01a3667b364c.png)
こうなるので最後の`successed`を確認したら<kbd><kbd>Enter</kbd></kbd>を押して閉じます。

#### Rubyを起動してみる
その後、任意の作業用ディレクトリを作成し開いたら
![rapture_20190428130639.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51874/dbf05329-87c1-41f5-c758-e6aa36068bd5.png)
アドレスバーに`cmd`と入力しコマンドプロンプトを起動します。

Railsを起動する際に`sqlite3`のビルドが厄介なので先にやっておきます。

```shell:コマンドプロンプトに入力
ridk exec pacman -S mingw-w64-x86_64-dlfcn --noconfirm
gem install sqlite3
```

なお、PATH登録をしていない場合はそれぞれフルパスを入力すること

#### Railsをインストールし起動

あとは、普通に

```shell:コマンドプロンプトに入力
gem install rails
rails new .
rails s
```

ができるはずです。


# Windowsでおきるトラブル
最後に、Ruby+Windowsで頻発するトラブルについて書いておきます。

- UTF-8とShift_JIS(cp932)絡みの文字化け
- コンソールに日本語が入力できない
- forkができない
- コンソールが止まる
- rbenvが使えなくてめんどくさい
- フォルダへのパスに日本語が混じっていると動かない(ことがある)
- Railsのcredentials.yml.encが編集できない

など、とてもめんどくさいので大人しくLinux環境を作りましょう。
Dockerチュートリアル

## Dockerとは
Dockerは、仮想マシンを構築するためのもの。
Dockerの特徴は以下の3点

- OS依存が少なく、導入が楽
- コンテナ型のため、移植性が高く本番環境への移行もスムーズに行える。
- ゲストOSがないため軽量になる(間違えっていたら教えてください)。

従来の仮想マシンの構築イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309490/49462e05-5395-715a-e24a-fc8e24ebbaa9.png)

Dockerの仮想マシン構築イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309490/ad160189-7623-b435-3aa1-4bdf5ef483e2.png)

## インストール
[こちら](https://www.docker.com/get-started)からインストールすることができる。
各自のOSにあったものをダウンロードしてください。
アカウントを作成する必要があります。
インストールがうまくいったかの確認
以下のようなものが出てくれば、うまくインストール出来ています

``` teriminal
$ docker --version

Docker version 18.09.2, build 6247962
```

## webサーバーを立てる&終了
初回起動はローカルにイメージがなく、公式からpullしているので起動に5秒ほどかかります。
2回目からはローカルに保存したイメージを使用する為、高速な起動が可能になります。

``` terminal 
$ docker run -d -p 8080:80 --name webserver nginx
```

コンテナがきちんとできているか確認する

```terminal
$ docker ps
#以下のような表示がされる
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS             
5b8b3dccc4cd        nginx               "nginx -g 'daemon of…"   About a minute ago   Up About a minute  
```

コンテナを終了したい場合は

```terminal
# CONTAINER IDでkill
$ docker kill 5b8b3dccc4cd 
or
# NAMESでkill
$ docker kill webserver
```

## コンテナの削除

```terminal
$ docker rm c5e7400c19c9
or
$ docker rm webserver
```
RustでJSONファイルを読み集計する


コード全体は、このような感じ。解説はコードの後に書いてます。

```rust
use std::fs::File;
use std::io::{BufReader, BufRead};
use std::collections::HashMap;

extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;

#[derive(Debug, Serialize, Deserialize)]
struct LogItem {
    method: String,
    path: String,
    code: isize,
    size: isize,
}

fn main() -> Result<(), Box<std::error::Error>> {

    let mut scores = HashMap::new();
    let f = "/path/to/file";
    for result in BufReader::new(File::open(&f)?).lines() {
        let l = result?;
        let log: LogItem = serde_json::from_str(&l).unwrap();
        //println!("{:?}",log);
        let count = scores.entry(log.path).or_insert(0);
        *count += 1;
    }

    for(k, v) in &scores {
        println!("{} {}", k, v);
    }

    Ok(())
}
```

ここから動作環境とコード解説。

まず、[apache-loggen](https://github.com/tamtam180/apache_log_gen)でJSON形式で出力したファイルを用意する。

```sh
gem install apache-loggen
apache-loggen --limit=1000 --json > test.json
```

こんな感じのログが出力される。

```
{"host":"224.117.48.63","user":"-","method":"GET","path":"/category/software","code":200,"referer":"/item/electronics/2875","size":41,"agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11"}
```

Rustでは、こんな感じの構造体を用意する。集計したいものだけ用意すればいい。

```rust
struct LogItem {
    method: String,
    path: String,
    code: isize,
    size: isize,
}
```

ファイルから１行読むたびにJSONとしてパースする。改行が入り複数の行にまたがるJSONは、ちょっと苦労しそうだ。（どれぐらいあるのかな？）

```rust
let mut scores = HashMap::new();
let f = "/path/to/file";
for result in BufReader::new(File::open(&f)?).lines() {
    let l = result?;
    let log: LogItem = serde_json::from_str(&l).unwrap();
    //println!("{:?}",log);
    let count = scores.entry(log.path).or_insert(0);
    *count += 1;
}
```

最後に、Hashmapの中身をforループでハッシュマップのキーと値のペアを走査する。

```rust
for(k, v) in &scores {
    println!("{} {}", k, v);
}
```

追記ですが、reqwestでも簡単に書けますね。

```rust
extern crate reqwest;

use std::collections::HashMap;

fn main() -> Result<(), Box<std::error::Error>> {
    let resp: HashMap<String, String> = reqwest::get("https://httpbin.org/ip")?
        .json()?;
    //println!("{:#?}", resp);
    println!("{}", resp["origin"]);
    Ok(())
}
```
インフラの勉強前の最低限の基礎知識②〜アプリケーション層のプロトコルについて〜

## 概要
前回の記事の続き
アプリケーション層について簡単にまとめて行きます

## 対象
インフラ勉強始めたいけど何からやったらいいのかよくわからない人向け

## 目次
- アプリケーション層のプロトコル
- HTTPについて
- mailについて
- FTPについて
- sshについて
- ピアトゥーピアについて


## アプリケーション層のプロトコルについて

アプリケーション層のプロトコルは、そのアプリケーションの特性に別れたプロトコルが採用されています。

なぜならアプリケーションごとに重視するものが異なるからです。

ウェブアプリであれば正確性、電話などにおいては正確性より速度と安定性がより重視されたプロトコルが採用されています。

以下ではそれぞれのプロトコルを見ていきます。

## HTTPについて
ウェブアプリケーションではHTTPプロトコルが採用されています。

#### HTTPメッセージ
ホストとクライアント間でやりとりされHTTPプロトコルに基づいたメッセージ。

リクエストとレスポンスの２種類が存在する。

#### URLとHTTPリクエスト
URLからHTTPリクエストが作成される。

```
http://ja.wikipedia.org/wiki/Wikipedia
```

上記の例で言えば、
http→スキーマ
ja.wikipedia.org→ホスト名
/wiki/Wikipedia→ディレクトリ名

となる。

これらを使用して、HTTPリクエストは生成される。

## mailについて

#### mailに使用されるプロトコル
SMTPとPOPの２種類が存在する。

SMTP→メールをクライアントから、メールサーバーに送る時に使用するプロトコル。
POP→メールをメールサーバーから送り先に送る際に使用するプロトコル。

SMTPには認証機能がないが、POPの認証機能を利用したりSMTP authなどの技術を使用して他のクライアントからの悪用を防いでいる。

#### IMAP
POPでは受信時にサーバー側のメールを削除してしまう。→端末側で保存する必要がある。

IMAPでは、サーバー側にメールを保存しておいてメールを毎回サーバー経由で読み込ませる。

## FTP
ファイル転送用プロトコル

#### コネクションの種類
FTPでは２種類の接続を行います。

- コントロールコネクション・・・FTPのコマンドをやりとりする接続
- エータコネクション・・・実際のファイルを送る接続

二つの独立した接続があることで、ファイルを送りながらコマンドを送ることができます。

## ssh
遠隔地のシェルの操作のための接続プロトコル。

## ピアトゥーピア
同一のネットワークに属すパソコン間で、お互いをサーバーとホスト両方として扱う通信。

有名なものだとAir dropとか？？

OSごとで異なる通信方式を採用している。

##終わりに
次回以降はさらにそれぞれを詳しくやっていきます。
Leetcode #104: Maximum depth of binary tree

BFS solution:

```swift
func maxDepth(_ root: TreeNode?) -> Int {
    if root == nil {
        return 0
    }
    var answer = 0
    var stack = [root!]
    while !stack.isEmpty {
        answer += 1
        for _ in 0..<stack.count {
            let node = stack.removeFirst()
            if let leftNode = node.left {
                stack.append(leftNode)
            }
            if let rightNode = node.right {
                stack.append(rightNode)
            }
        }
    }
    return answer
}
```

DFS solution:

```swift
func maxDepth(_ root: TreeNode?) -> Int {
    if root == nil {
        return 0
    }
    return max(maxDepth(root!.left), maxDepth(root!.right)) + 1
}
```
多言語Universal Sentence Encoderを使う

# はじめに
この記事では、Tensorflow Hubに公開されている [多言語Universal Sentence Encoder](https://tfhub.dev/google/universal-sentence-encoder-xling-many/1) を試してみます。

# Universal Sentence Encoderとは
Transformerを自然言語処理の様々なデータセットを使ってマルチタスク学習させて得られた文表現ベクトルのエンコーダーです。今回使うのは多言語バージョンで、英語、フランス語、ドイツ語、スペイン語、イタリア語、中国語、韓国語、日本語のタスクで学習されたものです。 

# 文の類似度の可視化
いくつかの文章を入力して文表現ベクトルを作成し、互いに内積を取ることで各入力文がどれくらい近いかを測ります。結果はヒートマップで可視化します。

## スクリプト
Googleが公開しているColabを参考にしたコードです。実行した時にmatplotlibとseabornの文字化けが発生する場合があります。そのときは例えば[この記事](https://qiita.com/yutapon988/items/855748de65ac780c98d5)に解決法が書いてあります。

```python
import tensorflow as tf
import tensorflow_hub as hub
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import tf_sentencepiece

module_url = "https://tfhub.dev/google/universal-sentence-encoder-xling-many/1"
embed = hub.Module(module_url)


def plot_similarity(labels, features, rotation):
  corr = np.inner(features, features)
  sns.set(font_scale=1.2)
  g = sns.heatmap(
      corr,
      xticklabels=labels,
      yticklabels=labels,
      vmin=0,
      vmax=1,
      cmap="YlOrRd")
  g.set_xticklabels(labels, rotation=rotation)
  g.set_title("Semantic Textual Similarity")
  plt.show()


def run_and_plot(session_, input_tensor_, messages_, encoding_tensor):
  message_embeddings_ = session_.run(
      encoding_tensor, feed_dict={input_tensor_: messages_})
  plot_similarity(messages_, message_embeddings_, 90)


messages = [
    # Smartphones
    "I like my smart phone.",
    "スマホが好きです。",
    "私のスマートフォンは品質が高いです",
    "キミのスマホかっこいいね！",

    # Weather
    "It will rain tomorrow.",
    "明日は雨かな?",
    "台風の季節ですね。",
    "地球温暖化の影響が現れ始めているのかな",

    # Food and health
    "りんごを一日一個食べると医者いらずですよ",
    "イチゴが食べたい",
    "ダイエットに効く食品を教えて?",

    # Asking about age
    "How old are you?",
    "何歳ですか",
    "いくつですか？",
]

similarity_input_placeholder = tf.placeholder(tf.string, shape=(None))
similarity_message_encodings = embed(similarity_input_placeholder)
with tf.Session() as session:
  session.run(tf.global_variables_initializer())
  session.run(tf.tables_initializer())
  run_and_plot(session, similarity_input_placeholder, messages,
               similarity_message_encodings)
```

## 実行結果
言語によらず似た意味の文は似た表現になっていることがわかります。

![Figure_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101644/3996d3d7-cb08-e255-b4eb-eaf338f51dd2.png)


# 感想
このエンコーダーを特徴量作成に使えば、英語の大規模なデータセットを使って学習し、日本語や他の言語で推論することもできそうです。

# 参考
- [M. Chidambaram, Y. Yang, D. Cer, S. Yuan, Y.-H. Sung, B. Strope, and R. Kurzweil. Learning Cross-Lingual Sentence Representations via a Multi-task Dual-Encoder Model. ArXiv e-prints, October 2018.](https://arxiv.org/abs/1803.11175)
- [コードを参考にしたColabノートブック](https://colab.research.google.com/github/tensorflow/hub/blob/master/examples/colab/semantic_similarity_with_tf_hub_universal_encoder.ipynb)
Leetcode #103: Binary Tree Zigzag Level Order Traversal

```swift
func zigzagLevelOrder(_ root: TreeNode?) -> [[Int]] {
    if root == nil {
        return []
    }
    var answer = [[Int]]()
    var stack = [root!]
    var leftToRight = true
    while !stack.isEmpty {
        var tmp = [TreeNode]()
        for node in stack {
            if let leftNode = node.left {
                stack.append(leftNode)
            }
            if let rightNode = node.right {
                stack.append(rightNode)
            }
        }
        if leftToRight {
            answer += [stack.map{ $0.val }]
        } else {
            answer += [stack.map{ $0.val }.reversed()]
        }
        stack = tmp
        leftToRight = !leftToRight
    }
    return answer
}
```
pythonのpackageのバージョンが違っていた時の対処法[pyenv][pip]

## 概要
pyenvでpythonのversion管理をしていますが、globalで使っていた本体のパッケージがconflictを起こしたので、それに対する対処法を書いて起きます。プロジェクトごとに仮想環境作れば問題ない話ですが。。

## 動作環境
Mac OS Mojave 10.14.4
python 3.6.5
pyenv 1.2.5
pip3 19.1

## エラー
```
Traceback (most recent call last):
  File "/Users/***/.pyenv/versions/3.6.5/lib/python3.6/site-packages/pkg_resources/__init__.py", line 574, in _build_master
    ws.require(__requires__)
  File "/Users/***/.pyenv/versions/3.6.5/lib/python3.6/site-packages/pkg_resources/__init__.py", line 892, in require
    needed = self.resolve(parse_requirements(requirements))
  File "/Users/***/.pyenv/versions/3.6.5/lib/python3.6/site-packages/pkg_resources/__init__.py", line 783, in resolve
    raise VersionConflict(dist, req).with_context(dependent_req)
pkg_resources.ContextualVersionConflict: (pycodestyle 2.4.0 (/Users/***/.pyenv/versions/3.6.5/lib/python3.6/site-packages), Requirement.parse('pycodestyle<2.4.0,>=2.0.0'), {'flake8'})
```
最後の一文を見ればわかりますが、どうもあるパッケージがconflictを起こしているみたいです。

## 解決策
現在のパッケージをuninstallして、新しく指定されているバージョンの範囲内のパッケージをinstallします。

```
$ pip3 uninstall pycodestyle
Uninstalling pycodestyle-2.4.0:
  Would remove:
    /Users/***/.pyenv/versions/3.6.5/bin/pycodestyle
    /Users/***/.pyenv/versions/3.6.5/lib/python3.6/site-packages/pep8.py
    /Users/***/.pyenv/versions/3.6.5/lib/python3.6/site-packages/pycodestyle-2.4.0.dist-info/*
    /Users/***/.pyenv/versions/3.6.5/lib/python3.6/site-packages/pycodestyle.py
Proceed (y/n)? y
  Successfully uninstalled pycodestyle-2.4.0
```

要求されているバージョンを再インストールします。

```
$ pip3 install pycodestyle==2.3.0                                                                                                                                    
Installing collected packages: pycodestyle
Successfully installed pycodestyle-2.3.0
```

globalで色々なプロジェクトのパッケージをごちゃごちゃにしていたら、このようなことが起こりかねないので、プロジェクトごとにパッケージを分けて管理するようにしたら良いと思います。
初めてのCSS〜ボックスモデルでの設計方法〜

## はじめに
私たちが初めてのWebページ開発を行うにあたり、
前提として、CSSについてどのように考え、開発を行ったのノウハウを共有します

## CSS
> CSS（Cascading Style Sheets）とは、ウェブページのスタイルを指定するための言語
ワープロソフトなどで作成される文書も含めて、文書のスタイルを指定する技術全般をスタイルシートという

CSSはHTMLファイル内やCSSファイル内になど、開発者が記載したい任意の箇所に記載することができる
※記載方法はそれぞれによって異なる
ケースによって使い分けは必要だが、
基本方針は以下のメリットから、別ファイル(CSSファイル)に記載で行くべき

メリット
- ページ間のデザインの統一
- ファイル単位の作業分担
- 変更時の変更箇所の局所化

### CSSの構成
以下の要素で構成されている

セレクタ:どのHTMLタグに対して適応するか
プロパティ:どういった内容のデザインを施すか
値:プロパティの値

### CSSのサイズ指定について
現在、PC・タブレット・スマホなどさまざまな画面サイズを持つデバイスが存在する
Web開発の際、各デバイス画面の特徴を元に切り替え基準(ブレイクポイント)を設定し、
メディアクエリーを用いた、CSSの切り替えを行う。

各デバイスの特徴を踏まえ、CSSは以下の3種類を用意すると無難
・スマートフォン用CSS:横幅480px以下に対して、縦長の画面を想定したCSS
・タブレット：横幅481px以上1023px以下に対して、正方形の画面を想定したCSS
・PC：横幅1024px以下に対して、横長の画面を想定したCSS
※横長・縦長画面の考慮は、基本画像に対してのみ行えば良い

## ボックスモデルについて
CSSはWebページのデザインを担当するため、目的のデザインを実現するために様々な考え方が存在する

その一例がボックスモデル
http://zero.css-happylife.com/img/basic/box_model.gif
文書の要素を一つのボックスと捉えて、全体にどのように配置していくかという考え方


### 設計手順
成果物は基本以下のようになる
・どの画面でも共通的に使用するCSS
・各デバイス種類ごとのCSS(計3つ)
・HTMLファイル
・画像(各デバイスごとにリサイズして用意する)

**【手順】**
1.全体のコンテンツ内容をデザインする(紙でも良い)
 ※好みにもよるが、確認のしやすいPC画面のレイアウトで考えるのがオススメ！

2.1の手順で考えたレイアウトに対して、スマホ・タブレットではどのように配置したいかデザインする
 ※ここで出た差分が切り替える必要のあるCSSの内容になる

3.メインCSSの内容を記載して行く
 ※基本、文字の大きさや、要素の幅は可変のプロパティを使用する(%,em,remなど)
 ※文字の大きさはデバイスの横幅に対していくつ、という指定をする
 ※%指定は親要素の幅を元に計算される点に注意

## まとめ
基本的なCSSのプロパティについては**display×position**の組み合わせを脳内でイメージできるようにすれば、十分です。
あとは行いたいデザインを随時ネットで調べることで、スムーズな開発が行えると思います。

また、幅の指定方法など、偉大な先人たちの知恵がネットにいっぱい転がっているので、
「イケテナイと思ったらすぐ調べる」、を徹底して行って下さい。(戒めも込めて)

※ここに記載された内容はあくまで開発手法の一例です
　使用するフレームワーク、プロジェクトの方針をまず1として下さい
【Mac】ローカルで開発しているRailsアプリをスマホ(実機)で見る

# はじめに

Google chromeの検証ツールでもレスポンシブデザインを見ながら開発はできますが、スマホのOSやブラウザ環境でビューの表示が異なる場合があります。

実際に本番環境にアップしてから自分のスマホで見ると「あれ？」となる時があります。

そんな時に便利です。ちなみにめちゃ簡単です。

## IPアドレスを調べる

まずはMacとスマホを同じWi-Fiにつなげます

次にMacの`システム環境設定`から`ネットワーク`を開きます

すると以下のような画面になるので、赤枠の部分の`IPアドレス`をコピーします

<img width="652" alt="スクリーンショット 2019-04-28 15.16.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335670/b5438e20-04f7-143a-fde2-7afc7085352f.png">

## ターミナルでコマンドを打つ

アプリケーションのディレクトリに移動してから`コピーしたIPアドレス`を元に以下のコマンドをターミナルで打ち込みます

```:ターミナル
bundle exec rails s -b コピーしたIPアドレス
```



```:IPアドレスが198.11.22.33の場合の例
bundle exec rails s -b 198.11.22.33
```

次にスマホブラウザのURLに以下を打ち込みます

```:スマホブラウザのURL入力画面
http://コピーしたIPアドレス:3000
```

以上で終了です:v:

PCのエディタで編集して、スマホを更新すると編集箇所が反映されます。

本番環境にデプロイしたアプリケーションのモバイル用のビュー修正に重宝してます。
Python3 初心者　集合

#集合
大まかに言うとキーだけを残した辞書と思いましょう。そして辞書と同様ミュータブルである。また返ってくる値もランダムである。集合といえば高校一年生で習ったものを思い出しますが、その要素もよく集合では使われます。
##集合の作り方
### set()での作成
リストから集合

```py
feeling=set(['Wow', 'Oops', 'Oh', 'Yeah'])
feeling
{'Wow', 'Oh', 'Oops', 'Yeah'}
```
set()に辞書を入れるとどうなるのか

```py
feeling=set({'my': 'Wow', 'Your': 'Oops', 'His': 'Oh', 'Her': 'Yeah'})
feeling
{'my', 'Your', 'His', 'Her'}
```

辞書でいうキーが集合の要素に当たる。

### {}による作成

```py
feeling={'Wow', 'Oops', 'Oh', 'Yeah'}
feeling
{'Oops', 'Yeah', 'Wow', 'Oh'}
```

##　inを使った要素の確認

これからピザを作ろうと思う。材料は何が必要なのか。そーゆう時に材料をまとめたりして集合化すれば良い。

```py
pizza = {'Margherita':{'Cheese', 'Tomato', 'Oil', 'organic'},
         'marinele':{'Suger', 'Cheese', 'Tomato'},
         'pesukatoro-ne':{'fish', 'Tomato', 'Orgnic'}
         }
```

これは大きな辞書である。'Margherita'などに当たるのがキーであり{'Cheese', 'Tomato', 'Oil', 'organic'}に当たるのがバリューであり、集合である。では本題のinを使った要素の確認をしていこう。

```py
for name, material in pizza.items():
    if 'Cheese' in material:
        print(name)

Margherita
marinele
```

細かく解説していこう。まず、一行目はこれから話していくfor文である。ここでのfor文は辞書のitems関数を使って全てを取り出しそれぞれに名前をつけている。nameはここでいう全てのキーの代入値である。もしprint(name)と出力すれば

```py
for name, material in pizza.items():
    print(name)

Margherita
marinele
pesukatoro-ne
```

と出力される。これはそのあとにあるmaterialでも同じことが言えこの場合バリュー全ての値が返ってくる。次にチーズとトマトどっちも材料を使っているピザが欲しいことを考えます。

```py
for name, material in pizza.items():
    if 'Cheese' in material and 'Tomato' in material:
         print(name)

Margherita
marinele
```

今両方欲しい時にandをしようした。だがこの場所をmaterial　& {'Cheese', 'Tomato'}のように打っても同じような結果が出力される。またmaterial　& {'Cheese', 'Tomato'}の前にnotをつければ「それ以外でお願いします」というようなオーダーが可能になります。
他にも「どちらか含んでいれば大丈夫だよ！」って時は&の代わりに「|」を使えばできます。
もう少し掘り下げると差集合（第一集合には含まれているけど第二集合には含まれていないもの「-」）や排他的集合（どちらかにはあるけど両方には含まれていないよ「^」）、真部分集合（第二集合のなかに入っているもの全てが第二集合に含まれているのかの確認「<=」）、上位集合（真部分集合の逆ver「>=」）などがあります。