OmniAICreator/Qiita-1.07M huggingface dataset:
.Netのformでメモリリーク（解放できないという問題）

#.Netのformでメモリリーク（解放できないという問題）

C# .Netでオリジナルのメッセージボックスを作り、usingで囲んでnew form()をして、showDialogするだけ、という単純なものを使っていたところ、メモリ使用量が増えていく現象が不思議で仕方ありませんでした。
結論からいうと、
>Control クラス（を継承するクラス）は特別で、特別なところから参照されています。
>null（VB なら Nothing）を代入しても解放されません。

ということがMSDNに記載されていました。
回避方法はformオブジェクトの再利用しかないということで、
>何度も表示／非表示を繰り返すなら、new - Show - Close ではなく、
>Visible プロパティを操作することを勧めます。
>また、ShowDialog を使う場合は、new - ShowDialog - Close - Dispose とするのではなく、
>ShowDialog - Close を繰り返します。

>new～Dispose を繰り返すと、リークはしませんが、メモリの確保量は
>（実験されているように）大きくなるので、パフォーマンスに影響が出ると思われます。
>再生ではなく、再利用することを勧めます。
ということで、厳密な名称についてメモリリークではないが、メモリが解放されないので正式な名称こそページ内に出てきませんが、メモリを解放する能力が無いという点でメモリリークと何が違うのかわかりませんが、利用者からは同じ現象に見えます。

[リンク]https://social.msdn.microsoft.com/Forums/ja-JP/9a19f648-a849-4090-a05e-e6ffccdc2adc?forum=csharpgeneralja

再利用ということで、staticでformオブジェクトを確保しておき、利用時の初期化用の関数を用意するしかなさそうでした。
実際、そのようにすると嘘のようにメモリの増加が無くなりました・・・
4/7 js コードレシピ集 学習 classList.toggle

# 要素のクラスの有無を切り替え

要素.classList.toggle(クラス)

引数のクラスがあればそのクラスを削除してfalseを返却し、無ければそのクラスを追加してtrueを返却する

要素.nextElementSibling
要素に隣接する次の要素を取得する

要素.classList
要素内のクラスを配列で取得する
https://syncer.jp/javascript-reference/element/classlist

querySelectorAll(要素)
要素を配列で取得する

## 例、buttonがクリックされたら、content内pタグのテキストを表示する

```js:js
// button要素を配列で取得
// forEachでその配列を変数buttonに代入して繰り返し処理
document.querySelectorAll('.button').forEach((button) =>
{
  // button要素がクリックされたらイベント発火
  button.addEventListener('click', () =>
  {
    // button要素に隣接する次の要素(content要素）に対し、showクラスを追加・削除をする
    button.nextElementSibling.classList.toggle('show');
  });
});
```

```html:html
  <section>
    <button class="button">HTML</button>
    <div class="content">
      <p>Text</p>
    </div>
  </section>

  <section>
    <button class="button">CSS</button>
    <div class="content">
      <p>Style</p>
    </div>
  </section>

  <section>
    <button class="button">Ruby</button>
    <div class="content">
      <p>Object</p>
    </div>
  </section>
```

```css:css
/* buttonを押す前は、content要素はdisplay: noneで非表示 */
.button + .content {
  display: none;
  font-size: 20px;
}

/* buttonを押すとcontent要素にshowクラスが追加され、display: blockでcontent要素を表示する */
.button + .content.show {
  color: red;
  display: block;
}
```

クリック前
<img width="82" alt="スクリーンショット 2019-04-07 9.29.59.png" src="https://qiita-image-store.s3.amazonaws.com/0/287122/0c98370a-8c16-1ee9-93cc-07814c0a279c.png">

クリック後
<img width="98" alt="スクリーンショット 2019-04-07 9.30.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/287122/f00f4feb-ba10-6419-a236-31fd9cbfc41b.png">
VS Codeでエディターとターミナルを行き来するショートカットキーを設定する

# 同じキーでエディターとターミナルを行き来する
VS Codeのデフォルトではエディターにフォーカスを移動するのは command+1 が設定されていますが、ターミナルにフォーカスを移動するショートカットキーは設定されていません。自分の場合これまで、command+0 に割り当てて使っていましたが、指がわちゃわちゃしてイマイチしっくりこないので、どっちにフォーカスがあっても同じキートグルで行き来できるショートカットキーを割り当ててみました。

# keybinding.jsonはどこに？
キーバインドはGUIで設定できますが、ささっと設定できないので、面倒ですよね。
以前はキーバインドの設定から keybinding.json　を開くリンクがあったはずなのですが、今使っているバージョン(1.33.0)だとなぜか表示されなくなっています。と、思ったら右上にある波括弧のボタンを押すと keybinding.json を開くことができました。

![スクリーンショット_2019-04-07_8_54_33.png](https://qiita-image-store.s3.amazonaws.com/0/77444/5295107e-4ea0-b533-db74-f2b48af4c916.png)

# 設定例
設定例を貼っておきます。これでフォーカスがどっちにあっても、いつも決まったショートカットキーで移動できるようになります。


![スクリーンショット 2019-04-07 8.54.55.png](https://qiita-image-store.s3.amazonaws.com/0/77444/b4d26444-96b2-c0d0-498e-bfa9a29a4f5c.png)

```json:Macの例(command+@)
[
    {
        "key": "cmd+[BracketLeft]",
        "command": "workbench.action.terminal.focus",
        "when": "editorTextFocus"
    },
    {
        "key": "cmd+[BracketLeft]",
        "command": "workbench.action.focusFirstEditorGroup",
        "when": "terminalFocus"
    }
]
```

```json:Windowsの例(Windows+@キー)
[
   {
       "key": "win+oem_3",
       "command": "workbench.action.terminal.focus",
       "when": "editorTextFocus"
   },
   {
       "key": "win+oem_3",
       "command": "workbench.action.focusFirstEditorGroup",
       "when": "terminalFocus"
   }
]
```
VS Codeをクラウド上にデプロイ

# 概要
デバイスに依存しない開発環境を構築したく、VS Codeをクラウド上に置く方法を検証した。

# 案1 - Linuxサーバー + X11を使う
## 構成
Dockerコンテナ上にLinuxサーバーを立て、クライアントのMacBook上にはXQuartzを起動しておく。リモートのVS Codeを起動した際はX11経由で画面を転送して、あたかもローカルでVS Codeを操作しているかのように扱う。

## 環境
**ホストOS**

* macOS: 10.14.4
* Docker: 18.09.2

**クライアントOS**

* Ubuntu 18.04.2 LTS

## 手順
### XQuartz起動
XQuartzを起動しておく。

### X11セットアップ
UbuntuのDockerイメージをプルし、起動してX11の設定を行う。

```terminal
$ docker pull ubuntu
$ docker run --rm -it ubuntu /bin/bash
$ apt-get update && apt-get install -y x11-apps
$ export DISPLAY=host.docker.internal:0.0
```

別のターミナルを開き、以下のコマンドを実行する。

```terminal
$ xhost +localhost
```

Dockerコンテナ上にて以下のコマンドを実行する。ホストOS上にウィンドウが立ち上がり、Xロゴが表示されることを確認する。

```terminal
$ xlogo
```

### VS Codeインストール
VS Codeの[docs](https://code.visualstudio.com/docs/setup/linux#_debian-and-ubuntu-based-distributions)を参考に、インストールを行う。

```terminal
$ apt-get install -y curl gpg
$ curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg
$ install -o root -g root -m 644 microsoft.gpg /etc/apt/trusted.gpg.d/
$ sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/vscode stable main" > /etc/apt/sources.list.d/vscode.list'
$ apt-get install -y apt-transport-https
$ apt-get update
$ apt-get install -y code # or code-insiders
$ apt-get install -y libx11-xcb1 libasound2 # 不足しているライブラリ
```

### VS Code起動と動作確認
VS Codeはrootユーザーでは実行できないため、適当なユーザーを作成する。作成したユーザーにスイッチしてVS Codeを起動し、ウィンドウが立ち上がることを確認する。

```terminal
$ useradd -m hoge -s /bin/bash
$ su - hoge
$ code
```

## 所感
この時点ではLinuxサーバーがホストOS上で動作している。リモートで動作させるためにはSSHの設定が必要だが、その前に、この段階で確認したVS Codeの操作感を記す。

* 描画のラグが大きい。
    * 特に大きくスワイプした場合の画面のスクロール量は期待を下回り、ストレスを感じる。
* 基本的なキーボードショートカット(Ctrl+C, Ctrl+Vなど)が使えない。
    * ホストOS上のそれを再現しようとすると余計な手間がかかるだろう。
* フルスクリーン化できない。
    * X11の設定からフルスクリーンを有効化すると、ウィンドウが消えてしまう。

# 案2 - Coderを使う
[Coder](https://coder.com/)はVS CodeのSaaS版のようなツールである。Dockerイメージ、あるいはバイナリファイルをデプロイすることでVS CodeライクなツールがWebブラウザ経由で使えるようになる。

## セットアップ
[公式サイト](https://coder.com/)に記載のDockerコマンドを実行すると、Dockerイメージのダウンロードと起動を行う。特筆することは無く、非常にシンプルである。

## 所感
操作のレスポンスは軽快でストレスを感じない。しかし、オリジナルのVS Codeではないため一部の機能が使えず、特に以下の点に不便さを感じた。

* 一部の拡張機能は検索でヒットしないため、代わりにVSIXファイルのインポートする。さらに、正常に動作させるために一手間が必要。
    * [PlantUML](https://marketplace.visualstudio.com/items?itemName=jebbs.plantuml)
        * レンダリングのためにJAVAが必要なので `docker exec` でコンテナにログイン後、`$ apt-get install default-jre` を実行する。

* 一部の拡張機能が使えない。
    * [Git History](https://marketplace.visualstudio.com/items?itemName=donjayamanne.githistory)が使えないのは痛手だ。

* ~~ターミナルの分割ボタンが機能しない。~~
    * v1.621（あるいは以前）より対応。

# 全体の感想
現時点ではどちらの案もローカル版のVS Codeと同程度の快適さは得られず、実用的ではない。前者は(特に)描画の高速化が可能であれば、より実用的になるだろう。後者はリリースされて間もないツールであるため、今後の改善に期待したい。
[誰か一緒に出ませんか？]Animal AI Olympics in 2019 @ Imperial College London

## URL
http://animalaiolympics.com/

## Timeline
- January - June 2019: Research and Development
- April 2019: 'Playground 1.0' released
- June 2019: Competition full release.
- June 2019 - November 2019: Online submissions open with regular progress updates and leaderboards
- November 2019: (Provisional) Deadline for final submission
- December 2019: (Provisional) Results announced at NeurIPS 2019 (TBC - subject to change)
2020+:
    - Results widely publicised and data made available
    - Testing platform made available to AI researchers to use for benchmarking
    - Results compared with animal data and large-scale analysis made
    - Task specifications made available to AI cognition community
    - Follow-up workshops in animal cognition and AI
    - Planning begins for future iterations of the competition
Macintosh入門」の入門

Macintoshを初めて触った人向けの説明。
普段は特定のアプリを使っていて、その操作方法は分かるが、別のアプリを触ろうとした時に戸惑っている人への説明。
MS Windowsには慣れているが、masOSには慣れていない人への説明。

３種類の説明を適当にまぜて記述予定。

# 電源入 
電源釦を押す。

林檎の印が画面に出て、棒が伸びていき。起動する。

# ソフトの起動
動かしたいソフトが、下に並んでいるものの中にあれば、それを二度押しする。

ならんでいなければ、一番左のFinderを二度押しする。
Finderが開いたらApplicationを選ぶ。

Applicationの一覧の中に見当たらなければ、そこに並んでいるフォルダの下にあるかもしれない。

# ファイルの保存
「command」釦を押しながら「S」釦を押す。

# 文字の複写
文字の範囲を指定して「command」釦を押しながら「C」釦を押す。

# 文字の貼り付け
文字の範囲を指定して「command」釦を押しながら「V」釦を押す。
#文字の切り取り
文字の範囲を指定して「command」釦を押しながら「X」釦を押す。

# ソフトの終了
窓の一番左上の赤い丸にXの印を押す。
メニューの中から、「終了を選ぶ」
画面の一番左上の林檎印を押し、「強制終了」を選び、終了したいソフトを選ぶ

# 参考資料(reference)
macでPATHを通す方法
https://qiita.com/k3ntar0/items/eb8cdbd8eba9da388def

# 文書履歴(document history)
ver. 0.01 初稿　20190407

### 最後までおよみいただきありがとうございました。
いいね　💚、フォローをお願いします。
####  Thank you very much for reading to the last sentence.
Please press the like icon 💚　and follow me for your happy life.
AWS XXXなのかAmazon XXXなのかのルール

AWSのサービスはいろいろありますが、名称が`AWS XXX`もしくは`Amazon XXX`なのか、ときどきわからなくなりませんか？何かルールがあるのかなと思い、調べてみた結果を共有します。

# 結論
Stack Overflowの回答を見つけました。しかも回答した人は、AWSの中の人のようです。それによると以下のルールとのこと。

* **Amazon XXX**
    * スタンドアローンのサービス
* **AWS XXX**
    * ユーティリティのサービス

[Why some services are called “AWS XXX” and the others “Amazon XXX”](https://stackoverflow.com/questions/33125790/why-some-services-are-called-aws-xxx-and-the-others-amazon-xxx)

# もう少し深掘り
上記回答によれば、`AWS XXX`のユーティリティ系は`他のサービスとの連携`があることも特徴らしい。具体例で挙がっていない別サービスを例に挙げてみて、このルールが適用されているか見てみる。

## AWS XXX
**AWS CloudHSM**
AWSでVPCあるのが前提だし、他サービスとの連携必須と考えるとユーティリティでよさそう。

**AWS Snowball**
AWSのデータを取り扱う事になるため、これもユーティリティでよさそう。

**AWS AppSync**
DynamoDBやLambdaと連携ありきなサービス。これもユーティリティでよさそう。


## Amazon XXX
**Amazon EC2**
たしかにスタンドアローンなサービス。他AWSサービスと連携が必須ではない。

**Amazon Cognito**
別に他AWSサービスと連携が必須というわけではなさそうだし、合ってそう。

**Amazon SQS**
確かにスタンドアローンな気がするが、他サービスとの連携有りきな気もするが...。まぁSQSをオンプレ環境からコールするのはユースケースとしてありそう。


## 感想
たしかに、自分が適当に挙げてみたサービスについては、ちゃんとルールに沿っていそうな気がする。
【Test.vim】「src/**/*.test.js」に配置したテストファイルを実行する

## やりたいこと

* `src/**/*.test.js`に配置したテストコードを[Test.vim](https://github.com/janko/vim-test)で実行したい。
デフォルトの設定だと、`tests`ディレクトリ配下のファイルのみがテストファイルとして認識されるため、うまくいかない。
* テストフレームワークはMochaを想定。

## 解決策

vimrcに以下の設定を追加する。

```vimscript
let g:test#javascript#mocha#file_pattern = '\v.*\.test\.js'
```

## 参考

https://github.com/janko/vim-test#file-pattern
Spotifyとfacebookアカウントを切り離す方法

# 概要
音楽ストリーミングサービスのSpotifyを初めて登録するときに皆さんはどの様に登録しましたでしょうか？
下記の画面から思わずfacebookアカウントで登録された方も多いのではないでしょうか。

![Screen Shot 2019-04-04 at 3.50.03 AM.png](https://qiita-image-store.s3.amazonaws.com/0/64211/9a305524-b5b4-73d8-1451-41a004ac76e8.png)

皆さんの中にはfacebookの情報を利用してログインすることに不安を感じている方も少なくないはず。ただでさえfacebookに依存しているのに更に依存することになりますからね。

でも既にfacebookアカウントでSpotifyを登録して使っている方も多いかと思います。
そこでここでは既にfacebookでSpotifyを登録してしまった方がfacebookアカウントとSpotifyを切り離して、メールアドレスとパスワードの管理に戻したいと思っている方々向けにその方法をご紹介出来ればと思います。

# 大まかな流れ
1. Spotify側でメールアドレスとパスワードを登録
2. facebook側でSpotifyに与えているfacebookへのアクセス許可を外す

# 方法
1. 下記の「**Forgot your password?**」からパスワードを作成
![Screen Shot 2019-04-04 at 4.06.02 AM.png](https://qiita-image-store.s3.amazonaws.com/0/64211/8e741642-7a09-8b34-d8d5-436bd0c0979d.png)

2. facebookの**設定**から「**アプリとウェブサイト**」という項目を選択
3. 上記の項目から最初にfacebookでアカウントを作成した方はSpotifyの項目があるはずなのでそれを探す
4. 見つけたら後はfacebookからのSpotifyへのアクセス許可を取り外せば良いだけ
ネコでも分かるSOLID原則(第5回)

お久しぶりです、らべねこです。
私は今「アジャイルソフトウェア開発の奥義」という本を読んでいます。
その中のSOLID原則の部分がよく分からなかったので、私なりにまとめて理解したものをQiitaに投稿しています。
今回は第5回です。
第1回はこちら https://qiita.com/labeneko/items/3033c9a0fa0772a864c2
第2回はこちら https://qiita.com/labeneko/items/92fd93ed1e4a07565869
第3回はこちら https://qiita.com/labeneko/items/6b41d717cd2a6b1d472b
第4回はこちら https://qiita.com/labeneko/items/d7073d50e809cbc51d78
間違い等ありましたらご気軽にコメントください。

# SOLID原則とは

多くの設計で用いられている考え方を原則としてまとめたものです
以下の5つの原則があります

S：SRP、単一責任の原則
O：OCP、オープン・クローズドの原則
L：LSP、リスコフの置換原則
I：ISP、インタフェース分離の原則
D：DIP、依存性逆転の原則
第5回は、依存性逆転の原則についてまとめました

# D：依存性逆転の原則(DIP: The Dependency Inversion Principle)

### 守るべきルール

- 上位のモジュールは、下位のモジュールに依存してはならない。どちらのモジュールも「抽象」に依存すべきである。
- 「抽象」は実装の詳細に依存してはならない。実装の詳細が「抽象」に依存すべきである。

### 上位のモジュールが下位のモジュールに依存しているとは？
例えばデータベースからデータを取ってくるとき、データベースを扱うモジュールを作って、使う側はそのモジュールを呼んでデータを取得するという実装があったとします。
この場合、データベースを扱うモジュールが下位のモジュールで、使う側が上位のモジュールです
例えばデータベースを扱うモジュールに実装の変更があり、その結果、返す結果の形式に変更があるといった場合があったとします。
このとき、呼ぶ側でも実装の変更をしないといけない場合は、それは「依存している」ということになります

## 上位のモジュールが下位のモジュールに依存しないために、「抽象」に依存するとは
データベースから返ってくるデータの形式を、抽象に依存するようにし、呼ぶ側もその抽象に依存するようにすれば、データベースを扱うモジュールに実装の変更があっても、返す結果の形式に変更がないため、呼ぶ側に実装の変更はありません。

##  「抽象」は実装の詳細に依存してはならない。実装の詳細が「抽象」に依存すべきであるとは
しかし、抽象が実装の詳細に依存し、抽象を変更しないといけない場合は、結果的に呼ぶ側の実装も変更しなければならないので問題になるということです。
できるだけ実装の詳細に依存しない抽象であることが大事です。

### 結論
上位のモジュールが下位のモジュールに依存するのではなく、下位のモジュールが上位のモジュールに依存するということかな？と思ったのですが、そうではありません
上位のモジュールが下位のモジュールに依存すると、下位のモジュール変更で上位のモジュールに変更が発生するので、結果的にOCP、オープン・クローズドの原則に違反してしまいます。
しかし、この原則にはデメリットもあります。抽象化は複雑性が増すので、保守が難しくなってしまいます。これはSOLID原則全てに言えることです。


SOLID原則の説明は以上です。
お付き合いいただきありがとうございました。
PythonistaでFTPアップロードする

Pythonistaを使って、iPhone内の写真をFTPでアップロードするスクリプトを作成しました。
https://itunes.apple.com/jp/app/pythonista-3/id1085978097?mt=8

ホスト名とかはconfigparser使ったほうがいいとは思うのだけれど...

```python
import os
import ftplib
import photos
from objc_util import ObjCInstance

# ***************************************************************
HOSTNAME = 'FTPホスト名'
USERNAME = 'FTPユーザ名'
PASSWORD = 'FTPパスワード'
UPLOAD_DIST = 'アップロード先'  # exp: '/var/www/html/wordpress/wp-content/uploads/'
# ***************************************************************


def ftp_upload(filenames):
	ftp = ftplib.FTP(HOSTNAME)
	ftp.set_pasv('true')
	ftp.login(USERNAME, PASSWORD)
	for file in filenames:
		fp = open(file, 'rb')
		ftp.storbinary('STOR ' + UPLOAD_DIST + os.path.basename(file), fp)
		fp.close()
	ftp.close()

def get_photo_filenames():
	p_list = photos.pick_asset(title='写真を選択', multi=True)
	if p_list is not None:
		filenames = []
		for p in p_list:
			file_name = str(ObjCInstance(p).valueForKey_('filename'))
			P=ObjCInstance(p)
			filenames.append(str(P.pathForOriginalFile()))
		return filenames
	
if __name__ == '__main__':
	ftp_upload(get_photo_filenames())
```
Next.jsのプロジェクトにJestとEnzymeを導入する手順

# はじめに

ReactのフレームワークであるNext.jsを使ったBoilerPlateは
[create-next-app](https://github.com/segmentio/create-next-app)で生成可能ですが、テンプレートURLを指定せずに生成したプレーンなBoilerPlateにはテスト用の仕組みが含まれていません。

当記事ではその状態から`Jest`と`Enzyme`を使ってテストを書ける環境を構築した手順を示します。

本記事で実施した内容は下記のリポジトリにpushしてあります。
https://github.com/nemolize/jest-enzyme-to-next

※ なお、本記事を書いた2019-04-07時点で最新リリースとなる `Nuxt.js v7.0.2` をベースに検証しています。`Nuxt.js`のバージョンが異なったり時期が異なる場合は適宜読み替えて下さい。

# 1. Next.jsプロジェクトの生成
サンプルとして`next-example`というプレーンなNextプロジェクトを生成し、それに対しての追加という形で進めていきます。

```console
# プロジェクト生成
$ npx create-next-app next-example
```

# 2. Jestのインストールと設定追加
JSX構文のトランスパイルが必要なので`babel`などもインストールします

```console
$ npm install --save-dev jest babel-jest babel-core babel-preset-env babel-preset-react
```

Jest設定ファイルを生成します

```console
$ jest --init

The following questions will help Jest to create a suitable configuration for your project

✔ Would you like to use Jest when running "test" script in "package.json"? … yes
✔ Choose the test environment that will be used for testing › jsdom (browser-like)
✔ Do you want Jest to add coverage reports? … yes
✔ Automatically clear mock calls and instances between every test? … yes
```

これで最低限Jestでテストを実行できるようにはなりますが、`*.js`を`JSX構文`で解釈させるために設定の追加と修正が必要です

```js:jest.config.js(更新)
module.exports = {
  // (省略)
  transform: { "^.+\\.jsx?$": "babel-jest" } // 拡張子がjs,jsxのファイルをbabel-jestでトランスパイルさせる
  // (省略)
}
```

```js:babel.config.js(追加)
module.exports = {
  presets: ["@babel/preset-env", "@babel/preset-react"]
};
```

# 3. Enzymeのインストールと設定追加
インストール

```console
$ npm install --save-dev enzyme enzyme-adapter-react-16
```

`Enzyme`の利用時は一度だけ`Enzyme.configure()`を呼ぶ必要があるので、下記のようなスクリプトを追加します。

```js:jest.setup.js(追加)
import Enzyme from "enzyme";
import Adapter from "enzyme-adapter-react-16";

Enzyme.configure({ adapter: new Adapter() });
```

`Jest`のテスト前に実行されるようにします。

```js:jest.config.js(更新)
module.exports = {
  // (省略)
  setupFiles: ['./jest.setup.js'],
  // (省略)
}
```

# 4. テストの追加
例として`create-next-app`で生成される`Home`コンポーネントのテストを追加してみます。
`Enzyme`が提供する`shallow()`を使ってコンポーネントを描画すると、外部コンポーネントがモックされるので、コンポーネントの単体テストを簡単に書くことができます。

```jsx:pages/index.spec.js(追加)
import React from "react";
import {shallow} from "enzyme";
import Home from "./index";

describe("Home", () => {
  test("h1タグが描画されること", () => {
    const wrapper = shallow(<Home />);
    expect(wrapper.find("h1").text()).toEqual("Welcome to Next!");
  });
});
```

# 5. テストの実行
```console
$ jest           
 PASS  pages/index.spec.js
  Home
    ✓ h1タグが描画されること (9ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        1.283s
Ran all test suites.
```
RDSインスタンスを削除しかできなくなった件と対処など


## DBインスタンス起動後、ステータスに "Incompatible-Network" と表示される件

### 原因 : 指定サブネットに 利用可能な IPv4 アドレス がない

* 「削除保護の有効無効」を切り替えることと、インスタンスを削除することしかできなくなる
* インスタンスの変更画面にて「削除保護を有効化する」のチェックを外し、インスタンスを削除する
* 利用可能な IPv4 アドレスがあるサブネットを設定し、起動することで解決する

### そもそも

* 起動実行時にエラーなどが出ず、作成中のステータスになってしまうのはどうなのか... システム側で弾けるなら弾いてほしい。。（作成中のステータス後にエラーになる）

### 参考

* https://aws.amazon.com/jp/premiumsupport/knowledge-center/rds-incompatible-network/


## DBのインスタンスタイプを変更後、ステータスに "Incompatible-Parameters" と表示される件

### 原因 : パラメータグループを変更していたことで、インスタンスタイプ変更前後の互換性がなかった為

* （上記と同様に）「削除保護の有効無効」を切り替えることと、インスタンスを削除することしかできなくなる
* 今回は、r5.largeに適用されていたパラメータグループをt3.mediumに適用しており、以下の通り、t3.mediumのメモリで同様のmax_connectionsを確保できなかった為に発生したということが判明

### 参考

* https://aws.amazon.com/jp/premiumsupport/knowledge-center/rds-incompatible-parameters/


## MySQLのmax_connectionsについて
* [Best practices for configuring parameters for Amazon RDS for MySQL](https://aws.amazon.com/jp/blogs/database/best-practices-for-configuring-parameters-for-amazon-rds-for-mysql-part-3-parameters-related-to-security-operational-manageability-and-connectivity-timeout/) にて、以下で計算されるものという記載がある

```
max_connections = DBInstanceClassMemory/12582880
```


## 今後

* Amazon Aurora はシャーディングするコストが低そうなので、また試したい
  * https://aws.amazon.com/jp/blogs/news/reduce-resource-consumption-by-consolidating-your-sharded-system-into-aurora/

* GCP、Azure も試したい
Tomcat(Catalina)のアーキテクチャ全体図

# Catalinaの全体図

Tomcatのサーブレットコンテナ、CatalinaはServer、Service、Engine、Host、Context、Warpperで構成される。それぞれのコンポーネントの親子関係・全体図は下の通り。
図中、重なりがあるコンポーネントは親コンポーネントに対しての多重度を示す。
例えば、Serverは1つ以上のServiceを持ち、Serviceは1つ以上のConnectorと1つのEngineを持つ。

※図中のValueは「Valve」の間違いです！手が空いたときに訂正します！
![全体図.png](https://qiita-image-store.s3.amazonaws.com/0/274106/0899bce2-f886-b3a8-9bd1-5596d074806c.png )

# 各コンポーネントのざっくりした説明
## Server・Serviceコンポーネント
**Server**はTomcatインスタンス自体のコンポーネント。1つ以上のService、Global Naming Resources、Listenerを持つ。Global Naming ResourcesはJNDIを用いてTomcat全体から参照可能。

**Service**は外部からのリクエスト処理を行うコンポーネント。1つのEngineと1つ以上のConnectorを持つ。Connectorがリクエストを受付け、コンテナ(Engine)がリクエストの実行を行う。WebサーバとしてTomcatを実行する際のHTTP、Apache HTTPDのバックエンドとしてのAJPプロトコルに対応したConnectorを持ち、CoyoteAdapterが各プロトコルごとのコネクターとEngineを連結させる。


![Conttectorアーキテクチャ.png](https://qiita-image-store.s3.amazonaws.com/0/274106/f782706d-7272-c56c-33d6-989469258c9f.png)



## コンテナコンポーネント(Engine、Host、Context、Wrapper)
Engine、Host、Context、Wrapperはコンテナコンポーネントと呼ばれ、Servlrtエンジンのコアコンポーネントを構成する。EngineはConnectorから受け取ったリクエストを処理/レスポンスを返す。コンテナを構成するコンポーネント（Engine、Host、Context、Wrapper）の基本的な説明は以下の通り。

- Engine :親サービスが保持するConnectorから受け取ったリクエストを処理/リクエストを返す。
 
- Host   :Engine内の仮想ホストを示す。
 
- Context:仮想ホスト内で実行されるWebアプリケーションを示す。Webアプリケーションと1対1に対応する。

- Wrapper:Webアプリケーション内のServlet1つに対応する。Servletのインスタンスと1対1に対応する。



（書き途中）
[自分メモ]FuelPHPでログイン・ログアウト


ここはそんなに難しいことはなさそう。

## やること

* ログイン
* ログアウト

## ログイン

`Auth::login()`を使えば割と簡単にできた。

* Auth::get_user_id()はarrayが返ってくるのは注意が必要。int/falseで返してほしいなあ。

### View

ユーザー名とパスワードをpostして判定する。emailは必要なさそう。

```
<?php if (Session::get_flash('message')): ?>
<div class="row alert alert-danger">
    <p><?php echo Session::get_flash('message') ?></p>
</div>
<?php endif; ?>

<div class="row" style="padding: 2rem;">
<?php echo Form::open(['action' => 'user/login', 'method' => 'post']); ?>
<div class="form-group">
    <label for="username">ユーザー名</label>
    <?php echo Form::input('username', null, ['id' => 'username', 'class' => 'form-controll']); ?>
</div>
<div class="form-group">
    <label for="password">パスワード</label>
    <?php echo Form::password('password', null, ['id' => 'password', 'class' => 'form-controll']); ?>
</div>
<?php echo form::button('submit', null, ['class' => 'btn btn-primary']); ?>
<?php echo Form::close(); ?>
</div>
```

### Controller

テンプレート設定の処理は冗長だけど今回は大目に見て。。。

```
    public function post_login()
    {
        if (empty($_POST['username']) || empty($_POST['password'])) {
            Session::set_flash('message', '入力は全て必須です');
            $data["subnav"] = array('register'=> 'active' );
            $this->template->title = 'User &raquo; Register';
            $this->template->content = View::forge('user/login', $data);
            return;
        }

        if (! Auth::login($_POST['username'], $_POST['password'])) {
            Session::set_flash('message', 'ログインに失敗しました');
            $data["subnav"] = array('register'=> 'active' );
            $this->template->title = 'User &raquo; Register';
            $this->template->content = View::forge('user/login', $data);
            return;
        }

        Response::redirect('/');
    }
```

## ログアウト

### View

```
<a href="/user/logout">ログアウト</a>
```

### Controller

```

    public function action_logout()
    {
        Auth::logout();
        $data["subnav"] = array('logout'=> 'active' );
        $this->template->title = 'User &raquo; Logout';
        $this->template->content = View::forge('user/logout', $data);
    }
```
テーブルの列同士の計算をレコード関数で

##やりたいこと
テーブル内の特定の複数列に，同じ行の特定の列の値をかけ，その結果は新しい列として持つ，というもの．イメージは下記画像のとおり．
※Power BI勉強会 Power Query 秘密特訓「虎の穴」 #3にて，お話の出た計算方法の再現です．
![キャプチャ.JPG](https://qiita-image-store.s3.amazonaws.com/0/370992/79512eb1-36be-8306-7d37-5d77f873191f.jpeg)




##モデルデータ
なんでもいいんですが，この際，最近のマイブームのList.Generate()を使い，テーブルを作りました．

```クエリ:モデルデータ
let
    ソース = List.Generate(
                ()=>[index=0,a=100,b=200,c=150,rate=1.5],
                each [index]<50,
                each [index=[index]+1,a=[a]+10,b=[b]+11,c=[c]+5,rate=[rate]+0.1]
    ),
    テーブルに変換済み = Table.FromList(ソース, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
    #"展開された Column1" = Table.ExpandRecordColumn(テーブルに変換済み, "Column1", 
                    {"index", "a", "b", "c", "rate"}, {"index", "a", "b", "c", "rate"})
in
    #"展開された Column1"
```


↓できあがるテーブル
![キャプチャ2.JPG](https://qiita-image-store.s3.amazonaws.com/0/370992/1481fe9a-dda7-18d8-ab11-32b1fc4f001e.jpeg)

##各行の計算結果をレコードで持つ列を追加するコード
下記コードでレコード持ちの状態になります．expandはUIでやったほうが列名付ける手間が省けるので，書いてません．

```
let
    ソース = モデルテーブル,
    列追加 = Table.AddColumn(ソース, "A国", 
                        (rec)=>Record.TransformFields(rec,{
                            {"a",each _*rec[rate]},
                            {"b",each _*rec[rate]},
                            {"c",each _*rec[rate]}
                            })
                        )
in
    列追加
```

##別法：列名のリストを渡して一気に計算させてみた
~~対象とする列名のリストを引数にしてやらせることも出来そうですね．
気が向いたら，記事に追加するかもです．~~

↓書き上げました．（追記2019.4.8）
列が多かったり，繰り返しこの計算をする場面が出るとかだと，活躍するかもしれません．
今回は引数が入り混じらないので，普通にeachと_で書きました．（もちろん上のコードと同じく手法も可）


```クエリ:列名リストを渡す版
let
    ソース = モデルテーブル,
    列追加 = Table.AddColumn(ソース, "カスタム", 
                each List.Accumulate({"a","b","c"},
                                        [],
                                        (state,current)=>
                                        Record.AddField(state,current,
                                            Record.Field(_,current)*_[rate]
                                        )
                )
    )
in
    列追加
```

###補足：List.Accumulate関数
- @PowerBIxyzさんの記事（お勧め）
[Power Query の List.Accumulate 関数ってなんだよー](https://qiita.com/PowerBIxyz/items/292c3cfa8a163e7a2ace)

- [公式リファレンス](https://docs.microsoft.com/en-us/powerquery-m/list-accumulate)（簡単な例が載ってます）
n × n+1の整数をテキストファイルから取得する

講義の課題でガウスの消去法を実装した過程で、係数の情報をテキストファイルから取得する必要があった。
いろんな人が使いそうなのでまとめます。
もっと良いやり方が必ずあると思うので、まあ動く、ぐらいのものだと思って見てください。

テキストデータはこんな感じ

```
3 4 2 1
5 4 7 2
2 1 4 8

```
3x_1 + 4x_2 + 2x_3 = 1
・・・・・・・・
みたいなイメージですね

ソースコードです

```c:main.c
//aはm*mの係数情報,bは定数項の情報
double **a,*b;

int main(void){
    int i;
	int countData = 0;
	FILE *fp;
	char fname[50]; // ファイル名の取得
	int c;
	


    // ファイル名の入力・ファイルオープン
	scanf("%s",fname);

	fp = fopen(fname, "r");

	//格納されてない時
	if ((fp = fopen(fname, "r")) == NULL) {
        fprintf(stderr, "%s\n", "error: can't read file.");
        return EXIT_FAILURE;
    }

	// ファイル名が変数fnameに格納されている場合
	//行数カウント
    while((c = fgetc(fp)) != EOF) {
    	if(c == '\n') countData++;
    }

    //fgetc使うとなぜかfscanfをしても0しか入らないので一旦fcloseしてopenし直す、ここは本当にわからなかった
    fclose(fp);

    if ((fp = fopen(fname, "r")) == NULL) {
        fprintf(stderr, "%s\n", "error: can't read file.");
        return EXIT_FAILURE;
    }
    printf("countData = %d\n",countData );

    //動的にメモリを確保
    a = malloc(sizeof(double) * countData);
    for(i=0;i<countData;i++){
		a[i] = malloc(sizeof(double) * countData);
	}
    b = (double *)malloc(sizeof(double) * countData);
    
    // ファイル内のデータを取得する
	for(i=0;i<countData;i++){
		for(n=0;n<=countData;n++){
			if(n<countData) fscanf(fp,"%lf",&a[i][n]);
			else fscanf(fp,"%lf",&b[i]);
		}
	}

	/*fscanfが正しく機能しているか確認
	for ( i = 0; i < countData; i++ ) {
        printf("%.2f, %.2f, %.2f, %.2f\n", a[i][0], a[i][1], a[i][2] b[i]);
    }*/

}

```

fgetcで行数取得してそれをcountDataとして、その分だけメモリを確保してます。
fgetcを使うとfscanfがうまくいかない（全部値が0になった）のは本当に謎でした。謎は解決してません。
応急処置で一旦fcloseしてまたfopenするという、、、

誰かの参考になれば嬉しいです。

それにしてもガウスの消去法実装するの思ったよりもきつかった、、、難しいです。
【Swift】BoolでUserDefaultsに保存した値をIntで読み込むことができた

# 概要
`UserDefaults` に `Bool`として保存した値を `Int` としても読み込むことができたという話です。
よく考えれば当たり前ですが、型に厳しいSwiftでもこういうことができるんだなーと思ったのと、予期しない動作にも繋がってしまいそうだと思ったのでメモしておきます。

# UserDefaults に Bool の値を保存する
まずは `UserDefaults` に `Bool` の値を保存します。

```swift
    // Bool を UserDefaults に保存
    UserDefaults.standard.set(true, forKey: "booleanKey")
    UserDefaults.standard.synchronize()
```

これでデバイスのplist内に値が保存されます。
<img width="430" alt="スクリーンショット 2019-04-07 0.18.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/202306/20b06ed0-e3a1-c3e0-073c-b1a3c81758ea.png">

# Int で読み込んでみる
これを `Int` の変数に入れて表示してみます。

```swift
    // Int の変数に読み込み
    let integer: Int = UserDefaults.standard.integer(forKey: "booleanKey")
    print(integer)
```

この時点でエラーになるかなとも思いましたが、保存した `true` が `1` として出力されました。

# まとめ
そもそもキーを変えずに違う型の値を `UserDefaults` に保存することはないと思いますが、
うっかりやってしまってもクラッシュしないので気付かずにそのまま...というケースもあるかもしれません。

何かの参考になれば幸いです。読んでいただきありがとうございました。
datetimeとjpholidayを組み合わせて、平日か土日祝日かを判定するスクリプト

仕事での反復作業の省力化するための自動化のスクリプトを書いている中で、「平日（営業日）」を判定するために作成したものです。
google検索してもヒットが少なかったので、自分のための備忘録も兼ねて、投稿することにしました。

## 使用するパッケージ
* datetime
* jpholiday

## コード

パッケージのインストール

```python

import datetime
import jpholiday

```
#### 平日か土日祝日かを判定する
指定した日が平日なら1、土日祝日なら0を返す関数は、下記で実装できます。

```python
DATE = "yyyymmdd" # 日付は８桁文字列の形式

def isBizDay(DATE):
    Date = datetime.date(int(DATE[0:4]), int(DATE[4:6]), int(DATE[6:8]))
    if Date.weekday() >= 5 or jpholiday.is_holiday(Date):
        return 0
    else:
        return 1

```
ちなみに、datetimeモジュールのdate.weekdayメソッドを使うと、曜日ごとに指定された数字（０が月曜日、６が日曜日）が取得できます。
私の職場は平日＝出勤日＝営業日なので、date.weekday()が5か6、又は祝日の場合には0を返すという条件にしました。
if文をアレンジするといろんな条件に対応できるので、よければ試してみてください。

---
### 指定した日以降の直近の平日を文字列(yyyymmdd)で返す
今回は、指定日以降の直近の平日を返したかったので、下記の関数を作成しました。

```python
DATE = "yyyymmdd" # 日付は８桁文字列の形式

def returnBizDay(DATE):
    Date = datetime.date(int(DATE[0:4]), int(DATE[4:6]), int(DATE[6:8]))
    while Date.weekday() >= 5 or jpholiday.is_holiday(Date):
        Date = datetime.date(Date.year, Date.month, Date.day + 1)
    return Date.strftime("%Y%m%d")

```
指定日が土日祝日の場合に、Date.day + 1で指定日を翌日に上書きし、指定日が平日になるまでループさせています。


## まとめ
* datetimeパッケージとjpholidayパッケージを組み合わせることで、容易に、祝日も含めた日付の制御ができます。
* jpholidayについては[こちらのリンク](https://github.com/Lalcs/jpholiday)を参照ください。
* python初心者です。もっとよい方法や改善点・ご指摘があれば、ぜひ共有していただけると嬉しいです。
ld: library not foundの解決方法

bundle installでmysql2を入れるときにハマったのでメモ

# TL;DR
```bundle config --local build.mysql2 --with-ldflags=-L/usr/local/opt/openssl/lib --with-cppflags=-I/usr/local/opt/openssl/include```

# エラー内容
```Don't know how to set rpath on your system, if MySQL libraries are not in path mysql2 may not load
...
ld: library not found for -lssl```
要はlinkerがlocal上にあるはずのライブラリを見つけることができなかったらしい

gemはlocal上にあるライブラリに依存しているので、**ライブラリの場所を指定することで対処できる**

# 依存ライブラリ指定の仕方
gcc等の通常のコンパイラであれば以下のようにライブラリを指定することができる
```LDFLAGS="-L/usr/local/opt/openssl/lib" CPPFLAGS="-I/usr/local/opt/openssl/include" PKG_CONFIG_PATH="/usr/local/opt/openssl/lib/pkgconfig"```
しかしbundleコマンドやgemコマンドではこの方法が通用しない

それぞれの指定方法を紹介する

## gem installの場合
gemコマンドの場合以下のようにライブラリを指定することができる
`gem install ジェムの名前 -- --with-環境変数=ライブラリのパス`

今回の場合は
`gem install mysql2 -- --with-ldflags=-L/usr/local/opt/openssl/lib --with-cppflags=-I/usr/local/opt/openssl/include`
でインストールすることができた。

## bundle installの場合
local上にgemをインストールせず、bundle installしたい場合、以下のように特定のgemをインストールする際のライブラリを指定することができる
`bundle config --local build.ジェムの名前 --with-環境変数=ライブラリのパス`

今回の場合は
`bundle config --local build.mysql2 --with-ldflags=-L/usr/local/opt/openssl/lib --with-cppflags=-I/usr/local/opt/openssl/include`
でインストールすることができた

# 参考
https://qiita.com/ts-3156/items/d53915307c77674b50ae
https://stackoverflow.com/questions/23559027/gem-install-with-additional-include-and-lib-paths
https://guides.rubygems.org/command-reference/#extension-install-failures
https://bundler.io/v1.16/bundle_config.html#BUILD-OPTIONS
一つの表から情報を抽出したファイルを作り、要素を一つづつ読み込む (2019/4/8追記)

##背景と目的
特定の数種類のファイルをサーバーからダウンロード、それを実験区の数だけ繰り返すというルーティンワークが業務の一環として存在する職に就いているのだが、どうやらこの業務に従事していたこれまでの担当者はこれらを全て手作業で行っていたようだ。これをある程度まで自動化するのが目的となります。


##作業の概要
ここでは、次世代シークエンサーによる解析後の生ファイル（Fastq）および解析後のファイル(Bam,Bai,Vcf等)の入手を想定しているのだが、ダウンロードするサーバーのディレクトリ構造を見ていると、どうやら単純にサンプル名が必要なだけではなく、サンプル識別用のインデックス配列(バーコードともいう)の情報が必要になるようだ。

1列目にインデックス名、2列目にそのインデックスを用いたサンプル、という形の情報が書かれたテーブルを用意し、個々の情報のみに絞ったファイルを一旦作り分けておいて、そこから個々の情報を読み込むことにする。

概念としては下図のようになる。
なお、サンプルシートはヘッダが存在せず、1行目からサンプル名、インデックス名が始まっているものとする。
![awk-sed.png](https://qiita-image-store.s3.amazonaws.com/0/284045/6889ace3-0ca5-ad84-629d-d6aa4a0614ab.png)


##ファイルの分割
- catとawkでファイルを分割する

```
#!/usr/bin/bash
cat sample_sheet.tsv | awk '{print $1}' > barcode_name.txt
cat sample_sheet.tsv | awk '{print $2}' > sample_name.txt
```
これで、インデックスまたはサンプルの情報のみを持つテキストファイルが出来上がった。

##個々のインデックス名、ファイル名を代入する
 - catとsedで特定の行の情報だけ取得する。

前提条件から、テキストファイルの行数イコールサンプル数となっているため、まずファイルの行数を取得。

```
row=`cat sample_name.txt | wc -l`
echo $row #行数の確認。

##以下、サンプルの数だけ繰り返し作業をする
for i in `seq $row`
do
	echo $i'番目' #何番目の繰り返しかを表示
cat barcode_name.txt | awk 'NR'==$i #何行目を取得するか指定
a=`sed -n $i'p' barcode_name.txt` #aに、指定した行数のインデックスを代入
echo $a #インデックスを表示

#続いて、同じ作業でサンプル名を取得
cat sample_name.txt | awk 'NR'==$i
b=`sed -n $i'p' sample_name.txt`
echo $b #指定した行のサンプル名を表示

. download.sh #別に用意したダウンロード用のコマンドを格納したシェルスクリプトを走らせる
done
##繰り返し
```
という感じで、ダウンロード用スクリプトには若干改善の余地があるものの、このファイル分割とファイル読み込みスクリプト自体はちゃんと動いたというささやかな喜び。

#追記（2019/4/8)
もう少し簡略化できないかと考えていたら、awkを2回連発したら中間ファイルを作成しないでもイケることに気づきました。

```
row=`cat sample_name.txt | wc -l`
echo $row
for i in `seq $row`
do
	echo $i'番目'
a=`cat sample_sheet.tsv | awk '{print $1}' | awk 'NR'==$i`
b=`cat sample_sheet.tsv | awk '{print $2}' | awk 'NR'==$i`
echo "バーコード名は"$a
echo "サンプル名は"$b
(中略)
done
```


###おわりに
本稿の作成にあたり、[sed, awk, grepの使い分け](https://qiita.com/lca367/items/e174ce6985a1e7f3c441)はじめ諸兄のサイト等を参考にさせていただきました。この場を借りてお礼申し上げます。
PHPの再勉強 array_map() 編

こんばんは tyamahori です。
PHPを普段から実装していたのですが、callbackについてよくわかっていなかったので、まとめます。

# array_map()

## サンプル1
なんの変哲もない関数

```sample.php

<?php

function watchAnimation($title)
{
    var_dump($title . 'を見る');
}

watchAnimation('転生したらスライムだった件');
```

結果

```
string(48) "転生したらスライムだった件を見る"
```

## サンプル2
array_map()を使う

```sample2.php

<?php

function watchAnimation($title)
{
    var_dump($title . 'を見る');
}

$animations = [
    'ポプテピピック',
    'ガルパン',
    '盾の勇者の成り上がり',
    'その他異世界転生モノ',
];

array_map('watchAnimation', $animations);
```

結果

```
string(30) "ポプテピピックを見る"
string(21) "ガルパンを見る"
string(39) "盾の勇者の成り上がりを見る"
string(39) "その他異世界転生モノを見る"
```
指定した配列`$animations`の各要素がコールバック関数`watchAnimation`の引数となって、実行されます。

## サンプル3
自己満として、なんかカッコよくする

```sample3.php
<?php

$animations = [
    'ポプテピピック',
    'ガルパン',
    '盾の勇者の成り上がり',
    'その他異世界転生モノ',
];

array_map(function ($anime) {
    var_dump($anime . 'を見る');
}, $animations);
```

結果

```
string(30) "ポプテピピックを見る"
string(21) "ガルパンを見る"
string(39) "盾の勇者の成り上がりを見る"
string(39) "その他異世界転生モノを見る"
```

### 理解の流れをまとめると
1. array_mapが出現する
2. 第一引数に無名関数が設定されているのを確認する
3. 第二引数に配列が定義されているのを確認する
4. 第二引数に定義された配列の各要素が第一引数の無名関数の引数に渡されて処理がされる
5. 第二引数に定義された配列にある要素の分だけ処理が繰り返される
アローダイアグラム

参考サイト:
http://www.pursue.ne.jp/jouhousyo/sysad/sysad015.htm

#最早結合点時刻
##ポイント 最早結合点時刻
>・最も早く作業が開始できる日(時間)
・最早結合点時刻 = 前の最早結合点時刻 + 作業時間

##ポイント 複数の最早結合点時刻が考えられる場合
><font color="red">最も日数の大きいもの</font>を最早結合点時刻にする

![最早結合点.png](https://qiita-image-store.s3.amazonaws.com/0/368574/401dd9e1-97b0-7f3b-077e-fe8b3549f5df.png)

#最遅結合点時刻
##ポイント 最遅結合点時刻
>・少なくともこの日までに作業を開始しなければならない日（時間）のことである。
・最早結合点時刻＝前の最遅結合点時刻－作業時間
・ゴール(右端)の結合点からスタート(左端)の結合点に向かって求める

##ポイント 複数の最遅結合点時刻が考えられる場合
><font color="red">最も日数の小さいもの</font>を最遅結合点時刻にする

![最遅結合点.png](https://qiita-image-store.s3.amazonaws.com/0/368574/a2d05203-6d47-f482-47a6-f00316145d22.png)

#余裕日数
##ポイント 余裕日数
>余裕日数 = 最遅結合点時刻 - 最早結合点時刻

![余裕日数.png](https://qiita-image-store.s3.amazonaws.com/0/368574/449f5111-d13e-7e9b-fc3a-0b9e49e7e5ce.png)



#クリティカルパス
##ポイント クリティカルパス
>余裕日数が0の結合点を結んだ経路

![critical.png](https://qiita-image-store.s3.amazonaws.com/0/368574/567bd1bd-5827-7c3f-3fd4-597d06925753.png)
Python datetime 0埋めしない方法(Windows)

Pythonのdatetimeは自動的に0埋めされます。

例えば、
2019年4月7日→2019/04/07
のように、4と7の前に0が入ります。

右側の書き方(2019/04/07)なら良いですが、
左側の書き方が0埋めされる(2019年04月07日)と不自然ですよね。

そこで0埋めしない方法を紹介します。

Linuxなどなら簡単です。
通常、datetimeの月と日は、%m, %dで書きますよね。
それを%-m, %-d とするだけです。

```date.py
from datetime import datetime

time_now = datetime.now()
date_with_0 = time_now.strftime("%Y/%m/%d")
date_without_0 = time_now.strftime("%Y/%-m/%-d")
print(date_with_0)
print(date_without_0)
```
これで出力は
2019/04/07
2019/4/7
（現在の日付）
となるはずです。

しかし！
Windowsでは使えません。

Windowsでも0埋めなしで出力したい･･･
という場合どうすればいいのか。

月と日を個別に出してlstripで先頭の0を削除します。
力業ですが･･･。
もっといいやり方あれば、是非教えてくださいm(_ _)m

```date_windows.py
from datetime import datetime

time_now = datetime.now()
year = time_now.strftime("%Y")
month = time_now.strftime("%m").lstrip("0")
day = time_now.strftime("%d").lstrip("0")
date_with_0 = time_now.strftime("%Y/%m/%d")
date_without_0 = year + "/" + month + "/" + day
print(date_with_0)
print(date_without_0)
```
出力は
2019/04/07
2019/4/7
（現在の日付）

lstrip("0")は、文字列の先頭が0なら削除します。

ちなみに、記事の上部のように
2019年4月7日
と出力したい場合は、

```date_windows.py
from datetime import datetime

time_now = datetime.now()
year = time_now.strftime("%Y")
month = time_now.strftime("%m").lstrip("0")
day = time_now.strftime("%d").lstrip("0")

date_without_0_jp = year + "年" + month + "月" + day + "日"
print(date_without_0_jp)
```

で実装できます。
Alexaのスキルを作ってみた・Webサーバーの準備

前回からの続き・・・。

Alexaでカスタムスキルを作ってみたので、
技術的なところも踏まえて説明していきたいと思います。
なお、今回はAWSLambdaは使用せず、自前のサーバーでPHPを利用しての開発となります。
（Lambdaでの解説は多くあるので、Lambdaでの開発メインであれば、そちらを参考にしてください）

さて、次に進みたいところではございますが、
その前にユーザーからの発音に対して応答するためのサーバーの準備しましょう！
っていっても、サーバーの準備が面倒と思える方は、潔くAWSlambdaでやるのがいいかと・・・。
あえて、今回は自前サーバーでやります！

## サーバーの要件
まず、以下の要件を満たすサーバーでなくてはいけません。
https://developer.amazon.com/ja/docs/custom-skills/host-a-custom-skill-as-a-web-service.html#requirements-for-web-service

上記を満たすサーバーを用意しましょう。
っていっても、よくわからない方もいるかと思うので、
吾輩のサーバー構築の内容を参照いただければと思います。

## サーバー構築例
私自身、クイズAPIを公開しているので、そのサーバーを利用しております。
以下、サーバーの設定になります。

ホスティング：さくらインターネットVPS
サーバーOS：CentOS
Webサーバー：Apache
プログラム：PHP7
DB：Sqlite
証明書：Let’s Encrypt

上記に加え、ドメインも取得済みです。

さくらのVPSとか、Webサーバーの構築についてはググればいろいろ出てくるかと思います。
エンドポイント側については、本件ではPHPで実装しました。
証明書は無料で利用可能な「Let’s Encrypt」にしました。

上記にて、外部からPHPをたたくことができれば、準備OKかと。

以降、再度Alexa側に戻って設定を継続します。
クリック時の画面出現　オーバーレイ

オーバーレイ？モーダルウィンドウ？と呼ばれるクリックしたら背景が暗くなり、削除ボタンがでる機能を実装してみました！

まずこちらがクリック時に出現するHTMLです！

```modal.html.haml
%aside.modal.is-show.is-animate
  .modal-inner.modal-banner
    .modal-body
      .modal-head.bold
        確認

      削除すると二度と復活できません。<br>削除する代わりに停止することもできます。<br>
      <br>
      本当に削除しますか？

    .clearfix
      .modal-btn.modal-btn-cancel
        キャンセル
      = form_for @item, method: :delete do |f|
        = f.submit '削除する', class: 'modal-btn modal-btn-submit'
```
上記の記述をどこでもいいので表示したいビューに記述します。部分テンプレートにするとわかりやすいかと思います！

次にボタンのデザインです。シンプルな長方形のボタンが出てくるはず、、、

```modal.scss
.modal .is-animate {
  opacity: 1;
  transform: translate(0,0);
}
.modal {
  display: none;
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 3000;
  overflow-x: hidden;
  overflow-y:auto;
  .modal-inner {
    position: relative;
    overflow: hidden;
    width: 600px;
    margin: 20px auto;
    background: #fff;
    text-align: center;
    .modal-body {
      padding: 64px;
      line-height: 1.5;
      .comment-text {
        margin: 16px 0 0;
        padding: 16px;
        background: #eee;
      }
      .info {
        margin-top: 16px;
      }
      .modal-head {
        font-size: 16px;
        font-weight: 600;
      }
    }
    .clearfix {
      @include clearfix;
      .modal-btn-cancel {
        float: left;
        line-height: 63px;
        cursor: pointer;
      }
      .modal-btn {
        border-top: 1px solid #ccc;
        width: 50%;
        text-align: center;
      }
      form {
        .modal-btn-submit {
          float: right;
          border-left: 1px solid #ccc;
          color: #0099e8;
          font-size: 14px;
          line-height: 63px;
          cursor: pointer;
        }
      }
    }
  }
}
```

次に画面を暗くする。CSSです！

```overlay.scss
.is-overlay {
  display: none;
  width: 100%;
  height: 100%;
  position: fixed;
  top: 0;
  left:0;
  z-index: 5;
  background-color: rgba(0,0,0,0.6);
}
```

最後にJSでの実装です！

```modal.js
$(document).on('turbolinks:load', function() {
  $('#delete-item').click(function(e){
    $('body').append('<div class="is-overlay"></div>');
    $('.is-overlay').fadeIn(300);
    $('.is-animate').fadeIn(400);
  });
  $('.modal-btn-cancel').click(function(){
    $('.is-animate').fadeOut(400);
    $('.is-overlay').fadeOut(300);
    $('.is-overlay').remove();
    $('#delete-item').prop('disabled', false);
    $('.modal-btn-cancel').prop('disabled', false);
  });
});
```

3,4行目でoverlay.scssの記述が適用されたdivタグが追加され、画面が暗くなります！

```
$('body').append('<div class="is-overlay"></div>');
$('.is-overlay').fadeIn(300);
```

アウトプット目的であげましたが、
初心者レベルで、無駄の多いこの投稿でも参考になれば幸いです！
リリースしたアプリの GoogleMap が表示されない！


# 前書き

この記事は GoogleMap を表示するアプリ( [東京公共交通オープンデータチャレンジ - サンプルアプリ -](https://play.google.com/store/apps/details?id=com.tokyo_kokyo_kotsu_open_data_challenge_sample_app) )
をリリースするまでの過程の中、実際リリースされた後 GoogleMap が表示されなかった体験とその解決方法を記述したものです。
同じ問題にぶつかっている方、ぜひ参考にしてみてください。

# GoogleMap が表示されない

<img width="500" alt="スクリーンショット 2019-03-31 22.02.34.png" src="https://qiita-image-store.s3.amazonaws.com/0/75978/82fc4591-082c-603c-3711-2d9b9b03cbd5.png">

ワクワクしながらコードを実行してみると、GoogleMap が表示されない… 
こういう経験してないでしょうか？
私は SHA-1 証明書のフィンガープリント問題でこのような経験をしていました。

# debug での GoogleMap 表示
ビルド設定 debug で GoogleMap 表示に失敗している場合は AndroidStudio の Logcat から簡単に表示設定ができます。

<img width="1589" alt="スクリーンショット 2019-04-06 23.46.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/75978/17f1e7e6-d3cd-8f53-a527-cbc52b31c2c8.png">

このようにエラーログを吐き出してくれるので、[Google Developer Console](https://console.developers.google.com) リンクをタップし 
API Key と SHA-1 証明書のフィンガープリントを設定するようにします。
API Key は、タップした Google Developer Console にて作れます。
SHA-1 証明書のフィンガープリントは、Logcat に出力されている FE:68(省略):46:83 までが SHA-1 証明書のフィンガープリントになりますので、コピーして APIキーで保存してください。
設定を保存してから 5分以内で GoogleMap は無事表示されます！

（プロジェクトと API Key の設定方法がよくわからない方は [GoogleMap を表示するアプリを 0から作ってみよう！](https://qiita.com/leebon93/items/d726392f0baafa907879) を参考してください）

# release での GoogleMap 表示

debug で GoogleMap の表示を確認してからリリースしたけど、ストアでインストールしたアプリの GoogleMap が表示されない！！
という問題が自分にはありましたが、これも同じく SHA-1 証明書のフィンガープリントの問題でした…
release は debug とはまた違う APIキーと SHA-1 証明書のフィンガープリントを設定しないといけません。

debug でやったように、今回は release 用の APIキーを作り、そのキーを `app/src/release/res/values/google_maps_api.xml` に入れてあげます。

<img width="265" alt="スクリーンショット 2019-04-07 0.27.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/75978/b9725de2-b4e6-8de0-f74d-bfb1e701d292.png">

そして release 用の APIキーで使う SHA-1 証明書のフィンガープリントは Logcat では確認できず、リリースしたアプリの [Google Store Console](https://developer.android.com/distribute/console?hl=ja) から確認できました。

<img width="600" alt="スクリーンショット 2019-04-07 0.34.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/75978/41ad92cf-0bd4-dbba-56b4-53f70009c55c.png">

ここで SHA-1 証明書のフィンガープリントをコピーし、release 用の APIキーに保存してあげるとちゃんとリリースしたアプリにも GoogleMap が表示されるようになりました。

<img width="600" src="https://qiita-image-store.s3.amazonaws.com/0/75978/05f55744-2dbd-fe8f-51f2-e54bb93a77ae.png">

めでたいめでたい :tada::tada:

# 関連リンク
初めて GoogleMap のアプリを作る方は必読！ [GoogleMap を表示するアプリを 0から作ってみよう！](https://qiita.com/leebon93/items/d726392f0baafa907879)
ShellScriptでプログラムの実行時間測定

# はじめに
プログラムをいじらずに時間測定する方法

# 実行時間測定

```script.sh
#!/bin/bash

start=`date +%s`

# 実行するプログラム
./program

end=`date +%s`

time=$((end - start))
echo $time
```
ShellScriptでディレクトリ内の全てのファイルに対してプログラムを実行

実行プログラム`program`の実行形式は`./program 入力ファイル 出力ファイル`とします。
プログラムの入力ファイルは`input/`ディレクトリから読み込み、出力ファイルは`output/`ディレクトリ、標準出力と標準エラーのログは`log/`ディレクトリに出力します。

```script.sh
#!/bin/bash

program="program"
in_dir="input/"
out_dir="output/"
log_dir="log/"

while read -d $'\0' file; do
	f=`echo ${file} | awk -F "/" '{ print $NF }'`
	nohup ./${program} ${in_dir}${f} ${out_dir}${f}.out > ${log_dir}${f}.log 2>&1
done < <(find ${in_dir} -mindepth 1 -maxdepth 1 -print0)
```

スクリプトファイルを実行するときは`&`をつけてバックグラウンドで実行すると良いでしょう。

```bash
$ ./script.sh &
```
Railsチュートリアル　第3章


#学習内容
[Railsチュートリアル](https://railstutorial.jp/)　　2周目
◯Progate
html,css,git,sql,Ruby,Ruby on rails
だいたい２周ずつ

◯Railsチュートリアル1-8章
流し読み
RailsチュートリアルでインプットしつつQiitaでアウトプット←ここ


# 環境
pc:MacBook Air
IDE:AWSCloud9
Rilsバージョン：5.1.6
Rubyバージョン：2.6.0

#第3章
<img width="335" alt="スクリーンショット 2019-04-05 22.07.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/390288/07c6bf38-fc47-0ce1-417a-0688e02d35cb.png">
ここの部分、R,C,Vの静的な部分

#branchについて
branchこれまでmaster権限でcommitしてきた、
branch→commit、branch→commit、branch→commit、branch→commit、……
しかし、masterは確実なものにしておくべき。
master　↘︎　　　　　　　　　　　　　　　master ……
　　　　　　branch　→　branch …… ↗︎

masterはセーブポイント！
branchで失敗したら、master(セーブポイントに戻れば良い).

```$ git branch```今いるbranchを表示
```$ git check -b```ブランチを作成

#コントローラの作成
```$ rails generate controller StaticPages home help```
StaticPages:コントローラ名←**コントローラは複数形、モデルは単数形**
home,help:アクションとビューの生成

#テスト駆動開発
Red→Green→Refactoring　　の順で行う
railsといえばテスト!!

```rails generate…```テストファイルが勝手に作られる

##デプロイできない(^_^;)
開発環境ではうまくいっていたが、```heroku create```で生成されたURLにリンクしてもエラー。
[このページ](https://qiita.com/NaokiIshimura/items/eee473675d624a17310f)を参考に最初からやり直してみるとうまくいった。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/390288/bde492a9-0cf8-471e-0e0f-4907426b577a.png)

あと関係あるかわからないがブランチをstatic-pagesでやっていたがmasterに戻した。
##３章後半
TDDのrefactorの部分
static_pages_controller_test.rbにテストを追加。

```ruby:static_pages_controller_test.rb
require 'test_helper'

class StaticPagesControllerTest < ActionDispatch::IntegrationTest

  test "should get home" do
    get static_pages_home_url
    assert_response :success
    assert_select "title", "Home | Ruby on Rails Tutorial Sample App"
  end

  test "should get help" do
    get static_pages_help_url
    assert_response :success
    assert_select "title", "Help | Ruby on Rails Tutorial Sample App"
  end

  test "should get about" do
    get static_pages_about_url
    assert_response :success
    assert_select "title", "About | Ruby on Rails Tutorial Sample App"
  end
end
```
テストを実行
```$ rails 
test 3 tests, 6 assertions, 3 failures, 0 errors, 0 skips```

（流れ）
３つのテストを実行した3/6が失敗している
↓
controllerにaboutがない、viewがない、ルートがない
↓
上記のものを作る
↓
テスト成功

最初にあるべきテストを書いてあえて失敗させる(Red)
その後ファイルをいじりながら失敗を少なくしていく(Green)
その後Refactoring

#TDDのRefactoringの話
タイトルの部分を動的にする
ex. Home | Ruby on Rails tutrial.....
↑
答えがわかっている=テストが書ける！

refactor→コードをGreenのままを保ちながら綺麗にコードを書いていく(冗長性:DRY)

#埋め込みRuby(.erb)
```<% provide(:test, 変数) %>```
```<%= yield(:test) %>```
CODE COMPLETE (上) -第1部 基礎を固める ①-

自分の理解を深めるために投稿します。
## 第1章：ソフトウェアコンストラクションへようこそ
### ソフトウェアコンストラクションとは
ソフトウェア開発のためのアクティビティはたくさんある！
コンストラクションに関わるものを上から並べると、

- **コーディングとデバッグ**(これがコンストラクションのほとんど)
- 詳細設計
- コンストラクション計画
- 単体テスト
- 統合
- 統合テスト

(以降はコンストラクション以外の重要なアクティビティ)

- ソフトウェアアーキテクチャ
- システムテスト
- 要求開発
- 保守
- 課題定義

詳細なアクティビティはこの後の章で説明していく

コンストラクションは**決して機械的ではなく、優れた想像力と判断力を必要とする**
「**コンストラクション = プログラミング**」という一般的な言葉の意味合いで捉えるといいかもしれない


### なぜソフトウェアコンストラクションは重要か
以下がその理由である

- (時間的に)**ソフトウェア開発の大部分**を占める 
- ソフトウェア開発の**中心的なアクティビティ**である
  - 他のプロセスはコンストラクションの準備や確認のために存在するイメージ(要求仕様書やシステムテストなど)
- コンストラクションに集中することで、**個々のプログラマの生産性は驚くほど向上**する
  - コンストラクションにおける生産性には10~20倍の開きがある！
  - 優れたプログラマが取り入れているテクニックを取り入れれば、生産性の向上につながる(この本の目指すところ)
- 成果物であるソースコードは、ソフトウェアを正確に書き表した唯一のドキュメントである
- **必ず実行される唯一のアクティビティ**である

### まとめ
- コンストラクションの品質は、ソフトウェアの品質を大きく左右する
- **コンストラクションの方法をどれだけ理解しているか**が、どれだけ優秀なプログラマであるかを決める(これがこの本のテーマ)
プログラミングの学習コストは20万以上かかるのか考えてみた

![image.png](https://qiita-image-store.s3.amazonaws.com/0/137987/19482628-2362-d292-2c21-5f8a1d417fc5.png)

こちらのツイートでプログラムの勉強をすると20万かかると言う意見を見たので自分なりに考えてみました
かかるわけ無いだろうという意見が多いことからも分かる通りネタ記事ですｗ


#前提
・プログラミング経験はない人が対象とします
・到達目標としては実務未経験可だけどプログラミングなどある程度できないと入社できない企業に入社するところを目標とします

ちなみに私は中学くらいにはプログラミングを齧っていたし、ITスキルを売り込んで今の会社に入社したわけではないので
「今考えるとこうなるかな？」
という想像になります

#準備
今はスマホで十分！PCは持っていないという人が多いのでPCを購入します
スマホやタブレットでもプログラミングはできますがPCを買います

よくエンジニアは20万以上するPCを持っていますが、そんなものは必要ないと思います
ここで学習コスト全額使い切るわけには行きません／(^o^)＼

![image.png](https://qiita-image-store.s3.amazonaws.com/0/137987/1d8b212c-abcf-c102-e615-5272949d4d31.png)

とりあえずこの記事を書いてる時点の価格コムの売れ筋ランキング上位くらいのPC
多めに見積もって10万前後のPCなら困らないと思います。

インターネットは今どきスマホでテザリングできるだろうって思ったりしますがポケットWifiを契約するとして1万円程度予算を取ります

**使用金額合計：11万円**

#基礎を学ぶ
インターネット上の動画サービスを使うのがいいと思います

最初は本を使って勉強するのはあまりおすすめできません
何もわからない状態から本で学習しようと思うと挫折します
わからないことがあった場合、素通りするか挫折すると思います
あと眠くなります

progateの利用が980円だったと思います
youtubeにもそういう動画があったりします
有料ですがudemyとかもいいかもしれません

progateが終わったら「～入門」的な本を本屋で買います
おそらく3000円程度で買えると思います

それと合わせてドットインストールで環境構築に必要な動画を視聴します
ドットインストールに課金する必要はないと思いますが、しても980円です

使う言語の選定はネットでしましょう
PHPがいいとかRubyが言ってる人がいると思います

スクールに入るという選択肢はあまりおすすめしません
~~理由はスクールの受講代で20万掛かりそうだからです~~
会社の金で行きましたが大したこと教えてくれませんでした

**使用金額合計：11万5千円**

#実践編
企業に見てもらうための成果物（ポートフォリオ）作ります

まずPCにプログラミングを出来る環境を作ります
次に開発環境を作るためにサーバーを立てたり、DBをインストールしたりします

ココらへんの知識はドットインストールとかにありますね
Qiitaで関係記事をあさってもいいかもしれませんが、動画を繰り返し見たほうが連続性があるのでわかりやすいかと思います

ソース管理するのにgitとかも必要かもしれません

全部無料なので0円です！
企業に見てもらうものを作るということでいくつか本を読んでおくといいと思います

思いつく限りだと
・リーダブルコードや達人プログラマーのようなコーディングテクニックに関する本
・DBに関する本（DB設計・SQL・選んだOOSDBなど）
・WEBやネットワークに関する本（これらは成果物には現れにくいので優先度は低めだが面接で聞かれるかもしれないので理解しておくといいと思う）

だいたい2万円分くらい読めば十分だと思います

あとはなにかWEBシステムを作って終わりかなと思います
レンタルサーバーとはいるかな・・・
借りても数百円とかだったと思います

ネタでPCを買うところからはじめましたが、それでも13万5千円ですかね・・・
本とか有料サービスをもっと利用しても**15万以下**に収まると思います

PCがあれば5万円くらいの投資でどうにかなると思います

#結論
20万も使わなくてもプログラミング学習は十分なレベルで出来る！

#過去に書いた似たような記事
[私がプログラミングの勉強をするときの手順とか使うサービスとか](https://qiita.com/nanaki11/items/c1f339df959667cdad4e)
[経験者と未経験者のプログラミング学習方法の違い](https://qiita.com/nanaki11/items/e92a0559f870bf9adb6a)
Rancher + k3s 環境での firewalld 設定 Centos7

#はじめに
OS は、CentOS7 の環境です。
VPSの環境なので、firewallの設定は、疎かにできないので、試行錯誤してみました。
シングルノードなので、複数ノードの場合は、もう少しポートを開ける必要があると思います。

##firewall の設定
デフォルトを trusted に設定して、外部接続のネットワークインターフェイスをpublicに設定するのがコツのようです。

```
# firewall-cmd --set-default-zone=trusted
success
# firewall-cmd --zone=public --change-interface=eth0 --permanent
The interface is under control of NetworkManager, setting zone to 'public'.
```
## Rancher へのアクセスのために
Rancherへのアクセスを544,5080に設定しているので、

```
# firewall-cmd --add-port=5443/tcp --zone=public --permanent
# firewall-cmd --add-port=5080/tcp --zone=public --permanent
```
##firewall の確認
```
# firewall-cmd --get-active-zones
public
  interfaces: etch0
# firewall-cmd --list-all --zone=public
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: eth0
  sources:
  services: ssh dhcpv6-client http https
  ports: 5443/tcp 5080/tcp
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:
# firewall-cmd --list-all
trusted (active)
  target: ACCEPT
  icmp-block-inversion: no
  interfaces: 
  sources:
  services:
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:
```