OmniAICreator/Qiita-1.07M huggingface dataset:
mergeとrebaseの違い


[未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)でインターンをしている[りく](https://qiita.com/rikukaikuu)です。

gitとやらが共同開発するのには必要だそうなので、gitのmergeとrebaseの定義をしてみました。
#mergeとrebaseの比較
##merge
-非破壊的操作である。
-既存のブランチは変更されない

**メリット**
- 非破壊的なので、情報が消えることはない
**デメリット**
- 頻繁にブランチしたりMasterが動いたりする場合だと、コミットグラフが乱雑する
- 他の開発者が履歴を閲覧しにくい

##rebase
コミットグラフは一直線にきれいになるが、消える情報がある
**メリット**
- コミットのグラフがきれいになる、不要なmergeコミットが除去される
- GitHubなどのオープンソースプロジェクトにプルリクエストを送る場合はrebaseして送るのが基本(マナー)
**デメリット**
- pushされたブランチをrebaseするとpushできなくなる
- 「マージした」事実がなくなる(情報が消える)
- mergeと比較するとコンフリクト(エラー)解消が面倒
- 中身は同じだが、別物として作成される



#コンフリクトした場合の違い
##mergeの場合
```
Auto-merging ???
CONFLICT (content): Merge conflict in ???
Automatic merge failed; fix conflicts and then commit the result.
```
が表示されたら　git mergeの処理は一時停止される(mergeの中断状態)
競合した相手と相談しようね。
修正する側は、
`git status`
で情報を確認する
するとコンフリクト(エラー)の箇所が分かる
**Unmerged path**にコンフリクトしたファイルが列挙される
コンフリクトしているファイルが分かれば直接修正する
インデックスにはマージ前のファイル状態が記録されているので、
`git add ???`
後は、commitすればマージコミットが作成された。

ちなみに、`git merge --abort`でgit mergeを取り消して中止できる
新たにマージコミットをコミットするか上のことをしないと他のGit操作できないからね。

##rebaseの場合
`git rebase master`
をしたらコンフリクト発生してもうたら、
`git diff`でコンフリクトしている部分を確認。
確認後、コンフリクトを修正したら`git add .`して、
`git rebase --continue`
んで、rebase成功。

#まとめ
gitは共同開発以外にも、以前まで使用していたデータを保存できるのも強みだと思うので、これからが楽しみです。
SwiftUIについて、ざっと

# この記事は何？
WWDC2019で発表されたSwiftUIについて、いつか自分が勉強するときのために2019.6.5時点の情報をざっとまとめました。

# SwiftUIは...
あらゆるAppleデバイス用のユーザーインターフェースを構築する方法
Xcode11に搭載される新機能
macOS10.15 Catalina 以降で使用可能
革新的で非常にシンプル
Swiftで動作するツールとAPIのセット

# キーワードから探るSwiftUI
### Better apps. Less code.
__少ないコードで、良いアプリを__
読みやすくて自然に書くことができる宣言型のSwift構文
Xcode11のデザインツールとシームレスに連携
コードとデザインを完全に同期
ダイナミックタイプ、ダークモード、ローカライズ、およびアクセシビリティの自動サポート

### Declarative Syntax
__宣言的な構文__
「宣言的」とは、制約や定義、性質を記述することらしい...。
ユーザーインターフェイスの動作をシンプルに表現できる。 
たとえば...

1. テキストフィールド項目のリストが欲しいと書いて、
2. 各フィールドの配置、フォント、色などを記述する

これまで以上にシンプルで読みやすいコードによって、時間とメンテナンスを節約する。

````swift:SwiftUIのコード例
import SwiftUI

struct Content: View {

    @State var model = Themes.listModel

    var body: some View {
        List(model.items, action: model.selectItem) { item in
            Image(item.image)
            VStack(alignment: .leading) {
                Text(item.title)
                Text(item.subtitle)
                    .color(.gray)
            }
        }
    }
}
````

宣言スタイルは、アニメーションのような複雑な概念にも適用される。
アニメーションをほぼすべてのコントロールに簡単に追加し、数行のコードですぐに使えるエフェクトのコレクションを選択できる。 
実行時に、システムはスムーズに動作させるために必要なすべてのステップを処理し、アプリを安定させるために中断を処理する。

### Design Tools
Xcode11に含まれる新しいデザインツール。
SwiftUIを使用して、インターフェイスをドラッグアンドドロップで簡単に作成できる。
デザインキャンバスで作業しているときは、編集したすべてのものが隣接するエディタのコードと完全に同期する。 
コードを入力すると、その結果がプレビューとして即座に反映される。
プレビューに加えた変更は、コードにすぐに反映される。 
Xcodeは変更を即座に再コンパイルして、実行中のバージョンのアプリに挿入する。
いつでも表示と編集ができる。

- Drag and drop
キャンバス上のコントロールをドラッグして、コンポーネントを配置できる。 
クリックしてインスペクタが開き、フォント、色、配置、その他のデザインオプションを選択できる。
カーソルを使ってコントロールを簡単に並べ替えられる。
ほとんどのビジュアルエディタはコードエディタ内でも使用できる。
インターフェイスの一部を手動でコーディングしたい場合、インスペクタを使用して各コントロールの新しい修飾子を見つけられる。 
ライブラリからコントロールをドラッグして、デザインキャンバスまたは直接コードにドロップすることもできる。

- Dynamic replacement
編集したコードとライブアプリを直接、置き換えるSwiftの新機能。
SwiftコンパイラとランタイムはXcodeに完全に組み込まれている。
アプリは常に構築され実行される。 
デザインキャンバスは、アプリ実物を描画する。

- Previews
SwiftUIビューのプレビューをいくつも作成できる。
サンプルのデータを表示できる。
フォント、ローカライズ、ダークモードなど、表示しうるほぼすべてを設定できる。 
任意のデバイスと任意の向きでUIを表示できる。

### Native All Apple Platforms
数十年に及ぶ世界で最も革新的で直感的なUI開発の経験に基づいて構築された。 
SwiftUIは完全にネイティブ。
わずかなコードと対話的なデザインキャンバスで、各プラットフォームのテクノロジに直接アクセスする。

# 公開されているチュートリアル
一歩ずつ学べるガイダンスと詳細なリファレンス

[SwiftUI Tutorials](https://developer.apple.com/tutorials/swiftui/)
[SwiftUI Reference](https://developer.apple.com/documentation/swiftui/)
Ansibleでtd-agentをインストール

公式ドキュメントに書かれている手順をやるだけのAnsible Playbook。

# 環境

- Amazon Linux 2

URLを公式ドキュメントに沿って変更すれば他のディストリビューションでも可能？

# Playbook

```yaml:td-agent/tasks/main.yml
- name: setup ulimit
  pam_limits:
    domain: "{{ item.domain }}"
    limit_type: "{{ item.limit_type }}"
    limit_item: nofile
    value: 655360
  with_items:
    - domain: root
      limit_type: soft
    - domain: root
      limit_type: hard
    - domain: "*"
      limit_type: soft
    - domain: "*"
      limit_type: hard
  become: yes

- name: setup sysctl
  sysctl:
    name: "{{ item.name }}"
    value: "{{ item.value }}"
    state: present
    ignoreerrors: yes
  with_items:
    - name: net.core.somaxconn
      value: 1024
    - name: net.core.netdev_max_backlog
      value: 5000
    - name: net.core.rmem_max
      value: 16777216
    - name: net.core.wmem_max
      value: 16777216
    - name: net.ipv4.tcp_wmem
      value: 4096 12582912 16777216
    - name: net.ipv4.tcp_rmem
      value: 4096 12582912 16777216
    - name: net.ipv4.tcp_max_syn_backlog
      value: 8096
    - name: net.ipv4.tcp_slow_start_after_idle
      value: 0
    - name: net.ipv4.tcp_tw_reuse
      value: 1
    - name: net.ipv4.ip_local_port_range
      value: 10240 65535
  become: yes

- name: install td-agent
  command: curl -L https://toolbelt.treasuredata.com/sh/install-amazon2-td-agent3.sh | sh
  become: yes
```

# 参考

- [Before Installation - Fluentd](https://docs.fluentd.org/installation/before-install)
- [Install by RPM Package (Redhat Linux) - Fluentd](https://docs.fluentd.org/installation/install-by-rpm)
[TreasureData]tdコマンド実行でTreasureData::AuthErrorエラーになる場合の対処

# TreasureData::AuthError について
tdコマンド実行で`TreasureData::AuthError`がでる場合はエンドポイントの設定が漏れていることが多い。

```
$ td db:list
Error: TreasureData::AuthError - List databases failed: Failed to Login
```

# TreasureData tdコマンド実行するには
## 公式サイトからダウンロード＆インストール
https://toolbelt.treasuredata.com/

公式サイトからダウンロードし、インストールする。

インストール完了したら、 `td --version` でインストールの確認を行う。

```
$ td --version
0.16.4
```

## エンドポイントの設定する
契約しているのが本家 (treasuredata.com) 以外の場合
デフォルトのエンドポイントのままでは接続できないため、以下のコマンドからエンドポイントを設定する。
 (今回は treasuredata.co.jp の場合)

```
$ td server:endpoint https://api.treasuredata.co.jp/
```

設定しない場合 毎回tdコマンドに `-e https://api.treasuredata.co.jp/` が必要となる。
ただし、クライアントサイドのコマンドにしか有効ではなくサーバサイドのコマンドの場合は
上記を設定しても 毎回tdコマンドに `-e https://api.treasuredata.co.jp/` が必要となる。
なんとかならないものか。。。

## アカウント情報の設定

```
$ td account
```

一度作成した場合はエラーがでるので `-f` オプションを付けて実行

```
$ td account
Account is already configured with 'xxxx@xxxx.com' account.
Add '-f' option to overwrite.
```


```
$ td account -f
Enter your Treasure Data credentials.
Email: [ログイン用メールアドレスを入力]
Password (typing will be hidden): [ログイン用パスワードを入力]
Authenticated successfully.
Use 'td db:create <db_name>' to create a database.
```

`td db:list`コマンドでdb一覧が取得できれば接続完了

```
$ td db:list
+----------------------+----------+
| Name                 | Count    |
+----------------------+----------+
| sample_datasets      | 0        |
| information_schema   | 0        |
+----------------------+----------+
2 rows in set
```

設定が完了されると以下にファイルが保存されている。
`endpoint`を消すと`TreasureData::AuthError`が発生するようになる。

```
$ cat ~/.td/td.conf
[account]
  endpoint = https://api.treasuredata.co.jp/
  user = xxxx@xxxx.com
  apikey = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```
ABC - 012- A&B&C

#AtCoder ABC 012 A&B&C
[AtCoder - 012](https://atcoder.jp/contests/abc012)

#A - スワップ

```java
	private void solveA() {
		int a = nextInt();
		int b = nextInt();

		out.println(b + " " + a);
	}
```

#B - 入浴時間

```java
	private void solveB() {
		int n = nextInt();
		int h = n / 3600;
		n %= 3600;
		int m = n / 60;
		n %= 60;
		int s = n;
		System.out.printf("%02d:%02d:%02d", h, m, s);
	}
```

#C - 九九足し算

 - $1 \times 1 から 9 \times 9 $の合計は2025

```java
	private void solveC() {
		int n = 2025 - nextInt();

		for (int i = 1; i <= 9; i++) {
			for (int j = 1; j <= 9; j++) {
				if (i * j == n) {
					out.println(i + " x " + j);
				}
			}
		}
	}
```
ABC - 011- A&B&C

#AtCoder ABC 011 A&B&C
[AtCoder - 011](https://atcoder.jp/contests/abc011)

#A - 来月は何月？

 - 12月だったら次は1月
 - 1月-11月だったら次は+1月

```java
	private void solveA() {
		int n = nextInt();

		out.println(n == 12 ? 1 : n + 1);
	}
```

#B - 名前の確認

```java
	private void solveB() {
		char[] n = next().toCharArray();
		for (int i = 0; i < n.length; i++) {
			if (i == 0) {
				n[i] = Character.toUpperCase(n[i]);
			} else {
				n[i] = Character.toLowerCase(n[i]);
			}

		}

		out.println(new String(n));
	}

```

#C - 123引き算

###再帰

```java
	private void solveC2() {
		int n = nextInt();
		int ng1 = nextInt();
		int ng2 = nextInt();
		int ng3 = nextInt();

		Map<String, Boolean> memo = new HashMap<String, Boolean>();
		boolean res = recursiveC2(ng1, ng2, ng3, 0, n, memo);
		out.println(res ? "YES" : "NO");
	}

	private boolean recursiveC2(int ng1, int ng2, int ng3, int currentI, int currentNum, Map<String, Boolean> memo) {
		if (currentNum == ng1 || currentNum == ng2 || currentNum == ng3) {
			return false;
		}
		if (currentNum == 0) {
			return true;
		}
		if (currentI == 100) {
			return false;
		}
		if (memo.containsKey(currentI + ":" + currentNum)) {
			return memo.get(currentI + ":" + currentNum);
		}
		boolean res = false;
		res = res || recursiveC2(ng1, ng2, ng3, currentI + 1, currentNum - 1, memo);
		res = res || recursiveC2(ng1, ng2, ng3, currentI + 1, currentNum - 2, memo);
		res = res || recursiveC2(ng1, ng2, ng3, currentI + 1, currentNum - 3, memo);
		memo.put(currentI + ":" + currentNum, res);
		return res;
	}
```

###DP

 - 再帰でACできたので練習代わりにDPでも解いてみた
 - $n-0$ までの数字 (```step[n + 1]```) を何手で作ることができるか？
    - パターンは$n-1 , n-2 , n-3$の3つ
    - 途中でNG数字になってしまう場合はそのパターンを採用することはできない
        - coninueで飛ばしている
    - 最終的に100手以下で作成できているなら成功

```java
	private void solveC() {
		int n = nextInt();
		int ng1 = nextInt();
		int ng2 = nextInt();
		int ng3 = nextInt();
		if (n == ng1 || n == ng2 || n == ng3) {
			out.println("NO");
			return;
		}
		long[] step = new long[n + 1];
		Arrays.fill(step, Long.MAX_VALUE / 10);
		step[n] = 0;
		for (int i = n; i >= 0; i--) {
			if (i == ng1 || i == ng2 || i == ng3) {
				continue;
			}
			if (i + 1 <= n) {
				step[i] = Long.min(step[i + 1] + 1, step[i]);
			}
			if (i + 2 <= n) {
				step[i] = Long.min(step[i + 2] + 1, step[i]);
			}
			if (i + 3 <= n) {
				step[i] = Long.min(step[i + 3] + 1, step[i]);
			}
		}

		out.println(step[0] <= 100 ? "YES" : "NO");
	}
```
キーボードを非表示にする方法

# [初心者]キーボードを表示から非表示にする方法

### 一度、キーボードを表示させた場合、なかなか非表示にできなかったので、共有です。
#### viewDidLoad()内で、以下のコードを実行してみてください！


    // テキストフィールド以外をタップした場合、キーボード非表示
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        self.view.endEditing(true)
    }
Cの開発環境

# macでGCCをつかう
趣味のC言語の学習にMacを選択する。
Winだと面倒くさそーなので
Macだと最初からgccのコンパイラが標準搭載されてる。

```terminal:
clang -v
Apple LLVM version 10.0.1(clang-1001.0.46.4)
```
で、確認OK。


```
vi hello.c
```

そんで、コンパイルは

```
gcc -o hello hello.c
```


Windows環境だとパスが通っているのだが、
Macはそんなんしてくれないので、
現在のフォルダパスにhelloの場所を明示しておく必要があるので

```
./hello
```

でけた


ちなみに、エスケープシーケンス

```
printf("\033[2J");　 //画面消去
printf("\033[33m");　// 黄くなる
printf("\033[39m");　//元に戻す
```

`visual studio codeの導入`
無料のIDE：vscode
C/C++のエクステンション機能（Code Runner)でプログラムをコンパイルして実行できる
 					
CodeBlocksは、Mac環境下だと2013年12月26日を最後にリリースがされてないから却下
正規表現の「または」OR句について

# 正規表現の「または」or句について

**「|」(パイプ)**は、「どちらかにマッチ」だと思うけど、**順番があるので注意**。

普通の IF 文などの論理演算の OR と同じだと早合点してしまうと、順番なんかどうでもいいや、と思いがちだけど、正規表現の場合は、**順番も重要**になるので、注意。

例えば、

「**ababc**」という文字列をターゲットにする

これに対して、以下の正規表現を考える

「**(([a-b])|(abc))+**」

意味は、『a～bまでの文字、または「abc」という文字列』 が、1文字以上の領域。

マッチ文字列は、「**abab**」

**最後の「c」がマッチしない**。

一方、順番を逆にした以下の正規表現を考えると、

「**((abc)|([a-b]))+**」

マッチ文字列は、「**ababc**」

と**最後の「c」も含まれる**。

つまり、「(([a-b])|(abc))+」の正規表現の処理としては、

先頭の1文字目は「a」で[a-c]の表現にマッチ、2文字目も[a-c]でマッチ、3文字目も[a-c]でマッチ、4文字目も[a-c]でマッチ、5文字目は「c」なので、[a-b]ではマッチしないので、次の表現「abc」に遷移するもののマッチしない(「c」という表現では「abc」とマッチしない)。

マッチしなかった時に、n文字までマッチしていたものをn-1文字(n-m文字)に戻ってマッチしなおす。という事はしない。

一方、「((abc)|([a-b]))+」の場合は、

先頭の1文字目は「a」は「abc」で**ひとまず**仮マッチするので、続けて1+1=2文字目は「b」なので、さらに継続して、1+2=3文字目は「a」なのでマッチしないので、1文字目からの「aba」は「abc」にマッチしないという事で、1文字に戻って、次の表現「a-b」でマッチ。2文字目も[a-b]でマッチ。3文字目は「a」なので、最初の表現「abc」に**ひとまず**仮マッチで、次の文字、その次の文字とあわせて「abc」なので、完全にマッチ。・・・という事で、マッチした文字列は「ababc」となる。

...という流れを考えてみると分かりやすいかもしれない。

# 以上
EC2のSSHポート番号を変更する(AWS)

デフォルトのSSHポート番号は22ですが、デフォルト故にハッカーからの標的にされやすい特徴があります。
EC2にて、インスタンスを作成後、ポート番号を変更する手順を記述します。

# 手順
1. EC2インスタンスにSSHで接続
2. `sshd_config`の中身を書き換える
3. `reload`で設定を反映
4. AWSコンソールにて、インバウンドの設定を変更

# インスタンスに接続

```
mbp:~ mac$ ssh -i .ssh/秘密鍵ファイル ec2-user@パブリックIP
Last login: Tue Jun  4 14:42:14 2019 from 110.235.247.88

       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-2/
```

`sshd_config`の設定を書き換えます
`# Port 22`となっている場所をコメントアウトし、任意のポート番号にします。
エフェメラルポート番号（49152～65535）から指定すれば良いので、今回は`50022`に指定しました。
なお、エフェメラルポート番号とはIANAという団体が使用を推奨しているポート番号範囲です。
参考記事：[エフェメラルポート  【 ephemeral ports 】  ダイナミックポート](http://e-words.jp/w/%E3%82%A8%E3%83%95%E3%82%A7%E3%83%A1%E3%83%A9%E3%83%AB%E3%83%9D%E3%83%BC%E3%83%88.html)

```
sudo vi /etc/ssh/sshd_config

# This is the sshd server system-wide configuration file.  See
# sshd_config(5) for more information.

# This sshd was compiled with PATH=/usr/local/bin:/usr/bin

# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented.  Uncommented options override the
# default value.

# If you want to change the port on a SELinux system, you have to tell
# SELinux about this change.
# semanage port -a -t ssh_port_t -p tcp #PORTNUMBER
#
Port 50022
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::
```

設定を反映するため、下記コマンドを入力します。

```
sudo service sshd reload
```

内容が反映されているか、`netstat`で確認します。
`LISTEN`に50022があることから、うまくいっています。
なお、`ESTABLISHED`に22と記載されていますが、これは現在ポート番号22で接続している状態を示しています。
後に、50022でssh接続したあとは、22と表示されません。

```
sudo netstat -anp | grep sshd
tcp        0      0 0.0.0.0:50022           0.0.0.0:*               LISTEN      3599/sshd
tcp        0     36 172.31.36.147:22        110.235.247.88:56226    ESTABLISHED 14847/sshd: ec2-use
tcp6       0      0 :::50022                :::*                    LISTEN      3599/sshd
```

# AWSコンソールにて、インバウンドの設定
TCP Ruleにポート番号50022を指定し、SSHの記述は削除します。

<img width="1159" alt="Screen Shot 2019-06-05 at 11.12.15 AM.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/291139/bf5501f7-fc74-7249-4926-09411adcb936.png">

# EC2インスタンスの接続確認
ポート番号50022を指定してSSH接続できるか確認します。

```
ssh -i .ssh/秘密鍵ファイル ec2-user@パブリックIP -p 50022
Last login: Wed Jun  5 03:45:55 2019 from 110.235.247.88

       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-2/
```

# 参照元
[AWS EC2 Amazon Linuxインスタンス起動後、最初にやることまとめ（SysVinit編）
](https://qiita.com/yangci/items/ef2ab9b6f0d28bad0881#sshd%E3%81%AElisten%E3%83%9D%E3%83%BC%E3%83%88%E5%A4%89%E6%9B%B4)
[【AWS】SSHのポート番号を変更してみよう 【使ってみた】](http://www.k-staging.com/?p=15)
GitHubに多数のファイル群をpushする際、RPC failed; curl 55 SSL_write() returned SYSCALL, errno = 32 が発生しエラー終了

## まずまとめ
- もともとGitで管理していなかった既存プロジェクトの改修のため、Gitリポジトリをローカルに作成し、プロジェクトデータを全てcommitした。ローカルへのcommitは成功したが、いざGitHubへpushしようとすると下記のエラーが発生して失敗してしまった。
 
~~~
error: RPC failed; curl 55 SSL_write() returned SYSCALL, errno = 32 
fatal: The remote end hung up unexpectedly
~~~
- 結論から言うと、原因は一度に多数かつ大容量のファイルをpushしようとするとデータの受け手側でチャンクが発生し、この際にメモリが足りなくなってしまうことだった。
- 解決策としては、手動で何度かのコミットに分けてpushすれば無事にpushできる。

## 状況

### 症状
冒頭でも述べたが、SourceTreeからpushすると下記のメッセージが出てエラー終了。

~~~
error: RPC failed; curl 55 SSL_write() returned SYSCALL, errno = 32 
fatal: The remote end hung up unexpectedly
~~~
アップするデータが全体で5GB程度あるため、チャンク処理が行われる際にデータの受け手側でメモリが足りなくなることが原因ではないかと思われる。じゃあ一度にチャンク処理を行うデータ量を減らしてあげないとやばいよねと言う推定。

### Git環境
- SourceTree
- GitLFSインストール済み(単体で150MB以上容量があるファイルをGitHubにpushするソフト)
- SSH通信
- git config --global ssh.postBuffer 524288000に変更済み（この値が小さいとより小さな容量でもチャンクが発生してしまう可能性があるかも？未調査。）

### ファイル
- Unityプロジェクト
- 単体で150MB以上のファイルはない
- 数MB程度のpsdファイルがいくつか存在
- プロジェクト全体で5GB程度

### このエラーに特徴的なメッセージ
pushしている最中に詳細を表示すると下記のような表示が出ている。
![スクリーンショット 2019-06-05 12.43.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196069/4ae6d9c4-b260-7fff-e394-277edc59a8b3.png)
最後の行でチャンクが発生していることがわかるが、これはpushするデータが小さい場合は表示されない特徴的なメッセージ。表示されたらメモリ容量的にかなり苦しい処理を行っているものと推定できる。ただし、このメッセージが表示されたらpush失敗すると言うわけではなく、メモリを食いつぶし切らなければ大丈夫な様子。（**逆に今回のエラーが発生しているときは必ずチャンクが発生している。**）

### 解決策
1.コミットの際に一度にステージするファイル数を減らし、一回のコミットが全体で数10MB程度になるようにする。
2.コミットの都度pushする（これは必要ないかも）
※SourceTreeは2MB以上のファイルを上げようとすると警告を出してくるが、これは無視してOK。

### 終わりに
普通にGitにはコミットできたのにpushだけできないので超焦りました・・・
和暦環境で、西暦の yyyy/MM/dd を .NET Framework で

Windows は、和暦表示に設定することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364126/64946b08-242c-d116-b738-730d500b8189.png)

タスクバーが和暦表示になりました!

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364126/05ca2303-b575-44b0-ea7f-bedbe7f90760.png)

ここで 1 つ問題になるのが…
.NET Framework での日付の文字列化です。

```cs
using System;

namespace ConsoleApp18
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(DateTime.Now.ToString("yyyy/MM/dd"));
        }
    }
}

```

実行結果

```plaintext
01/06/05
続行するには何かキーを押してください . . .
```

これ固定で西暦になると思っていたら、ならないのです…

C 言語の [strftime](https://linuxjm.osdn.jp/html/LDP_man-pages/man3/strftime.3.html) のように、`%Y 世紀部分を含めた ( 4 桁の) 西暦年。` と明示されていれば良いのですが…
.NET Framework の ["yyyy" カスタム書式指定子](https://docs.microsoft.com/ja-jp/dotnet/standard/base-types/custom-date-and-time-format-strings#yyyySpecifier) には `年` とだけ書いてあります。

ここでは西暦年を表示するための書き換え案だけ、記録のために残していきます。

```cs
Console.WriteLine(DateTime.Now.ToString("yyyy/MM/dd"));
// ↓
Console.WriteLine(DateTime.Now.ToString("yyyy/MM/dd", CultureInfo.InvariantCulture));
```

```cs
Console.WriteLine(string.Format("{0:yyyy/MM/dd}", DateTime.Now));
// ↓
Console.WriteLine(string.Format(CultureInfo.InvariantCulture, "{0:yyyy/MM/dd}", DateTime.Now));
```

```cs
Console.WriteLine($"{DateTime.Now:yyyy/MM/dd}");
// ↓
Console.WriteLine(((IFormattable)$"{DateTime.Now:yyyy/MM/dd}").ToString(null, CultureInfo.InvariantCulture));
```

個別にではなく、アプリケーション全体に西暦を適用したい場合

```csharp
    var ja = new CultureInfo("ja-JP", true);
    ja.DateTimeFormat.Calendar = new GregorianCalendar(GregorianCalendarTypes.Localized);

    Thread.CurrentThread.CurrentCulture = ja;
```

参考: [日付の年号を略称で表示するには？［C#、VB］
](https://www.atmarkit.co.jp/ait/articles/1506/10/news022.html)
Premiere pro cc シーケンス内の各セクション（シーン）の割合を出す。

#今回は？
編集の際にオープニング・メインA・メインB・エンディングと４つのセクションがあるとします。
その各セクションの尺の長さの割合を計算します。

#何の為に？
先方に割合を伝えたかったのと、役に立つと思ったから。
って事でさっそく。

#使い方
今回のプログラムはシーケンスマーカーでセクションを分けておきます。

![bandicam 2019-06-05 12-11-00-507.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178061/ea9dd8fd-c743-016a-1808-2c209c4306e9.jpeg)

準備はこれだけでOK！

プログラムを実行すると・・・
まずはFPSの入力ダイアログが表示されるのでシーケンスのフレームレートを入力します。
現状シーケンスのフレームレートを取得するグローバル変数がないようです。
![bandicam 2019-06-05 13-06-15-246.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178061/dd6421df-6b57-4409-e2c4-d7c5f188fdc9.jpeg)
入力したら・・・
![bandicam 2019-06-05 12-44-01-947.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178061/21ccb955-e761-272d-0bc8-8e0f672aa210.jpeg)

ちょっと小さくて見えないのでテキストに

```console
Sequence Duration:45sec
========
MarkerName:オープニング
markerDuration:10sec
Percentage:22.2%
========
MarkerName:メインA
markerDuration:10sec
Percentage:22.2%
========
MarkerName:メインB
markerDuration:10sec
Percentage:22.2%
========
MarkerName:エンディング
markerDuration:15sec
Percentage:33.3%
========
```
マーカー名とマーカーの尺と割合が返ってきます。

以上。
たまーに使う機会がありそうですね。
全体構成の割合を見たりするのにいいのではないでしょうか。

#では最後にスクリプトです。

```jsx
var res= prompt('What Sequence FrameRate ?', '29.97','FPS');
//アクティブシーケンスの尺を取得
var tb = app.project.activeSequence.timebase;
var se = app.project.activeSequence.end;
var frame = se/tb;
var sec = frame/res;

//マーカー情報
var numMarkers = app.project.activeSequence.markers.numMarkers;
var markers = app.project.activeSequence.markers;
var markAry = [];
var currentMarker;
var markerDuration;
var Percentage;
var info = "Sequence Duration:"+sec+"sec";

markAry.push(info)
markAry.push("========")
for(i=0;i<numMarkers;i++){
    if(i==0){
        currentMarker = markers.getFirstMarker();
        markerDuration =  currentMarker.end.seconds-currentMarker.start.seconds;
        Percentage = markerDuration/sec*100;
        markAry.push("MarkerName:"+currentMarker.name);
        markAry.push("markerDuration:"+ markerDuration+"sec");
        markAry.push("Percentage:"+Math.round(Percentage*10)/10+"%");
        markAry.push("========")
    }
    if(i>0){
        currentMarker = markers.getNextMarker(currentMarker);
        markerDuration =  currentMarker.end.seconds-currentMarker.start.seconds;
        Percentage = markerDuration/sec*100;
        markAry.push("MarkerName:"+currentMarker.name);
        markAry.push("markerDuration:"+ markerDuration+"sec");
        markAry.push("Percentage:"+Math.round(Percentage*10)/10+"%");
        markAry.push("========")
    }
}

alert(markAry.join("\r"))


```
JetBrains IDEからPrestoに繋ぐ

# 動機
- GUIからPrestoにクエリを投げたい
- [yanagishima](https://github.com/yanagishima/yanagishima)等のWebUIツールはあるけど接続設定とか導入がちょっと面倒くさい
- Prestoの動作検証やクエリチューニングをIDEの画面のみで完結させたい

# 環境
- macOS Mojave 10.14.2
- PHPStorm 2019.1.2
- Presto 0.218

# 導入方法
#### 1. JDBC Driverのセットアップ
PrestoのJDBC Driverを[ここ](https://prestodb.github.io/docs/current/installation/jdbc.html)からダウンロードしてくる
IDEの[Data Sources and Drivers] => [+] => [Driver]を選択
ダウンロードしてきたjarファイルを[Driver files] => [+] => [Custom JARs]で追加する

![step1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431054/3b912c11-3d1f-1c64-5976-e0254b7774d2.png)


#### 2. 接続設定
[Data Sources and Drivers] => [+] => [Presto]を選択

- User: 任意のユーザー名
- Password: 特に設定していないなら未入力でOK
- URL: 接続先URL
    - jdbc:presto://host:port/catalog/schema
    - catalogとschemaは省略可

上記入力後[Test Connection]を押して疎通確認を行う
[Schemas]タブから使いたいschemaにチェックを入れてOK

![step2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431054/8e4c0f1e-b8c7-f1e7-4d79-1729cee4f54e.png)

#### 3. おわり
[Database]のウィンドウで追加したやつが表示されていればおわり

# 参考元
- https://prestodb.github.io/docs/current/installation/jdbc.html
macOSをCatalinaに上げたらDocker for Macが起動しなくなった時の対応

Docker for Macを起動してもすぐ停止してしまう！
`docker ps`を実行すると以下のエラーが出る！という状態になったので解決すべく調べてみました。

    $ docker ps
    Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

まず、`docker-machine ps`でDocker ホストが作られているか確認

    $ docker-machine ls                                                                                                                                                                                                                                                ~
    NAME   ACTIVE   DRIVER   STATE   URL   SWARM   DOCKER   ERRORS

default が作られているはずですが居ません。

### 対応

以下の3つをインストール

    $ brew install docker-machine docker virtualbox

default を作成

    $ docker-machine create --driver virtualbox default

Dockerクライアントのために環境変数を設定

    $ eval "$(docker-machine env default)"

以上

結果的にDockerホストが消えたという問題でした。
尚、応急処置的な対応なので詳細については別の記事を参考にしてください。

## 参考

- https://stackoverflow.com/a/49719638
[Angular] テストレシピ - fakeAsyncの使い処

# はじめに

Angularのテストの中で、以下のような記述を見かけたことはないでしょうか？

```ts:
it('世界に挨拶します (async)', fakeAsync(() => {
    // テストコード
}));
```

ここでは何が起きているのか？
どんなときにこのように書けばよいのか？
すでに解説記事がいくつもありますが、自分なりにまとめてみます。

# fakeAsyncを使うと何が起きるの？

[マニュアル](https://angular.io/api/core/testing) には、このように書かれています。

> Wraps a function to be executed in the fakeAsync zone:
>
> -   microtasks are manually executed by calling flushMicrotasks(),
> -   timers are synchronous, tick() simulates the asynchronous passage of time.

簡単に訳すと、

> fakeAsyncゾーンの中で実行するように関数をラップします。
> 
> - microtaskは、flushMicrotasks()を呼ぶことで手動実行されます。
> - タイマーは同期します。tick() を使うと、非同期な時間待ちをシミュレートできます。

なんのことやらですね。

## fakeAsyncゾーンとは？

「fakeAsyncゾーン」というのは、「fakeAsync」という名前の「ゾーン」です。
「ゾーン」というのは、実行コンテキストのようなものだそうです。

ゾーンを解説するプレゼン動画 → https://www.youtube.com/watch?v=3IqtmUscE_U&t=150 [^1]

[^1]: YouTubeは自動翻訳字幕出せるようになってた。素敵！

何をしてくれるかというと、非同期コールバックをプロキシ化して、AOPできるようにしたようなものです。
非同期コールバックが複数箇所にあったとして、呼び出し前に実行コンテキストを整えて、非同期コールバック間で情報を共有できるようにしてくれます。

どのように実現しているかというと、`setTimeout`やらなんやらにモンキーパッチをあてているそうです。

## microtaskとは？

[Zone.jsのドキュメント](https://github.com/angular/zone.js/blob/master/doc/task.md)によると、microtaskというのは、Promise.Thenに渡される非同期コールバックのことです。

つまり、`flushMicrotasks()`を呼ぶと、キューに溜まったPromise.Thenコールバックを全て実行してくれ（るんだと思い:sweat_smile: ）ます。

ちなみに、非同期コールバックはmicrotaskとあわせて3つに分類されます。

- MicroTask
- EventTask
- MacroTask

## `tick()`は？

`tick()`は簡単です。引数に指定したミリ秒時間待ってくれるだけです。


# fakeAsync使うと美味しいの？

おけ、テストをラップしてくれるのはわかった。
どんなシーンで使うと嬉しいでしょうか。

## 解決しないといけないPromiseがあるとき

Promiseの解決結果がテストに影響するのであれば、fakeAsyncで囲みます。

例えば、`Router.navigateByUrl()`を呼び出しているクラスをテストするときに使います。

```ts:
it('xxxしたら、oooへ遷移', fakeAsync(() => {
  // Given
  const location = TestBed.get(Location);

  // When
  instance.xxx(); // この中で、navigateByUrl を使っている

  flushMicrotasks(); // 溜まっているPromiseを強制解決

  // Then
  expect(location.path()).toBe('ooo'); // location.path() が変わっている
}));
```




# 参考リンク

- [Angular 公式ガイド](https://angular.io/guide/testing#async-test-with-fakeasync)
- [AngularとZone.jsとテストの話](https://qiita.com/Quramy/items/83f4fbc6755309f78ad2)
- [async awaitでキレイなコードが書けないと辛い気持ちになってたところ、zone.jsを使ったらいろいろと解決できそうなことが分かった](https://qiita.com/kodo_san/items/b31d8125cce438ff3706)
- [Angular: Testing async stuff in the fakedAsync zone VS. providing custom schedulers](https://medium.com/@golbie/angular-testing-async-stuff-in-the-fakedasync-zone-vs-providing-custom-schedulers-27a7f83c7774)
- [Angular fakeAsyncTest 使い方の纏め](https://qiita.com/Jialipassion/items/89bdaac33b3f2fbbffed)
- [Implements Zones for JavaScript ](https://github.com/angular/zone.js/)
TravisCI上でkarmaからFireFoxを動かすときの.travis.yml

[Karma側の説明](https://karma-runner.github.io/4.0/plus/travis.html)

```
language: node_js
node_js:
  - "4"
before_script:
  - export DISPLAY=:99.0
  - sh -e /etc/init.d/xvfb start
 ```
この書き方をしていると以下のようなエラーでTravisCIのJOBが失敗することがある。

```
sh: 0: Can't open /etc/init.d/xvfb
The command "sh -e /etc/init.d/xvfb start" failed and exited with 127 during .
```

TravisCI上でGUIを使う場合の正解はこっち
[Using xvfb to Run Tests That Require a GUI](https://docs.travis-ci.com/user/gui-and-headless-browsers/#using-xvfb-to-run-tests-that-require-a-gui)

```
services:
  - xvfb
```
Google Cloud Text-To-Speechが、非公式?にWavenet「男声」日本語版対応してる件

[Cloud Text-To-Speech サポート音声一覧](https://cloud.google.com/text-to-speech/docs/voices)では、高音質のWavenet日本語音声はja-JP-Wavenet-A(女声)だけとなってます。
しかし、[デモページ](https://cloud.google.com/text-to-speech/?hl=ja)で日本語を選ぶと、さりげなくWaveNetA/B/C/Dの4種類が選択可能になってました。
A,Bが女声、C,Dが男声です。

[以前の記事](https://qiita.com/tinoue@github/items/9772b8a41348264b3ca6)と同じように見えますが、「男声」に対応してるよというのが主な内容です。
macOSの複数バージョンを同一パーティションにインストール

macOSでいつも問題になるのは自分の使う環境との共存です。業務用のメイン機を更新すると支障が出ますし、別のmacに入れると使い分けやデータ移行が問題になるし、外付けディスクに入れておくのも起動が遅かったりして不便ですよね。

何より新しいベータ環境を普段使いしたいのだ！

と思っていたらAPFSボリュームを使うと簡単に別ボリュームを作ってインストールすることで容量を（共存しているボリュームと）共有にすることができます。必要に応じて再インストールや削除も可能で非常に便利だったのでメモしておきます。

# APFSボリュームを作成

ディスクユーティリティを開き、左上のボリュームで「＋」を押します。

<img width="937" alt="スクリーンショット 2019-06-05 9.20.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14768/928fa7e8-d4ae-f710-121a-d6524e6383a1.png">

特に容量などを設定せず、名前をつけて「追加」を押すと、すぐ完了します。

<img width="937" alt="スクリーンショット 2019-06-05 9.21.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14768/55372ab5-77bf-07fa-b3fa-4241b383db96.png">

# インストール

<img width="912" alt="スクリーンショット 2019-06-05 9.21.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14768/204e586b-6f6c-a330-1aac-9eceda2b82ce.png">

「すべてのディスクを表示」をクリックすると、先ほど作ったボリュームも表示されます。

<img width="912" alt="スクリーンショット 2019-06-05 9.21.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14768/fe0bfe17-9321-e468-d740-1d45526a6b9a.png">

あとは普通にインストールを行います。


# 起動ディスクの切り替え

システム環境設定の起動ディスクで切り替えます。

<img width="780" alt="スクリーンショット 2019-06-05 12.23.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14768/178498fe-d85a-3d1c-9ce5-cb9fbf560385.png">

# ぶつぶつ

これで、普段使いの環境をベータOSに移行しつつ、必要なときには戻せるようになりました。リリース後も同じようにインストールすることで環境にアップデートによるゴミが残るのを防ぐができます。ぜひぜひお試しください。

# 参考

調べたらAppleサポートにも情報がありましたので、参考まで。
https://support.apple.com/ja-jp/HT208891
OjichatClone 絵文字や句読点マシマシでドン引きされがちなおじさんメッセージをボタン1つで作り出せるおじさん文章ジェネレーター　

ぐれさんさんが開発した「ojichat」をiMessage用の拡張アプリケーションとして移植した OjichatClone をリリースしました。
「顔文字や絵文字を乱用する」「句読点を多用する」「やたらとご飯に誘う」「褒め方が絶妙に気持ち悪い」「ちゃん付け」など、
中年男性が若い女性に対して送るメッセージの特徴をつかんだ文章を自動で生成してくれます。

[OjichatClone](https://itunes.apple.com/jp/app/ojichatclone/id1466639287?mt=8&uo=4)のダウンロードはこちらから。

すれみさんという方が、いわゆる「おじさんLINE」はどんな特徴があるメッセージなのかを以下のツイートでわかりやすくまとめていましたが、

[すれみさんのツイートはこちら](https://twitter.com/_Smitter2/status/848109554894118913?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E848109554894118913&ref_url=https%3A%2F%2Fgigazine.net%2Fnews%2F20190603-ojisan-bunshou-generator%2F)


これをもとに[ぐれさん](https://github.com/greymd/ojichat)がシェル用のスクリプトとしてリリースしたものを、私の方でiOS用アプリに移植させていただきました。

とにかく急いでリリースにまで持って行ったので、本家のOjichatとは若干仕様が異なってます。これはいずれアップデートしようと思ってます。

* 本家は、女の子の名前がランダムで表示されるが、Ojichatは固定で「ベイベー」。（岡村靖幸を意識）
* 語尾をカタカナに変換する機能は今後実装予定。（「●●だね」→「●●ダネ」と書きがち）
* 読点を多めに入れる機能も今後。
before_actionとストロングパラメーターの編集について

#1.具体例の提示

以下のコードにおけるbefore_actionとストロングパラメーターの編集の内容について解説する。

```ruby
class ApplicationController < ActionController::Base
  before_action :configure_permitted_parameters , if: :devise_controller?

  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:nickname, :avatar])
  end
end
```
#2.before_actionについて

before_actionとは、コントローラのフィルタリング的役割を担うものである。つまり、before_actionをApplicationControllerに定義することで、ApplicationControllerを継承しているコントローラー内の全てのアクションが実行される前に、before_actionが実行される。
上記の例で言えば、処理の流れとして、最初にbefore_actionが実行される。そして、次にそこに定義されたconfigure_permitted_parametersが実行される。
また、これを定義しないと、configure_permitted_parametersメソッドが読み込まれない。そのため、編集したストロングパラメーターが反映させるためにも**必ずbefore_actionを定義する**。

#3.ストロングパラメーターの編集について
ストロングパラメーターとは、ストロングパラメータはコントローラーで送られてきたパラメータを安全に受け取るための仕組みのことをいう。
ストロングパラメーターは、初期設定の段階では、**メールアドレス**と**パスワード**のみを受け取るように設定してある。そのため、新しいキーをコントローラに受け取らせるためには、ストロングパラメーターを編集しなければならない。

上記の例において、ストロングパラメーターの編集は、以下のコードによってなされている。

```ruby
def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:nickname, :avatar])
end
```
devise_parameter_sanitizerメソッドを使うことで設定されているにストロングパラメーター対して、新たなパラメーターを追加することができる。
編集の書式としては、以下のようになる。

```ruby
devise_parameter_sanitizer.permit(追加したいメソッドの種類, keys: [追加したいパラメーター名])
```
　　　　　　　　　　　　　　　　　　　　　　　　以上
Domain-Driven Design Quickly ② -ユビキタス言語-

## 共通言語の必要性

DDDでは**ソフトウェアの専門家**と**ドメインの専門家**が協力してドメインモデルを作っていく
→ それぞれが専門用語を使っていても仕方ない
→ **共通言語(ユビキタス言語)** が必要

### ユビキタスとは

- 「遍在する」という意味のラテン語「ubique」を語源とする言葉
- いつでも、どこでも

### 共通言語(ユビキタス言語)の利点

- 設計の全ての部分が結びつく
- 効率よく作業するための前提ができる
- ドメインの専門家は間違った設計を見つけやすくなる
- ソフトウェアの専門家は設計に紛れこみやすい曖昧さや矛盾を見つけやすくなる

## ユビキタス言語の作り方

1. ドメインの定義と設計の方向を決めるような重要な要素を見つける
2. これらの要素に適切な名前をつけて、その名前を使っていく

- 簡単に見つかる名前も、難しい名前もある
- ドメインの専門家は不適切な名前やモデルの構造に反対する必要がある

### 超重要ポイント
- **チームのすべてのメンバ**が共通言語を作らなければならないと自覚し、**重要な点に常に注目**するように気をつける
- 必要なときは**いつでも作成した共通言語を使う**ようにする
- このような作業のときには、**独自の専門用語を可能な限り使わない**ようにする
英語のUdemyの字幕を日本語にリアルタイム翻訳する方法

ブラウザはChromeです。

２ステップあります。

# ①字幕を「ビデオの下に表示」

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111366/4d24848f-a44f-d4c0-8760-8da32d75de25.gif" width=480>

# ②右クリックして「日本語に翻訳」

![字幕.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111366/8078dc38-88a6-b2f6-c8cb-f649bcf73bb1.gif)

以上です。
Spring アップロードファイルを読み込んで中身を表示する方法


build.gradleでstater-webのところのライブラリを導入しないと必要なクラスがimport出来ないので
はじめに記述する。
書けたらGradleをリフレッシュする。

```gradle:build.gradle
dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-web'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
	compile('org.springframework.boot:spring-boot-starter-thymeleaf')
	compile('org.springframework.boot:spring-boot-starter-data-jpa')
	compile ('org.springframework.boot:spring-boot-starter-web')
}
```

コントローラーのpostメソッドの引数に**MultipartFile**クラスのインスタンスを追加する。
これがHTMLから\<input type="file">で選んで\<input type="submit">で投稿されたファイルの
インスタンスになる。

```java:ModelAndViewController.java
	@RequestMapping(value="/",method=RequestMethod.POST)
	public ModelAndView post(
			@RequestParam("upload_file")MultipartFile uploadFile,
			ModelAndView mav) 
	{
		mav.setViewName("index");
		mav.addObject("file_contents", fileContents(uploadFile));
		mav.addObject("recordSet", list);
		return mav;
	}
```	

読み込んだファイルの中身をテキスト形式に変換して取り出すところ。
**MultiPartFile**から読み出した時はバイトストリームなのでcsvファイルなどのテキスト形式に変換するには**Reader**->**BufferedReader**と変換していく。（Readerを挟む必要はあるかわからない。）
最終的にはこのコードでいうとbuf変数にファイルの中身がテキスト形式で入っているので後はSwingとかのローカルアプリと同じように読み出すだけ。

```java:ModelAndViewController.java
private List<String> fileContents(MultipartFile uploadFile) {
		List<String> lines = new ArrayList<String>();
		String line = null;
		try {
			InputStream stream = uploadFile.getInputStream();			
			Reader reader = new InputStreamReader(stream);
			BufferedReader buf= new BufferedReader(reader);
			while((line = buf.readLine()) != null) {
				lines.add(line);
			}
			line = buf.readLine();
			
		} catch (IOException e) {
			line = "Can't read contents.";
			lines.add(line);
			e.printStackTrace();
		}
		return lines;
	}
```

htmlのformタグに**enctype="multipart/form-data"**を記述しないとアップロードできない。

```html:index.html
<!-- ファイルのアップロードボタンの実装-->
	<form method="post" action="/" enctype="multipart/form-data">
		<input type="submit" value="ファイルをアップロード">
		<input type="file" name="upload_file">	
	</form>
	<p th:text="${file_name}"></p>
	<table>
<!-- ここから下が結果表示-->
	<tr th:each="line:${file_contents}">
		<td th:text=${line}></td>
	</tr>
	</table>
```
Ruby on Railsでミニアプリ

####はじめに
初学者のアウトプット記事です。

今回の内容は
就職活動中で作ったポートフォリオ(ミニアプリ)の説明です。

ご指摘アドバイス等ありましたらよろしくお願いします。

#ポートフォリオ
###開発環境

ruby 2.5.1
rails 5.2.3
本番環境 AWS/S3
DB:Mysql5.6

###URL

[http://3.13.98.161/](http://3.13.98.161/)

- ログイン用テストユーザー
 - email: testtaro@test
 - password: 123456

###主な機能
■deviseを用いたユーザー管理機能
 □ ユーザー新規登録
 □ ユーザーログイン・ログアウト

■記事管理機能
□記事投稿(写真、タイトル、記事文章、カテゴリ、日時、ユーザー名)
□記事編集(更新、削除)
□記事詳細
□カテゴリ毎に投稿を一覧表示
□ログインユーザーの投稿一覧表示

■その他
□投稿記事への非同期通信イイね機能。
□font-awesome
□ページネーション(kaminari)
□フッター部分にTwitter・Facebook・LINEのシェアボタン
□capistranoを用いてAWSに自動デプロイ
□画像の保存先をS3に指定

###概要
主におもちゃに特化した写真記事を投稿しユーザ同士共有して閲覧できるアプリです。

###何ができるのか

**・おもちゃに関する記事投稿(写真、タイトル、記事文章、カテゴリ、日時、ユーザー名)ができます。**

![ポートフォリオ用投稿.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368735/97e160dc-9d1b-9dfb-125c-ae251d7abdca.gif)






**・記事一覧表示(カテゴリ毎、ログインしてるユーザの投稿一覧)し、写真をクリックすると詳細画面にアクセスできます。**
![一覧.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368735/6ac244b3-d94c-4b41-d0be-cc485a44ac48.gif)






**・記事詳細画面にて記事に対してイイねボタンが押せます。**
![ポートフォリオイイネボタン.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368735/6bad671e-d018-d434-f724-5b7e06271f2b.gif)

**・記事詳細画面から編集画面に進み削除、内容の更新ができます。**
**更新**
![更新ポート.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368735/9f1311b8-1a75-8e73-986c-8ef3a9e5a0b0.gif)
**削除**
![削除.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368735/a33fee75-1112-cc0e-2c57-b28d7fc156aa.gif)

**・Twitter,Facebook,LINEでシェアできるシェアボタン**
![シェアボタン.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368735/787b2b67-a7ba-0607-c176-0cf60719d3cc.gif)


#DB設計
#### productsテーブル

|Column|Type|Options|
|------|----|-------|
|name|text|null: false, unique:true|
|description|text|null: false|
|like_count|integer|
|category_id|integer|
|user_id|integer|
### Association
- belongs_to :category
- belongs_to :user
- has_many :likes, dependent: :destroy
- has_many :images, dependent: :destroy


#### usersテーブル

|Column|Type|Options|
|------|----|-------|
|name|text|null: false, unique:true|
|e_mail|text|null: false , unique:true|
|password|text|null :false|
### Association
- has_many :products, dependent: :destroy
- has_many :likes, dependent: :destroy


## likesテーブル

|Column|Type|Options|
|------|----|-------|
|user_id|reference|foreign_key: true|
|group_id|reference|foreign_key: true|
### Association
- belongs_to :product, counter_cache: :likes_count
- belongs_to :user


## categoriesテーブル

|Column|Type|Options|
|------|----|-------|
|name|string|null: false|
### Association
- has_many :products


#今回の作成をしてみて
必要な機能を洗い出しDB設計して各機能を実装しました。
実装している段階でエラーが発生しbiding.pryやrails cをよく使用し仮説検証をしました。
今回特にAWSへのデプロイでのエラーが多く、本番環境のlogを確認してどこで何が起きているのかを考え分からない部分は検索しながら解決していきました。
特に今回ハマった部分の記事です。
[Rails本番環境(AWS)S3に画像投稿できなかった](https://qiita.com/hellhellmymy/items/35154c90cd0bb0d91aa9)
今回の作成を通して自分の中ではlogをしっかり確認するのが大事だということの学びが大きかったです。

####課題
□記事に対するコメント機能実装(非同期通信)
□rspecでモデルのバリデーションテストは書けたが、コントローラーのテストは書けてない。
□レスポンシブ化(スマホ対応していない)

###最後に

Github
https://github.com/RyunosukeFuku

Twitter
https://twitter.com/hellhellmymy?lang=ja
パフォーマンスインサイトについて

AWSのDB問題が発生している場合、パフォーマンスインサイトが利用できる。
>
データベースの負荷（どのSQL文が負荷を発生させており、それはなぜなのか）を可視化するダッシュボードを使用して、エキスパートな方とエキスパートではない方の両方が、Performance Insights でパフォーマンス問題を容易に検出できます。


https://aws.amazon.com/jp/blogs/news/analyzing-amazon-rds-database-workload-with-performance-insights/

利用可能なDBは以下の通り。
>
- MySQL と互換性がある Amazon Aurora バージョン 1.17.3 以上の 1.x バージョン
- Aurora MySQL 1.x バージョンは MySQL 5.6 と互換性があり、Aurora MySQL 2.x バージョンは MySQL 5.7 と互換性があります。現在、Amazon RDSパフォーマンスインサイトは Aurora MySQL 2.x バージョンをサポートしていません。
- Amazon RDS MariaDB バージョン 10.2.21 以上の 10.2 バージョン
- Amazon RDS MySQL バージョン 5.7.22 以上の 5.7 バージョン
- Amazon RDS MySQL バージョン 5.6.41 以上の 5.6 バージョン
- Amazon RDS SQL Server (SQL Server 2008 を除くすべてのバージョン)
- PostgreSQL との互換性がある Amazon Aurora
- Amazon RDS PostgreSQL バージョン 10
- Amazon RDS Oracle (すべてのバージョン)

https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_PerfInsights.html

~~注意が必要なのはAuroraの場合、現時点でMySQL5.6互換は対応しているが、5.7互換はまだ対応できていないこと。AuroraのVerはDBログイン後、以下で確認できる。~~

* (追記)MySQL5.7も対応したとのこと。
https://aws.amazon.com/jp/about-aws/whats-new/2019/05/Performance-Insights-GA-Aurora-MySQL-57/

```
select AURORA_VERSION();
select @@aurora_version; 
```
https://aws.amazon.com/jp/premiumsupport/knowledge-center/aurora-version-number/

Aurora MySQL、RDS MySQL, RDS Maria DB において、パフォーマンスインサイトを利用する場合、performance_schemaのパラメータを変更する必要があり、その際にDBインスタンスの再起動を伴う。逆に言うと、既にperformance_schemaが設定済みの場合は、F/Oや再起動は伴わない。

>
performance_schema パラメータの値を変更すると、DB インスタンスの再起動が必要になります。パフォーマンスインサイトが有効な新しい DB インスタンスを作成すると、performance_schema パラメータがデフォルトで 1 (有効) に設定されます。

https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/USER_PerfInsights.Enabling.html#USER_PerfInsights.EnableMySQL

その他、細かい話は下にあり。基本的に性能影響はないように設計されているが、ワークロードにもよるため、試験環境で事前実施したほうが望ましい、とのこと。

https://aws.amazon.com/jp/rds/performance-insights/faqs/
AppBundleでビルドしたaabファイルを端末にインストールする

2018年のGoogleI/Oで発表されたApp Bundleです。
apkファイルよりもファイルサイズを端末環境により不要なものを除去して小さくしてくれる優れものです。

apkとちがい、adbインストールができないのでインストール方法をメモしておきます。

## bundletoolをインストールする

bundletoolはアプリバンドルを操作するためのコマンドラインツールです。

### bundletoolのインストール
homebrewでインストールします。

```
brew install bundletool
```

### aabファイルからapksファイルを作成
aabファイルからapksというファイル一覧を作成します

```
bundletool build-apks --bundle=aabファイルパス \
                      --output=出力apksファイルパス \
                      --ks=keystoreファイルパス \
                      --ks-pass=pass:ストアパスワード \
                      --ks-key-alias=キーエイリアス \
                      --key-pass=pass:キーパスワード
```

たとえば

```
bundletool build-apks --bundle=hoge.aab \
                      --output=hoge.apks \
                      --ks=hoge.keystore \
                      --ks-pass=pass:hogehoge \
                      --ks-key-alias=HOGE \
                      --key-pass=pass:hogehoge
```

### 端末にインストール

```
bundletool install-apks --apks=出力apksファイルパス
```
[Vue.js]パスワードとパスワード確認をチェックするフォームのバリデーション

# やりたいこと

表題の通り、こういった、何かと何かを比較して
判定するよくあるフォームのバリデーション

前提として、**veevalidate**というプラグインを使用しております。

今後よく使いそうなので簡単にメモ

<img width="369" alt="スクリーンショット 2019-06-05 11.37.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224077/f48be1d4-70b5-8a8f-56b7-93165b93c5de.png">


# やったこと

```html
 <the-heading02 :title="'パスワード再発行'" />
    <div class="c-input-text__wrap">
      <div class="input__wrap">
        <base-input
          ref="email"
          v-model="email"
          v-validate="'required|email|max:256'"
          :placeholder="'メールアドレス'"
          name="email"
          data-vv-as="このメールアドレス"
          class="first_input"
          :class="{ 'has-error': errors.has('email') }"
        />
        <base-input
          v-model="re_email"
          v-validate="'required|email|max:256|confirmed:email'"
          :placeholder="'メールアドレス確認用'"
          name="re_email"
          data-vv-as="このメールアドレス"
          class="second_input"
          :class="{ 'has-error': errors.has('re_email') }"
        />
      </div>

      <!-- ERRORS -->
      <div v-show="errors.any()" class="validate__area">
        <div v-if="errors.has('email')">
          <p class="alert-danger">
            {{ errors.first('email') }}
          </p>
        </div>
        <div v-if="errors.has('re_email')">
          <p class="alert-danger">
            {{ errors.first('re_email') }}
          </p>
        </div>
      </div>
```
Pythonのfoliumで岩手県内の病院の場所を可視化してみる

#この記事について
Pythonのfoliumモジュールを使って、岩手県の病院の位置情報を可視化してみる
完成図↓
　<img width="634" alt="スクリーンショット 2019-06-05 10.07.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248826/095cd143-792b-02ad-b7a1-8a5cc4ea690a.png">

#参照データ
岩手県の病院の一覧
https://www.med-info.pref.iwate.jp/pdf/meibo.pdf

病院毎の緯度・経度のcsv↓
https://github.com/koheikobayashi/open_jupyter/blob/master/iwate-hospital/latitude_and_longitute.csv

#コード
```main.py
import pandas as pd 
import folium
from folium.plugins import FastMarkerCluster

lons = pd.read_csv('latitude_and_longitute.csv')  #参照データの病院毎の緯度・経度のcsvを使用
data = lons.values.tolist()

map1 = folium.Map(location=[39.250285, 141.636919], zoom_start=6.0)
FastMarkerCluster(data=data).add_to(map1)
map1.save("result.html")
```


[完成したものはこちら](https://koheikobayashi.github.io/open_jupyter/iwate-hospital/index.html)

[このデータの考察についてはてなブログに書いてみました](https://kihei171.hatenablog.com/entry/2019/06/05/095600?_ga=2.167579262.1120074260.1559651407-703677462.1558339018)
Laravel5.8のCSRFとは？その書き方

Laravel5.8の
**@csrfってなに？**

```hoge.blade.php
<form method="POST" action="/profile">
    @csrf
    ...
</form>
```

Laravelではテンプレートで（View側で）上記のような記述をします。
しかし@csrfとだけかかれていてもどういう処理になっているのかさっぱりですよね。

ぼくもさっぱりわからないので、まとめてみます。

まずLaravelの@csrfは、クロス・サイト・リクエスト・フォージェリ(CSRF)からアプリケーションを簡単に守ることができるものです。
CSRF攻撃の詳細な説明は省きます。
各自調べておいてね。（最後にwikiから引用して少しだけ説明してるよ）

##@csrfでどうやって守るの？
めっちゃ簡単です。
POSTリクエストを送るときに@csrfを書くだけです。というか書かないと送信時にエラーになります。

**Laravelでformタグを書いたら脳死で@csrfを書きましょう。**
**それだけです。**


@csrf を記述した箇所には次のような input 要素が出力されます。

```
<input type="hidden" name="_token" value="loiuhJKkjhUI664hjgk6jhg6fjg675JHGGOogo">
```

inputタグですがhiddenになっているのでサイト上では見えないようになっています。
そしてこのvalue属性のランダムな文字列が CSRF トークンです。

このCSRFトークンを用いて自分のサイトからのPOSTリクエストだけを受け付けるようにします。
下記のような流れです。
CSRFトークン（ランダムな文字列）を発行し、セッションに保存。hidden属性でinputに埋め込む。これでリクエストを送るのと同時にトークンも送信することになるのでークンが含まれていて、かつセッションに入れた値と一致する場合のみ正規のリクエストとして受け入れることができます。

これで予期しない（悪意のある）POSTリクエストが送信されることを防ぎます。


##クロスサイトリクエストフォージェリとは

結局こいつは何？
ようは不正規のやりかたでHTTPリクエストを送信して攻撃することだよ。

wikipediaで見てみる。
>攻撃者はブラウザなどのユーザ・クライアントを騙し、意図しないリクエスト（たとえばHTTPリクエスト）をWebサーバに送信させる。Webアプリケーションがユーザ・クライアントからのリクエストを十分検証しないで受け取るよう設計されている場合、このリクエストを正規のものとして扱ってしまい、被害が発生する。CSRF攻撃はURL、画像の読み込み、XMLHttpRequestなどを利用して実行される。


例まで書いてあった。以下引用

>CSRF脆弱性を具体例を用いて説明する。 今ある銀行のWebサイト（標的サイト）にログインしているユーザALICEが自身の口座からBOBという別のユーザの口座に100ドルを送金する際、ALICEのブラウザから

```
GET http://bank.com/transfer.do?acct=BOB&amount=100 HTTP/1.1
```

>というHTTPリクエストが銀行のWebサイトに向かって送信されるものとする.攻撃者MARIAは

```
http://bank.com/transfer.do?acct=MARIA&amount=10000 HTTP/1.1
```

>というURLを公開掲示板に張ったり、不特定多数にメールしたりする
銀行のユーザALICEがこのURLをクリックしてしまうと、ALICEのブラウザから

```
GET http://bank.com/transfer.do?acct=MARIA&amount=10000 HTTP/1.1
```

>というHTTPリクエストが銀行に向かって送信される[7]。この際たまたまALICEが銀行にログインしていたら、銀行のサーバはこのリクエストを送金要求だと解釈してしまい、ALICEの口座からMARIAの口座に一万ドルが不正送金されてしまう。

>本来、銀行のサーバは、ALICEのブラウザから受け取ったHTTPリクエストが本当にALICE当人の意志で送られたものなのかをチェックし、チェックを通った時のみHTTPリクエストを受け付けるべきである。

>しかし上述した銀行サーバのWebサイトの実装にはこのようなチェック機構は備わっておらず、これがMARIAにCSRF攻撃を可能にしてしまった原因である。


###参考にしたサイトさん
[Laravelチュートリアル](https://www.hypertextcandy.com/laravel-tutorial-introduction)←Laravel始めたい人はこれからやるのがいい
[Wikipedia-クロスサイトリクエストフォージェリ](https://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%82%B9%E3%82%B5%E3%82%A4%E3%83%88%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E3%83%95%E3%82%A9%E3%83%BC%E3%82%B8%E3%82%A7%E3%83%AA)
Github GraphQL API v4

# Github GraphQL API v4 って？

公式ドキュメント
https://developer.github.com/v4/

文字通り、GraphQLベースのAPIです。
GraphQLの詳細については他の投稿でも解説されておりますので、割愛します。

# Github GraphQL API v4 を使ってみる

今回はGithubから色んな情報を持ってきたいと思います。
GraphQLを利用の際は、
https://developer.github.com/v4/explorer/
こちらからログインをして、GUIベースのものからJSONを入力するケースと、cURLコマンド等でリクエストするケースがあります。
※事前にGithubのアカウントから、 `Personal access tokens` を発行しておく必要があります。

以下は、特定のプルリクエストに投稿されたコメントを取得するものです。

![a095e0b8-8020-1797-5deb-e470c7a072af.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55290/2c0d9236-03f4-f54b-3d6e-e59bd587944c.png)

```bash
$ curl -H "Authorization: token [発行したtoken]" -X POST -d '
> {
> "query":"query{repository(owner:\"[ユーザー名]\", name:\"[リポジトリ名]\"){pullRequest(number:1){comments(first:100){nodes{bodyText}}}}}"
> }
> ' https://api.github.com/graphql
{"data":{"repository":{"pullRequest":{"comments":{"nodes":[{"bodyText":"テストコメント１"},{"bodyText":"テストコメント２"},{"bodyText":"テストコメント３"}]}}}}}
$ 
```

# Github GraphQL API v4 のJSON構成を調べるためには

https://developer.github.com/v4/query/
こちらを参考に組み立てて行くのですが、結構クセが凄いんじゃなドキュメントです。

先を例に解説していくと、まずは特定のリポジトリの情報が知りたいので、

```
repository (Repository)
Lookup a given repository by the owner and repository name.
```

こいつを指定し、対象をさらに絞っていくのでリンクが貼られている `Repository` にアクセスします。
※`GitHub Enterprise` 利用時は複数のOrganizationがあると思うので、こちらから掘り下げて行きます。

```
organization (Organization)
Lookup a organization by login.
```

リポジトリからさらに絞り混む条件が新たに表示されます。
リポジトリに登録されているプルリクエストの情報が知りたいので、次にこれを掘り下げて行きます。
※プルリクエストの番号を指定します。

```
pullRequest (PullRequest)
Returns a single pull request from the current repository by number.
```

プルリクエストからさらに絞り混む条件が新たに表示されます。
プルリクエスト内のコメント情報を取得したいので、次にこれを掘り下げて行きます。
※取得するコメント数を指定します。

```
comments (IssueCommentConnection!)
A list of comments associated with the pull request.
```

次に絞り込む条件では、以下を利用していきます。
nodes -> bodyText

```
nodes ([IssueComment])
A list of nodes.
```

```
bodyText (String!)
The body rendered to text.
```

という感じで、JSONを組み立てて行きます。

## サンプル

```json:プルリクエスト内で更新されたファイルを取得
{
  repository(owner: "[ユーザー名]", name: "[リポジトリ名]") {
    pullRequest(number: 1) {
      files(first: 100) {
        nodes {
          path
        }
      }
    }
  }
}
```

```json:プルリクエストの一覧（タイトル）を取得
{
  repository(owner: "[ユーザー名]", name: "[リポジトリ名]") {
    pullRequests(first: 100) {
    	nodes {
        title
      }
    }
  }
}
```

プルリクエストを指定する場合は `pullRequest` で番号を指定するのですが、プルリクエストの一覧情報を取る場合は `pullRequests` で指定します。この辺りがクセが凄い（と個人的に）思っています。
他にも並び順を指定したり、取得数等を一旦変数で置いて変数の値を指定して取得する方法等があり、なかなか奥深い機能です。