OmniAICreator/Qiita-1.07M huggingface dataset:
普段の業務でよく使うGitコマンドと使い所

# はじめに
普段の業務でよく使っているコマンドとその使い所の紹介です。
Gitの使い方をなんとなく知っていることを前提にしています。
使い所をコマンド実行時の心境とともにお伝えします。

### 「どのファイル触ったっけ？」「どこで競合起きてんの？」 `git status`
リポジトリの状態を確認するコマンド、とりあえず何かあるたびにこれ。

### 「作業ブランチで作業するでー。」 `git checkout -b <branch name>`
ブランチを作成し、作成したブランチへ切り替えるコマンド。 
下記でも同様の結果を得られますが、コマンド一発で切替までやってくれるのでこちらのほうが早いです。
```
git branch <branch name>
git checkout <branch name>
```

### 「この変更全消しで。」「やっぱ、今のなし。」 `git checkout .`
ソースの変更をcommitしたところまでに戻したいときに使うコマンド。
ソースファイルが前回commitしたところ(HEAD)に戻ります。
`git checkout <file path>`
としてやると部分的に戻すこともできます。

### 「あ、今のcommitメッセージちょっと待った。」 `git commit --amend`
commitメッセージを書いたものの、なんとなくイマイチなときに使えます。
上記コマンドで直前のcommitメッセージを編集できます。

### 「あ、今のcommitちょっと待った。」 `git reset HEAD^`
commitしたものの、commit内容にいらないファイルや足りないファイルがあったときにcommit前からやり直せます。(push前)
ただし、commitしたものをpush済であれば、revertするか追加変更をcommitするかのほうがよいです。

### 「このバグいつからあんの？」「なんでこんなソースなん？」 `git log -p -- <file path>`
特定のファイルの変更履歴を表示させるコマンドです。謎のソースコードやバグの混入原因を調べるのに使っています。
次のコマンドも合わせて使うことも多いです。

### 「このcommitで何があったんや・・。」 `git show <commit id>`
commit単位でどんな変更があったのをか調べるコマンドです。上のコマンドと合わせてバグが混入したcommitの内容を確認し、ほかに怪しいところがないかが見られます。

### 「ソースコード記述完了、内容確認するで。」 `git diff HEAD`
HEADからの変更分を表示させるコマンドです。commit前のチェックで変なところがないか、余計な箇所を編集していないかを確認するのに使っています。

### 「えーい、変更ファイル全部がcommit対象じゃー。」 `git add -u`
git管理下にあるファイルで変更があるものすべてをstaged状態にするコマンドです。
`git diff HEAD`で変更を確認した後に使用することをおすすめします。変更差分が多い場合は次のコマンドを使用しています。


### 「作業分をセーブしていくで。」 `git add -p`
インデックスに追加するソースをファイルの行単位で選択できるコマンドです。このコマンドを利用することで大きなcommitを意味のある単位に分割することも可能です。コマンドラインのyだとかnだとか聞かれるところで無回答のまま回答するとそれぞれの回答の意味を教えてくれる(はず)です。

### 「commit前の最終チェック！」 `git diff --cached`
HEADからの変更分を表示させるコマンドですが、`git diff HEAD`と違ってインデックスに追加しているものだけを対象とします。
これからgit commitを叩くという直前で使用し、commit内容の最終チェックしています。
作業完了時は以下のコマンドを繰り返すことでソースコードをcommitしています。
`git status` → `git diff HEAD` → `git add -p` → `git diff --cached` → `git commit`

# おわりに
普段の業務で使っているコマンドを挙げてみました。ローカルでのgit操作は上記コマンドたちがあればだいたい事足りる気がします。
説明が変だとか間違っている箇所などあればご指摘下さい。
また、他にもこんな便利コマンドがあるよというのがあれば教えて下さい。
dnf のレポジトリ操作

- リポジトリの一覧

```
$ dnf repolist
```

- リポジトリの無効化

```
$ sudo dnf config-manager --set-disabled リポジトリ名
```

- リポジトリの有効化

```
$ sudo dnf config-manager --set-enabled リポジトリ名
```

- リポジトリの追加

```
$ sudo dnf config-manager --add-repo リポジトリ URL
```

# 元ネタ
https://docs-old.fedoraproject.org/en-US/Fedora/23/html/System_Administrators_Guide/sec-Managing_DNF_Repositories.html
http://dnf.readthedocs.io/en/latest/command_ref.html
新しく追加されたClassKitについて

# はじめに
2018年3月27日にAppleは、iOSの新しいフレームワークとして「[ClassKit](https://developer.apple.com/news/?id=03272018a)」を発表しました。

ClassKitは、同時に発表されたiPadアプリや、リリース済みのサービスと併用することが必須となっています。

そこで、それぞれのツールの用途と関係性を紐解きたいと思います。

# 登場人物
 * [Apple School Manager](https://help.apple.com/schoolmanager/?lang=ja#/tes7909096bf)：IT管理者向けのWebベースのポータル
 * [Classroom](https://help.apple.com/classroom/ipad/2.1/?lang=ja#/cad6d39b9338)：iPad App
 * [Schoolwork](https://www.apple.com/jp/education/teaching-tools/)：iPad App
 * [ClassKit](https://developer.apple.com/classkit/)：[Framework](https://developer.apple.com/documentation/classkit/)

## Apple School Managerとは
> Apple School Managerは、iPad、Mac、Apple TVのすべての導入を一つの場所で行うことのできる、IT管理者向けのシンプルなWebベースのポータルです。デバイス設定の構成、すべての生徒と職員のアカウントの作成、Appとブックの購入と配信ができます。また、Apple School ManagerはStudent Information System (SIS) やSFTPと統合されているため、学校の名簿とクラスを使用してアカウントをすばやく作成できます。

source: https://help.apple.com/schoolmanager/?lang=ja#/tes7909096bf

 * 用途
   * デバイス管理
   * 生徒と職員のアカウントの管理
 * ざっくり言うと
   * **情報の先生が、デバイスとアカウントを一括管理するのに使います**

## Classroomとは
> 「クラスルーム」は、教師が学習を指導したり、作業を共有したり、生徒のデバイスを管理したりできる iPad App です。教師は、教室の任意の iPad で特定の App、Web サイト、教科書のページを開くことができます。生徒との間で書類を送受信したり、Apple TV を使って生徒の作業をテレビ、モニタ、プロジェクタで共有したりすることもできます。また、教師は生徒がどの App で作業しているかを確認したり、生徒のデバイスをミュートしたり、生徒のパスワードをリセットしたりすることができます。

source: https://help.apple.com/classroom/ipad/2.1/?lang=ja#/cad6d39b9338

アプリ紹介動画も公開されています。こっちの方が分かり易い。
https://www.apple.com/105/media/us/education/2018/58294786_e60e_42db_be00_20b3c18747da/films/classroom-app/education-classroom-app-cc-us-20180124_1280x720h.mp4

 * 用途
   * 担任の教師は、クラスを作成し生徒を招待する
   * 生徒のデバイスコントロール。AppやWebページを開くなど
   * AirDropでファイル送受信
   * 外部スクリーンへの出力

## Schoolworkとは
 * 用途
   * 教師が生徒へ課題を配布する
   * 生徒の学習進捗状況を確認する
 * 近日公開予定となっています

## ClassKit frameworkとは
> ClassKitフレームワークはXcode 9.4で提供され、教員や学生が課題や進捗状況を把握するのに役立つ、Schoolworkという強力な新しいiPadアプリと連携しています。ClassKitを使用すると、教師がアプリ内の特定の学習活動を簡単に発見し、1回のタップで適切なアクティビティに直接参加できます。また、進捗状況を安全かつ個人的に共有して教師の指導に役立てることができます。

source: https://developer.apple.com/news/?id=03272018a

 * 用途
   * 学習・教材アプリが、「ClassKit framework」に対応することで「Schoolwork」と連携可能になる
   * 教師が生徒へ課題を配布すると、「Schoolwork」からアプリの該当ページへ飛べるようになる
   * 教師は「Schoolwork」で、生徒の学習進捗状況を確認出来る
 * Xcode 9.4から提供

# まとめると
 * 上述の4サービスを組み合わせることで、学習体験が成り立つ
   * 「Apple School Manager」で、デバイス・生徒と職員のアカウントを管理し、
   * 「Classroom」で担任の教師は、クラスを作成し生徒を招待。
   * 「Schoolwork」で課題を配布する。
   * ただしアプリは「ClassKit framework」に対応している必要がある。

# さいごに
AppleはiPad（第1世代）から、オフィススイート（Pages、Keynote、Numbers）を提供するなど、ビジネス用途としてのPCの置き換えを図ってまいりましたが、（成否は別として）
今度のターゲットは、教育機関です。

27日に発表された内容は、初めはたったこれだけ？と感じてしまいましたが、
上手く組み合わさることで、素晴らしい学習体験（ラーニングエクスペリエンス）を生むのかも知れません。
Fedora のアップグレード

まれにしかしないので、コマンドを忘れるので、、、、

元ネタ
https://fedoramagazine.org/upgrading-fedora-25-fedora-26/

```
$ sudo dnf upgrade --refresh
$ sudo dnf install dnf-plugin-system-upgrade
$ sudo dnf system-upgrade download --releasever=26 -> ver を目的のバージョンに
$ sudo dnf system-upgrade reboot
```
初心者向け windowsからMacにしたときの快適な環境設定はこれを抑えとく

<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-116132394-1"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'UA-116132394-1');
</script>

# 背景(ただの昔話)
[本題はこちらから](#環境設定)

もう5年前のはなし、ユーザー系Sierに就職したぐらいにSurfacePro3を使っていました。
当時は重厚なPCが多い中、地方出身の自分はオシャレカフェでワークする人達に憧れポータビリティ重視で選んだのが、小さなサイズに従来同等以上の処理能力を持ったSurfacePro3でした。（2in1の目新しさに食いついていたのかもしれません。。笑）

ただ、実際使ってみるとファンの音がうるさく充電も5hくらいしか持ちませんでした。電源も専用のため汎用性が無くコンセントも占有してしまうのは副次的な障害でした。
特にファンの音は辛くて長時間の作業に支障が出るほどでした。
（新入社員当時の私は勉強のため色々ツールいれたり、重たいIDEをいれたりとやっていたためしょうがない点はあるので、決っしてSurfaceをディスってる訳ではありません。2台持ちになった今も重宝しています。）

購入したMacはMacBookPro13インチ（MacOS High Sierra、2.3GH、Corei5、mem:8G、SSD:128G）です。

# 環境設定
## キーボード

- リピート設定(押しっぱなしの時の入力スピード)
- ファンクションキーをFn無しで有効にする
- ライブ変換をOFF
- widowsのかな変換を有効にする(F7~F10)

<img width="670" alt="スクリーンショット 2018-04-06 17.10.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/56388/13929ece-9d10-7eff-c5de-4e90a34dfc4f.png">
キーのリピートは「速い」にしないとバックスペースとかキー押しっぱなしの入力が遅い。
ファンクションキーはデフォルトだと調光や音量コントロールが設定されている。


<img width="419" alt="スクリーンショット 2018-04-06 17.06.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/56388/ed764d91-c664-96dc-2b92-7ba10439cc01.png">
windowsのF8(半角ｶﾅ変換)を有効にするには入力モード半角カタカナにチェックする。
ライブ変換はWindowsに慣れてると余計なお世話感がすごいです。

## コンピュータ名
<img width="671" alt="スクリーンショット 2018-04-06 17.13.34.png" src="https://qiita-image-store.s3.amazonaws.com/0/56388/c6db3741-3e04-99ef-3cba-2779894edd99.png">
デフォルトだとPCユーザー名で「誰々のMacBookPro」などと表示されるので気になる人は変更しておく。

## 画面のロック
セキュリティ対策として当たり前です。パンツ履く履かないレベルです。履かない人は生まれて間もないか、何かの罠でしょう。

- スリープ解除のパスワードの設定
- スリープのショートカット

<img width="671" alt="スクリーンショット 2018-04-06 20.12.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/56388/5863b1f4-16fe-1067-1d7c-66b10814db7a.png">
スリープ解除にパスワードを要求するには「スリープとスクリーンセーバ〜」にチェックをいれます。

<img width="778" alt="スクリーンショット 2018-04-06 20.19.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/56388/ea996afd-0ac3-4c8f-cf82-dc2bc9087762.png">
カーソルを画面の４隅に移動させるとスリープするようにします。
画面ロックのショートカット（Windows+Lみたいなやつ）もありますが、ホットコーナーで設定しておくと便利です。

# 参考

windowsとMacでは各種操作が異なっているので習うより慣れましょう！

- ファイルのオープンがEnterではできない！
    - Cmd+oのショートカットがある。
- PtScrnキーがない！
    - Shift+Cmd+3でデスクトップのスクリーンショット
    - Shift+Cmd+4で画面の切り取り
    - Shift+Cmd+4でSpaceを押すとカメラマークが表示されるので選択ウィンドウのスクリーンショット
    - 上記は全てデスクトップにpngで保存されます
- Cmd+dでファイル消すはずが複製される！
    - ファイル削除のショートカットはCmd+Deleteでできます。

**※Macはショートカットを比較的自由に設定できるので自分好みに設定するのが一番です!**
存在しないファイルでもFile.Existsがtrueを返すことがある

# 現象

File.Exists()を使って、リモートフォルダの削除済みファイルに対して存在チェックを行ったら存在すると言われてしまった。

# 環境

OS: Windows 7
.NET Framework: Ver 4
IDE: Visual Studio 2010

# 対策

ファイルが存在するかどうかの判断にFile.OpenRead()を使用するようにした。

```csharp

bool FileExists(string filePath)
{
    if (File.Exists(filePath) == false)
    {
        return false;
    }

    // File.Exists()で存在するとなっても、実際は存在しないことがあるので再チェック
    try
    {
        using (FileStream fs = File.OpenRead(filePath)) { }
        return true;
    }
    catch (FileNotFoundException ex)
    {
        return false;
    }
}
```

# 追記(2018/11/02)

同僚から情報をもらったところ、どうやらSMB2.0のキャッシュ機能が原因みたいです。
https://support.microsoft.com/ja-jp/help/3040578
pitneybowesでGeoCode変換してYellowfin上に緯度経度を出力する


#この機能はYellowfin7.4以上で動作します
PitneyBowes forward ジオコーディングAPIを活用することで、インプットしたアドレスから緯度/経度を取得し、ジオポイント値へ変換することができます。

こちらのステップを使用するためには、Yellowfinの環境に、PitneyBowesジオコードのプラグインをインストールしなくてはいけません。

Yellowfinのマーケットプレイスからプラグインをダウンロードします。（トランスフォーメーションステップ項目から検索することができます）
https://portal.yellowfinbi.com/YFWebsite-Marketplace-77991
![image.png](https://qiita-image-store.s3.amazonaws.com/0/223443/6a3d82bf-2833-b03d-3256-2e09fff85a64.png)
日本ではYellowfinのサポートにお問い合わせするとプラグインを受け取ることができます。
https://yellowfin.co.jp/contact

#pitneybowesからGeoCodeAPIを活用するためのKeyを入手します
https://locate.pitneybowes.com/geocode
まずは60日間のトライアルから・・・
各種項目を入力して、APIKey・Secretを入手します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/223443/d2aeb336-74cd-8ae2-851f-4797721d29ed.png)


#Yellowfinへこのプラグインをインストールします
管理からプラグイン管理を選択し、追加ボタンを押下します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/223443/46313937-5fc5-55e5-d125-705401817ea0.png)

受け取ったプラグインをuploadします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/223443/9cfac64e-ca00-1e84-b8f8-871095153eff.png)

#新規変換フローを作成します
変換フローを選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/223443/62c487e2-ce86-7b77-61a0-ac236e9644a3.png)

#今回は既に作成したレポートから緯度経度を生成します
![image.png](https://qiita-image-store.s3.amazonaws.com/0/223443/56e93034-ff00-89d5-e763-efe1140484b7.png)

##トランスフォーメーションステップでPB - Forward GeoCodeを繋ぎます
![image.png](https://qiita-image-store.s3.amazonaws.com/0/223443/999fab14-46ab-d192-3eed-d035d2e53c2f.png)

#データをつないで各種カラムを設定します
標準モードのフルアドレスでは結果が返ってきませんでした。のでより詳細に出力したい場合は分割でカラムを設定する必要がありそうです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/223443/c0b7064f-08de-c346-a388-f065fcc9a79b.png)

ちなみに標準モードではcityレベルで指定できれば結果を取得することができました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/223443/964c4dd0-00cb-9e99-809c-d3780bb4b417.png)

緯度経度を住所から簡単に割り出すことができるので、地図での表示に大いに役立ちそうです！！
オブジェクト指向について調査した結果まとめ【随時更新】

# オブジェクト指向について調査した結果まとめ【随時更新】
随時追加・整理します。
※個人的に気に入った説明を自分の言葉で書いているので理解できなかったらすみません。

## オブジェクト指向とは？
概念そのものだとか、明確な説明はない、などありますが。

**「変更されない箇所を軸に、頻繁に変更されるであろう箇所をクラスに抽出する、プログラミングスタイル」**

要は後から仕様変更・機能拡張しやすいようにプログラムするための考え方だと理解します。

## 継承 is-aとは？
**継承の本質は、抽象概念をまとめ上げられるインターフェイス**

- 「機能の受け継ぎ」が本質ではない
- クラスの継承とインターフェイスの違いは、継承はスーパークラスから機能を受け継ぐことができるということ
- 継承よりコンポジションが良く使われる
    - EX.)　new 部品1, new 部品2, new 製品(部品1, 部品2)

## ポリモーフィズムとは？
**インターフェイス（抽象）に対してプログラムすること**

- 具象に対してプログラムしてはいけない（「new」は具象）
- 依存するクラスが増えることは問題ではなく、問題なのは具象に依存してしまうこと
- ファクトリを作るまでもないインスタンス生成は、メインクラスで行うようにする


## カプセル化とは？
**無駄を省き洗練させてわかりやすいものを作ること**

- 継承やポリモーフィズムとはレイヤーが異なる
- クラスに正しい名前をつける(これが一番苦手かも。。。)
- 現実世界をオブジェクト指向のソースに落とし込んでもうまくいかない。

## 名前の付け方
とりあえず以下だけ守ろうと思います。

- キャメルケース
- クラスは名詞 or 動名詞
- メソッドは動詞を最初に持ってくる


## ５つの原則（SOLID原則）


### 単一責任の原則（Single Responsibility Principle）
**クラスを変更する理由は、1つ以上存在してはならない（役割=責任=変更する理由）**


### オープン・クローズドの原則（Open-Closed Principle）
**・仕様変更があった場合に、振る舞いを追加することで変更に対処することができる
・振る舞いを追加しても、既存コードは影響を受けない**


### リスコフの置換原則（Liskov Substitution Principle）
望まれるのは、次のような置換性質である

S型オブジェクトo1各々に対して, T型オブジェクトo2が1つ存在
o2を使って定義されたプログラムpが存在
このとき、**o2の代わりにo1を使ってもpの振る舞いが変わらない性質**


### インタフェース分離の原則（Interface Segregation Principle）

**・クライアントに、クライアントが利用しないメソッドへの依存を強制してはならない**

・利用していないメソッドに依存してしまうと、そのメソッドが変更されたときに本来無関係であるはずのクライアントまで影響を受けてしまう場合がある

・それぞれのクライアントが**実際に利用するメソッドだけ**に依存するようにする

**・関連性を持ったインタフェースはグループ化し、クライアントごとに特化したインタフェースを用意**
これによりクライアントは、自分が利用しないメソッドとの依存関係を断ち切ることができる


### 依存性逆転の原則（Dependency Inversion Principle）

・上位のモジュールは下位のモジュールに依存してはならない、**どちらのモジュールも「抽象」に依存すべきである**

・「抽象」は実装の詳細に依存してはならない、**実装の詳細が「抽象」に依存すべきである**

・下位モジュールが宣言したインタフェースに上位モジュールが従う形は、インタフェースの所有権が下位モジュールにある状態といえる

**・具体的なクラスに依存せず、 プログラム内の関係は抽象クラスかインタフェースで終わるようにする**
        　具体的なクラスから派生するクラスはだめ
        　基本クラスで実装されているメソッドは上書きしちゃだめ


## 抽象化のやり過ぎに注意
**・早まった「抽象」をしないことと「抽象」を使うことは同じように大事**

という説明がありました。意味・効果のある抽象化を見極めて行いたいと思います。
Github の Private リポジトリ を Maven リポジトリ として使う

3年前くらいに [Github Pages を利用して Maven リポジトリを構築する方法](https://qiita.com/tanjo/items/844d0444d7ffa541120e) を Qiita に書いた.

今回は Private リポジトリでやってみる.
利用者にプラグインの強要をしないようにしたいので 「gradle-git-repo-plugin」 等をプラグインを使わずに Github の機能だけでダウンロードできるようにする.

## はじめに

私は Android エンジニアなので、 Android Studio の build.gradle をターゲットとして書く.

基本はパブリックに置くのと同じなので AAR ファイルの生成とかは省略する.

## ライブラリ側

- プライベートリポジトリ
- ライブラリのユーザーには Read 権限を付与
- リポジトリは **hoge/android-sdk** に配置
- groupId は **jp.hoge.library**
- artifactId は **android-private-sdk**
- version は **1.0.0**

## アプリ側

### 1. Github の [Personal Access Token](https://github.com/settings/tokens) を生成

権限は `repo` を設定すればよい. 

### 2. プロパティファイルの作成

取得した Personal Access Token と Github のユーザー名を Gradle で使えるようにする.

```:github.properties
username=USERNAME
token=GITHUB_PERSONAL_ACCESS_TOKEN
```

セキュリティを考慮して Personal Access Token はユーザーごとに用意しよう.

`.gitignore` に以下を追加することをオススメする.

```:.gitignore
github.properties
```

### 3. Maven リポジトリを追加する

- URL は `https://raw.githubusercontent.com` を利用
- `credentials` に先程のプロパティファイルの情報を設定
- `authentication` を設定 （ベーシック認証）

```gradle:build.gradle
allprojects {
    repositories {
        google()
        jcenter()
        maven {
            def propsFile = rootProject.file('github.properties')
            def props = new Properties()
            props.load(new FileInputStream(propsFile))
            url "https://raw.githubusercontent.com/hoge/android-sdk/master"
            credentials {
                username props['username']
                password props['token']
            }
            authentication {
                basic(BasicAuthentication)
            }
        }
    }
}
```

### 4. 依存関係を記述する

```gradle:build.gradle
dependencies {
  implementation "jp.hoge.library:android-private-sdk:1.0.0"
}
```

## おわりに

2段階認証をしている方でも利用できます.
トークンは利用しなくなったら必ず **Revoke** しよう.
GCPのLB経由のNginxでアクセス元IPによるアクセス制限

# 背景
- GCPのLB配下で特定パス以下の場合のみアクセス元IPでアクセス制限したかった
- ELB同様、GCPのLBの経由の場合はIPがLBのものになってしまうので `xxx.xxx.xxx.xxx allow` は使えない
- 調べたらif分でゴリッと実装してる場合が多かった
- もっといい方法合ったら知りたい

# 実装(nginx.conf)

```conf

  # アクセス許可するアクセス元IPであれば$allowedに'allow'を代入。そうでなければ、deny。
  map $http_x_forwarded_for $allowed {
        default deny;
        ~\s*127.0.0.*$  allow; # 127.0.0.0/24 のアクセスを許可 
  }

  location / { 
　　　　　　　　　　　略 
　　　　}

  # $allowedが'deny'の場合は403を返す
  location /some_path/ {
     if ( $allowed = "deny" ) {
        return 403 ;
     }

    proxy_pass http://unicornapp;
  }
```

# 参考
http://d.hatena.ne.jp/end0tknr/20150618/1434608411
https://gist.github.com/mosson/7008082
http://takeyuweb.hatenablog.com/entry/elb_ec2_nginx_ip
Rのunnest_tokens関数。備忘録。

2度目の投稿です。
見にくかったら、すんません。

#前置き
Rの勉強してたら「unnest_tokens」という便利そうな良く分からん関数に出会いました。

この記事は
1．自分への備忘録として
2．誰かの役に立つかも
というのを目的として、拙い説明文を書きました。


https://www.rdocumentation.org/packages/tidytext/versions/0.1.6/topics/unnest_tokens
のサイトの例文が一番分かりやすいかなと思ったので、この例文に、「#」使って、説明文書きました。


#コードと説明文
```

library(dplyr)
library(janeaustenr)

# jane austenの「pride and prejudice」って長編小説らしいです。
d <- data_frame(txt = prideprejudice)
d

# dには、各行に文章が入っているし、空白の行もある。
# unnest_tokensをデフォルトで（引数を指定せずに）使うと、文章を単語に分けて、一行一単語にする。しかも空白行は削除。
# 今回はtxtという列名の文章を、一行一単語に分解している。且、wordという列名に変更。
d %>%
  unnest_tokens(word, txt)
d2<- d %>% 
  unnest_tokens(word, txt)

# dは結果を出力しているだけだが、d2にはunnest_tokensの結果を代入している。
# 行数が10倍になっているのでわかるかも。
nrow(d)
nrow(d2)
View(d)
View(d2)

# token="sentence"にすることで、文章を「.」「!」「?」で区切る。そして、列名をtxtからsentenceに変更。
# だから「mr.」とか変な感じになってる。
d %>%
  unnest_tokens(sentence, txt, token = "sentences")
d3 <- d %>%
  unnest_tokens(sentence, txt, token = "sentences")

# バイグラム。
d %>%
  unnest_tokens(ngram, txt, token = "ngrams", n = 2)
d4 <- d %>%
  unnest_tokens(ngram, txt, token = "ngrams", n = 2)


# 1グラム毎に、2単語スキップする4グラム
# 例：「pride and prejudice by jane austen chapter 1 it is a truth」なら、
# まず1つ目のグラムは一単語目の「pride」。そのあと2単語（andとprejudice）スキップして、
# 2つ目のグラムは「by」。そして、2単語（janeとausten）をスキップして、
# 3つ目のグラムは「chapter」。そして、2単語（1とit）をスキップして、
# 4つ目のグラムは「is」。
# 「pride and prejudice by jane austen chapter 1 it is a truth」の、2skip_4gramは、「pride by chapter is」。
d %>%
  unnest_tokens(ngram, txt, token = "skip_ngrams", n = 4, k = 2)
d5 <- d %>%
  unnest_tokens(ngram, txt, token = "skip_ngrams", n = 4, k = 2)


############################# regexはよー分からん。
# [\\d]は「1|2|3|4|5|6|7|8|9|0」の略。今回屋と、「1チャプター1行」
# だから1行目は、「chapter 1」以前の文章が入ってる。
# 2行目は、「chapter 1」と「chapter 2」の間の文章が入ってる。
# 3行目は、「chapter 2」と「chapter 3」の間の文章が入ってる。4行目以降も同じ感じで続く。
# でも「chapter [\\d]」の部分は削除される。だから、11行目以降は、数字が1つ入ってるけど、
# これは、チャプター数が二桁になってて一桁目だけ削除されずに残ったから
d %>%
  unnest_tokens(chapter, txt, token = "regex", pattern = "Chapter [\\d]")
d6 <- d %>%
  unnest_tokens(chapter, txt, token = "regex", pattern = "Chapter [\\d]")


# 引数の詳しいことは良く分からんかったけど、
# とりあえず、「一行一単語」、且、「空白の行もそのまま残す」ってこと。
d %>%
  unnest_tokens(word, txt, token = stringr::str_split, pattern = " ")
d7 <- d %>%
  unnest_tokens(word, txt, token = stringr::str_split, pattern = " ")
# d2は「一行一単語、且、空白削除」
# d7は、空白残してる。d2より行数が多いことからも確認できる。
nrow(d2)
nrow(d7)



#######################################################################
############################ワケワカメ###################
# tokenize HTML
h <- data_frame(row = 1:2,
                text = c("<h1>Text <b>is</b>", "<a href='example.com'>here</a>"))

aaa <- h %>%
  unnest_tokens(word, text, format = "html")
######################################################################

```


#最後に
「regex」とか「stringr::str_split」とか最後のHTMLが良く分からんまんま終わりました。すみません。。。
誰か分かる人いたら教えてください（。＿。）
訂正や改善点のコメントもあると嬉しいです！
この拙い記事が、少しでも役に立ったら幸いです！！！


最後まで読んで頂き、有難うございましたぁ！！！

![98617b866a4698561f23ba16d29d8b67_400.jpg](https://qiita-image-store.s3.amazonaws.com/0/241219/cf9bcef7-ae9a-02a3-7ed7-d0ce38cc87f5.jpeg)
actions on googleテンプレ

# google assistantのアクションを作るときの俺用テンプレ

学習段階で作ったものだから、これから変更していく可能性あり。
バージョンは`"actions-on-google": "^1.5.x"`にて使用。

```js
'use strict';

const functions = require('firebase-functions'); 
const DialogflowApp = require('actions-on-google').DialogflowApp;
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
    const app = new DialogflowApp({request: request, response: response});
    
    

    const actionMap = new Map();
    // ○○を開いて、って言った時に呼ばれる
    actionMap.set("input.welcome", welcomeIntent);
    // ここは自分で定義したアクション名。プロジェクトごとに帰る必要あり
    actionMap.set("start_action", startIntent);
    app.handleRequest(actionMap);
});

function welcomeIntent (app) {
}
function startIntent (app) {
}


// ssmlに対応させる
function makeSsml(msg){
    return "<speak>" + msg + "</speak>";
}
```
俺が考えた最強の Reactのステートレスコンポーネントの書き方

最近自分はこう書いてるという例。意見が欲しい。
この記事に redux は出てこない。

参考: https://qiita.com/mizchi/items/bcb1aef8d1f14f8d0b4a

## 構成要素

- React
- flow
- styled-components
- recompose

以下 SFC = Stateless Functional Component

```js
/* @flow */
import React from "react"
import styled from "styled-components"
import pure from "recompose/pure"

type Props = {|
  value: string
|}

export default pure(function Example(props: Props) {
  const { value } = props

  return (
    <Container>
      <Value>{value}</Value>
    </Container>
  )
})

const Container = styled.div`
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
`

const Value = styled.span`
  color: #f00;
`
```

## 解説

- prettier: `semi: false`
    - ノーセミコロン派
- `/* @flow */`
    - flow の有効化
    - デフォルト有効化は(主にnode_modules以下で勝手に死にまくるので)さすがにきつい
- `import styled from "styled-components"`
    - 最近もう完全に styled-components の css-in-js でいいじゃん派になった
    - 実際流行ってる。便利
- `import pure from "recompose/pure";`
    - SFC はデフォルト pure ではないので、パフォーマンスを気にする場合は pure を使う (extends React.PureComponent {} 相当)
    - `flow-typed install recompose@0.x.x` で型定義ファイルを入れておく
    - パフォーマンスを気にしないなら（後回しにするなら）サボっても良い
    - recompose/pure だけ使っておけばあわよくば参照絞れる
        - コンポーネント集だけのライブラリに切り出すときとか
- `type Props = {| ... |}`
    - `$Exact<...>` 相当で完全一致を要求する。 指定された props 以外の値を与えられるとエラー
    - `<Example onClick={...} onClickItem{...} >` みたいに名前を変えた時にコードに残ってしまうことがあった
- `export default pure(function Example(props: Props) {`
    - しない派閥もいるようだが、自分は `export default` 「しか」しない派
    - 代わりにファイル名とコンポーネント名は一致させる。なので UpperCamelCase
    - `function <Name>()` の Name 部分はReact が render後にコンポーネント名のデバッガとして使うので与えておく。これも面倒だったらサボって良い。その場合、 `(anonymous)` になる。
    - `pure(...)` すると PureComponent になってすべてのキーに shallow equal が比較され描画されるかどうか決まる
    - compose(pure)(Component) とすると 型が消えてしまう(合成されたものに対して片づけし直す必要がある)ので、複雑なことをしないSFCなら pure だけ使う
- `const { value } = props`
    - 関数内で、値が SFC の props か React.Component のときの this.props, this.state か、というコンテキストを除くために、一旦使う値を全部バラしてしまう
    - 一度バラしてしまえば他のコンテキストに移した時のリファクタで便利
- `const Container = styled.div`
    - styled-components はそのファイルスコープ内の `export default` の後に書く習慣にしている。 
    - ファイルを開いた時に export default` を目視するコストを少なくしたい
    - 大抵 Container みたいな名前のラッパーを書く
    - コンポーネント志向だと 縦横 100%, 100% の display: flex になることが多い
    - 本当は web/react-native の抽象化のために https://github.com/lelandrichardson/react-primitives を使いたいが、時代が追いついてきてない
    - atom の language-babel 入れてると css でハイライトされるし、 prettier のCSS整形も掛かる

## 省エネ版

デバッガの情報を減らしてでもショートハンドで横着する人向け

```js
/* @flow */
import React from "react"
import styled from "styled-components"

export default ({value}: {| value: string |}) =>
  <Container>
    <Value>{value}</Value>
  </Container>

const Container = styled.div`
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
`

const Value = styled.span`
  color: #f00;
`
```
MySQLのslaveを追加するスクリプト

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

# replicationを開始するscript

master_host="db-master"
master_user="root"
master_password="hogehoge"

slave_host="localhost"
slave_user="root"
slave_password="hogehoge"

target_db="fugafuga"
dump_file="/root/db_master_dump.sql"

while ! mysqladmin ping -h $master_host --silent; do
  sleep 1
done

# masterのdumpを取得する
# mysqldumpのオプションについて
#   --master-data
#   masterのbinlogファイル、positionを出力する
#   https://dev.mysql.com/doc/refman/5.6/ja/mysqldump.html#option_mysqldump_master-data
#   
#   --single-transaction
#   https://dev.mysql.com/doc/refman/5.6/ja/mysqldump.html#option_mysqldump_single-transaction
mysqldump -u$master_user -p$master_password -h $master_host --databases $target_db  --master-data --single-transaction  --events > $dump_file

# slave停止 & リセット
mysql -h$slave_host -u$slave_user -p$slave_password -e "STOP SLAVE"
mysql -h$slave_host -u$slave_user -p$slave_password -e "RESET SLAVE"

# slaveにmasterの向き先を設定する
mysql -h$slave_host -u$slave_user -p$slave_password -e "CHANGE MASTER TO MASTER_HOST='$master_host', MASTER_USER='$master_user', MASTER_PASSWORD='$master_password'"

# slaveにdumpを流し込む
# dumpに CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.XXXXXX', MASTER_LOG_POS=XXXXX; が含まれているため、
# MASTER_LOG_FILE、MASTER_LOG_POSの設定もされる。
mysql -h$slave_host -u$slave_user -p$slave_password < $dump_file

# slave再開
mysql -h$slave_host -u$slave_user -p$slave_password -e "START SLAVE"
```
this.emit(":tell", msg)をやめた

最近`this.emit(":tell", msg)`って書き方をやめることにしたから、自分用のメモ。

## なぜやめた

`this.emit(":アクション名", msg);`の形だと、AudioPlayがやりにくい。
よって、もっと柔軟なことができるやり方に統一する事にした。

## :tellに相当するもの

```js
this.emit(':tell', msg); 

thi.response.speak(msg);
this.emit(':responseReady');
```

## :ask相当するもの

```js
this.emit(":ask", msg, repronmt);

this.response.speak(msg).linsten(repronmt);
this.emit(":responseReady");
```

## 参考
https://qiita.com/HeRo/items/8475505a55cc9e737687
Polygon-point containment in Python

```python
def contains(g, p): 
  n = len(g)
  x = False
  for i in range(n):
    a = np.array(g[i]) - np.array(p)
    b = g[(i+1)%n] - p 
    if (np.linalg.norm(np.cross(a,b)) < np.finfo(np.float).eps \
        and np.dot(a,b) < np.finfo(np.float).eps):
        return 1
    if (a[1] > b[1]):
        b,a = a,b 
    if (a[1] < np.finfo(np.float).eps and np.finfo(np.float).eps < b[1] \
        and np.cross(a,b) > np.finfo(np.float).eps):
        x = not(x)
  if (x):
      return 2
  return 0

g = []
n = input()
for i in range(n):
    a = []
    a.append(map(int, raw_input().split()))
    for aa in a:
        x = aa[0]
        y = aa[1]
        g.append([x,y])
#print(g)
n = input()
for i in range(n):
    a = []
    a.append(map(int, raw_input().split()))
    for aa in a:
        x = aa[0]
        y = aa[1]
        ret = contains(np.array(g), np.array([x,y]))
        print(ret)
```

```
4
0 0
3 1
2 3
0 3
3
2 1
2
0 2
1
3 2
0
```
# Refs.
* [行途中の折り返し](https://www.glamenv-septzen.net/view/185)
* [swap](http://lenia23.hateblo.jp/entry/python_swap)
* [リスト追加(append)](https://www.pythonweb.jp/tutorial/list/index6.html)
* [リストサイズ(size)](https://www.pythonweb.jp/tutorial/list/index5.html)
Qiitaでも投げ銭がしたい！！　~chrome拡張入門~

#概要
少し前にtwitter上で仮想通貨（Monacoin）を投げ銭できるサービス「 [tipmona](https://twitter.com/tipmona) 」を用いて、Qiitaの良記事に投げ銭できる拡張機能 **「[DevelopMona](https://chrome.google.com/webstore/detail/developmona/dakfcfjijjjdbbealnnoggmddhcbpegh?hl=ja)」**を作ったので、その過程を紹介します。

なお、今回作るのはコンテンツスクリプト（特定ページに要素が追加されるもの）です。
こんな感じになります。
![無題.png](https://qiita-image-store.s3.amazonaws.com/0/211349/80ae5080-5cb4-c14a-bfd9-f422cb481600.png)

![無題.png](https://qiita-image-store.s3.amazonaws.com/0/211349/326b79cd-49de-fa87-0bab-df9de93348a6.png)




#manifest.json
jsonにはコメント構文がないらしいので、"（括弧で囲んだ部分:"）"をコメントとします。
実際コピペするときは（括弧）の行を外してください。

```json

{
    "manifest_version": 2 ,
    "name": "拡張機能の名前",
    "version": "0.1",
     "(バージョンを決める":")"
    "description": "拡張機能の説明",
    "icons": {
        "16": "{16pxアイコンのurl}"
    },
    "content_scripts": [
         {
              "matches": ["https://qiita.com/*"],
　　　　　　　　"（今回は「Qiita上で投げ銭」がしたいので、Qiitaを指定します":"）"

              "js": ["jquery-3.2.1.min.js", "main.js"],
　　　　　　　　"（今回はJqueryを使いました":"）"
         }
    ],
    "web_accessible_resources": [
        "*.png"
      ]
　　　"（これでページにPNGを使えるようになります":"）"

}
```
#main.js
作りたいものによってコードを書きます。


document.createElemtとかを使って要素をそのページに埋め込みます

```javascript

var twitter;

slash = location.href.split("\/")
//URLをスラッシュで分ける　["https:","","qiita.com","著者","items","記事番号"]


if (slash[2] == "qiita.com" && slash.length == 6 && slash[4] == "items") {
  //Qiitaの記事ページかどうかを判定

    var author,
        twitte;
    jQuery(document).ready(function ($) {
        $('a.it-Header_authorName').each(function () {
            author = $(this).text().slice(1)
        })
    })
    //ページから一番下の著作者ボタンを探す


    setTimeout(function () {
        fetch('https://qiita.com/' + author).then(res => res.text()).then(txt => twitter = ($("li.newUserPageProfile_socialLink-twitter>a", txt).attr("href")));
    //そのページの著者のページへアクセスして、twitterへのリンクを取得

  }, 1000)//ページのロードを待つ


    setTimeout(function () {
        console.log(twitter.split("\/"))
        authorstwitter = twitter.split("\/")[3]
        //著者のTwitterIDを取得

        if (authorstwitter){ //twitter連携していれば
            const imageURL = chrome.extension.getURL('monage_button.png')
            const imageURL_on = chrome.extension.getURL('monage_button_on.png')


            const imageTag = `<a  href="https://twitter.com/intent/tweet?text=@tipmona tip @` + authorstwitter + ` 0.114　%23DevelopMona \n あなたの記事【` + document.title + `】に投げ銭です。詳しくはこちら \n https://monappy.jp/memo_logs/view/monappy/123">
<img src="${imageURL}" onmouseover="this.src='${imageURL_on}' "onmouseout="this.src='${imageURL}'" width="100px" height="28px" ></a>`
            const monage = $("div.it-AuthorInfo_footer > div").after(imageTag)
        }//twitter投稿へのリンク付きボタンを作る



    }, 3000)

}

```

#デプロイ（？）
![無題.png](https://qiita-image-store.s3.amazonaws.com/0/211349/e04c0a3d-911a-e37b-5d59-2170c63d931d.png)

Chromeでその他のツール→拡張機能　の後、
パッケージ化されていない拡張機能を読み込む　フォルダを指定します。

#終わりに
初めての開発のわりに、案外簡単にできたかなという印象です。
質問・意見などありましたらコメントください
WSHのおまじない帯。node.js風フェイク。

node.js 相当の console.log, process.exit, process.argv をフェイクする。
が、UTF-8は仕方がないので日本語は諦めるか。

```js
// magic spell for WSH ///////////////////////////////////////////////////////
if(typeof console==="undefined")  console={log: function(s){WScript.Echo(s)}};
if(typeof process==="undefined"){ process={exit:function(e){WScript.Quit(e)}};
var v=process.argv=[];v.push(WScript.FullName);v.push(WScript.ScriptFullName);
var n=WScript.Arguments.Unnamed;for(var i=0;i<n.length;i++)v.push(n.item(i))};
//////////////////////////////////////////////////////////////////////////////


for(var i = 0;i < process.argv.length; i++){
  console.log("argv[" + i + "] = " + process.argv[i]);
}

process.exit();
```
Sourcetreeでforce pushする(git)

Mac版限定かもしれない

2018年4月6日時点

# 手順
## 設定を変更
デフォルトではforce pushできないので設定を変更する必要がある。

1. Preferencesで設定画面を表示
2. Advancedタブに切り替え
3. Allow force pushにチェックを入れる

![preferences.png](https://qiita-image-store.s3.amazonaws.com/0/98727/c4582459-fa9b-5dc1-33c3-c2cb450cf6b5.png)
![allow_force_push_check.png](https://qiita-image-store.s3.amazonaws.com/0/98727/4b8d9ba5-17ae-04a0-3379-16a366cc1064.png)

## force push
pushするときに `Force push` を選べるようになっているのでチェックを入れてOKを押す。
![force_push.png](https://qiita-image-store.s3.amazonaws.com/0/98727/f1fd9927-7396-788a-488d-f24dc4f32820.png)

# 備考
最初に書いてあるとおりMac版限定可もしれない。
コマンドでgitが使えるなら `git push -f` で良い。
React-Leaflet


[React-Leaflet · ⚛️ React components for 🍃 Leaflet maps](https://react-leaflet.js.org/)


webプロジェクト作成

package.jsonに追加

```
    "leaflet": "1.3.1",
    "@types/react-leaflet": "1.1.5",
    "@types/prop-types": "15.5.2",
    "react-leaflet": "1.9.1"
```

### site.css

```css
.leaflet-container {
    height: 400px;
    width: 100%;
}
```


### boot.tsx
/ClientApp/boot.tsx

```
// leaflet css
import '../node_modules/leaflet/dist/leaflet.css';
```

### routes.tsx
/ClientApp/routes.tsx

```
import { MapWanNavi } from './components/Map';

export const routes = <Layout>
    <Route path='/Map' component={MapWanNavi} />
</Layout>;
```


### Map.tsx

/ClientApp/components/Map.tsx

```
import * as React from 'react';
import { RouteComponentProps } from 'react-router';
import { Map, TileLayer, Marker, Popup } from 'react-leaflet';
import { LatLngLiteral } from 'leaflet';


interface ReactLeafletState {
    lat: number;
    lng: number;
    zoom: number;
}


export class MapWanNavi extends React.Component<RouteComponentProps<{}>, ReactLeafletState> {
    constructor() {
        super();

        this.state = {
            lat: 51.505,
            lng: -0.09,
            zoom: 13,
        }
    }


    render() {
        var position: LatLngLiteral = { lat: this.state.lat, lng: this.state.lng};

        return (
            <Map center={ position }  zoom={this.state.zoom}>
                <TileLayer
                    attribution="&amp;copy <a href=&quot;http://osm.org/copyright&quot;>OpenStreetMap</a> contributors"
                    url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
                />
                <Marker position={ position }>
                    <Popup>
                        <span>
                            A pretty CSS3 popup. <br /> Easily customizable.
                        </span>
                    </Popup>
                </Marker>
            </Map>
        )
    }
}
```

## result

![image](https://qiita-image-store.s3.amazonaws.com/0/49910/5b7fa0f5-0585-3714-9c46-f5718f684ab5.png)



## link
[Installation · React-Leaflet](https://react-leaflet.js.org/docs/en/installation.html)
CentOS 7(RHEL 7) 初期設定 Ansible 編

はじめに
--------

[CentOS 7(RHEL 7) 初期設定](https://qiita.com/kouji-kojima/items/f60d1948b9bb445fc487) の 内容を Ansible の Playbook に 置き換えてみます。

ロケール、タイムゾーンの設定
-------------------------

```ruby:ロケールの設定,Winボタン付きの日本語キーボード設定
- name: set locale
  shell: localectl set-locale LANG=ja_JP.utf8

# Mac の 場合は「us-mac」を指定
- name: change keymap to Japanese 109
  shell: localectl set-keymap jp-OADG109A

- name: change x11 keymap to Japanese 109
  shell: localectl set-x11-keymap jp-OADG109A
```

```ruby:タイムゾーンの設定
- name: set timezone to Asia/Tokyo
  timezone:
    name: Asia/Tokyo
```

Proxyの設定
-----------

```ruby:サーバのProxy設定
# proxy.sh を templetes ディレクトリに配置
- name: set proxy.sh
  template:
    force: yes
    src: proxy.sh
    dest: /etc/profile.d/proxy.sh
    owner: root
    group: root
    mode: 0644
  register: proxy_file
- name: source proxy.sh
  shell: source /etc/profile.d/proxy.sh
  when:
  - proxy_file is changed
```

```ruby:yumのProxy設定
# /etc/yum.conf に Proxy設定を追加
- name: set yum proxy
  lineinfile:
    dest: /etc/yum.conf
    state: present
    regexp: "^proxy=.*$"
    insertafter: EOF
    line: "proxy={{ http_proxy }}"
```

```ruby:パッケージの最新化
- name: yum update
  yum:
    name: '*'
    state: latest
    skip_broken: yes
```

```ruby:rpmのproxy設定
# macros を templates ディレクトリに配置
- name: set rpm proxy
  template:
    force: yes
    src: macros
    dest: /etc/rpm/macros
    owner: root
    group: root
    mode: 0644
```

```ruby:wgetインストール
- name: install wget
  yum:
    name: wget
    state: latest
    skip_broken: yes
```

```ruby:wgetのproxy設定
# /etc/wgetrc に Proxy設定を追加
- name: set wget proxy
  lineinfile:
    dest: /etc/wgetrc
    state: present
    regexp: "^{{ item }} = .*$"
    insertafter: "^#{{ item }}"
    line: "{{ item }} = {{ http_proxy }}"
  with_items:
    - http_proxy
    - https_proxy
    - ftp_proxy
```

```ruby:gitのインストール
- name: install the latest version of git
  yum:
    name: git
    state: latest
```

```ruby:gitのproxy設定
- name: set git proxy
  shell: "git config --global {{ item }} {{ http_proxy }}"
  ignore_errors: yes
  with_items:
    - http.proxy
    - https.proxy
```

社内CA証明書の設定
-----------------

```
# CA証明書のハッシュ値を取得(証明書が変わった時にエラーにする為)
sha256sum xxx.ca
ca_sha256(ハッシュ値)
```

```ruby:社内CA証明書の設定
- name: set Local CA Certificate
  get_url:
    url: "{{ ca_url }}"
    dest: /etc/pki/ca-trust/source/anchors
    checksum: "sha256:{{ ca_sha256 }}"
    use_proxy: no
    force: yes
  register: downloaded_ca

- name: extract ca
  shell: update-ca-trust extract
  when:
  - downloaded_ca is changed
```

さいごに
--------

具体的なソースは [GitHub](https://github.com/kouji-kojima/sample-ansible-el7) を ご参照ください。

次は、今回作成したロールを [Ansible Galaxy に登録して再利用する方法](https://qiita.com/kouji-kojima/items/2525ea87952d4039bad7) を 紹介したいと思います。
intra-mart実践入門～環境構築編～ 特設ページ

# 「intra-mart実践入門 ～環境構築編～」の販売を開始しました
![cover.jpg](https://qiita-image-store.s3.amazonaws.com/0/228081/62aabc9b-25fc-0936-a3d2-93b5486369f5.jpeg)
## 販売チャンネル１「easypay」
paypalアカウントをお持ちの方は以下のリンクから直接購入できます。
[intra-mart実践入門 ～環境構築編～](https://easypay.jp/8BFY "intra-mart実践入門 ～環境構築編～")
価格は15,000円(税込)となります。

### easypayでの購入者特典
書籍内で使用しているサンプルコードやサンプルモジュールを格納した
Visual Studio Team ServicesのGitリポジトリへの一定期間のアクセス権限を与えます。
詳細は購入時に届くメールをご確認ください。

## 販売チャンネル２「Amazon Kindleストア」
paypalアカウントをお持ちでない、または販売者としての未来生活研究所を信用できない方は以下のリンクからも購入できます。
[intra-mart実践入門 ～環境構築編～](https://www.amazon.co.jp/dp/B07BZ2FJ4M/ref=sr_1_1?ie=UTF8&qid=1522998440&sr=8-1&keywords=intra-mart%E5%AE%9F%E8%B7%B5%E5%85%A5%E9%96%80 "intra-mart実践入門 ～環境構築編～")
価格は20,000円となります。

### Amazon Kindleストアでの購入者特典
ありません。

## どうして価格や購入者特典が違うのか？
既にAmazonで書籍販売している方はご存知と思いますが利益率が低いからです。
しかしながら、世界最大の事業者なので信用度とSEO効果は圧倒的に高いため使わせていただきます。

# 書籍説明
## 注意
本書は書籍「intra-mart実践入門」の環境構築編のみを抜粋したものです。
全四部の中の第二部のみが収録されており、他の部は目次のみとなっています。
## 内容
エンタープライズ向けのシステム開発基盤ということもあり、intra-mart Accel Platform(以下、intra-mart)に関する技術情報は、NTTデータ・イントラマート社や周辺ベンダーから公表されている情報がほぼ全てで、有識者による参考書籍や個人の技術ブログ等はほとんど存在しません。
本書はintra-martを使って社内システムを自社開発した筆者の２年ほどの経験に基づいて執筆されています。筆者はintra-martについて精通した技術者でもありませんし、それを取り巻く周辺技術についてにも精通しておりません。それでも、intra-martをこれから使い始める人、既に使っているけれどもっと深く知りたい人、そして何より社内システムをintra-martを使って自社開発することになって悩んでいる人にとって、本書が何らかのヒントになれば筆者としてこれ以上の喜びはありません。
## 対象読者
本書が対象とする読者は以下の条件に合致する方です。

* intra-martを使って社内システムを自社開発している
* 社員数１００から１０００人程度の中規模企業に在籍している
* 社内システムの企画、設計、開発、運用、またはマネジメントを担当している
* これまでにエンタープライズ系のシステム開発プロジェクトを経験している
* intra-martとその周辺技術について広く浅くスキルを身に着けたい
* スキル向上に興味はないが、そのまま使えるサンプルがほしい

逆に対象としていない読者は以下の条件に合致する方です。

* intra-martを使っていないが興味があるので概要を掴みたい
* 社内システムは自社ではなくベンダー企業に委託して開発している
* 他社システムを開発するベンダー企業に在籍している
* 社員数１００人以下の小規模企業、または１０００人以上の大規模企業に在籍している
* これまでにエンタープライズ系のシステム開発プロジェクトを経験していない
* intra-martやその周辺技術について深く掘り下げたスキルを身に着けたい
* スキル向上に熱心であり、どんな状況でも使える汎用的なスキルを身に着けたい

## 構成
本書はintra-martを使った社内システムの自社開発プロジェクトを支援する参考資料でありたいと考えています。
そのため以下のような構成で説明を行います。

* プロジェクトマネジメント編
* 環境構築編
* 組織設計編
* アプリケーション編

第一部では、プロジェクトチームの心身と雇用を守り、プロジェクトを成功させるために何を知っておくべきかについて説明します。本書はプロジェクトマネジメントの専門書ではありませんので、PMBOKガイドの解説のような一般論ではなく、プロジェクトの定義やよくある失敗要因について例を挙げて説明していきます。

第二部では、intra-martで開発するために必要となる環境構築について説明します。開発から運用までを考慮した環境構築のサンプルを用意しています。環境構築についてどうしても理解できない場合は、サンプルの変数だけを変更してそのまま使用してもらっても問題ありません。

第三部では、intra-martのワークフローを利用するときに重要になってくる組織設計について説明します。既存の組織構造からシステム運用するために必要な組織モデルを設計するために必要となる一般的な組織構造やイレギュラーケースの扱いについての考え方をまとめました。

第四部では、intra-martのアプリケーション開発で使う要素技術について説明します。標準機能をどこまで使い倒せるか、
限界に挑戦した内容となっています。intra-mart Developer Siteをさらに濃くしたものと考えていただければ内容が想像しやすいかと思います。

# 書籍の残りは？
第四部＞第三部＞第一部の優先順位で適宜、執筆していきます。
第二部の売れ行きによってモチベーションが変化します~~が、第四部までは確実に出版する予定です~~。
ありがたいことに2冊売れましたが、需要もあまりないようですので蔵入りとしておきます。
macでバージョンを指定してyarnをインストールする

homebrewからだとうまくいないかつ、前回困ったときも探すのにけっこう時間をかけてしまった気がするのでメモ

# コマンド

```bash
curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version [version]
```

あとはnpmでバージョン指定でも

```bash
npm install -g yarn@[version]
```

# 参考
[Use homebrew-versions to install an old version of yarn #1882](https://github.com/yarnpkg/yarn/issues/1882)
Cross points of circles in Python

```python
def arg(p):
  return np.arctan2(p[1], p[0])

def polar(a, r): 
  return [np.cos(r) * a, np.sin(r) * a]

def getCrossPoints(c1, c1r, c2, c2r):
  d = np.linalg.norm(c1-c2)
  a = np.arccos((c1r * c1r + d * d - c2r * c2r) / (2*c1r*d))
  t = arg(c2 - c1) 
  return [c1 + polar(c1r, t-a), c1 + polar(c1r, t+a)]

a = []
a.append(map(int, raw_input().split()))
for aa in a:
    cx = aa[0]
    cy = aa[1]
    r = aa[2]
    c1 = np.array([cx,cy])
    c1r = r 
a = []
a.append(map(int, raw_input().split()))
for aa in a:
    cx = aa[0]
    cy = aa[1]
    r = aa[2]
    c2 = np.array([cx,cy])
    c2r = r 

# print(c1,c1r,c2,c2r)
gcp = getCrossPoints(c1, c1r, c2, c2r)
# gcp = np.sort(gcp,axis=0)
out = ""
for x in gcp:
    for xx in x:
        if (out):
            out = out + " " 
        out = out + str(xx)
print(out)
```

```
0 0 2
2 0 2
1.0 -1.73205080757 1.0 1.73205080757
```

# Refs.
* [[Python]Numpyデータの並べ替え](https://qiita.com/supersaiakujin/items/c580f2aae90818150b35)
Windows10でnode_modulesをサクッと消す手順

#前置き
Windows10にnode_modulesをダウンロードし消せなくなっている状況で
サクッと消すことができる環境を設定した記録です。
作業手順の中に再起動があります。
もともとWindows Subsystem for Linuxを使用されていた方は
参考記事をご確認の上ubuntuのセッティングをしたほうが良いと思います。

#方法１ウィンドウズで完結（homeエディションは参考記事を参照）
1.Cortana(画面左下のウィンドウズマークの右にある検索窓)に「グループポリシーの編集」を入力して立ち上げます。
２．左メニューからコンピューターの構成 > 管理用テンプレート > システム > ファイルシステムとすすんだら右側のWin32の長いパスを有効にするをダブルクリックします。
３．小ウィンドウが立ち上がったら有効にチェックを入れます。

#方法２windowsアプリのubuntuを使用する
１．Cortana(画面左下のウィンドウズマークの右にある検索窓)に「Windowsの機能の有効化または無効化」と入力します。
２．小さいウィンドウが立ち上がるので『Windows Subsystem for Linux』にチェックを入れます。
　　ここでWindows Subsystem for Linux(Beta)となっていた場合は参考記事を参照してください。３．インストールが実行され終了したら一度再起動する必要があります。
４．Cortanaからmicrosoft storeを立ち上げ検索窓からubuntuを検索、インストールします。
５．ubuntuを立ち上げます。見つからない場合はcortanaに聞いてみましょう。
６．Node_modulesディレクトリに移動します。

```
cd /mnt
ls -la
```

でwindowsPCのドライブが出てくると思います。
そこからnode_modulesディレクトリを探して削除コマンドを実行するとサクッと削除できます。
削除する際は慎重に。

#ubuntuでクリップボードからコピペしたい
ubuntuを起動→タイトルバーで右クリック→プロパティ→簡易編集モードをonにするとできます。

#参考記事
本記事は自分のケースを中心に書いています。
環境が違ったり捕捉情報が必要な方は下記も参考になると思います。

[windows設定でnode_modulesを削除する方法](http://beachside.hatenablog.com/entry/2017/07/25/183000)
[Windows 10でnpmのnode_modulesを削除する方法](https://qiita.com/kusano_k/items/570b6442780538b83a41)
[Windows Subsystem for Linuxインストール](https://qiita.com/Aruneko/items/c79810b0b015bebf30bb)
[Windows Subsystem for Linuxでコピペ](https://qiita.com/onelittlenightmusic/items/8c62b6ff6dd557dcacd3)

#備考
・windowsで削除ができないのはパスの長さが250文字以上をデフォルトで認識しないようになっているから。
・ubuntuに関してはvirtualboxなどをインストールしている環境では影響を受けそうなイメージがしたが
結果影響はなさそう。現時点では。
・macではmacos自体がLinuxベースということで最初からターミナル＋linuxコマンドでOS上のファイルを操作したりできるがWindows Subsystem for Linuxでは似たような感覚でlinuxコマンドが使える。（アプリケーションや組み合わせで動かないこともあるらしい。参考記事参照。）
・ubuntuということでdockerなども相性が良いのでは？（※当方は使ったことないので予測です。）
Uipath 検索ウインドウが反応しない


検索ウインドウにUipathで自動でワードを打ち込んでも、検索が始まりません。

Uipathで使用できないタイプの検索ウインドウが存在するのでしょうか。

今回の事象が発生しているのは、下記のような検索ウインドウに文字を打ち込むと勝手に検索が始まるタイプの検索ウインドウなのですが、それが関係しているのでしょうか。
![スクリーンショット 2018-04-06 16.03.22.png](https://qiita-image-store.s3.amazonaws.com/0/246657/c3026700-0ebc-f524-914c-8af9fcab8ddc.png)
WPFで年月を選択するコントロールを作成

# NengetsuPicker
WPFで年月を選択するコントロールです。
![NengetsuPicker1.PNG](https://qiita-image-store.s3.amazonaws.com/0/136187/04fa520c-b9a3-cb95-33e6-7a7177989060.png)
![NengetsuPicker2.PNG](https://qiita-image-store.s3.amazonaws.com/0/136187/50ba1713-a953-3151-9e4b-53ced0fc2cd6.png)


さらっと見たところ中々良いコントロールがなかったので作ってみました。
ついでに[nuget](https://www.nuget.org/packages/NengetsuPicker)に上げてみたので使ってみてください。

ソースは[GitHub](https://github.com/kyamamoto03/NengetsuPicker.git)に置いておきます。

# 動作
モードは２つ
- シンプルモード：年月のみ表示し、年月クリックで選択ポップアップが開くタイプ
- ノーマルノード：年月の表示の横に選択ボタンがあり、ボタン押下でポップアップが開くタイプ

# 使い方
nugetでダウンロードし

```MainWindow.xaml
<Window
    xmlns:NengetsuPicker="clr-namespace:NengetsuPicker;assembly=NengetsuPicker"
    >
    <StackPanel>
        <GroupBox Header="Simple" Margin="10">
            <StackPanel>
                <TextBox Text="{Binding Nengetsu1}"/>
                <!-- Simpleは年月をクリックでポップアップ -->
                <NengetsuPicker:NengetsuControl 
                    IsSimple="True" 
                    IsEnabled="True" 
                    SelectedItem="{Binding Nengetsu1,Mode=TwoWay}" />
            </StackPanel>
        </GroupBox>

        <GroupBox Header="Normal" Margin="10">
            <StackPanel>
                <TextBox Text="{Binding Nengetsu2}"/>
                <NengetsuPicker:NengetsuControl 
                    IsEnabled="True" 
                    SelectedItem="{Binding Nengetsu2,Mode=TwoWay}"/>
            </StackPanel>
        </GroupBox>
        
    </StackPanel>
</Window>
```
といった感じで記入してください。

GitHubにはコントロールの動作を確認するサンプルが入ってます。
Macから標準出力に録音データを流す方法

チャンネル 1
サンプルレート 16k
10秒録音
ファイル名を指定する箇所に `-p` を指定することで標準出力になる。

```
rec -c 1 -r 16000 -p trim 0 10 > pp.raw
```

標準出力から標準入力に入れて再生する

```
rec -c 1 -r 16000 -p | play -p
```
Bladeテンプレートのyieldはdefaultが使えるよ

LaravelのBladeテンプレートはdefaultが使えます。

```
<title>@yield('title', 'サイトのタイトル')</title>
```

サイトのtitle部分などをこうしておくと便利です。
ドキュメントに載ってなかったので書いておきます。
phalconのチュートリアル学習記録 -Vökuró編-



phalconのチュートリアルを学習してみます。

こちらを元に勉強しました。
phalconチュートリアル-Vokuro編-

macでxamppの上に置いてやっています

#githubからクローンする

ターミナルでhtdocsがあるところまでいってください。そしてクローンします。
僕は、macでxamppの上に置きたいので、このようなコードになります

```
cd /Applications/XAMPP/xamppfiles/htdocs
git clone https://github.com/phalcon/vokuro.git
```

すると、テンプレが出来上がりました。

次にvokuroに移動して、composerをインストールします
そのあとに、composer installをすればいいらしい

```
cd vokuro 
curl -sS -k https://getcomposer.org/installer | php
composer install
```

#チュートリアル通りにするとエラーに・・・解決策見つけた！！

チュートリアルでは、これにアクセスせよと書かれていますが・・・
http://localhost/vokuro


エラーが出ました。

`Warning: Phalcon\Mvc\View\Engine\Volt\Compiler::compileFile`

でも、解決策見つけましたよ。

エラーに、index.php on line 41がどうのこうの書いてましたけど、そんなん関係ない！！！
cacheフォルダにアクセス権がないためにエラーが発生しているらしいです。

解決策はこれ
ターミナルで以下のコマンドを打ってください
chmod -R 777のあとは、cacheまでのパスを書いてくださいね。

```
chmod -R 777 /Applications/XAMPP/xamppfiles/htdocs/vokuro/cache
```

これで、cacheのアクセス権限はクリア！
もう一度見てみると、いけてました！よかった！


#あとはカリキュラム通り

Vökuróは、Swiftという言語を使って、登録ユーザーのサインアップを確認するための電子メールを送信しているそう。
 sends emails to confirm the sign up of registered users using Swift

composer.jsonはこうなるそうです。
実際に見たら、若干違うけど、ほとんど同じ。

```vokuro/composer.json
{
    "require" : {
        "php" : ">=5.5.0",
        "ext-phalcon" : ">=3.0.0",
        "swiftmailer/swiftmailer" : "^5.4",
        "amazonwebservices/aws-sdk-for-php" : "~1.0"
    }
}
```

app / config / loader.phpには、最後に自動読み込み用の設定があるそう。
うん、確かにあった。

```app/config/loader.php
<?php

// ...

// Use composer autoloader to load vendor classes
require_once BASE_PATH . "/vendor/autoload.php";
```

VökuróはINVOとは違って、コントローラとモデルに名前空間を使っているそう。
ちょっと初心者の僕には理解できない・・・どういうことなんだろう、どういう違いがあるんだろう。

```app/config/loader.php
<?php

use Phalcon\Loader;

$loader = new Loader();

$loader->registerNamespaces(
    [
        "Vokuro\\Models"      => $config->application->modelsDir,
        "Vokuro\\Controllers" => $config->application->controllersDir,
        "Vokuro\\Forms"       => $config->application->formsDir,
        "Vokuro"              => $config->application->libraryDir,
    ]
);

$loader->register();

// ...
```

registerDirectories()を使う代わりに、registerNamespaces()を使うらしい
全ての名前空間？はapp / config / config.phpで定義されたディレクトリを指すらしい。
例えば、Vokuro\Controllersはapp/controllersを指すらしい。

でも、config.phpにそんな記述ないぞ・・・？
まあいっか、

```app/config/config.php
<?php

namespace Vokuro\Controllers;

class AboutController extends ControllerBase
{
    // ...
}
```

create an accountをクリックしたら、エラーが出ました。

(未解決ですが一旦終わります・・・)
gitでコミット&プッシュしたのにgithubで見てみるとアイコンでないし、コミットがカウントされていない

# 解決策

.gitconfigの中身のemailになんの値も入っていなかったのでgithubに登録しているメールアドレスと同じものを
git config --global user.email メールアドレス
で登録した！
LARADOCK で LARAVEL を開発しよう（Part 1）

#1. はじめに

この記事でざっとDOCKERでLARAVELの開発環境設定方法について紹介したいと思います。
#2. DOCKERの基本概念

DOCKERについ別の記事で紹介したいと思いっていますが、今回LARADOCKのことがわかりやすいようにDOCKERの基本概念を共有させていただきます。

**IMAGE:**
IMAGEは一つの仮想マシンの設計です。
注意：IMAGEは仮想マシンではなくて、仮装マシンの設計だけです。
わかりやすいように、IMAGEがOOPのCLASSと同じだと思いってもいいです。OOPのCLASSなら、一つのCLASSを作成するため、そのCLASSの関数や変数などを定義しないといけません。DOCKERのIMAGEの場合、同じのロジックで、作成した仮想マシンの中に、なんのOSとかそのOSになにをインストールしたいのかとかを定義しないといけません。
IMAGEの属性が書かれるファイルはDockerfileと呼びます。

Dockerfileの例：

```ruby:Dockerfile
FROM ubuntu:14.04

RUN apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0x5a16e7281be7a449

RUN apt-get update -y \
    && apt-get install -y software-properties-common wget \
    && wget -O - http://dl.hhvm.com/conf/hhvm.gpg.key | sudo apt-key add - \
    && add-apt-repository "deb http://dl.hhvm.com/ubuntu $(lsb_release -sc) main" \
    && apt-get update -y \
    && apt-get install -y hhvm \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

RUN mkdir -p /var/www

ADD server.ini /etc/hhvm/server.ini

RUN usermod -u 1000 www-data

WORKDIR /var/www

CMD ["/usr/bin/hhvm", "-m", "server", "-c", "/etc/hhvm/server.ini"]

EXPOSE 9000
```


上記はHHVMというIMAGEのDockerfileです。詳細を見ると、このIMAGEのOSはubuntu:14.04です。あとそのUBUNTU仮想マシンの上でHHVMをインストールするため、たくさんのコマンドを実行するように定義しました。
最後の行は「EXPOSE 9000」なんですが、意味は何かというと、外からこのHHVMに9000ポートでアクセスできるという意味です。

**CONTAINER**
CONTAINERはIMAGEのインスタンスで、仮想マシンです。
IMAGEはOOPのCLASSと同じなら、CONTAINERはOOPのOBJECTと同じだと連想してもいいです。
複数のCONTAINERの連携を管理するため、DOCKERーCOMPOSEを使います。
#3. LARADOCK

LARADOCKのホームページ：http://laradock.io/
LARADOCKは何かというと、LARAVELの開発やデプロイなどのためのIMAGEのDockerfileのセットです。それらの中に、使いたいIMAGEを決めて、PULLして、実行します。
そういえば、LARADOCKを使わないで、自分で最初から、自分の好きなIMAGEを洗濯して、自分のDockerfileを書いて使ってもいいという人が結構いると思いますが、LARADOCKから自分のカスタマイズができるから、それを使うのがいいでしょう。
LARADOCKの使い方は、LARADOCKのホームページに細かく書いてあるが、パーツ２で少し紹介したいと思いっています。ぜひ参考してください。
https://qiita.com/nguyenngocpfievk56/items/241c415c662b8499d96f


**メリット：**
・DOCKERを使ったら、どんなPCでも、どんなサーバーでも、DOCKER以外、何もインストールしなくて、どんなプロジェクトでも実行できます。そのため、PCやサーバーなどのための不明点がなくなります。
・仮想マシンなので、色々技術を導入して試しても安全で、本番に影響がでるのは心配なしです。
・LARADOCKがちゃんと作られたので、使う可能性があるものが全部入ってると思います。便利だし、使いやすいです。
#4. 結論

これから、新しプロジェクトがあれば、DOCKERを使って開発したいと思いっています。特に、LARAVELのプロジェクトなら、LARADOCKをカスタマイズして使いって見ます。
pythonで関数が呼ばれることをテストする方法


こんなプログラムがあったとして、`print_high_score`の入力値の`score`が80以上の場合に`print_score`が呼ばれる事をテストする方法を紹介します。

```python
def print_score(score):
    print "score is {}".format(score)


def print_high_score(score):
    if score >= 80:
        print_score(score)
```

呼ばれるかテストしたい関数をmock化し、そのmockが呼ばれたかをassertすることで、関数が呼ばれるかどうかのテストを実現することができます。

実際のコードは次の通り

```python
# coding:utf-8
# !/usr/bin/python
import unittest
from mock import patch


def print_score(score):
    print "score is {}".format(score)


def print_high_score(score):
    if score >= 80:
        print_score(score)


class Test_ShowHighScore(unittest.TestCase):
    @patch("__main__.print_score")
    def test_print_high_score_over_80(self, mock):
        print_high_score(80)
        self.assertTrue(mock.called)

    @patch("__main__.print_score")
    def test_print_high_score_less_than_80(self, mock):
        print_high_score(79)
        self.assertFalse(mock.called)


if __name__ == "__main__":
    unittest.main()
```
mysqlへのDDLインポート

コマンドライン上からMySQLへのDDLインポートは

```
mysql -u root -p <db_name> <<ddl_path> 
```

インポートの際に

```
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'TYPE = InnoDB'
```

このエラーはmysqlのバージョンによる記法の違いが原因なので、対応する箇所を「ENGINE=InnoDB」に書き換える
gitでtracked filesのみマスターブランチの内容で上書きする

# やりたいこと
開発中の内容（untracked files）はいったんキープして、
別のブランチに一時的にスイッチしたい
commitしたりstashしたりしてもいいが、tracked filesに微妙な差分が出ているため、
それを含めたくない

# コマンド
```
git ls-files -m | xargs git checkout $1 origin/master
```

ls-filesの-mでmodifiedがとれるらしい。
それをxargsでcheckoutに流してフィニッシュ