OmniAICreator/Qiita-1.07M huggingface dataset:
【Java】インスタンスメソッド、インスタンスフィールド、クラスメソッド、クラスフィールド、コンストラクタまとめ

> Javaを学んでいく中で結構混乱した部分をまとめます。
参考にしているのはProgateです。

## 1.インスタンスメソッド

インスタンスメソッドはインスタンスが持つ・インスタンスに持たせる「振る舞い」。
### メソッドの定義の仕方

```java
public <戻り値の型> <メソッド名>(){
 <メソッドの中身>
}
```
のように書く。

### メソッドの呼び出し方

```java

/* Personクラスのインスタンス、person1を作成　*/
Person person1 = new Person();

/* helloメソッドの呼び出し */
person1.hello();
```

のように呼び出す。


## 2.インスタンスフィールド

インスタンスフィールドはインスタンスが持つ情報を格納する変数。

### インスタンスフィールドの定義の仕方

```Java
class Person {
  /* 変数なので型を宣言する */
  public String name;
}
```

### インスタンスフィールドのアクセス方法

```Java
/* インスタンスを生成 */
Person person1 = new Person();
/* nameに値をセット */
person1.name = "Suzuki";

/* nameの値を取得 */
System.out.println(person1.name);

```

このようにアクセスできる。


## 3.クラスメソッド

クラスに属するメソッド。

### クラスメソッドの定義の仕方

```Java
class Person {
  public static <戻り値の型> <メソッド名>() {
    <メソッドの中身>
  }
}
```

※インスタンスメソッドと異なり、`static` をつけることに注意。

### クラスメソッドの呼び出し方

```Java
<クラス名>.<メソッド名>();
```

このように呼び出す。
親の顔ほど見た`public static void <メソッド>(){ }` は実はクラスメソッドのこと。


## 4.クラスフィールド

クラスに属するフィールド。
クラスに持たせる情報を格納する変数。

### クラスフィールドの定義の仕方

```Java
class Person {
  public static <データ型> <変数名>;
}
```

※インスタンスフィールドと異なり、`static` をつける

### クラスフィールドへのアクセス方法

```Java:Main.java
class Main {
  public static void main(String[] args) {
    System.out.println("合計" + Person.count + "人です");
    Person person1 = new Person( ... );
    System.out.println("合計" + Person.count + "人です");
  }
}
```

```Java:Person.java
class Person {
  /* countという変数に人数という情報を格納していく */
  public static int count = 0;
  .........
  Person(String firstName, ...) {
    Person.count ++;
  }
}
```

```console:
> 合計0人です
> 合計1人です
```

※インスタンス生成のたびに`count`に1ずつ足していっている


## 5.コンストラクタ
`new`でインスタンスを生成後自動で呼び出されるメソッド。
定義方法が決まっているので注意

### コンストラクタの定義方法

```Java:
class Person {
  public String name;
  Person() {
    /* インスタンス生成時行いたい処理 */
  }
}
```

コンストラクタは`Person() {}` の部分。
メソッドの宣言と書き方が似ている。
しかしメソッドとは違い戻り値はないしvoidも不要。
なぜなら、コンストラクタの戻り値は必ずそのクラスのインスタンスであり、
明示しなくてもコンパイラはわかってくれる。
以下はコンパイラの実例。

### インスタンス生成時に、インスタンスフィールドにセットしたい値をコンストラクタの引数に渡す

```Java:Person.java
class Person {
  public String name;
  Person(String name) {
    this.name = name;
  }
}
```

### コンストラクタの呼び出し方

```Java:Main.java
Person person = new Person("Suzuki");
System.out.println(person.name);
```

## 6.まとめ

| | 修飾子 | static | データ型 | メソッド名orフィールドの変数名 | メソッド名 |
|:--:|:--:|:--:|:--:|:--:|:-:|
|インスタンスメソッド|public|-|データ型|メソッド名| |
|インスタンスフィールド|public|-|データ型|フィールドの変数名| |
|クラスメソッド|public|static|データ型|メソッド名| |
|クラスフィールド|public|static|データ型|フィールドの変数名| |
|コンストラクタ|public|-|データ型|変数名|クラス名|



混乱しやすいですね！
以上です！
intra-mart スクリプトメモ 画像にリンクを設定するをスクリプトで設定する

intra-mart IM-BIS / IM-FormaDesiner のスクリプトメモ
画像のリンクをスクリプトで設定する。

#対象
・intra-mart Accel Platform
・IM-BIS
・IM-FormaDesiner

#やりかた
画像に< a >タグ作成してhref に設定するだけ。

```Javascript:sample.js
// 画像ID
var item_id = 'xxxxx';
// URL
var url = 'https://qiita.com/';
// 画像にリンクを設定
$( '#' + item_id ).wrap(
  $( '<a></a>' ).attr( { href: value, target: "_blank" } )
);
```
【Node.js】Slackのuser idから情報を取得する

Slack APPでユーザーを取得しようとするとユーザーIDが取得される為
APIを用いてユーザーIDからユーザーの詳細情報を取得する

# requestモジュール
https://www.npmjs.com/package/request
requestモジュールは HTTP/HTTPS 通信を行うためのクライアント。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/354659/f0fcaf5a-5354-0f06-2c3a-6b80ffd2d854.png)


# users.infoメソッド
https://api.slack.com/methods/users.info

Slack APIには様々なメソッドが用意されている
今回はアカウントの詳細情報を取得したいので `users.info`を使って取得する

# Slack APIからの情報取得

簡単に言うと下記のURLにトークンとユーザーIDをつけてアクセスすると詳細情報が返ってくる仕組み

`https://slack.com/api/users.info?token=トークン&user=ユーザーID&pretty=1`

# サンプルコード
Node.jsでAPIを叩くときは以下のように書く
TOKENとUSERIDを書き換える

```index.js
// パッケージの読み込み
let request = require('request');

// ヘッダーを定義
var headers = {'Content-type': 'application/json'};

// オプションを定義
var options = {
  url: 'https://slack.com/api/users.info?token=TOKEN&user=USERID&pretty=1',
  method: 'GET',
  headers: headers,
  json: true,
};

// リクエスト送信
request(options, function (error, response, body) {
  console.log(body); // body内に取得したJSONが入っている
})
```

# ユーザーIDを動的にしてAPIを叩く

Slack APPなどから取得したユーザーIDを使って検索する際はES2015(ES6)から追加されたテンプレート構文を用いると便利

[JavaScript (ES2015) 文字列中に変数展開できるテンプレート構文のメモ](https://chaika.hatenablog.com/entry/2018/10/02/090000)

```index.js
// パッケージの読み込み
let request = require('request');

// message.channels eventで取得した場合
if (payload.event && payload.event.type === 'message'){

  // 取得したユーザーIDを代入
  user_id = payload.event.user;

  // ヘッダーを定義
  var headers = {'Content-type': 'application/json'};

  // オプションを定義
  var options = {
    // バックスラッシュ内のテキストに　${変数名}　で変数を入れられる
    url: `https://slack.com/api/users.info?token=TOKEN&user=${user_id}&pretty=1`, 
    method: 'GET',
    headers: headers,
    json: true,
  };

  // リクエスト送信
  request(options, function (error, response, body) {
    console.log(body); // body内に取得したJSONが入っている
  })
};
```

前まではuserを取得したらメールアドレスが返ってきていたような気がするけど
こっちのほうがユーザーIDから一気に様々な情報が取れるから便利
ABC - 050- A&B&C

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

**2019/05/27**
　問題名修正
　B問題のコードの書き方を修正 ``int[][]の生成部分``

#A - Addition and Subtraction Easy

 - operandをcharで判定して $\pm$ する

```java
	private void solveA() {
		int numA = nextInt();
		char operand = next().charAt(0);
		int numB = nextInt();

		int res = operand == '+' ? numA + numB : numA - numB;

		out.println(res);
	}
```

#B - Contest with Drinks Easy

 - 全てのパターンでforをするのは時間が間に合わないので
    - 薬を飲まない場合の総時間を算出しておく
    - 薬$P_i$を飲んだ場合、$T_i$と$X_i$の差分を総時間から引くようにする

```java
	private void solveB() {
		int numN = nextInt();
		int[] arrayT = IntStream.range(0, numN).map(i -> nextInt()).toArray();
		long sumT = Arrays.stream(arrayT).sum();
		//		int[] arrayT = new int[numN];
		//		long sumT = 0;
		//		for (int j = 0; j < numN; j++) {
		//			arrayT[j] = nextInt();
		//			sumT += arrayT[j];
		//		}
		int numM = nextInt();
		int[][] arrayPX = Stream.generate(() -> new int[] { nextInt(), nextInt() }).limit(numM).toArray(int[][]::new);
		//		int[][] arrayPX = IntStream.range(0, numM).collect(() -> new int[numM][2], (t, i) -> {
		//			t[i][0] = nextInt();
		//			t[i][1] = nextInt();
		//		}, (t, u) -> {
		//			Stream.concat(Arrays.stream(t), Arrays.stream(u)).toArray();
		//		});

		for (int[] js : arrayPX) {
			long res = (sumT - arrayT[js[0] - 1]) + js[1];
			out.println(res);
		}
	}
```

#C - Lining Up

 - 隣にいるという意味を以下に示す

**奇数人**

|人|1人目|2人目|3人目|4人目|5人目|6人目|
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|両隣の人数の差分|5|3|1|1|3|5|

**偶数人**

|人|1人目|2人目|3人目|4人目|5人目|6人目|7人目|
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|両隣の人数の差分|6|4|2|0|2|4|6|

```java
	private void solveC() {
		int numN = nextInt();
		int[] wk = IntStream.range(0, numN).map(i -> nextInt()).toArray();

		int size = numN - 1;
		int min = 0;
		int max = 0;
		int cntVal = 0;
		int totalCount = 0;

		Arrays.sort(wk);

		if (numN % 2 == 0) {
			if (wk[0] != 1) {
				out.println(0);
				return;
			}
			min = 0;
			max = wk.length - 1;
			cntVal = 1;
		} else {
			if (wk[0] != 0) {
				out.println(0);
				return;
			}
			min = 1;
			max = wk.length;
			cntVal = 2;
		}

		for (int i = min; i < max; i = i + 2) {
			if (wk[i] == wk[i + 1] && wk[i] == cntVal) {
				totalCount++;
			} else {
				out.println(0);
				return;
			}
			cntVal += 2;
		}

		final long CONST = (long) Math.pow(10, 9) + 7;

		long res = LongStream.range(0, totalCount).reduce(1, (sum, i) -> {
			sum = (sum * 2) % CONST;
			return sum % CONST;
		});
		out.println(res);

	}
```
【質問です】暗号化されたウェブサイトの内容を丸々バックアップする方法を教えてください。

【環境】Macユーザーですが、windows 7もあります。
SiteSuckerというソフトで試みたのですが、URLを入力したところ、https://enfac.tv/index.php?action=login
と表示され、statusがIdleとなり完了できません。

enfac.tvという学習サイトの教材ページを、動画やPDFをすべてダウンロードして自分用にバックアップしたいです。動画が多く、ユーザーIDとパスワードが必要な教材ページです。

勉強不足で恐縮ですが、お知恵をお借りできたら幸いです。
プログラミング学習記録46〜あと少し〜

##今日やったこと
- ブログ執筆
- Railsで作っているWebアプリのいいね！欄の投稿をいいね！した順に表示されるように調整

インプット→アウトプットの流れを加速させるためにブログ書きました。
[プログラミング学習記録をQiitaに45日連続で投稿してわかったこと
](https://kinoopy.com/qiita-45days/)

Qiitaにプログラミングの学習記録を投稿して気づいたこと、考えたことについてまとめています。

どんな形であれ、インプットした内容を自分の言葉でアウトプットするのは大事だなと改めて思いました。

1日１記事は難しくても、1日1000字ならなんとかいけそうなので、まずはそこから習慣化していこうと思います。

Qiitaで学習記録の投稿を続けてみた結果、「続けよう！」と思うよりも「途切れさせたくない！」という状態になった方が続けられることがわかりました。

なので、ブログ執筆もその状態にするために、その日書いたブログの記事数と文字数を記録していこうと思います。

とりあえずグーグルのスプレットシートで記録していきます。

<br>
Railsで作ってきたアプリもようやく形になりそうです。

いいね！欄は投稿順にできたので、あとはユーザーページの投稿を作成順に並び替えて、投稿詳細画面に「投稿一覧」に戻るボタンをつけたら、一旦完成ということにしたいと思います。

ユーザーページの投稿はいいね！欄と若干構造が違うので同じようにはいかないですが、もう一度Progateのスライドを見て、並び替えれたらと思います。

ということで、明日からも引き続きプログラミング学習頑張ります。

おわり
ABC - 051- A&B&C

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

#A問題

 - カンマをスペースで置換する

```java
	private void solveA() {
		Scanner scanner = null;
		String wk = "";

		try {
			scanner = new Scanner(System.in);
			wk = scanner.next();

			System.out.println(wk.replaceAll(",", " "));

		} finally {
			if (scanner != null) {
				scanner.close();
			}
		}
	}
```

#B問題

 - $X+Y+Z=S$をみたす数値を総当りで走査

```java
	private void solveB() {
		Scanner scanner = null;
		int numK = 0;
		int s = 0;

		try {
			scanner = new Scanner(System.in);
			numK = scanner.nextInt();
			s = scanner.nextInt();

			int startK = 0;
			if (numK <= s / 3) {
				startK = numK;
			}
			int res = 0;
			for (int i = 0; i <= numK; i++) {
				for (int j = 0; j <= numK; j++) {
					if (s - i - j < 0) {
						break;
					} else if (s - i - j <= numK) {
						res++;
					}
				}
			}

			System.out.println(res);

		} finally {
			if (scanner != null) {
				scanner.close();
			}
		}
	}
```

#C問題

 - 最速の方法は一つ
    - 下に表で記載した図が最速
        - 番号が道順
    - 解説の図がわかりやすい


||1|2|3|4|5|6|
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|1|||||||
|2||4|4|4|||
|3||4|2|E|3||
|4||4|S|1|3||
|5|||3|3|3||
|6|||||||

```java
	private void solveC() {
		Scanner scanner = null;
		int lineSX = 0;
		int lineSY = 0;
		int lineTX = 0;
		int lineTY = 0;

		try {
			scanner = new Scanner(System.in);
			lineSX = scanner.nextInt();
			lineSY = scanner.nextInt();
			lineTX = scanner.nextInt();
			lineTY = scanner.nextInt();

			StringBuilder builderRes = new StringBuilder();

			StringBuilder builderGo = new StringBuilder();
			StringBuilder builderBack = new StringBuilder();

			for (int i = 0; i < lineTY - lineSY; i++) {
				builderGo.append("U");
				builderBack.append("D");
			}
			for (int i = 0; i < (lineTX - lineSX); i++) {
				builderGo.append("R");
				builderBack.append("L");
			}

			builderRes.append(builderGo).append(builderBack);

			builderGo.setLength(0);
			builderBack.setLength(0);

			builderGo.append("L");
			builderBack.append("R");

			for (int i = 0; i < (lineTY - lineSY) + 1; i++) {
				builderGo.append("U");
				builderBack.append("D");
			}
			for (int i = 0; i < (lineTX - lineSX) + 1; i++) {
				builderGo.append("R");
				builderBack.append("L");
			}

			builderGo.append("D");
			builderBack.append("U");

			builderRes.append(builderGo).append(builderBack);

			System.out.println(builderRes.toString());

		} finally {
			if (scanner != null) {
				scanner.close();
			}
		}
	}
```
ROSを使用しRealSenseを複数台繋げる方法

これは，[How-to: Multiple camera setup with ROS](https://www.intelrealsense.com/how-to-multiple-camera-setup-with-ros/)を中途半端に補足，再現したものです．当然原典の方が説明は詳しいので英語力に自身がある人は原典を見たほうが絶対良いです．

なお，ROSの基本的な使用方法や環境構築については述べません．

# 使用環境

|||
|:--:|:--:|
|OS|Ubuntu16.04|
|ROS|ROS kinetic|
|librealsense|v2.18.1|
|realsense ros wrapper|build 2.1.4|
|RealSense|D435i(D435)|

ROSラッパーは使用するlibrealsenseのversionに合わせ適宜入れてください．[librealsenseリンク](https://github.com/intel-ros/realsense/releases)
ここでは，2台のRealSenseを使用することを前提としています．

# 下準備

### librealsense ROS wrapperのビルド

参考記事
[ROS Wrapper for Intel® RealSense™ Devices](https://github.com/intel-ros/realsense/tree/2.0.1)
[RealSense D435をROSで使う](https://demura.net/misc/14263.html)


# 手順

## 1. RealSense各個体のシリアル番号の確認

調べ方

- rosラッパーから  
```
$ roslaunch realsense2_camera rs_camera.launch
```
- realsense-viewerから  
realsense-viewer起動後，個体情報にてシリアル番号を確認します．

## 2. ROSにてRealSenseを起動

#####作業ディレクトリ
```
$ cd ~/catkin_ws
```

#####1台目
```
$ roslaunch realsense2_camera rs_camera.launch camera:=cam_1 serial_no:=<1台目のシリアル番号> enable_pointcloud:=true
```

#####2台目
```
$ roslaunch realsense2_camera rs_camera.launch camera:=cam_1 serial_no:=<2台目のシリアル番号> enable_pointcloud:=true
```

## 3. 位置関係を設定してくれるpublisherを起動

基準としているRealSenseに対して，もう1台のRealSenseがどの位置，姿勢であるかを設定することで，set_cams_transforms.pyが位置関係を調整してトピックを出力してくれます．

```
X: X軸移動量
Y: Y軸移動量
Z: Z軸移動量
Y: Yaw軸の姿勢
P: Pitch軸の姿勢
R: Roll軸の姿勢
```

```
$ python src/realsense/realsense2_camera/script/set_cams_transforms.py cam_1_link cam_2_link X Y Z Y P R 
```
##### 実行例

```
$ python src/realsense/realsense2_camera/script/set_cams_transforms.py cam_1_link cam_2_link 0 0 0 0 40 0
```

## 4. rvizに表示させてみる

```
$ rviz
```

##### 1台目の点群を表示
Displaysにある設定項目の内，**Fixed Frame**を**cam_1_link**に設定します．

![add.png](https://qiita-image-store.s3.amazonaws.com/0/215782/9b894012-e8f6-c28d-60b8-6127498e80a8.png)

Displaysにある設定項目の内，**Add**メニューを開く．  
1台目のRealSenseで取得した点群を表示させたい場合，**By topic**から
`/cam_1 > /depth > /color > /points > PointCloud2`を選択．

![p2.png](https://qiita-image-store.s3.amazonaws.com/0/215782/763c1fb4-2432-2d18-24a8-95f3b4b20923.png)

##### 2台目の点群を表示

**Fixed Frame**は**cam_1_link**の設定のまま，1台目と同様の手順で
`/cam_2 > /depth > /color > /points > PointCloud2`を選択．

## 5.トラブルシューティング

###### rvizの設定で**PointCloud2**が表示されない

- 各RealSenseのノードを立ち上げた時，`enable_pointcloud:=true`を設定したか?
- RealSenseは適切に認識されているか?

## 6. 表示例

1台分のみ表示
![1.png](https://qiita-image-store.s3.amazonaws.com/0/215782/a4a747f7-8528-b417-173d-f973d0774301.png)


2台分を表示
![picture.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215782/32af34a8-df50-6391-04c8-83a259c718ec.png)
Unity カードの移動方法

```csharp:Player.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : MonoBehaviour {
	public Hand hand;
	public Field field;

	public void PushSettingCardOnFieldFromHand(){
		Card card = hand.Pull(0);
		field.Add(card);		
	}
}
```

```csharp:Field.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Field : MonoBehaviour {
	public List<Card> cardList = new List<Card>();
	public void Add(Card _card){
		_card.transform.SetParent(this.transform);
		cardList.Add(_card);
	}
	public Card Pull(int _position){
		Card card = cardList[_position];
		cardList.Remove(card);
		return card;
	}
}

```
```csharp:Hand.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Hand : MonoBehaviour {
	public GameObject cardPrefab;
	public List<Card> cardList = new List<Card>();

	void Awake () {
		for(int i=0; i<5 ; i++){
			GameObject cardObj = Instantiate(cardPrefab);
			Card card = cardObj.GetComponent<Card>();
			this.Add(card);
		}
	}
	void Add(Card _card){
		_card.transform.SetParent(this.transform);
		cardList.Add(_card);
	}
	public Card Pull(int _position){
		Card card = cardList[_position];
		cardList.Remove(card);
		return card;
	}
}
```
```csharp:Card.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Card : MonoBehaviour {	
}
```


スタジオしまづでゲームの作り方を学びたい人向けのサロン▶︎https://camp-fire.jp/projects/view/149191
Google Maps Directions api のGET値まとめ

Google Maps Platform内に含まれるDirections apiを使うことでルート検索時の結果を取得できるっぽい。
実際に経路検索データを取得した過程と取得できたjsonファイルの中身まとめをリアルタイムで更新しています。
確認できていない内容もありますがそこはご容赦ください。


api keyの取得方法が済んでいる前提で話を進めていきたいと思います。
開発環境はmacOS mojave(10.14.4)です。

# データの取得
今回はjupyter notebookを使ってデータを取得して確認しました。
内容を表示するだけなのでライブラリはrequestsのみを使用したシンプルなコードになっています。
requestsが入っていなかったらpip等でインストールしておいてください

    pip install requests


以下コード。今回は東京駅から皇居までの道のりを調べてみます。
パラメータはorigin(出発地点),destination(到着地点),key(api key)が必須です。
他のパラメータについては公式サイトを確認してください（https://developers.google.com/maps/documentation/directions/intro?hl=ja）
時間がパラメータもまとめたい。

    path="https://maps.googleapis.com/maps/api/directions/json" #apiリンク

    #keyは自身が取得したapi keyを入力
    params={"origin":"東京駅","destination":"皇居","key":"api"} 

    return=requests.get(path,params=params)

returnの値を確認してみます。200ならGETできてる。うまくいかなかったらURL, keyあたりを確認してください。

    return
`<Response [200]>` 

jsonファイルの中身を確認。余談だけどいつもjsonの後にかっこをつけ忘れます。

    return.json()

`{'geocoded_waypoints': [{'geocoder_status': 'OK',
   'place_id': 'ChIJC3Cf2PuLGGAROO00ukl8JwA',
   'types': ['establishment',
    'point_of_interest',
    'subway_station',
    'train_station',
...`

どじゃっと値が取得できていることが確認できました。


# jsonファイルの中身

上の項で取得したjsonファイルは以下の3つのステータス？に値が格納されてます。


- geocoded_waypoints : origin,distinationに検索ワード(?)を入れた場合にジオコーディングした結果を返してくれるorigin,distinationの結果が配列内にjson形式で格納されている
- routes : 出発地点から到着地点までの経路と諸々の情報を格納してくれてる。詳細は後述
- status : 検索結果のステータス。OKとかZERO_RESULTの文字列が返ってくる。詳細は要確認




　
geocoded_waypointsとstatus値を実際に確認してみます。

    geocoded_waypoints
`[{'geocoder_status': 'OK',
  'place_id': 'ChIJC3Cf2PuLGGAROO00ukl8JwA',
  'types': ['establishment',
   'point_of_interest',
   'subway_station',
   'train_station',
   'transit_station']},
 {'geocoder_status': 'OK',
  'place_id': 'ChIJTQbYAg2MGGARt22eNwtfGtE',
  'types': ['establishment', 'park', 'point_of_interest', 'premise']}]`

0番目の配列に東京駅の情報が、1番目の配列に皇居の情報が格納されています。ジオコーディングした緯度経度は取得できないみたい？
続いてstatus

    status
`'OK'`

経路探索結果を文字列で取得できます。


## routes
routesですが経路ごとに配列に詳細がjson形式で格納されています。

- bounds : 表示するマップの右上と左下を格納しているっぽい？要確認
- copyrights : googleさんの著作物であることが文字列で格納されています。
- legs : 距離、時間、始点及び終点の住所と緯度経度、経路が格納
- overview_polyline : ルート検索用パス
- summary : google map上で検索した時に表示される経路のまとめが文字列で格納
- warnings : 要確認。
- waypoint_order 要確認。


# まとめ
経路情報を処理して何かしたいなら基本的にroutes内のlegsに格納されている情報で事足りそう。
今日中に全部まとめ終えるように頑張ります。
ブラウザがJavaScriptを直接サポートしない世界

# TL;DR

- WASMって凄いね．JavaScript処理系すら実装できるんだって．
- ならブラウザはWASMだけをサポートすれば楽なんじゃないかな．

という考察記事です．

# 経緯

私は少し前からRustで[JavaScript処理系](https://github.com/maekawatoshiki/rapidus)を書いています．(まだまだ機能不足ですが)

ある日，ふと思いました．*Rustで書いてるんだからWASMに変換するのも楽なんじゃないか?*と．
面白そうなので，試してみたわけです．


# 意外と面倒だった

RustからWASMへと変換する方法を説明した記事は，調べればいくらでもでてきます．無論そのとおりに手を動かしてみるわけです．

しかし，いざやってみるとコンパイラに結構文句を言われます．考えてみれば当たり前ですが，``libc``なんて使っていたらWASMには変換できません．

なので余分なコードは削り，WASMに変換できるようコードを書き直しました．
すると，すんなりWASMに変換することができました．やったね．

# 動いた

そしてついに，ブラウザ上でJavaScript(on WASM)が動いたわけです:

<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">Rustで書かれた JavaScriptエンジンが WASMとして Webブラウザ上で動きました!</p>&mdash; uint256_t (@uint256_t) <a href="https://twitter.com/uint256_t/status/1112688001669173249?ref_src=twsrc%5Etfw">April 1, 2019</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

実際に[ここから](https://maekawatoshiki.github.io/rapidus)試すことができます．まだES6に全然準拠できていないので，お遊び程度のものだと思ってください．

# 何が嬉しいのか

現在，ブラウザは直接JavaScriptをサポートしています．``<script>``の中に書けば動きますね．
ですが，最近は生JavaScriptを書く人は少なくて，TypeScriptなどのAltJSを使う人が多いようです．

こうなると，JSってなんで存在してるんだろうなーと思えてきます．もちろんWebページに動きを加えるためのものですが，別にJSじゃなくても良いわけです．もうちょっと変な挙動のない言語が欲しくなります．

そこでWASMです．
WASMからDOM操作などの今までJSがやっていた仕事が可能になれば，JS処理系をWASM上で動かすことで後方互換性は保たれる．さらに，JS処理系をブラウザ本体から切り離すのも簡単になります．
任意の言語をブラウザ上で実践的に使うことすらできるようになるかもしれない．

--- 

自分で作ったJS処理系が実際にWASM上で動いて，いろんなことを想像しました．
WASMは，確実に今のWebを変えていくんだろうなぁと思っています．
QuantXでグラフを上手く活用する方法

# 自己紹介
株式会社Smart Tradeでインターンをしているkatakyoです。
今回は豆知識を投稿

#QuantXのグラフ分けたい！
<img width="807" alt="スクリーンショット 2019-04-03 19.11.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/318447/1720e03c-5fe6-4b13-ce18-b2e4f29de3c4.png">
9日間のRCIをreturnで描画しました。
これが大量の折れ線グラフを描画するととても見にくいですよね。

##これが今のreturnの書き方です。

```python:
      return {
        "buy:sig":buy_sig,
        "sell:sig":sell_sig,
        "rci9":rci9
      }
```
他のQiitaの記事と特に変わりませんね。

#グラフ２について

**みなさん**
<img width="807" alt="スクリーンショット_2019-04-03_19_11_26.png" src="https://qiita-image-store.s3.amazonaws.com/0/318447/640094f4-ca8e-2a7a-a394-1d510b525262.png">
ここ気になりませんか？

実はQuantXはデフォルトで２つのグラフが用意されているんですよね。
こっちの下に自在に描画できるようになりたい！

#実装は簡単！

```python:
      return {
        "描画したい名前:g2":参照データ名,
      }
```

先ほどのコードだと

```python:
      return {
        "buy:sig":buy_sig,
        "sell:sig":sell_sig,
        "rci9:g2":rci9
      }
```
という風に書きます。


#バックテスト結果
<img width="801" alt="スクリーンショット 2019-04-03 19.10.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/318447/dce04e88-995a-12a5-ad99-e17e9b5ecdc0.png">

ちゃんと描画されていますね！

#終わりに
このグラフ機能は複雑なアルゴリズムを使うほど、データ整理に役に立つと思います。
興味がある方は是非使って見てください！！

#免責注意事項
このコードや知識を使った実際の取引で生じた損益に関しては一切の責任を負いかねません。
Bitriseでtag打ち〜リリースノート作成まで自動化する

## 今回のゴール

1. releaseブランチにマージされたら、それをhookにBitriseのリリースビルドのワークフローを起動
2. 自動でtag打ちし、リリースページをGitHub上に作成する
3. リリースノートにはそのリリースで実装したコミットログが列挙されており、どのリリースでなんの対応をしたか後から把握できる

Bitriseの公式ブログ「[Create release notes and versioning with the release workflow](https://blog.bitrise.io/create-release-notes-and-versioning-with-the-release-workflow)」でタグ打ちをトリガーにリリースノートを自動生成する記事があるが、
タグ打ちまで自動化するといくつかカスタマイズが必要だったので記事にした。

## 完成形
最終的にこんな感じでiTunes Connectデプロイ後、自動でリリースノートが生成される
タグに紐づいたコミットログとそのリンクが一覧で確認できる

<img width="979" alt="release.png" src="https://qiita-image-store.s3.amazonaws.com/0/30423/ee10db09-8bac-4f16-6d94-eec3f6d30df3.png">

## 手順

Stepの手順はこんな感じ。
※実際はDeploy to iTunes Connectの前にビルド番号をインクリメントしたり色々Stepがある

<img width="374" alt="steps.png" src="https://qiita-image-store.s3.amazonaws.com/0/30423/1a42ad75-0345-a7f0-bd56-d9fa6c324646.png">


事前準備としてPUSHトリガーの設定が必要
適宜GitHubのPersonal Access Tokenなど設定してwebhookを有効にする

<img width="1604" alt="trigger.png" src="https://qiita-image-store.s3.amazonaws.com/0/30423/7babd327-8db2-5d26-8b5c-520b3b819196.png">



### 1. タグ名を環境変数としてセットしておく
後工程のリリースノート作成のステップ `Github Release` でタグ名が必要になるが、そのステップでデフォルト指定されている `$BITRISE_GIT_TAG` はタグ打ちをトリガーにしないと値が格納されない。
今回はタグ打ちがトリガーではなく、Pushトリガーのため自前で定義する

#### 自前の環境変数の設定の仕方
Bitriseの環境変数の管理はBitrise社製の[envman](https://github.com/bitrise-io/envman)を使用している。
`script` のステップ内で `envman` コマンドを使えば自前の環境変数が設定できる

参考: [Exposing env vars and using them in another step](https://devcenter.bitrise.io/tips-and-tricks/expose-environment-variable/)

独自環境変数 `GIT_TAG` を設定

```
envman add --key GIT_TAG --value "${XPI_VERSION}(${BITRISE_BUILD_NUMBER})"
```

※ `XPI_VERSION` は `Xcode Project Info` のステップで生成される

### 2.タグ打ちをする
Step: `Git tag` を追加
`Tag to set on current commit` に、1.で指定した環境変数をセットする


### 3.CHANGE LOGを作る
Step: `Generate Changelog` を追加

このステップで生成されるチェンジログは　`$BITRISE_CHANGELOG` として次のリリースノート作成のステップで使える

### 4.リリースノートを作る
Step: `Github Release` を追加
1. の手順で設定した `GIT_TAG` をTag, Release nameに設定

yamlはこんな感じ

``` yml
    - github-release:
        inputs:
        - username: "$GITHUB_USERNAME"
        - name: "$GIT_TAG"
        - body: "$BITRISE_CHANGELOG"
        - tag: "$GIT_TAG"
        - api_token: "$GITHUB_PERSONAL_ACCESS_TOKEN"
```



## メモ
Stepで生成される環境変数は、各ステップ詳細の最下部にある `This step will generate these output variables:` の項目で確認できる

<img width="1095" alt="output.png" src="https://qiita-image-store.s3.amazonaws.com/0/30423/5d6235dd-7045-b2fb-13c8-bd4d8a695c6c.png">
モック使用時におけるexpectとallowの違い

Rspecでモックを作っている際に

expectとallowの違いにつまづいたので、まとめたいと思います。

##モックの作成

```
mock_obj = double('mock name')
```

doubleメソッドでモックを作成することができます。

引数で渡す文字列（この場合だと``mock name``）は任意ですが、設定することでテスト失敗時にメッセージで表示されるので、名前を付けといた方がわかりやすいかもです。


##allowの使い方

```
 allow(Hoge::Grpc) .to receive(:call)
```

RSpecでは ``allow(モックオブジェクト).to receive(メソッド名)`` の形で、モックに呼び出し可能なメソッドを設定することができます。

因みにこの場合だと、``Hoge::Grpc``というモックオブジェクトに、``call``メソッドを設定しています。

**メソッド名はシンボル**で記述することに注意してください。

##expectの使い方

```
expect(Hoge::Grpc).to receive(:call)
```

``expect(モックオブジェクト).to receive(メソッド名)``で、そのメソッドが呼び出されたかを確認することができます。

あれ？両者の違いは・・・？？

##では違いは？？

結論から言うと・・・

``・allowを使って呼び出し可能なメソッドをセットアップしたときは、メソッドが呼び出されなくてもテストが通る。
・expectを使うと、そのメソッドが呼び出されないとテスト失敗になる。``

ということです。


つまり、**モックを使うときは単に実装を置き換えたいだけなのか？**

それとも**メソッドの呼び出しも検証したいのか？**に応じて

allowとexpectを使い分ける必要があるということですね。

##withで引数の確認をすることも可能

```
expect(Hoge::Grpc).to receive(:call).with('Alice')
```

因みに、withをつけることで引数の中身の確認をすることが可能になります。

ここだと``Alice``ですね。

仮に引数に複数の値を渡したいときは、「,」で区切ってあげればOK


```
expect(Hoge::Grpc).to receive(:call).with('Alice', 'alice@example.com')
```

こんな感じですね！

引数がどんな値でも良い場合は``anything``を設定すればOK

```
expect(Hoge::Grpc).to receive(:call).with('Alice', anything)
```



【参考記事】
https://qiita.com/jnchito/items/640f17e124ab263a54dd
https://qiita.com/sesame/items/8d4419da0afde3bb845f
Interface BuilderでUITextViewのテキストに改行を入力する

# Enter キーを押しても改行にならない

Interface Builder の Attributes Inspector でテキストに改行を挿入したいとき、挿入箇所にカーソルを移動して `Enter` キーを押しても改行は入力されません。


ここで `Enter` キーを押しても
![スクリーンショット 2019-04-03 18.49.06.png](https://qiita-image-store.s3.amazonaws.com/0/27943/7b532904-0fd4-a666-0541-459f8b4f4a37.png)


こうなるだけ... :sweat:
![スクリーンショット 2019-04-03 18.49.30.png](https://qiita-image-store.s3.amazonaws.com/0/27943/0862e22f-0540-c079-cd9d-60324551de90.png)

# Option + Enter で改行を入力

改行を挿入したい箇所にカーソルを移動して `Option + Enter` キーを押すと
![スクリーンショット 2019-04-03 18.49.06.png](https://qiita-image-store.s3.amazonaws.com/0/27943/7b532904-0fd4-a666-0541-459f8b4f4a37.png)

無事入力されました :tada:
![スクリーンショット 2019-04-03 18.49.59.png](https://qiita-image-store.s3.amazonaws.com/0/27943/a2e491ff-c8c0-052f-51f2-c133334818c5.png)
WindowsでノートPCをネットワークブリッジにする

#あらすじ
新しくタワー型のデスクトップPC買ったけど、イーサネットしかついてなかった！っていうドジをやらかしたからには、Wi-Fiとイーサネット両方のアダプターを持ったノートPCをブリッジにして、解決っしょ！

#やったこと
「コントロールパネル＞ネットワークとインターネット＞ネットワーク接続」を開く
![bridge1.png](https://qiita-image-store.s3.amazonaws.com/0/167549/9e922266-1316-b084-f3e0-1805c21b1d3d.png)
「Wi-Fi」のプロパティを開き、「共有」のインターネット接続の共有から、チェックボックスにチェックを入れ、「ホームネットワーク接続」のプルダウンメニューから「イーサネット」を選択する
![bridge2.png](https://qiita-image-store.s3.amazonaws.com/0/167549/00f26d93-4993-907e-5443-22a3a93566de.png)

これでイーサネットで繋がるPCが、このノートPCを介してWi-Fiを利用することができる

#最後に
「コントロールパネル＞ネットワークとインターネット＞ネットワーク接続」で「イーサネット」を右クリックで「ブリッジ接続」を選ぶだけでいいかと思ったけど何故かできなかった
Unity   カードの生成と反映方法


```csharp:Card.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Card : MonoBehaviour {
	public Text hpText;
	int hp;
	string name;

	public void Load(CardData _cardData){
		hp = _cardData.hp;
		hpText.text = hp.ToString();
		name = _cardData.name;
	}
}

```


```csharp:CardGenerater.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CardGenerater : MonoBehaviour {
	public GameObject cardPrefab;
	public GameObject hand;
	// Use this for initialization
	List<CardData> cardDataList = new List<CardData>(){
		new CardData(1, "スタジオしまづ", 1),
		new CardData(2, "マリオネットAI", 10),
		new CardData(3, "コマンドクラフト", 5),
	};

	void Start () {
		for(int i=0; i<cardDataList.Count; i++){
			GameObject cardObj = Instantiate(cardPrefab);
			cardObj.name = cardDataList[i].name;
			cardObj.transform.SetParent(hand.transform);

			Card card = cardObj.GetComponent<Card>();
			card.Load(cardDataList[i]);
		}
	}
		
}
```



```csharp:CardData.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CardData {
	public int id;
	public string name;
	public int hp;

	public CardData(int _id, string _name, int _hp){
		id = _id;
		name = _name;
		hp = _hp;
	}
}
```
スタジオしまづでゲームの作り方を学びたい人向けのサロン▶︎https://camp-fire.jp/projects/view/149191
Pythonを使って基本変形で逆行列を求める。


## np.linalgを使わず逆行列を求めたい。

Pythonを用いて正則行列Aの逆行列を求めるには、numpyを用いてnp.linalg.inv(A)と入力すれば
あっという間に出てきます。




しかしここではあえてその方法を用いず、基本変形を用いて逆行列を求めてみたいと思います。

---
#### まずは正則行列Aをひとつ定める。
例えば今回はAとして以下の様な行列をとることにします。

```python:
import numpy as np
A = np.array([[2.,1.,1.,1.],[3.,0.,-2.,1.],[0.,-1.,0.,-2.],[3.,1.,1.,1.]])
```
※行列の成分の数字を書くとき、3 などと書かずに3. のように書かないとその後の計算がうまくいきません。

因みに、以下の様に書くと軸の数が分かります。

```python:
A.ndim
```
#### 次に単位行列を定義。
通常単位行列はEやIという記号を使って表しますが、ここではこの後この行列に色々操作を加えていくため、Xを使うことにします。

```python:
X = np.array([[1.,0.,0.,0.],[0.,1.,0.,0.],[0.,0.,1.,0.],[0.,0.,0.,1.]])
```

#### 関数(写像)を定義。
では、正則行列Aをインプットするとその逆行列がアウトプットされる関数Inv(A)を実際に作っていきます。

```python:
import numpy as np

def Inv(A:list) -> list:
    X = np.array([[1.,0.,0.,0.],[0.,1.,0.,0.],[0.,0.,1.,0.],[0.,0.,0.,1.]])
    #まずAを上三角行列にする。
    for p in range(len(A)):
        pivot = A[p][p]
        for j in range(p+1, len(A)):
            coef = A[j][p] / pivot
            A[j] -= A[p] * coef
            X[j] -= X[p] * coef
    #途中経過確認。
    #print(A)
    #print(X)
    #対角成分を1にする。
    for i in range(len(A)):
        X[i] /= A[i][i]
        A[i] /= A[i][i]
    #途中経過確認。
    #print(A)
    #print(X)
    #答えを出す。
    for i in range(len(A)-1,0,-1):
        for j in range(i):
            X[j] -= X[i] * A[j][i]
            A[j][i] = 0
    return X
```
あとはこの関数にAを代入すれば完了です。

```python:
#逆行列を基本変形により求める。
A = np.array([[2.,1.,1.,1.],[3.,0.,-2.,1.],[0.,-1.,0.,-2.],[3.,1.,1.,1.]])
print(Inv(A))
```
React Native で、 Release ビルドの時のみ、 resizeMode="center" がバグる

原因不明だが、メモ。

```js
<Image resizeMode="center" source={require('./image.png')} style={styles.image} />
```

とすると、 **本番ビルドの時のみ** 画像がおかしくなる。

`resizeMode="contain"` とすると、ほぼ同じ挙動で治るので、可能であればこちらを使う。

```js
<Image resizeMode="contain" source={require('./image.png')} style={styles.image} />
```

ちなみに Android ではこうならない。謎。
CATransitionはアニメーションさせたいとき毎回追加する必要がある

UILabelでテキストを変更した際に遷移アニメーションをさせたくて、以下のようなクラスを作成しました。

```swift
class AnimatedLabel: UILabel {
    override init(frame: CGRect) {
        super.init(frame: frame)
        setup()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setup()
    }

    private func setup() {
        let animation = CATransition()
        animation.type = .reveal
        animation.subtype = .fromBottom
        animation.timingFunction = CAMediaTimingFunction(name: .easeOut)
        animation.duration = 1
        layer.add(animation, forKey: "transition")
    }
}
```

これでテキストを変更するたびにアニメーションが実行されるだろうと思っていたのですが、アニメーションが実行されませんでした。

テキストを変更するコードの直前でアニメーションオブジェクトを確認したところ、`nil`となっていました。

```swift
print(label.layer.animation(forKey: "transition"))  // nil
```

ドキュメントで確認ができていないのですが、一度アニメーションを実行したらオブジェクトは削除されてしまうのでしょうか。

仕方ないのでアニメーションさせたいときは以下のように毎回CATransitionオブジェクトを作ってレイヤーに追加するようにしました。

```swift
let animation = CATransition()
animation.type = .reveal
animation.subtype = .fromBottom
animation.timingFunction = CAMediaTimingFunction(name: .easeOut)
animation.duration = 1
label.layer.add(animation, forKey: nil)

label.text = "Changed!"
```
Selenium webdriverメソッド~PHP~

SeleniumをPHPで書くときのメソッドのまとめがほしいなと思ったので
よく使うであろう基本的なメソッドをまとめました。
# メソッド一覧
## 指定したURLへ遷移
```php
$driver->get("URL");
```
## ウィンドウを閉じる
```php
$driver->close();
```
## 全てのウィンドウを閉じる
```php
$driver->quit();
```
## 一つもどる
```php
$driver->navigate()->back();
```
## 一つ進む
```php
$driver->navigate()->forward();
```
## ブラウザを更新する
```php
$driver->navigate()->refresh();
```
## URLを取得する
```php
$driver->getCurrentURL();
```
## タイトル取得
```php
$driver->getTitle();
```
## スクリーンショット取得
```php
$driver->takeScreenshot("場所とファイル名");
```
## 要素取得
```php
$driver->findElemenet(WebDriverBy::id("ID"));
$driver->findElemenet(WebDriverBy::name("NAME"));
$driver->findElemenet(WebDriverBy::tagName("TAGNAME"));
$driver->findElemenet(WebDriverBy::cssSelector("CSSSELECTOR"));
// 複数取得
$driver->findElements(WebDriverBy::className("CLASSNAME");
```
## 要素をクリック
```php
$driver->findElement(WebDriverBy::id("ID"))->click();
```
## 要素のテキストを取得
```php
$driver->findElement(WebDriverBy::id("ID"))->getText();
```
## テキスト入力
```php
$driver->findElement(WebDriverBy::id("ID"))->sendKeys("入れたいテキスト");
```
## 入力された値をクリア
```php
$driver->findElement(WebDriverBy::id("ID"))->clear();
```
## 属性の取得
```php
$driver->findElement(WebDriverBy::id("ID"))->getAttribute("属性");
```
## 要素が表示されるまで待つ
```php
$driver->wait(10)->until(
  WebDriverExpectedCondition::visibilityOfElementLocated(WebDriverBy::id("ID"))
);
```
また更新します。
ネームサーバとは

お客さんに、サイトの移行をしたい時にネームサーバを移行してサーバを変えます。
と言われた時に、ネームサーバについて誤解があったので適切な説明をしたかったが語彙力がなくうまく説明できなかった話です

実際のところ、ネームサーバを変更しただけではサイトは移行できないかもしれないし、メールをロストすることにもつながる。

ネームサーバは、ドメイン設定の管理台帳をどのサーバが持つか設定できるものと考える。
管理台帳の所有権？優先権？の情報のみのため、ネームサーバだけ移行すると、ドメインがどのサーバに向けられているか、という情報が消えてしまう。
あらかじめ転記しておくか、新たに新しいネームサーバ側に設定しておく必要がある。

https://www.xserver.ne.jp/manual/man_domain_namesever_setting.php

> ネームサーバーとは、対象のドメインをどのサーバーで使用するか決定するためのアドレス、とお考えください。

某レンタルサーバの説明がおかしい気がするのは気のせいでしょうか

だれかもっと分かりやすい説明があったら教えてください
DockerでWordPress環境を構築したらしくじった。でも頑張ったら上手く行ったので情報共有します。

初投稿です。覚書のようなものなので、ざーっとラフに記載します。

- [dockerでWordPressローカル開発環境を作りました。](https://qiita.com/pugiemonn/items/809e847ff0b4235a8380)
- [今更だけどDockerでWordPress環境を用意してみたら超簡単だった](https://qiita.com/maimax/items/5090fd37f9832fe3c5fd)

こちらの記事を参考にさせていただきつつ、Docker上でWordPressのローカル環境を構築してみたものの、自分の環境ではうまく動きませんでした。環境は下記。

- MacBookPro2018 + MacOSX Mojave(10.14.3)
- DockerDesktop 2.0.0.3(31259)

ローカルWEBサーバー(WordPress側)、ローカルDBサーバー(MySQL側)共に動作しているのですが、WordPress側がMySQL側を参照できていないようで `Error establishing a database connection` が表示されました。

原因を調べたところ、MySQLのバージョンがVer8系だったことに起因していました。バージョン未指定でMySQLのImageをDocker Hubからpullすると、latest(Ver8系最新版)がダウンロードされます。しかしWordPressはそのままではMySQL Ver8系では正常動作しないようです。

ググってみたところ、MySQL Ver8系でWordPressを正常動作させる方法は色々あるようですが、一旦動作するところまで持っていきたかったため、 `docker run` コマンドでコンテナを走らせる際、Ver5.7系のImageを使うよう、下記の指定をしたところ無事に動作しました。

```
docker pull mysql:5.7.25
docker pull wordpress:4.9.1

docker run --name mysql5.7.25 -e MYSQL_ROOT_PASSWORD=password -d mysql:5.7.25
docker run --name wordpress4.9.1 -v /Users/dee909/dev/docker:/tmp --link mysql5.7.25:mysql -d -p 8080:80 wordpress:4.9.1
```

動作検証は、WordPress Ver4.9.1、MySQL Ver5.7.25で行いました。
もし、私と同様に行き詰まった際はお試しください。
セキュリティ等の観点からWordPress、MySQL共に最新版が望ましいので、自力解決できる方はチャレンジいただければと思います。
そしてヒントを下さった、@pugiemonnさん、@maimaxさん、ありがとうございました。

##### 追記1
コンテナを走らせる際に、MySQL側にポートフォワーディングを追加してやると、[Sequel Pro](https://www.sequelpro.com/)等からもDBへのアクセスが可能になります。下記はポート3307を3306にフォワードさせています。GUI操作がお好みの方は、一緒に設定してしまうと良いと思います。

```
docker run --name mysql5.7.25 -e MYSQL_ROOT_PASSWORD=password -d -p 3307:3306 mysql:5.7.25
```
![スクリーンショット 2019-04-03 20.58.45.png](https://qiita-image-store.s3.amazonaws.com/0/391533/b6c31e02-9c7a-e3b9-2c04-20287b477b0c.png)

##### 追記2
WordPress側の `-v` オプションはホストとコンテナ内のディレクトリ共有のための紐付けですので、ご自身の環境に合わせて変更してください。共有が不要ならば、まるっと削除しても問題ないです。
サンプルの `docker run` コマンドではホスト上の `/Users/dee909/dev/docker` ディレクトリをコンテナ内の `/tmp` ディレクトリに紐付けしていますが、 `-v /Users/dee909/dev/docker:/var/www/html` と変更することで、ホスト側（MacOSXやWindows上）に設置したWordPressをコンテナのWEBサーバー上で動作させることができます。
こちらの方がホスト側のテキストエディタでコード編集が行えますし、ホスト上のディレクトリをgit管理することもできますので、使い勝手が良いと思います。

##### 追記3
社内の人間から「複数のディレクトリ共有はできないのか？」と聞かれました。結論を述べますと「できます」。非常に簡単でして、 `-v ホストディレクトリ名：コンテナ内ディレクトリ名` の引数を複数指定するだけです。またMySQL側のコンテナも、データベースファイルのディレクトリをホストとコンテナで共有してやることで、データベースの永続化（コンテナを作り直してもデータベースが初期化されない）が可能となります。最終的に私の環境では下記の設定でコンテナを起動、運用する形を取っています。

```
docker run --name mysql5.7.25 -v /Users/dee909/dev/docker/mysql:/var/lib/mysql -v /Users/dee909/dev/docker/tmp:/tmp -e MYSQL_ROOT_PASSWORD=password -d -p 3307:3306 mysql:5.7.25

docker run --name wordpress4.9.1 -v /Users/dee909/dev/docker/html:/var/www/html -v /Users/dee909/dev/docker/tmp:/tmp --link mysql5.7.25:mysql -d -p 80:80 wordpress:4.9.1
```
batファイルを利用した簡単なスタートアップを作成してみた

##なぜ作ろうと思ったか
「やる気を出すには形から」という事で、開発に利用する諸々を一動作で全て起動する事が出来ればとても素晴らしいのではと考え、実際に作成してみました。

##開発環境
・windows10

##やりたい事
一動作での
・テキストエディタの起動
・よく使うwebページ達の表示
・WorkSpaceまでCDされたコマンドプロンプトの起動

##実際に書いていく
###テキストエディタの起動

```startup.bat
START C:\Users\ajun\AppData\Local\atom\atom.exe
```

`START C~`で指定したパスのアプリを起動
僕はatomを利用しているので、今回はatom.exeのパスを記入しました。


###webページの表示
初めに駄目な例を記載します。初めはこう書いていました

```notstartup.bat
START https://github.com/ajunajunajun?tab=repositories 
START https://qiita.com/ajunajunajun
```
既にwebブラウザが開かれている状態であればこれで全てのurlを開けますが、webブラウザが開かれていない場合一番上に書かれたurlしか開けないようです。
webブラウザの起動に時間が掛かるのが問題だと思います。
なので初めにwebブラウザを起動する所から書いていきます。

```startup.bat
START "" "C:\Program Files\Mozilla Firefox\firefox.exe" https://github.com/ajunajunajun?tab=repositories https://qiita.com/ajunajunajun
```
`START "" "C:\Program Files\Mozilla Firefox\firefox.exe"`で webブラウザを起動。
その後ろに開きたいurlを記入する事により開くことが出来ます。
複数開きたい場合はurlを空白で区切ってください。


パス内に空白があった場合、パス自体を`""`で挟まないとエラーが起きてしまいます。
また、挟むだけだとそのパスがタイトルとなったコマンドプロンプトが起動されてしまうので、パスの前に`""`で空白のタイトルを指定する事が必要となります。

###WorkSpaceまでCDされたコマンドプロンプトの起動
```startup.bat
@echo off
cmd /k cd C:\Users\ajun\WorkSpace
```
`cmd`でコマンドプロンプトを起動、
`/k`で後ろのコマンドを利用することが出来ます。
この一行だけで十分ですが、利用したコマンドが表示されてしまいますので、
`@echo off`で表示を消して綺麗にしておきます。

##まとめ

```startup.bat
@echo off
START C:\Users\ajun\AppData\Local\atom\atom.exe
START "" "C:\Program Files\Mozilla Firefox\firefox.exe" https://github.com/ajunajunajun?tab=repositories https://qiita.com/ajunajunajun
cmd /k cd C:\Users\ajun\WorkSpace
```

これにて完成です。
このbatファイルを起動するだけで開発の為の諸々を起動する事が可能となりました。
bat触るの初めてでしたが1時間程度で形に出来ました。
初めてのqiita投稿の為つたない記事かと思いますが、閲覧していただきありがとうございました。

##参考文献
バッチファイルでいつも使うアプリケーションやホームページをらくらく起動
https://tonari-it.com/windows-bat-start/
batファイルを使いfirefoxで複数のtabを開く
https://teratail.com/questions/74163
Kotlin の Suspending 関数を Mockito で spy する

[mockito-kotlin](https://github.com/nhaarman/mockito-kotlin) を使って Suspending 関数を含むクラスのテストを書いていたところ、現状ではちょっとしたコツが必要なことが分かった。

以下の `DownloadService#downloadFile()` を呼び出す別のメソッドをテストするため、このインターネットと通信する `downloadFile()` メソッドをモックに置き換えようとした。

`mock()` を使った以下のコードは正常に実行可能。

```kotlin

class DownloadService {
    suspend fun downloadFile(url: String): File {
        // 省略
    }

    // 実際には別のメソッドも定義されている
}

@Test fun testDownloadFile() {
    val file = createTempFile()
    val target = mock<DownloadService>() {
        onBlocking{ downloadFile(any()) } doReturn file
    }
    runBlocking {
        val downloadedFile = target.downloadFile("http://example.com")
        assertEquals(file, downloadedFile)
    }
}
```

実際には `DownloadService` クラスに含まれる `downloadFile()` メソッド以外はモックを使わずにそのまま実行されて欲しかったので、`mock()` を `spy()` に置き換え、このメソッドだけをモック実装する形に。

```kotlin
@Test fun testDownloadFile() {
    val file = createTempFile()
    val target = spy<DownloadService>() {
        onBlocking{ downloadFile(any()) } doReturn file
    }
    runBlocking {
        val downloadedFile = target.downloadFile("http://example.com")
        assertEquals(file, downloadedFile)
    }
}
```

ところが、このテストコードを実行すると `NullPointerException` がスローされてしまう(4 行目で実行される Stub 処理中に)。

`mock()` はいいけど `spy()` だとダメ。
しかしながら、このように `spy()` を使ってもモック対象(今回の例で言うと `downloadFile()` メソッド)が引数を取らない場合は、NPE がスローされることなくテストを実行できることが分かった。

試行錯誤した結果、`spy()` にラムダ式でモック処理を渡すのではなく、次のように `doReturn().whenever().xxxx()` のコードでモック処理を書けば正常にテストが実行できるようになった。

```kotlin
@Test fun testDownloadFile() = runBlocking {
    val file = createTempFile()
    val target = spy<DownloadService>()
    doReturn(file).whenever(target).downloadFile(any())
    val downloadedFile = target.downloadFile("http://example.com")
    assertEquals(file, downloadedFile)
}
```
sqliteを使ってCRUDができるサイトを作ってみた(前編)

#はじめに
このブログは2部構成です。
前編では、プロジェクト、コントローラー、モデル、テーブルの作成、サイトへのアクセスを
後編では、CRUDの作り方、データの１連の流れを紹介していきます。

# 狙い
mysqlのバージョンをあげてからmysqlを使えなくなった。
(migrationコマンドは通るが、データの登録が通らないのでsqliteを使うことでデータの登録、更新ができた。)

#バージョン(2019年4月3日時点)

```
$ php -v
PHP 7.3.3 (cli) (built: Mar  8 2019 16:40:07) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.3, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.3.3, Copyright (c) 1999-2018, by Zend Technologies
```


#開発環境
vagrantを使う。

vagrantを使用した開発環境の構築についてはここでは紹介しない。



#仮想環境にアクセスする
```
$vagrant up
```
でvagrantを立ち上げる。

```
$vagrant ssh
```

で、vagrantにssh接続する

```
vagrant@homestead:~$ cd /vagrant/
```

することでホームディレクトリに移動する

##プロジェクトを作成する
```
vagrant@homestead:/vagrant$ composer create-project laravel/laravel example
```
プロジェクトに移動する

```
vagrant@homestead:/vagrant$ cd example/
vagrant@homestead:/vagrant/example$ 
```

## コントローラーとモデルを作成する
上：コントローラー、下：モデル(migrationファイルも作成される)

```
php artisan make:controller ExampleController -r
php artisan make:model Example -m
```

##.envを編集する
```php
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret
```
を

```php
DB_CONNECTION=sqlite
```
にした後でsqliteを使うために以下コマンドをうちます。


```

$touch database/database.sqlite
```

ここまで来たらもう少しです。頑張ってください。

## migrationファイルの作成

```
database/migration/20YY_MM_DD_HHMMSS_create_examples_table.php
```
ファイルを編集していく

```php
public function up()
{
    Schema::create('examples', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->timestamps();
    });
}
```

```php
public function up()
{
    Schema::create('examples', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->string('title');//追加
        $table->text('content');//追加
        $table->timestamps();
    });
}
```
ちなみに、create_user,create_passwordテーブルは今回使用しないので、削除しても構いません。


できたら、migrateコマンドを打ってテーブルを作成します。

```
$php artisan migrate
Migrating: 2019_04_03_084022_create_examples_table
Migrated:  2019_04_03_084022_create_examples_table

```

 が出てきたら成功です。

#サイトを見てみよう

もう一つterminalを開いて自分が作成したフォルダまで移動して以下のコマンドを打つ。


```
$php artisan serve
Laravel development server started: <http://127.0.0.1:8000>
```

と出てくるので、ブラウザで<a href="http://localhost:8000"target="_brank>http://localhost:8000</a>にアクセスする。
![スクリーンショット 2019-04-03 17.59.11.png](https://qiita-image-store.s3.amazonaws.com/0/343721/19a4ea76-7f98-8fee-5024-8d8aecf186c5.png)

このページが見れたらOK！

(後編へ続く)
macos+homebrew+postgres で接続エラー「PG::ConnectionBad: 〜"/tmp/.s.PGSQL.5432"?」を解決

### 2022/10/19 追記

Homebrew でインストールしていると、postmaster.pidのパスが変わっていた。
こちらを削除することで解決できる。
```
cd /opt/homebrew/var/postgres
rm postmaster.pid
```

# 環境
* macOS Mojave 10.14.4
* postgres (PostgreSQL) 11.2
* `brew install postgresql`しています


```terminal:エラーを確認
 $ psql -l
 PG::ConnectionBad: could not connect to server: No such file or directory
     Is the server running locally and accepting
     connections on Unix domain socket "/tmp/.s.PGSQL.5432"?
```

```terminal:これで解決できた報告あったけど、解決できませんでした
 $ rm /usr/local/var/postgres/postmaster.pid
```

```terminal:サービスを開始・停止・再起動させてみる
 $ brew services start postgresql
 $ brew services stop postgresql
 $ brew services restart postgresql
```

```terminal:postgresのメジャーバージョンアップ時（v9.0->v10.0など）
 $ brew postgresql-upgrade-database
```

ここで解決できていることを🙏っていたのですが、🙅。

## それでもダメ→postgresのログを確認

以下のコマンドを実行したときに表示されるログで気づきました。**postgresが使うディレクトリが不足していてサービスの起動ができない挙動** をしていました。

```terminal:それでもだめなら。ログを見てエラー箇所を特定
 $ postgres -D /usr/local/var/postgres
 // TODO: ここでエラーになっているメッセージに従う
```

以下、作成したディレクトリ（環境によって異なるかもしれません。`postgres -D /usr/local/var/postgres`を実行しながら１つずつ解決していってください）

```terminal:足りなかったディレクトリ
 mkdir /usr/local/var/postgres/pg_replslot
 mkdir /usr/local/var/postgres/pg_twophase
 mkdir /usr/local/var/postgres/pg_stat
 mkdir /usr/local/var/postgres/pg_tblspc
 mkdir /usr/local/var/postgres/pg_commit_ts
 mkdir /usr/local/var/postgres/pg_logical
 mkdir /usr/local/var/postgres/pg_logical/snapshots
 mkdir /usr/local/var/postgres/pg_logical/mappings
 ```

## 追記：2020/01/09 libicui18n.61.dylibがみつからない

ログに、**libicui18n.61.dylibがみつからない**エラーが出ました。

```terminal
dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.61.dylib
  Referenced from: /usr/local/bin/postgres
  Reason: image not found
```

[PHP \-vしたら「dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n\.61\.dylib」と出るときの対処法 \- Qiita](https://qiita.com/yasu_yyy/items/2f6a6b0bc562f082d999)を参考にhomebrewをアップデートすることで解決できました。 :pray: 

```terminal
brew update && brew upgrade
```

## 追記：2020/03/12 データベースのバージョンが違う

バージョン10から11にアップグレードしたときもこのエラーが出る場合がありました。

```console:postgresqlのバージョンが違っていますという旨のエラーがでます
$ postgres -D /usr/local/var/postgres
FATAL:  database files are incompatible with server
DETAIL:  The data directory was initialized by PostgreSQL version 11, which is not compatible with this version 12.2.
```

[この記事](http://unot13.hatenablog.com/entry/2018/01/22/145354)によると「`brew info postgresql`すると、DBのアップグレードコマンドも表示される」とあったので試してみると、うまくいきました。

```console
$ brew postgresql-upgrade-database
・・・（省略）
==> Upgraded postgresql data from 11 to 12!
==> Your postgresql 11 data remains at /usr/local/var/postgres.old
==> Successfully started `postgresql` (label: homebrew.mxcl.postgresql)
```
Imagickで斜体文字を合成する備忘録

ItalicではなくObliqueらしい。
https://cottala-becco.com/italic_and_oblique/


```php:sample.php
<?php
declare(strict_types = 1);

/*
 文字
 */
$text	= "あああああ\nいいいいい";
$x		= 0;
$y		= 100;
$o_text = new ImagickDraw();
$o_text->setFillColor( new ImagickPixel('#0000ff') );
$o_text->setTextUnderColor( new ImagickPixel("rgba(204, 204, 204, 0.5)") );	//背景色(デバッグ用)
$o_text->setTextAntialias(false);				//アンチエイリアス解除
$o_text->setFontSize(35);
$o_text->setFont('フォントファイルのパス');
$o_text->skewX(-15);							//水平方向に傾ける
$o_text->setGravity( imagick::GRAVITY_NORTH );	//一旦中央寄せ
$o_text->annotation($x, $y, $text);				//その後、位置を微調整

/*
 背景画像合成
 */
$o_base = new Imagick('base.png');
$o_base->drawImage($o_text);
$o_base->setImageFormat('png');
$o_base->setImageCompressionQuality(0);	// https://stackoverflow.com/questions/9710118/convert-multipage-pdf-to-png-and-back-linux/12046542#12046542

//ファイル保存
if (!true) {
	$o_base->writeImage('hoge.png');
}
//直接表示
else {
	header("Content-Type: image/png");
	echo $o_base;
}

/*
 メモリ解放
 */
$o_base->destroy();
$o_text->destroy();
```

# できあがり

![generate.png](https://qiita-image-store.s3.amazonaws.com/0/166473/26db6184-62ce-6ed1-14cf-28b6566567da.png)
【AMP】Gmailで「AMP for Email」をテストしてみた

「AMP for Email」とは、AMPのテクノロジーを利用し、動的なコンテンツの配信をメールで可能にするものです。

今回、AMPを使った動的メールをとりあえずテストして、実際にできることと、動作を試しに確認してみました。

「[AMP for Email Playground](https://amp.gmail.dev/playground/)」を使用すると、気軽にAMP Eメールの下書きができたり、ライブプレビューの確認や、送信テストのため、実際に自分のGmailアカウントへ作成したAMP Eメールの送信を行うことができます。

## テストするにはGmailの設定変更が必要

Gmailを開き、[設定]→[全般]→[動的メール]に移動して、[動的メールを有効にする]にチェックをいれます。

<img width="1284" alt="スクリーンショット_2019-04-03_17_06_04.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/67591/35c62ac6-5fd4-7f16-fe1d-1e77dde19156.jpeg">

これにより、テスト目的で動的なEメールを送信できるEメールアドレスをホワイトリストに登録できるダイアログが開きます。

ホワイトリストに入力したアドレスからGmailアカウントに送信されたAMPが適用されたメールは、アカウントがGoogleに登録されていなくても表示されます。

以上の設定で、自分のアカウントに動的メールを送信すれば、期待どおりに機能しているかテストすることができます。

「[AMP for Email Playground](https://amp.gmail.dev/playground/)」から自分のアカウントにAMP Eメールを送信するには、ホワイトリストに「amp@gmail.dev」を登録します。

<img width="1283" alt="スクリーンショット_2019-04-03_17_06_27.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/67591/d5ad4ab3-ea4e-3d27-d43d-d028dcc4d9b7.jpeg">

##実際のメールデモ

##カルーセル
`<amp-carousel>`を使ってみました。
外部から画像を読み込む場合は、Gmailの[設定]→[全般]→[メッセージ内の画像]で、[外部画像を常に表示する]にチェックをいれる必要があります。

![amp_mail.gif](https://qiita-image-store.s3.amazonaws.com/0/67591/794125c8-2e45-c041-650b-bad50e0e4f9f.gif)

##フォーム
`<amp-form>`を使ってみました。
フォームに関しては活用方法を色々考えることができ、夢が拡がりそうですね。

![amp_mail2.gif](https://qiita-image-store.s3.amazonaws.com/0/67591/a170380a-53ea-c66a-088f-c3899f6c5dde.gif)
railsチュートリアル１章　herokuへのデプロイに七転八倒。

#railsチュートリアル１章後半のherokuへのデプロイにつまづきまくったので、2度とここでつまづかないようにまとめておきます。

railsチュートリアル1.5で

`git push heroku master`

を実行した後に生成されたアドレスをブラウザで開こうとしたら、
Application Errorの文字が、、、

下に書いてある
`heroku logs --tail`
を実行しても、

```
2019-04-02T08:45:11.178789+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/" host=cherry-pudding-18708.herokuapp.com request_id=418c602d-6211-4552-9488-abbfd39fae16 fwd="115.69.237.151" dyno= connect= service= status=503 bytes= protocol=https
2019-04-02T08:45:11.634170+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/favicon.ico" host=cherry-pudding-18708.herokuapp.com request_id=7d395db1-345a-40ad-833c-8e770f0b8b7b fwd="115.69.237.151" dyno= connect= service= status=503 bytes= protocol=https
^C
```
何言ってるか分かりません。笑

ここで
`heroku run rails console`
を実行。

```
`Add `gem 'sqlite3'`to your Gemfile (and ensure its version is at the minimum required by ActiveRecord). (Gem::LoadError)
```

の文字が。

railsチュートリアルのいうことを正確に聞いてきた人には分かりますが、`sqlite3`はGemfileで実行してますよ！？！？

ここで、またググる。

すると、ここの記事に答えに繋がりそうなことが、、、！
[Rails Tutorial](https://qiita.com/Tonkachi0620/items/28aa3ce0c00a7e93d568)


原因
---
.bundle/config　の中身が
`BUNDLE_WITHOUT: "production"`
になっていることが原因らしい。

あと、`database.yml`も変更する必要があるっぽい。

---
対策
---
.bundle/configってどこにあるんだと思って探したけど、どこにも見つからなかったので、c9コマンドでそこまで移動。
`BUNDLE_WITHOUT: "production"`
を
`#BUNDLE_WITHOUT: "production"`
に変更。





それでもうまくいかない。
そこで、

```datebase.ytml
production:
  <<: *default
  adapter: postgresql
  database: db/production.pg
```
に変更。

それでもうまくいかない、、、。

一旦、もう一度`heroku run rails console`をしてみると、

```
Add `gem 'pg'` to your Gemfile (and ensure its version is at the minimum required by ActiveRecord). (Gem::LoadError)
```
あれ？ `Add gem 'pg'`に変わってる！！
これを解決すれば、デプロイできるぞ、、、と思い、ググるが、答えが見つからない。
そこで、色々いじった後に　`git push heroku master`を実行してないことに気づき、実行。

これでデプロイが完了した。２日間格闘した甲斐があった。（おそらく、ここまで分からなかったら飛ばして次に行くほうが効率がいい）

---

まとめ
---
おそらく、`database.yml`の変更が解決法に繋がったと考える。
それと、`heroku run rails console`で確認をすると丁寧にどこが間違っていたのかを教えてくれるので、有効活用していきたい。


---