OmniAICreator/Qiita-1.07M huggingface dataset:
Java Sound APIを使ってMIDIファイルを再生する方法

#はじめに
この記事では、Java Sound APIを使用してMIDIファイルを再生する方法を備忘録的にまとめます。
とりあえず再生・停止ができる程度な初歩的な記事です。
#サンプルコード
こちらがサンプルのソースコードです。
コンソール入力でMIDIファイルのパスを入力すると、MIDIが再生されるというシンプルなプログラムです。
めちゃくちゃ適用な例外処理を行っているので、そこらへんは勘弁してください。m(__)m

```java:SamplePlayer.java
import java.io.File;
import java.io.IOException;
import java.util.Scanner;

import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.MidiUnavailableException;
import javax.sound.midi.Sequence;
import javax.sound.midi.Sequencer;

public class SamplePlayer {

	public static void main(String[] args) {
		// MIDIデータを再生するハードウェア/ソフトウェア・デバイスのインスタンス。
		Sequencer sequencer = null;

		try {
			// デバイスに接続されたデフォルトのSequencerを取得する。
			sequencer = MidiSystem.getSequencer();

			// デバイスを開き、リソースを獲得する。
			sequencer.open();
		}
		catch (MidiUnavailableException e) {
			e.printStackTrace();
		}

		// コンソール入力からMIDIファイルのパスを取得する。
		Scanner scanner = new Scanner(System.in);
		System.out.print("MIDIファイルのパス >> ");
		String path = scanner.next();

		try {
			// MIDIファイルからMIDIデータ(Sequenceオブジェクト)を取得。
			File file = new File(path);
			Sequence sequence = MidiSystem.getSequence(file);

			// 取得したMIDIデータをシーケンサに設定する。
			sequencer.setSequence(sequence);
		}
		catch (InvalidMidiDataException e) {
			e.printStackTrace();
		}
		catch (IOException e) {
			e.printStackTrace();
		}

		// シーケンサー再生
		sequencer.start();

		// キー入力待ち
		System.out.println("適当に文字列を入力すると終了します。");
		System.out.print(">>");
		scanner.next();
		scanner.close();

		// シーケンサー停止
		sequencer.stop();

		// シーケンサーを閉じ、使用していたリソース解放する。
		sequencer.close();
	}
}
```
#解説

###シーケンサーを用意
MIDI再生に必要なオブジェクトを取得します。
以下のコードでは、APIが用意しているデフォルトのデバイスを自動で取得してくれます。
(再生するだけならデフォルトで十分です。)

**※[1],[2]は"MidiUnavailableException"をスローするので、必ず例外処理を行ってください。**

```java

	Sequencer sequencer = null;
	try {
		// [1] デバイスに接続されたデフォルトのSequencerを取得する。
		sequencer = MidiSystem.getSequencer();

		// [2] デバイスを開き、リソースを獲得する。
		sequencer.open();
	}
	catch (MidiUnavailableException e) {
		e.printStackTrace();
	}
```
###MIDIファイルを読み込む
MIDIファイルからMIDIデータを取得します。
取得したMIDIデータは"Sequence"というオブジェクトで管理されます。

シーケンサーに取得したオブジェクトを設定します。

**※先程と同様に[1],[2]は"MidiUnavailableException"をスローするので、必ず例外処理を行ってください。**

```java
	try {
		// [1] MIDIファイルからMIDIデータ(Sequenceオブジェクト)を取得。
		File file = new File(path);
		Sequence sequence = MidiSystem.getSequence(file);

		// [2] 取得したMIDIデータをシーケンサに設定する。
		sequencer.setSequence(sequence);
	}
	catch (InvalidMidiDataException e) {
		e.printStackTrace();
	}
	catch (IOException e) {
		e.printStackTrace();
	}


```
###MIDI再生/停止
あとはシーケンサーの再生(start)、停止(stop)をコールすることで、再生/停止を制御できます。

```java
	// シーケンサー再生
	sequencer.start();

	// シーケンサー停止
	sequencer.stop();
```
###システムリソースの解放
プログラム終了時は、close()を実行することを忘れないように注意してください。

```java
	sequencer.close();
```
Ubuntu16.04のターミナルでバックスラッシュを表示したい


まずはゴシックフォントのインストール

```
sudo apt-get install -y fonts-vlgothic
```

ターミナルから`編集>プロファイルの設定>全般>文字の外観>フォントを指定する`を選択し,VLゴシック系を選択する.
これでターミナルにバックスラッシュを表示できるようになる.

![image.png](https://qiita-image-store.s3.amazonaws.com/0/195174/142eeba2-d97d-084a-6e3d-3406126050ed.png)
同一ネットワーク内にいるのにExpoのLanが使えない時（Windows）


![expo_icon.png](https://qiita-image-store.s3.amazonaws.com/0/102978/c742cab4-00ff-6e27-1f21-afc0c4283f46.png)

React Native開発時にExpoを使っているのですが、以前しょうもないミスで時間を喰ったことがありました。誰かのためにと共有しておきます。
PCとデバッグ機が同一ネットワークに接続しているにも関わらず、同期が取れないことがありました。その際に行った対処を載せています。

# 原因と対処

**不要なネットワークインターフェイスによってNATされている可能性があります。**
:point_right: ネットワークのコントロールパネルから、不要なインターフェイスを無効化しましょう。

![expo_serve.PNG](https://qiita-image-store.s3.amazonaws.com/0/102978/203599ef-69c1-83cc-726e-2f6556a04c09.png)

**Expo XDEが誤ったIPアドレスを指定している場合があります。**
:point_right: PCとデバッグ端末の、ネットワークアドレスが同一であるか確認しましょう。

![expoide.PNG](https://qiita-image-store.s3.amazonaws.com/0/102978/06de52e4-d77d-4de3-97e9-e314d8799f2e.png)

同一のネットワークアドレスであるか確認する方法として
:point_right: Windowsでは`ipconfig`や`ping`を使って確認して下さい。
:point_right: 検証端末では、各端末毎の端末設定よりIPアドレスを確認して下さい。

# 背景

### エラー文

> 
There was a problem loading the requested app. It looks liek you may be using a LAN URL. Make sure your device is on the same network as the server or try using a tunnel.

### 動作環境

- Windows10-64bit
- VSCode
- Expo XDE
- React Native3.0

###  Expo XDEを使って実機デバッグする手段は3つあります。

- Tunnel（別ネットワーク間。操作の反映に少し時間が掛かる）
- Lan（同一ネットワーク内。ほぼストレスなくリアルタイムに操作を反映してくれる）
- Local（同一PC内？）

Lan使用時に、同一ネットワークなのにも関わらず検証端末と同期できない場合があります。一つの可能性として不要なネットワークインターフェイスが起動していることが考えられます。意図しないインターフェイスのIPアドレスをExpo XDEが指定する場合があり、その場合正しく通信できません。
自分の場合、以前`Docker for Windows`を使用していたことがあり、その際作成されたNATインターフェイスをExpo XDEが指定していることに気が付かず、ハマった過去があります。
不要なネットワークインターフェイスを終了させるには、Windowsの場合右クリックから`Disable`で終了できます。（削除ではないので後々復活させられます）

もしお困りでしたら、一度確認してみてはいかがでしょうか。

あと、Expoの小技ですが、端末を物理的に振る（シェイク）するとメニューが飛び出ます。知っていると便利なTipsです（笑）
Progate学習コースJavaScript Ⅰ ES6

今回は、Progateの学習コースJavaScriptⅠ ES6で学んだ内容をアウトプットしていきます。 
PHPとは文法が微妙に異なる点があるので注意が必要です。

###出力

```.js
console.log("「ES6 学習コース」へようこそ！");
console.log("にんじゃわんこと一緒にES6を学んでいきましょう。");
```

###演算

```.js
// 5と3を足した値を出力してください
console.log(5+3);

// 20から8を引いた値を出力してください
console.log(20-8);

// "4 + 5" を文字列として出力してください
console.log("4+5");

// 8と4をかけた結果を出力してください
console.log(8*4);

// 24を4で割った結果を出力してください
console.log(24/4);

// 7を2で割った余りを出力してください
console.log(7%2);

```

###文字列の連結

```.js
// 「ひつじ」と「仙人」を連結してコンソールに出力してください
console.log("ひつじ"+"仙人");

// 文字列の「20」と「15」を連結してコンソールに出力してください
console.log("20"+"15");
```

###変数

```.js
// 変数nameを定義し、「にんじゃわんこ」を代入してください
let name ="にんじゃわんこ";

// 変数nameの値を出力してください
console.log(name);

// 変数lengthを定義してください
let length = 5;

// 変数lengthの値を出力してください
console.log(length);

// 変数lengthを用いて、円の面積を出力してください
console.log(length*length*3);

```

###定数

```.js
// 定数languageを定義してください
const language = "フランス語";

// 定数languageの値を出力してください
console.log(language);

// 定数languageを用いて、「〇〇を話せます」と出力してください
console.log(language+"を話せます");

```

###if文
```.js
const age = 17;

// ageの値が10以上20未満のとき、「私は20歳未満ですが、10歳以上です」と出力してください
if (age >= 20) {
  console.log("私は20歳以上です");
} 
 else if(age>=10){
   console.log("私は20歳未満ですが、10歳以上です");
 }
 else {
  console.log("私は10歳未満です");
}
```

###switch文
```.js
const  rank = 5;

switch (rank) {
  case 1:
    console.log("金メダルです！");
    break;
  case 2:
    console.log("銀メダルです！");
    break;
  case 3:
    console.log("銅メダルです！");
    break;
  // defaultの処理を追加してください
  default:
  console.log("メダルはありません");
  break;
}
```
日時データの何がめんどくさいのか

##ネタ元というか発端
[【新元号】改元のシステム改修で慌てるシステム屋は「無能」とのこと](https://qiita.com/KMKZ/items/7a530a127a438a13f333)

##入力と表示だけの話ではない点
このセクションは和暦や改元とはまったく関係ないです。でも一応触れておく必要があると思ったので。
今では日時の内部データがUnixTimeや[ユリウス日](https://ja.wikipedia.org/wiki/%E3%83%A6%E3%83%AA%E3%82%A6%E3%82%B9%E9%80%9A%E6%97%A5)などの「ひとつの数値」として扱えるし、ライブラリなども充実しているのでそれほど厄介なことはないです。
それでも「表示や入力だけの問題だろ」は違うよ、という話。

+ ソート： 日付順にソートする必要があることはそんなに珍しくないよね

+ 範囲指定： 「〇年〇月のデータ一覧」とか「過去〇日分の一覧」みたいなの

+ 日数計算： 「有効期限〇日」とか金利計算とかで、ある日付からもう一つの日付までの期間の長さを知りたい場合はけっこうある

範囲指定や日数計算は今でも厄介な罠が潜んでいて「月の日数に違いがある」「うるう年のために年の日数にも違いがある」というのはけっこう面倒。
2月25日に「過去一か月分」といったら何日前までのデータが来ることを期待しますか？2月だから(うるう年でなければ)28日分?それとも1月25日～2月24日までの31日分?
一応ライブラリなどではルールを決めているので、細かいこと気にする必要がなければ`DateTime.Now.AddMonth(-1)`などと書けば「一か月前の日付」を得ることができるんだけど、ライブラリ内部ではそういうめんどくさいことも気にして計算ルールを作っています。

そういう便利なライブラリがなかった時代や、ライブラリの採用しているものとは違う計算ルールを使う必要がある場合などは独自に実装する必要があり、けっこう慎重に設計していないとおかしなことになってたりします。

あと「5分しか経ってなくてもその間に日付が変われば1日経過、23時間経ってても日付が変わってなければ0日」みたいな計算はわりとあります。
このとき内部で保持している日時がUTCだと「ローカルタイムに変換してから"日"未満の端数を切り捨てた数字同士で日数計算」みたいなことが必要になります。

##「年」「月」「日」「時」「分」「秒」を別フィールドに持つ日時形式
CPUが8bitや16bitの時代は日時を「ひとつの大きな数字」として扱うのはビット数が長くなるので大変でした。
計算速度も遅いのでその大きな数字を割り算して年月日…などに分解するのを表示のたびにやってたら遅くて実用にならない。
だから年月日などを別々のフィールドとして記録する方が一般的でした。
たとえばCP/MやMS-DOSのファイルタイムスタンプ。Windowsの時代になってもBIOSはIBM-PC由来のレガシーAPIだったのでやっぱりRTCは年月日時分秒が別フィールド。ようやくUEFIになってその過去を捨てられました。

そのため古いプログラムではファイルシステムやBIOSと同じように年月日別フィールドは割と当たり前にありました。
さすがにデータベースシステムは比較的早いうちから内部形式としては「ひとつの大きな数字」として持っていたみたいだけど、PC用のローカルデータベースではパフォーマンスの問題などで年月日形式のもあったと思います。

##そこに和暦が入ってくると
年月日別フィールドは日数計算などでかなりめんどくさいことになって、さらに2000年問題でやべーことになったわけだけど、それでも西暦で持っていれば「年の数字が大きい方が新しい日付」となるのでまだシンプルです。
ところがいろいろ事情はあったのだろうけど「年号」「年」「月」…といった内部形式が和暦なデータも存在したりします。
「年号は年より上の桁」と解釈すれば年以下の大小関係は維持されるのでまだいいんだけど、年号同士の大小関係は人間が指示しないとコンピュータにはわかるわけない。これが和暦ハードコーディングの温床のひとつです。
とはいっても「それぞれの年号に番号を振ってその番号でソートすればいい」という解決策はある。実際.NET Frameworkの和暦カレンダーなどではそういう方法を取っています。
でも年号と番号の対応付けには標準的なルールは存在せず、システムローカルな対応付けでしかありません。
それに3つか4つしかない年号のために対応表を用意するのも冗長と考える人も多かっただろうから、年号は文字列として持っていてソートや日数計算に必要な大小関係はハードコーディングで対処しているものも少なくないです。

##データの内部形式を変えるのはかなり大変
そういうシステムの改元対応の仕事が回ってきたらそんなシステム作った人を呪いたくなるだろうけど、そのシステムが使えなくなったら困る人がいるからそういう仕事が来るわけで、がんばってなんとかするか逃げ出すかくらいしかないでしょう。

そのシステムで扱ってるデータは「年月日別フィールド」。根本的に解決するなら日時データをすべてユリウス日やUnixTimeなど今どきの形式に置き換えたいところだけど、それをするにはシステム内で日時を扱っている箇所すべてを書き換えてテストする必要がある。既存のデータの変換作業も必要です。
そして「そんな大きな変更をする予算も時間もないから、最小限の変更で何とかしてくれ」というパターンもきっと多いはずです。
問題があるシステムだとわかっていても、既存コードが年号の大小関係をハードコーディングしていたらそれに合わせてハードコーディングしないと「最小限の変更」では済まなくなってくることもあるでしょう。

##もし改元対応をお願いされたら、まず日時の保存形式を確認しましょう
実際には年月日別フィールドまではありえても、内部形式まで和暦というのはそう多くないはずです。(でも存在する)
それでも古いシステムだと西暦と和暦の変換をしてくれるようなライブラリが存在しなかったため、変換機能はシステム独自にハードコーディングというのは少なくないはずです。
そうなると内部形式を変えられないのであれば、その場しのぎにしかならなくても西暦和暦の変換機能を再実装して、そのついでで将来の改元でも最小限の変更で済ませられるようにする程度でお茶を濁すしかない案件はけっこうあると思います。

##個人的には年号がなくなってほしい
別に完全には消滅しなくてもいいので、今の旧暦くらいの存在感になって少なくともオフィシャルな文書関係で「和暦でないとダメ」はなくなってほしいです。
どうせ明治5年以降は月日の部分はグレゴリオ暦なんだし。
実際のところ、昭和のころは西暦より和暦の方が一般的だったんですよ。昭和が何十年も続いてるから大して不都合はなかったからでしょう。
それが平成になって年号をまたぐめんどくささはコンピュータがらみだけではなく「平成5年の7年前って何年？」みたいに日常生活でも微妙に煩わしくなってきたこともあってか、いつのまにか西暦表記の方が一般的になっているんですよね。
ReactNativeでローカルに保存された画像を表示する

 ExpoのCameraコンポーネントからローカルファイルシステムに保存した画像のURIを取得できるが、`file://`　プロトコルなURIをそのままImageのsourceとして指定してもうまくいかない。

```
<Image style={{width: 100, height: 100}} source={{isStatic:true, uri:"file://var.....}} />
```

`isStatic: true`を指定すると表示ができる。もちろんネットワーク上から取得した画像のように、widthとheightの指定も必要になる。
TSLintでTypeScriptの循環的複雑度(cyclomatic-complexity)を検証する

一般的に条件分岐やループが多ければ多いほどその関数のバグの混入確率が上がると言われています。関数の複雑度を測るために循環的複雑度(cyclomatic-complexity)を用いて複雑度を数値として計測し、閾値を超えていないかをlintで検証する方法を紹介します。

前半部分はほぼ同じ内容ですが、別記事でESLintを使った方法を紹介しています。
[ESLintでJavaScriptの循環的複雑度(cyclomatic-complexity)を検証する - Qiita](https://qiita.com/shisama/items/557a68e0aaafc4858be1)

# 循環的複雑度(cyclomatic-complexity)とは
[循環的複雑度 - Wikipedia](https://ja.wikipedia.org/wiki/循環的複雑度)

一言で言えば、プログラムの複雑度です。分岐の数が多ければプログラムの実行経路は多くなり複雑度は上がります。逆に少なければ下がります。`if`や`for`など分岐がないプログラムの循環的複雑度は1となります。
循環的複雑度の数え方は大まかに言えば「`if`などの条件分岐や`for`などのループなど制御構文の数」+1した数です。
`else`は含みません。
参考: [Project Metrics Help - Complexity metrics](http://www.aivosto.com/project/help/pm-complexity.html)

## 循環的複雑度の閾値

非常に古い統計データですが、循環複雑度が高ければバグは発生しやすいということは以下のグラフを見るとわかります。

![Prob for Cyclomatic](https://res.infoq.com/news/2008/03/cyclomaticcomplexity/en/resources/mccabegraph.jpg)

|循環的複雑度|バグ混入確率|
|---|---|
|11|25%|
|38|50%|
|74|98%|


参考: [Cyclomatic Complexity Revisited](https://www.infoq.com/news/2008/03/cyclomaticcomplexity)

循環的複雑度が10を超えるとバグ混入確率がゆるやかに上昇していっているので、1つの関数の循環的複雑度は10以内に抑えるようにコードを書くようにするといいでしょう。

## tslintでの検証

[TSLint](https://palantir.github.io/tslint/)はTypeScriptの静的解析ツールです。  


TSLintは様々なルールがありますが、循環的複雑度を検証するルールも存在します。

それが[Rule: cyclomatic-complexity](https://palantir.github.io/tslint/rules/cyclomatic-complexity/)です。

ルールの設定は簡単で循環的複雑度が10を超える場合はエラーにしたい場合はtslint.jsonに以下のように追記します

```json
{
  "cyclomatic-complexity": [true, 10]
}
```

を追記すれば循環的複雑度の設定は完了です。
設定する値は検証を行うかのフラグと閾値です。

例えば分岐が10ある関数が存在する場合は以下のようにエラーになります。
循環的複雑度の閾値を10に設定した場合、条件分岐が10ある関数があれば以下のようなエラーメッセージを出力します。

```
ERROR: /path/to/sample-code.ts:1:1 - The function test has a cyclomatic complexity of 11 which is higher thanthe threshold of 10
```


# あとがき
最近ではJavaScriptといえばTypeScriptと言わんばかりにTypeScriptが使われるようになってきていると感じています。
TypeScriptはJavaScriptに比べると型安全やnull安全などバグの混入確率は少なくなったもののロジックが複雜であればバグの混入確率は上がりますし、可読性も下がります。
なので、循環的複雑度を下げるようにするためにもTSLintでチェックすることをおすすめします。

最後までお読みいただきいただきありがとうございました。質問や不備などがあればコメント欄または[Twitter(@shisama_)](https://twitter.com/shisama_)までお願いいたします。
Giteaとdroneの環境をdocker-composeで用意する


![image.png](https://qiita-image-store.s3.amazonaws.com/0/330873/f1b75ea7-7a3b-c895-4586-ef4e557072d1.png)


```txt:.env
GITEA_SV_ADDR=192.168.1.100
```

```yml:docker-compose.yml
version: '3'
services:
  web:
    image: gitea/gitea:1.7
    volumes:
      - ./gitea-data:/data
    ports:
      - 3000:3000
      - 10022:10022
    environment:
      - TZ=Japan
      - SSH_PORT=10022
    restart: always
  drone-server:
    image: drone/drone:1.0.0-rc.4
    ports:
      - 3080:80
    volumes:
      - ./drone-data:/data
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - TZ=Japan
      - DRONE_GIT_ALWAYS_AUTH=false
      - DRONE_RUNNER_CAPACITY=2
      - DRONE_SERVER_HOST=${GITEA_SV_ADDR}:3080
      - DRONE_SERVER_PROTO=http
      - DRONE_TLS_AUTOCERT=false
      - DRONE_GITEA_SERVER=http://${GITEA_SV_ADDR}:3000
    restart: always
```

```
docker-compose up
```

あとは`192.168.1.100:3080`にアクセスしてログイン、Giteaに登録したレポジトリが同期されると準備完了。`.drone.yml`に従ってCIが実行できる。
上の図は`.drone.yml`用意していないので`Not Found`となっている。



# 参考
[Single Machine](https://docs.drone.io/installation/gitea/single-machine/)

[IIJのサービス開発を支えるGithub Enterpriseとdrone\.io \| IIJ Engineers Blog](https://eng-blog.iij.ad.jp/archives/2238)
>IIJでは共通で使えるイメージ置き場として Docker Registry 、Web UIとして Docker Registry Frontend を提供しており、droneで使うテスト用イメージを自由に置いておくことができます。

[Docker\-Compose の変数定義について \- Qiita](https://qiita.com/kimullaa/items/f556431b8103e686f356)

[0-8-0.docs.drone.io](https://0-8-0.docs.drone.io/)

[Publish](http://plugins.drone.io/tags/publish/)

[drone\.io Advent Calendar 2017 \- Adventar](https://adventar.org/calendars/2181)

[Gitea Release \| Plugins \| Drone](http://plugins.drone.io/drone-plugins/drone-gitea-release/)

[SCP \| Plugins \| Drone](http://plugins.drone.io/appleboy/drone-scp/)

[Droneのビルドをスキップするコミットメッセージ \- Qiita](https://qiita.com/naokazuterada/items/9f352bad2f01f35decec)

https://github.com/drone/drone/blob/6d144de7355facbee613dd99afc5c4657b580808/server/hook.go#L57
MySQLのバージョンをMacで変更した際、 ERROR! The server quit without updating PID file エラーで起動出来なくなった問題

お馴染みのよくQiitaで見かけるMySQLが起動出来ないエラーに関する記事です。
新マックにて、homebrewでMySQLのバージョンを8から5.7に変更した際に起こりました。

```
$ brew install mysql@5.7
```
この後MySQLを起動するため、

```
$ mysql.server start
```
と打つと、
. ERROR! The server quit without updating PID file (/usr/local/var/mysql/user/pid)
のエラーが起きました。

ググってヒットしたのは、パーミッション系です。
```
sudo chown -R _mysql:_mysql /usr/local/var/mysql/
```
のコマンドで解決したケースが多いみたいだったので、打ってみますが、エラーは解消せず。

次によくあったのが、mysqlのプロセスをkillしてみたり、入れ直したりなどで、それらも試みましたが、ダメでした。

いくつかググって見ていると、[こちら](https://qiita.com/asmsuechan/items/7abdf45d071539a1db80)でログを見るように書かれていたので、まずはログを確認しました。
これも、どれがログファイルかすぐには分からず、`sudo tail -f`を打ってリアルタイムに書き換わっている場所を、/usr/local/var/mysql/下で探しました。

`/usr/local/var/mysql/マック名.err`
というファイルにログが更新されていたので、そちらを見てみました。

`sudo tail -f /usr/local/var/mysql/マック名.err`

おびただしいエラーログがあったので、エラーの発生時点まで遡ってみると、

<img width="613" alt="スクリーンショット 2019-01-16 23.46.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/311188/479236ed-2959-e40e-10d4-0084e1181c02.png">

NoteからERRORに切り替わっている場所が！

[ERROR] Can't start server: Bind on TCP/IP port: Address already in use
2019-01-16T14:03:24.236514Z 0 [ERROR] Do you already have another mysqld server running on port: 3306 ?

どうやら既に起動中との事です、それを見てハッとしました。自分はDockerでMySQLを立ち上げていたので、それとローカルのMySQLがもしやポートで競合しているのではと思い、my.cnfからポートを変更するようにしました。

`$ mysql --help | grep my.cnf`
を打って、出てきた候補から、ファイルが書き込まれている部分を調べました。

自分の場合は`/usr/local/etc/my.cnf`にあったので、そちらにて、port=3307という指定を追加しました。

```
# Default Homebrew MySQL server config
[mysqld]
# Only allow connections from localhost
bind-address = 127.0.0.1
# この行を追加
port=3307
```

再度
`$sudo mysql.server start`すると、
`$..Success!`

と表示。ようやく解決しました。

同じ環境でDockerなどを立てて複数動かしてる場合は、ポートを変える必要があるという事です。

# 追伸
Mac自体を再起動すると、バージョンが8に戻っていてまたコケた。

とりあえず[こちら](https://weblabo.oscasierra.net/mysql-57-homebrew-install/)の方法で、MySQLを入れ直して対処。
GitHub GraphQL API v4のschema.jsonファイルの取得方法がわからなかったのでメモ

# 概要

AndroidでGraphQLを採用したAPIへのリクエストに[Apollo GraphQL Client for Android](https://github.com/apollographql/apollo-android)を利用する場合が多いと思います。

Apolloでは、`.graphql`ファイルで定義したクエリからリクエスト処理で使用するコードを生成します。この時、`schema.json`と呼ばれるGraphQLのスキーマ定義ファイルが必要になります。

# GitHub GraphQL API v4のschema.jsonの取得

[Androidプロジェクト向けの公式ドキュメント](https://www.apollographql.com/docs/android/essentials/get-started.html#download-schema)で解説されている方法がそのままでは実行できませんでした。`apollo-codegen`は[apollographql/apollo-tooling](https://github.com/apollographql/apollo-tooling)に統合されたようで使い方が変わっています。

## Apollo CLIを使用したschema.jsonの取得

Apollo CLIをインストールし、apollo-codegenの代わりに`apollo service:download`コマンドを使用します。

まずnpmでCLIをインストールします。

```bash
$ npm install -g apollo
```

そして`apollo service:download`を実行します。`--endpoint`オプションでgraphqlエンドポイントを指定し、`--header`オプションで認可情報を追加します。GitHubのPersonalアクセストークンは、[SettingsのDeveloper settings](https://github.com/settings/tokens)から取得しましょう。

GitHub GraphQL API v4のschema.jsonファイルの取得は、次のようなコマンドになります。

```bash
$ apollo service:download --endpoint https://api.github.com/graphql \
  --header "Authorization: Bearer <GitHub personal access tokens>"
```

# 実行

以下のように表示されればOKです。

```bash
$ apollo service:download --endpoint https://api.github.com/graphql \
--header "Authorization: <GitHub personal access tokens>"
  ✔ Loading Apollo Project
  ✔ Saving schema to schema.json
```

`apollo service:download`で指定できるオプションの詳細は[こちら](https://github.com/apollographql/apollo-tooling#apollo-servicedownload-output)をご覧ください。

# 参考資料

- https://www.apollographql.com/docs/android/essentials/get-started.html
- https://github.com/apollographql/apollo-tooling
- https://github.com/apollographql/apollo-android
Lambdaがタイムアウトした時に実行中の処理はどうなるのか

# 概要

下記を実験します。

* Lambdaだけで実行してタイムアウトさせるとどうなるか
* API Gatewayと繋いだ時のLambda処理とAPIのレスポンスがどうなるか

## 環境

* Lambdaのタイムアウトを3秒にし、Lambda自体の処理が3秒以上かかる状態にしてLambdaを起動させる。

## Lambdaだけで実行してタイムアウトさせるとどうなるか

LambdaをLambdaのページから単体で起動します。
※Lmabdaのページの"テスト"ボタンを押すだけ

### ソース

```python

import json
import time

def lambda_handler(event, context):
    
    for idx in range(10):
        print(idx)
        time.sleep(1)
        
    return "hello"
```

### 結果

#### Lambdaのログ

タイムアウト以降の処理は実行されず、タイムアウト時点で処理が強制終了させられます。

```
Response:
{
  "errorMessage": "2019-01-16T14:06:59.665Z fbb0936c-1997-11e9-a789-77de14672ab0 Task timed out after 3.00 seconds"
}

Request ID:
"fbb0936c-1997-11e9-a789-77de14672ab0"

Function Logs:
START RequestId: fbb0936c-1997-11e9-a789-77de14672ab0 Version: $LATEST
0
1
2
END RequestId: fbb0936c-1997-11e9-a789-77de14672ab0
```

## API Gatewayと繋いだ時のLambda処理とAPIのレスポンスがどうなるか

これだけだと面白みに欠けるので、API GatewayからLambdaへプロキシする形にしてLambdaがタイムアウトした時にどうなるかを見てみます。

### 結果

#### APIへのリクエストのレスポンス

API Gatewayの中のAPI毎の設定の "ゲートウェイのレスポンス" の "DEFAULT 5XX" で設定した内容が出力されます。

```
{"message": "Internal server error"}
```

#### Lambdaのログ

3秒以降はAPI Gatewayから繋いでも強制終了されています。

```
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|       @timestamp        |                                                                      @message                                                                      |
|-------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------|
| 2019-01-16 14:30:20.242 | START RequestId: 40618977-199b-11e9-97b8-1dd8c5fdb605 Version: $LATEST                                                                             |
| 2019-01-16 14:30:20.317 | 0                                                                                                                                                  |
| 2019-01-16 14:30:21.318 | 1                                                                                                                                                  |
| 2019-01-16 14:30:22.319 | 2                                                                                                                                                  |
| 2019-01-16 14:30:23.254 | REPORT RequestId: 40618977-199b-11e9-97b8-1dd8c5fdb605 Duration: 3003.36 ms Billed Duration: 3000 ms  Memory Size: 128 MB Max Memory Used: 21 MB   |
| 2019-01-16 14:30:23.254 | END RequestId: 40618977-199b-11e9-97b8-1dd8c5fdb605                                                                                                |
| 2019-01-16 14:30:23.254 | 2019-01-16T14:30:23.253Z 40618977-199b-11e9-97b8-1dd8c5fdb605 Task timed out after 3.00 seconds                                                    |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
```
Webアプリからブロックチェーンの内容を読み込む（ブロックチェーン入門２）

# 概要

ブロックチェーン（Ethereum testnet (Ropsten)）に、textを書き込むコントラクトから
Webアプリ（Node.js + TypeScript + vue.js）で、書き込んだ内容を表示するまでを
書きます。

なお、私もブロックチェーン初学者なので、内容に誤り等ありましたらご指摘いただけると幸いです。

コントラクトの実装は下記を参照ください。
https://qiita.com/wadanobuya/items/e4ac53ba78a6bf4d38d6

webアプリのgithub　クローンしてお試しください。
https://github.com/wadanobuya/set-message-dapps

## 1．デプロイしたコントラクトの接続情報を取得

### 1-1．デプロイしたコントラクトの接続情報(ABI)を取得

ABIとは、、、
Contractの取り扱い説明書のようなもの

<img width="714" alt="スクリーンショット 2018-11-21 23.14.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/108760/6e4fa156-6e72-3ed6-6917-28b0ae81a5de.png">

タブをcompileにもどしてABIを取得
(コピーしたABIを適当なテキストに貼り付けておいてください。あとで使います)

<img width="772" alt="スクリーンショット 2018-11-21 23.16.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/108760/02c21f2a-0498-a1b2-c57c-5b878b8d6dad.png">

### 1-2．デプロイしたコントラクトのアドレスをコピー

デプロイ時のログからropstenのTransactionからアドレスを取得します。

RopstenのTransactionを参照する。

<img width="712" alt="スクリーンショット 2019-01-16 22.54.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/108760/2dcd3c52-8f03-a9cb-83b3-6e6235de9eef.png">

RopstenのTransaction

<img width="1210" alt="スクリーンショット 2019-01-16 22.53.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/108760/605288d1-b73b-bbf9-6189-f282cc9228de.png">

下記、コントラクトのアドレスをコピー
(コピーしたアドレスを適当なテキストに貼り付けておいてください。あとで使います)


<img width="862" alt="スクリーンショット 2019-01-16 22.54.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/108760/a1028a82-d92b-fab2-db08-642027de04ab.png">

## ２．Webアプリケーションとの接続設定

### 2-1.ABIを設定

※SetMessageのコントラクトを使用する場合このままでもOK

web_app/src/contractInfo.tsを編集して
ABIを設定します。

コピーしたABIをabi: に貼りつけ
すでに書き込んである[]に

<pre>
export default {
  Token: {
    // Every time you deploy a contract, you have to update address.
    address: '0xa4ac37f7c15d12d9c57768bad57781ee974d4cbf',
    // Every time you change the contract interface, you have to update abi.
    abi: 
〜省略〜
  },
};
</pre>


### 2-2.ABIを設定

address:にコピーしたコントラクトのアドレスを設定
ここがデプロイしたコントラクトのアドレスになるのでここは
自身で実装したコントラクトを設定ください。

※変更しないと、私がデプロイしたコントラクトのアドレスになっています。

<pre>
export default {
  Token: {
    // Every time you deploy a contract, you have to update address.
    address: '0xa4ac37f7c15d12d9c57768bad57781ee974d4cbf',
</pre>

## 3．Webアプリケーションの接続確認

### 3-1． npm インストール

下記の位置でnpm インストールを実行
web_app/

<pre>
npm install
</pre>

### 3-2． web アプリケーションを実行

<pre>
npm run serve
</pre>

※　エラーが出ますが気にせずに、、、
ゆくゆく修正いたします、、、

<pre>

  App running at:
  - Local:   http://localhost:8080/
  - Network: http://192.168.54.118:8080/

  Note that the development build is not optimized.
  To create a production build, run npm run build.

</pre>

### 3-3 chromeブラウザからアクセス

<pre>
http://localhost:8080/
</pre>

web画面が表示され「getMessage」のしたに、コントラクトでsetしたteｘｔが表示されていれば
接続完了です。

コントラクトのsetMessageで違うtextを書き込み表示が変わるのを確認してもらえたらと思います。

<img width="340" alt="スクリーンショット 2019-01-16 23.30.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/108760/453a5688-5e7f-deed-e160-d4e9ddc46ccd.png">

※画面デザインはなんとかしたいです。

## まとめ

これで
コントラクトを実装しwebアプリでのアクセスまで
できました！

今後はwebアプリからのsetMessageを実行を
できたらと思います、、、
Ionic3のion-footerがキーボード表示時に押し上げられてしまう問題について

## はじめに
Ionicで提供されている`ion-footer`を使ってフッターを実装したときに、キーボードを表示するとそれが押し上げられてしまい、入力フォームと被ってしまうという問題が実装中におきました。
その時どう対処したか、を自分の記録も兼ねて共有します。

## 同じ問題を抱えている人がいた
調べてみると同じ問題を抱えている人がいたので、回答からヒントを得ました。
[Hide footer when keyboard appear](https://forum.ionicframework.com/t/hide-footer-when-keyboard-appear/9254)
[Hide footer when Keyboard Appears- IONIC2](https://stackoverflow.com/questions/42716744/hide-footer-when-keyboard-appears-ionic2)
[Hide footer on keyboard open Ionic3](https://stackoverflow.com/questions/48386422/hide-footer-on-keyboard-open-ionic3?rq=1)

keyboardプラグインを使ったりするようですが、自分は外部からうまいこと対処するフッターとそうでないフッターを切り分けられるようにしたほうが今後を考えると良いのかなと思い、 **ディレクティブ**で実装しました。

## 実際に対処してみる。

``` KeyboardDisplayBySwitchDirective.ts
import { Directive, HostListener, Input, OnInit } from '@angular/core';

@Directive({
    selector: '[keyboard-display-by-switch]',
})
export class KeyboardDisplayBySwitchDirective implements OnInit {

    @Input() footerId: string;
    private footerEle: any;

    constructor() {}

    ngOnInit() {
        this.footerEle = document.getElementById(this.footerId);
    }

    // ネイティブのキーボードが表示されたらフッターを非表示にする
    @HostListener('window:native.keyboardshow')
    footerHide() {
        this.footerEle.style.display = 'none';
    }

    // ネイティブのキーボードが閉じられたらフッターを表示する
    @HostListener('window:native.keyboardhide')
    footerShow() {
        this.footerEle.style.display = 'block';
    }
}
```
上記のディレクティブを実装しました。
ディレクティブは要素の設定やサイトによっては振る舞いを持たせると書いてあったのですが、個人的には**仕様を決める**と言った方がしっくりくるかなと思いました。
例えばこのディレクティブを指定された要素はこんな仕様を持った要素だよとわかるようにみたいな。

内容ですが、まずプロパティとしてフッター要素のIDを親から受け取るものとフッターの要素を格納するプライベート変数を用意しました。
このディレクティブを指定するときは、

``` HTML
<ion-footer id='hoge-footer' keyboard-display-by-switch [footerID]="'hoge-footer'">
```
というように指定します。

そしてngOnInitのタイミングで指定されたフッター要素を取得します。

`@HostListener`に関してですが、これは`addEventListener`に似たもので、引数に対象とイベントを指定します。
今回はネイティブのキーボードが表示されたとき、閉じられたときのイベントを実装しました。

それぞれキーボードが表示されたらフッターを非表示に、キーボードが閉じられたらフッターを再表示するという処理になっています。

これでキーボードの表示によってフッターが押し上げられるといったことが解決できます。

## さいごに
今回フッター要素のIDを渡していますが、実は初めdocument.getElements.byTagName('ion-footer')でやってました。
しかし、ページを切り替えたとき、前に取得した要素が変数に残ったままで切り替え先ではうまく動かないというところで少々躓きました。

[MDN Document.getElementsByTagName()](https://developer.mozilla.org/ja/docs/Web/API/Document/getElementsByTagName)
>返された HTMLCollection は生きたものであり、つまり document.getElementsByTagName() を再度呼び出さなくても DOM ツリーと同期を取り続けるよう、自動的に自分自身を更新します。

この辺りが怪しそう…？
基本を改めて勉強し直そう(戒め)
ｱｯ aws configure でアクセスキーとか入れちゃったけどやっぱ要らんやんけ！となった人へ

# はじめに

なにかの記事を見たり、あるいはaws-cliの促すとおりにAWSの**EC2サーバー**で`aws configure`と入力してしまうことが、特に初心者にはよくあるはずです。そう私のような。
けれどもそのaws configureはもしかしたらセキュリティ的にリスクがある行動かもしれません。なぜならconfigureしたEC2上では、その認証情報（アクセスキーやシークレット）が残り続けるからです。
ここでは「えっもうconfigureしちゃったよ」という人向けに消し方を書いておきます。

結論を先に書いておくと、ホームディレクトリに作成されているはずの.awsを消すだけです。

```shell
$ rm -r ~/.aws
```

# まずaws configureがやっていること

```shell
$ aws configure

AWS Access Key ID [None]: AKIAIOSFODNN7EXAMPLE
AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Default region name [None]: ap-northeast-1
Default output format [None]: text
```

こうすると、入力した情報のプロファイルの権限で、AWSの機能にアクセスできるようになりますよね。
この情報を書いたファイルがどこにあるかというと、aws configureを行ったユーザーのホームディレクトリの直下にあります。

例えばec2-userでaws configureしたら、/home/ec2-user/.awsが作成されます。

```bash
$ ls -l ~/.aws

-rw------- 1 ec2-user ec2-user  48 Jan 16 13:41 config
-rw------- 1 ec2-user ec2-user 225 Jan 16 14:12 credentials
```

その.aws隠しディレクトリの下に、configとcredentialsというファイルがあります。
viなどで中身を見たら、入力した情報が書かれていることが確認できるはずです。

```
$ vi ~/.aws/credentials
```

```shell:/home/ec2-user/.aws/credentials(一例)
[default]
aws_access_key_id = AKIAIOSFODNN7EXAMPLE
aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
```

# それを踏まえた上でやること

とても簡単です。ホームディレクトリの.awsフォルダを消します。

```shell
$ rm -r ~/.aws
```

# EC2でaws-cliを使うには？

EC2でaws-cliを使うには、基本的にEC2インスタンスそのものに、権限を与えましょう。
例えばS3の読み書きをしたいのであれば、S3の読み書きのできるポリシーを割り当てたロールを、EC2にアタッチします。
そうすることでaws configureをしなくても、.awsがなくても、そのEC2で割り当てられた権限の範囲でaws-cliを使えるようになります。
MacでFiddlerを起動してみる

#目的
自宅PCでもパケットキャプチャしたい。

#参考にしたサイト
[MacにFiddlerをインストールするには](https://qiita.com/yut-nagase/items/19be8d4df706f8373ff0)

[Mac > Fiddler](https://qiita.com/sugasaki/items/5476ad81a257b125a28b)

#つまづいた所
上記の手順でmonoをインストールしたのですが、monoがないと出てしまいました。

~~~
$ mono --arch=32 Fiddler.exe
-bash: mono: command not found
~~~

下記のサイトをみてパスを通したら無事にmonoコマンドを実行できました。

[MacでC#プログラミング](http://gdexplorer.wp.xdomain.jp/2015/12/16/mac%E3%81%A7c%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0/)

~~~
$ PATH=$PATH:/Library/Frameworks/Mono.framework/Versions/5.16.0/bin/
~~~

#つまづき中

上記手順のようにしてmonoコマンドを実行してもFiddler.exeが立ち上がらない。
何が悪いのだろうか？？
rspecのassignsで割り当てられた要素の個数をカウントする方法

コントローラーspecのassignsでの割り当てテストの際に、どのように割り当てた要素数をテストするか実装の際に調べたので備忘録としてメモしておく。

# 方法
実際使用したコード

```ruby
#related_productsに割り当てられている要素数は４個であるはず。
expect(assigns(:related_products).size).to eq 4
```

例のように`size`を使用し、`be`や`eq`で数字を指定すればOKぽい。

ちなみに以前は、

```ruby
expect(assigns(:related_products)).to have(4).items
```
でいけたらしいがrspec3.0~は削除された模様。今後もし要素の個数を数えるテストが必要になった場合は上の方法を使用するのがよさそう。でも調べたらあまり該当記事がなかったのであまり使用するケースも多くないのかな〜

# 参考
https://stackoverflow.com/questions/24111204/rspec-to-haven-items-undefined-method
数値計算を含む置換をperlのワンライナーでやってみた 

# やりたいこと
例えばHTMLコーディングしていて思いつきでつけたクラス名hoge1,hoge2,hoge3があったとして、そのクラス名を下記のように変更したい場合

| 置換前 -> 置換後 |
|:-----------------:|
| hoge1 -> hoge2 |
| hoge2 -> hoge3 |
| hoge3 -> hoge4 |

※ひどい命名を変更するのではなく番号をずらします

普通に置換しようと思うと一旦hoge1を別の文字列に置換してその後hoge3に置換し直すというような２段階の工程が必要。１ページ分くらいならそれでも良いのですが、量が多いと意外と面倒なのでなんとか一発で置換できないかと試行錯誤した結果、perlのワンライナーで実現することに。

# そもそもなぜperlを使うに至ったか
今回の肝は**計算が必要になる**という点です。
テキストエディタの置換機能もsedも対応していない...さらに調べたところ、perlは数値計算を含む置換に対応しているようだったので、これをワンライナーで実行すればいけるのでは...早速やってみました。

# 最終的なワンライナー

```bash

cat target.html | perl -pe 's/(?<=class\=(?:\x22|\x27)hoge)([1-3])(?=(?:\x22|\x27))/$1+1/eg' > replaced.html
```

# Perlの部分解説
`perl -pe 's/(?<=class\=(?:\x22|\x27)hoge)([1-3])(?=(?:\x22|\x27))/$1+1/eg'`

## オプション
perl **-pe** 's/(?<=class＼=(?:\x22|\x27)hoge)([1-3])(?=(?:\x22|\x27))/$1+1/eg'

- \-e<br>
`-e`の後ろに実行したいスクリプトを記載することでワンライナーでのprelスクリプトとして認識される。
- -p<br>
入力データの各行を再帰的に処理。

## スクリプトの内容

perl -pe '**s/** (?<=class＼=(?:\x22|\x27)hoge)([1-3])(?=(?:\x22|\x27)) **/** $1+1 **/eg**'

- s/*正規表現パターン*/*置換後文字列*/<br>
perlの正規表現による基本的な文字列置換の構文。
- /g<br>
１行内に複数マッチするパターンがあった場合、全てに対して置換処理を行う。
- /e<br>
評価可能な計算式、変数を展開。※eをつけた回数分評価を行うというオプションなので、例えば`/ee`という使い方も可能。

## 正規表現
perl -pe 's/**(?<=class＼=(?:\x22|\x27)hoge)([1-3])(?=(?:\x22|\x27))**/**$1+1**/eg'

- ?<=<br>
肯定後読み。今回の場合は**直前**に`class="`(または`class='`)を含む場合true(`class="`自体はマッチ文字列に含まない)
- ?=<br>
肯定先読み。今回の場合は**直後**に`"`(または`'`)を含む場合true(`"`自体はマッチ文字列に含まない)<br>
- ?:<br>
()の中をキャプチャしない。`"`,`'`はキャプチャしたい文字列ではないので除きます。
- \x22 \x27<br>
`\x`の後ろにASCIIコードの16進数表記下二桁を記載すると、ASCIIコードで文字列検索が出来ます。`\x22`は`"`、`\x27`は`'`を表します。（ワンライナーで実行する都合上ASCIIコード表記を使用します）

このように肯定後読みと肯定先読みを使用して、**数値部分のみマッチ**するような正規表現を組みます。

### 補足
普通に`/class="hoge([1-3])"/class="hoge$1+1"/`とやりたいところですが、/eオプションは`/class="hoge$1+1"/`全体を数式と捉えるため、文字列が含まれているとエラーになります。そのため、数値のみをマッチさせるように、先読み・後読みを使用しました。

# まとめ
perlのワンライナーを使えば数値計算出来ると分かった後、正規表現で**数値だけ**抜き出すというところが地味に第二関門でした。正規表現だけで本が１冊書けるのも納得です。ぜひとも親友になりたいです。

# 参考
- http://perldoc.jp/docs/perl/5.6.1/perlrun.pod
- https://rfs.jp/sb/perl/02/09.html
- http://www-creators.com/archives/2746
【ActiveAdmin】showのデフォルトaction itemsを消去する

マスタ管理機能を楽に実装できるActiveAdminに関する記事です。
以前ActiveAdminで簡単な管理ツールを作っていたのですが、そのときにログインユーザーの権限毎に実行できるアクションを制限したいと考えました。その際にshowのデフォルトaction itemsがどうしても消せずに困ったので記事にしておきます。

## ユーザー権限によって実行できるアクションを限定する
この手の情報は既に多くの記事が存在するのでここでは詳述しません。

### Userテーブルへのカラム追加
まずは下記を参考に、Userテーブルにroleカラムを追加します。

[cancanを使わずにactive_adminの管理画面で、current_userの権限によるviewの出し分けをする - Qiita](https://qiita.com/kamille/items/9730ffc9e200c34e6208)

これで、`admin_current_user.role`で、ログインユーザーの権限を取得することができます。あとは煮るなり焼くなりご自由に・・・ということで、早速実装してみました。

### index
まずはindexに権限振り分けを設定します。ここでは、roleがadminのアカウントでログインしたユーザーのみレコードの「削除」を行えるようにしています。

```ruby
  index do
    actions defaults: false do |daily|
      item '閲覧', admin_daily_path(daily), class: 'view_link member_link'
      item '編集', edit_admin_daily_path(daily), class: 'edit_link member_link'
      item '削除', admin_daily_path(daily), class: 'delete_link member_link', method: :delete, data: { confirm: '本当に削除しますか？' } if current_admin_user.role == 'admin'
    end
  end
```

Admin（管理者）ユーザーでログインした場合
<img width="760" alt="スクリーンショット 2019-01-16 22.07.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/344380/12f63bc0-4c9d-7fbe-ccd9-c00e0067212d.png">

User（一般）ユーザーでログインした場合
<img width="753" alt="スクリーンショット 2019-01-16 22.08.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/344380/6f7d26c7-732e-24c9-e404-48c177d59c95.png">

いいカンジ。

### show

では、次にshow行ってみましょう。
indexと同様、Adminユーザーのみ削除を許可します。

```ruby
  action_item :only => :show do
    link_to('日報（実績）を編集する', edit_admin_daily_path(daily))
  end
  action_item :only => :show do
    link_to('日報（実績）を削除する', admin_daily_path(daily), method: :delete, data: { confirm: '本当に削除しますか？' }) if current_admin_user.role == 'admin'
  end
  action_item :only => :index do
    link_to('日報（実績）を作成する', new_admin_daily_path)
  end
```

ではAdminユーザーで確認します。
<img width="914" alt="instruction01.png" src="https://qiita-image-store.s3.amazonaws.com/0/344380/bf88b029-a3d6-17ce-e170-9c1d2959826e.png">

うーん、なんか同じようなボタンがいくつかありますね。
どうやらデフォルトのaction itemsが表示されているみたいです。

どうすればデフォルトのaction itemsがクリアできるのかわからず、結構悩みました。
indexで指定するときは`actions defaults: false`で済んだんですが・・・。


その結果、以下に答えがありました。

[Editing/Removing Action Items? · Issue #760 · activeadmin/activeadmin · GitHub](https://github.com/activeadmin/activeadmin/issues/760#issuecomment-3436130)

`config.clear_action_items!`を指定すると、action itemsがクリアされるみたいですね。
早速修正して実行してみます。

Admin権限
<img width="540" alt="instruction2.png" src="https://qiita-image-store.s3.amazonaws.com/0/344380/18df4a18-8f94-2f0e-6360-92545f580c35.png">

User権限
<img width="596" alt="instruction3.png" src="https://qiita-image-store.s3.amazonaws.com/0/344380/58fe52a9-755b-dad4-d8cf-d76e21fb5034.png">


めでたしめでたし。
erb2hamlでhamlにファイルが変換できない・・・

## 理由は簡単でした！
Rails内のerbファイルを更新する場合はデフォルトで配置されるディレクトリに対象ファイルがないと適用されません。

<img width="901" alt="スクリーンショット 2019-01-16 22.45.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/344357/d65df81b-46af-e906-d467-51bdfc812bed.png">

簡単すぎる内容なので調べても中々解決策に出会えず・・・。
恥ずかしながら分かる人に聞いてやっと解決しました。

プログラミング初心者の方で同じ部分で悩んでいる方の解決策になれば幸いです。
VirtualBoxの仮想HDD追加

VirtualBoxの仮想HDD追加の備忘録です。

## 手順

仮想HDD追加を実施するには、追加したいVMを電源オフ状態にしておくこと。じゃないと、ストレージ追加の設定がVirtualBox上行えなかった。

### VirtualBox上での作業

追加するVMのストレージ設定画面を開きます。
「コントローラー： SATA」を選択すると右のほうにHDD追加ボタンHDD追加アイコンがでるので、それをクリックします。

![rapture_20190116222616.png](https://qiita-image-store.s3.amazonaws.com/0/203502/a99bb062-e6e1-3547-5c2e-7c962ab54926.png)

「新規ディスクの作成」をクリックします。

![rapture_20190116222728.png](https://qiita-image-store.s3.amazonaws.com/0/203502/0a967ed3-6749-e249-043b-2e6dba386377.png)

自分の場合は、デフォルトの「VDI」を選択して次へ。

![rapture_20190116222842.png](https://qiita-image-store.s3.amazonaws.com/0/203502/bfa0623b-d07f-83cc-165e-e385ffc70ca2.png)


可変サイズ/固定サイズは、自分の場合は、固定サイズを選択し、次へ。

![rapture_20190116223019.png](https://qiita-image-store.s3.amazonaws.com/0/203502/cc882710-ef9b-4be7-3e75-8b89af6ae053.png)

仮想ディスクイメージのファイル名と、サイズを設定し、作成を押下。

![rapture_20190116223217.png](https://qiita-image-store.s3.amazonaws.com/0/203502/7902d93c-b661-36a8-3f93-7efac8ab8e4f.png)

少し待つとディスクが作成された。

![rapture_20190116223405.png](https://qiita-image-store.s3.amazonaws.com/0/203502/194f054e-e7d7-19f9-9dd7-c85ae10ee9bb.png)

最後に、上記画面で「OK」を押下。（これしないと反映されなかった。）

### Terminalで確認

ディスクが追加されているか確認します。

```terminal
fdisk -l

Disk /dev/sda: 21.8 GB, 21832744960 bytes, 42642080 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
Disk label type: dos
ディスク識別子: 0x000abc3e

デバイス ブート      始点        終点     ブロ
ック   Id  システム
/dev/sda1   *        2048     2099199     1048576   83  Linux
/dev/sda2         2099200    42641407    20271104   8e  Linux LVM

Disk /dev/sdb: 5368 MB, 5368709120 bytes, 10485760 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト


Disk /dev/mapper/centos-root: 18.6 GB, 18601738240 bytes, 36331520 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト


Disk /dev/mapper/centos-swap: 2147 MB, 2147483648 bytes, 4194304 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
```

上記だと、パーティションが作成されていない```/dev/sdb```が追加されたディスクになります。

あとは、fdiskとかlvmでよしなにパーティション作成や拡張作業をすればOK。

## 参考サイト
- [VirtualBoxで仮想HDDを追加して Linuxのディスク空き容量を増やす](https://qiita.com/egnr-in-6matroom/items/d284dd306753b2f0591a)
私メモ

プログラム初心者が全くわからないま開発チームに投入されたので、
右も左もわからず１週間

なにがわからないかわからない。。。

会社だとききづらいので
家で色々調べて実際に試してみたいと思います。


Node.jsとnpmのインストールしたい
調べたところ、下記でできるらしい

＄ brew install nodebrew


You should change the ownership of these directories to your user.
→これらのディレクトリの所有権を自分のユーザーに変更する必要があります。

らしい。
変更のやりかたを調べてみる。
＄ sudo chown -R [username] /usr/local/include


usernameはコンピューター名を入れるみたい
sudo は最強権限のコマンドという認識（多分）


usernameってなんだろう。。。
色々やってみたら、どうやらターミナルのllllllllllの部分がそうらしい！
本名noMacBook-Pro:~ llllllllll$ 
＄ sudo chown -R llllllllll /usr/local/include


エラーが出ないから成功したのかな？


...またエラー
The following directories are not writable by your user:
/usr/local/share/man/man5

You should change the ownership of these directories to your user.
  sudo chown -R $(whoami) /usr/local/share/man/man5


？？何言ってんのかさっぱり。。。
調べてみると、記載してあるコマンドをたたけばいいとのこと
＄ sudo chown -R $(whoami) /usr/local/share/man/man5


それでもうまくいかなかった。。。
それで再度試してみたのがこちら
一回homebrewをアンインストールして、再アンインストールをする
＄ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/uninstall)"
＄ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"


この後に、再度このコマンドを実行するとうまく実行できた！

nodebrewをインストール
＄ brew install nodebrew


node.jsインストールの最新版をインストール
＄ nodebrew install-binary latest


…エラーが発生。。。
fetch: http://nodejs.org/dist/v6.9.1/node-v6.9.1-darwin-x64.tar.gz
Warning: Failed to create the file
Warning: /Users/sonoda/.nodebrew/src/v6.9.1/node-v6.9.1-darwin-x64.tar.gz: No
Warning: such file or directory

うーーん。
調べてみると、ディレクトリがないからダメらしい

作ってみる
＄ mkdir ~/.nodebrew
＄ mkdir ~/.nodebrew/src

再度インストールをしてみると、成功したみたい！！！！！
＄ nodebrew install-binary latest
Installed successfullyと表示されました！




…でも、なんだかんだうまくいかない！なぜ…
さらに調べてみると、インストーラーからインストールしちゃえば？との記載を発見
https://nodejs.org/en/
（LastFueturesの方をダウンロードしました）

インストーラーを起動（全部同意でおk）

コマンドを実行してみると、ちゃんとバージョンが表示されました！！！よかった！
よくわからないけど、npmもインストールされてる！
（パッケージなのかな？）
＄ node -v
v11.6.0
＄ npm -v
6.5.0-next.0




これでやっとnpmコマンドが実行できるよ…（ここまで２時間かかりました。。。とほほ）












さて、Vue-cliをインストールして、npm run testの実行までさせたいとおもいます。

＄ npm install -g vue-cli
…エラーになりました。
これは、先頭にsudoを入れることで解決

＄ sudo npm install -g vue-cli
パッケージがインストールされたよとのメッセージがでました。よかった

これで下記を実行
サンプル？がインストールできるらしい
＄ vue init webpack my-project

色々質問されるけど、基本的にyで、テストUnitは流行りのJestにします。
Jestの使い方を知りたくて…


今日はここまで。
明日以降がんばります。。。
[Angular] (Tips)テンプレート内でng-templateを使い回す

### Angularの`ng-template` のHowToメモ


## よくあるベタなケース

```html
<!-- ......略 -->
<!--コンポーネント側で変数 "hoge"があるとする -->
<ng-container *ngIf="hoge; else elseTemplate">
  hoge is true  :)
</ng-container>

<ng-template #elseTemplate>
hoge is false !
</ng-template>

```

 と書くと、hoge = falseのときは`ng-template`で定義した`elseTemplate`が表示される。
(ベタ。でも*ngIf="!hoge"と書くのとそこまで変わらないからあんまりありがたくない。*ngIfの条件が長いときはあり。)



## 知っておくと便利かもしれないやつ①

```html
<!-- ......略 -->
<!-- 同じテンプレートファイル内で単純にhtmlを使いまわしたい場合 -->

<ng-template #kurikaesi>
<dl>
  <dt>name</dt>
  <dd>hoge</dd>
</dl>
<ng-template>

<!-- これでつかいまわせる -->
<ng-container *ngTemplateOutlet="kurikaesi"></ng-container>
<ng-container *ngTemplateOutlet="kurikaesi"></ng-container>
<ng-container *ngTemplateOutlet="kurikaesi"></ng-container>

```
マイナーかもしれない。

## 知っておくと便利かもしれないやつ②

```html
<!-- ......略 -->
<!-- 同じテンプレートファイル内でhtmlを使いまわしたい場合でng-template内で変数を使いたいとき -->
<!--
コンポネント側で hoge = { name:string , age:number} が定義されている場合
-->

<ng-template #kurikaesi let-hoge>
<dl>
  <dt>{{hoge.name}}</dt>
  <dd>{{hoge.age}}</dd>
</dl>
<ng-template>

<!-- これでつかいまわせる -->
<ng-container *ngTemplateOutlet="kurikaesi; context:{$implicit:hoge}"></ng-container>

```

*ngForでループさせるときに、ngForのletで定義したテンプレート上の変数を `context:{$implicit:hoge}`のhoge部分に渡したりすると、(コンポーネント(*.ts)を汚さなくて手軽に使いまわしが効いて)結構便利。
けっこうマイナーな使い方かもしれない。


## コンポーネント間のテンプレートの受け渡し(ng-Templateでやる場合)
```typescript:hoge-component.ts
/**
*  @ContentChildでTemplateを渡せるようにしておく
*/

@Component({
  selector: 'hoge',
  templateUrl: '....', // 略
  styleUrls: ['....'],// 略
})

export class SsPopoverComponent{
  @ContentChild(TemplateRef) bodyTemplate: TemplateRef<any>;
}

```

```html:hoge-component.html
<!-- ......略 -->
<ng-container *ngTemplateOutlet="bodyTemplate"></ng-container>
<!-- ......略 -->
```

```html:parent-component.html
<!-- 親のコンポーネントからhogeコンポーネントへテンプレートを渡す -->
<!-- もちろん、親コンポネント内で`.hoge-content`へスタイルを当てられる -->
<hoge>
  <ng-template>
  <span class="hoge-content">
    hogehoge
  </span>
  </template>
</hoge>

```
おそらく今回の受け取ったテンプレートをただ表示するだけのようなユースケースでは`ng-content` を使ったほうがいいが、子(今回はhoge)コンポーネント内で、親からテンプレートを渡されるかどうかで表示を切り分ける場合は`ng-template`を渡したほうがきれいに書ける(気がする)。


```html:hoge-component.html
<!-- 親からテンプレートを渡されるかどうかで表示を切り分ける場合 -->

<!-- ......略 -->
<ng-template #defaultTemplate>
  is Empty!
</ng-template>

<ng-container *ngTemplateOutlet="bodyTemplate? bodyTemplate : defaultTemplate"></ng-container>
<!-- ......略 -->

```

> 参考
> https://alligator.io/angular/reusable-components-ngtemplateoutlet/
> https://blog.angular-university.io/angular-ng-template-ng-container-ngtemplateoutlet/
VisualStudio2017環境でVue開発。Typescriptで行う

項目メタデータエラーということでnodeModuleフォルダ内のファイルが260文字以上はダメという感じのエラーで止まりました。OSの仕様とのこと。

グループポリシーのシステム、管理者テンプレートでwin32の長いファイル名を使用するを有効にするのと、VS2017でファイルを全て見えるにし、nodemoduleフォルダ内を削除。
その後npm不足分はインストールするとこのエラーは出なくなった。
Ruby on Railsチュートリアル（２日目）

# 振り返り
前回はAWSのアカウント登録と、Cloud9にIDE環境作成の作成をしました。
（RubyとかRails全く関係ないけど）
[※前回　Ruby on Railsチュートリアル（１日目）](https://qiita.com/okky_eng/items/7f5985cb2ef7ee084fb5)

### .gemrcへの設定

gemパッケージを利用しているRailsのオプションを設定します。
（これで毎回オプションを打たなくても良くなる）

```
printf "install: --no-rdoc --no-ri\nupdate:  --no-rdoc --no-ri\n" >> ~/.gemrc
```

ユーザフォルダにできていればOK
<img width="482" alt="asdf.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/341731/9c1efe72-f4d6-a761-4b7d-9b4e26771ccf.png">

### Railsのインストール

さっき設定した.gemrcが効いてきます。

```
gem install rails -v 5.1.6
```


### HelloWorldを表示するWebアプリを生成する

newコマンドで、Railsのフレームワークに則ったファイルを生成してくれます。

```
rails _5.1.6_ new hello_app
```

<img width="209" alt="dasth.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/341731/5792a1b7-0783-3b12-4cad-d805f858c84b.png">


### Bundleの実行

**Gemfile**に記述すると、gemパッケージのバージョン管理ができる。
→バージョンを固定して管理することで、不必要な問題を防ぐことができる。

編集後、Bundleを実行する

```
bundle install
```

おっと、こけました。:thinking:
<img width="383" alt="rtbsgfds.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/341731/e0e00bca-0e91-20b6-4363-5048cf2f8bc3.png">

Bundle updateを実行してくださいということみたいなので、実行しておく

```
bundle update
```

もう一度、bundle installを実行することで、無事完了しました。

<img width="426" alt="vvhbbhxvddgfs.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/341731/41d1cb75-35ac-27b6-cda8-64fc524cea64.png">


### Webアプリの表示

下記コマンドを実行する

```
cd hello_app
rails server
```

<img width="921" alt="cfafasffa.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/341731/b87f723e-5cf9-0b9d-75b9-821487e78412.png">

表示できましたね！最低限の環境構築は良さそうです。


### ブラウザ上で、HelloWorldを表示する。

#### MVCモデル
Ruby on RailsはMVCモデル(Model View Controller)を使っています。
ModelはRubyのオブジェクト（データとか）
Viewはブラウザに表示するHTMLそのもの。
Controllerはブラウザのリクエストに応じたViewを生成、表示します。

また、RailsではRouterというブラウザとControllerの間に立つオブジェクト？が存在し
ブラウザからのリクエストをルータが判断して、各Controllerに振り分けているみたいですね。

<img width="368" alt="dasvasfdsa.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/341731/69d09b27-9072-b23d-6829-4b0acb1fba7e.png">

無事出せました。

# 終わりに

無事投稿が続けることができてよかったです。
次は、Herokuまでできたらと思います。
LSP学習記 #4 シンボルのリネーム


自作言語の LSP サーバーを作るプロジェクトの第4回です。今回はソースコードを変更する機能の例として、シンボルのリネームを実装してみました。

- 初回: [LSP学習記 #1](https://qiita.com/vain0x/items/d050fe7c8b342ed2004e)
- 前回: [LSP学習記 #3 シンボルとハイライト](https://qiita.com/vain0x/items/31252d77066505ce6117)
- 今回のソースコード: [curage-lang v0.5.0](https://github.com/vain0x/curage-lang/tree/v0.5.0)

## 名前の変更

変数などの名前を変更するとき、単純な文字列置換では「同名だが異なる変数」といったものまで巻き添えにしてしまいます。安全に変更するには、前回のようにシンボル情報を解析しておくほうがよいです。そういうわけで、LSP サーバーの機能に「名前の変更」があります。

具体的には、 LSP クライアントは [textDocument/rename リクエスト](https://microsoft.github.io/language-server-protocol/specification#textDocument_rename) で、どの位置にあるシンボルをどんな名前に変えるべきかという情報をサーバーに送信してくれます。

このとき、具体的なソースコードの変更点を生成してレスポンスすれば、名前の変更ができるようです。

- 注: 前回と同様に、LSP クライアントからのリクエストをもらうには、サーバーの `capabilities` に `textDocument.renameProvider: true` の指定が必要です。

### 名前の変更: 変更操作の表現

ソースコードに対する変更は `TextEdit` インターフェイスで定義されていて、「ある範囲の文字列を別の文字列で置換する」ような形式です。 `Array.splice` 方式。

例えば次の文字列の範囲 ``[0, 4] .. [0, 5]`` (`x` の部分) を文字列 "new_x" で置換する、みたいな感じです。

```
let x be 1
```

```
let new_x be 1
```

いまのクラゲ言語は1つのファイルにしかソースコードを書けませんが、一般には名前の変更は複数のファイルを変更することになります。`rename` レスポンスで返すべきオブジェクトは、 `WorkspaceEdit` というインターフェイスで定義されていて、ファイルの URI から変更操作へのマップのようなものです。

```typescript
interface WorkspaceEdit {
    // URI から変更操作の配列へのマップ
    changes?: { [uri: string]: TextEdit[]; };

    // 以下略
}
```

## 実装

実装は、前回作ったシンボルテーブルを利用すれば簡単です。

前回は「ドキュメントのハイライトする範囲」を計算しましたが、今回はそれを「名前の変更を適用する範囲」として使えばOK。

```typescript
  const { definition, references } = symbolDefinition // ヒットテストで見つけたシンボル

  // 変更操作の配列
  const textEdits: TextEdit[] = []

  // 定義の置換
  textEdits.push({
    range: definition.range,
    newText: newName,
  })

  for (const r of references) {
    // 参照の置換
    textEdits.push({
      range: r.range,
      newText: newName,
    })
  }

  // WorkspaceEdit インターフェイスに合うオブジェクトを作る
  const changes = { [uri]: textEdits }
  return { changes }
```

- 変更点: [feat: Support symbol renaming](https://github.com/vain0x/curage-lang/commit/603b2c52fe19390a667c25710ad1bcf8af78aaba)

## prepareRename

`textDocument/prepareRename` リクエストという、 `rename` の前に送られてくるリクエストがあります。名前の変更ができない位置 (例えば let キーワードの上) では `prepareName` の結果として `null` を返すことで、名前の変更が不可能であることをクライアントに伝えられる……らしいんですが、実装してみても効果が見られなかったので詳細は略。

- 変更点: [feat: Support 'prepareRename'](https://github.com/vain0x/curage-lang/commit/e91697aed1edd1cd56be54a2c701112aed71e504)

## TextDocumentEdit

LSP の仕様をよく読むと `WorkspaceEdit.changes` ではなく `documentChanges` を使ったほうがよいみたいです。

LSP サーバーが処理をしている間にも、ドキュメントはユーザーによって絶え間なく変更されているので、同じドキュメントにも古いバージョンと新しいバージョンがあります。名前の変更がどのバージョンを処理したのかを指定すると、クライアント側が嬉しいらしいです。

`WorkspaceEdit.documentChanges` には `TextDocumentEdit` (の配列) を指定しますが、これはドキュメントの URI だけでなくバージョンも指定した変更操作を表しています。

- 変更点: [feat: Provide document version in response ](https://github.com/vain0x/curage-lang/commit/a666135fe04e3345bcaef09bc80b8b269d24415f)

## 注意: 安全でない変更

今回の実装では、場合によってはコードの意味を変えてしまいます。例えば次のコードの `x` を `y` という名前に変えると、2つ目の `x` が途中に挟まってる `y` を指すものになってしまいます。これは本来ならユーザーに警告したほうがよいです。

```
let x be 1
let y be 2
let _ be x
```

## 次回

次回は未定です。そろそろ簡単な計算のできる言語にしつつ、入力補完やホバーあたりをやっていこうかと考えています。
【Rails】基礎：MVCモデルについて

#MVCモデルとは？
Railsを理解する上で重要になる考え方。
M＝モデル
V＝ビュー
C=コントローラ

図にすると下記の通り
※ただし、<font color="red">「④モデル」に関してはデータベースとのやり取りがない場合は不要</font>

![Rails_MVC.jpg](https://qiita-image-store.s3.amazonaws.com/0/321593/93c6ca22-2ce3-d154-2394-3f948ee25586.jpeg)


図の用語を見ていくと・・・
##ルーティング(/config/routes.rb)
・ブラウザとコントローラをつなぐ役割
・ユーザーがブラウザ経由でRailsで作成したサービスにアクセスすると、ルーティングが受け取ったURLを分析し、「どのコントローラのどのアクションを実行するか」を判別し、適切なコントローラのアクションを呼び出す。
つまり・・・対応表。

```
get "URL" => "コントローラ名"#"アクション名"
```

##コントローラ(controllersフォルダ内に複数存在）
・コントローラ内のメソッドのことをアクションという
・アクションの役割：ブラウザに返すビューをviewsフォルダの中から見つけ出す役割
（コントローラと同名のビューフォルダから、アクションと同名のHTMLファイルを探してブラウザに返す）

##データベースとモデル
【データベース】
・データベース→表(=テーブル)で管理
・テーブルの列をカラム、行をレコードという

【モデル】
・ApplicationRecordを継承したクラスをモデルという

```ruby:post.rb
class Post < Application #Post部分は単数形
end
```
・モデルは、データベースから情報を取り出したり、逆にデータベースに情報を格納したり、データベースとのやり取りを行う
・Railsにおいては、使用しているデータベースのテーブル毎にモデルが用意されている
(=モデルはデータベースのテーブルに対応するクラス)

```ruby:モデルの作成方法
#下記コマンドを実行する
rails generate model モデル名 #「rails generate」は「rails g」に省略可

# => app/modelsフォルダに、「モデル名.rb」というファイルが作成

#例
rails g model post
# => app/models/post.rbが作成。
# => データベースにPostsテーブルが作成(テーブルは複数形になる！)
```

##ビュー
ページの見た目を作るためのHTMLファイル。
ちなみに・・・CSSファイルはapp/assets/stylesheetsフォルダ内に。
画像ファイルはpublicフォルダ内にある
Swiftで多次元配列を作る際に特定の文字で初期化したい

Swiftで特定の文字で配列を初期化するときは、下記のように書きます。

```swift:
let Array = [String](repeating: [String](repeating: ".", count: 2) //[".."]
```

んで、これが多次元配列だとどうなるか。

Swiftの二次元配列の扱い方がわからなくて、だいぶトライアンドエラーしました。
下記で出来ました。

```swift:
let y = 2
let x = 2
let multiArray = [[String]](repeating: [String](repeating: ".", count: x), count: y) //[[".."],[".."]]
```

考え方としては、二次元配列の要素として一次元配列を突っ込むような記法となっているみたいです。
三次元以上もそのイメージで書けると思うんですが、試してはいません。
クロージャとか使ってもっとオシャレな書き方がある気がするんですが、今の所とりあえずこれを使えばできるというところで。
tensorflow.jsで倒立振子

#概要

tensorflow.jsで倒立振子を立たせてみた。

#写真

![image](https://qiita-image-store.s3.amazonaws.com/0/18104/9d0fed17-e7d3-f6b9-7323-dcba65996190.png)

#モデルを作って、教師データを学習する。

モデルは、入力1、出力1、全結合12、tanh, 全結合1、tanhの回帰。
オプチマイザーは、adam
学習は、9000回
biasとweightをsaveする。

http://jsdo.it/ohisama1/IYm1

#学習したモデルを使ってデモ。

学習済みモデルを読み込む。

http://jsdo.it/ohisama1/4X4R

以上。