OmniAICreator/Qiita-1.07M huggingface dataset:
ShellSort

ShellSortについて、Javaでサンプルプログラムを書いてみました。


```java:ShellSort.java

import java.util.Scanner;
public class ShellSort {
    static int debug = 0;
    public static void main(String[] args) {
	if (args.length > 0 ){
	    if(args[0].equals("-d")) debug = 1;
	    else if (args[0].equals("-d2")) debug = 2;
	}
	Scanner sc = new Scanner(System.in);
	System.out.print("データの個数を入力して下さい  ");
	int n = sc.nextInt();
	int[] a = new int[n];
	for (int i=0; i<n; i++) a[i] = sc.nextInt();
	sort(a);
	System.out.println(toString(a));
    }
    public static void sort(int[] a) {
	int h;
	for(h=1; h<a.length/9; h=h*3+1);
	for(; h>0; h/=3) {
	    for(int i=h;i<a.length;i++){
		for(int j=i;j>=h&&a[j-h]>a[j];j-=h){
		    int tmp = a[j];
		    a[j] = a[j-h];
		    a[j-h] = tmp;
		    if(debug > 1)
			System.out.println("h="+h+"i="+i+",j="+j+": "+toString(a));
		}
		if(debug>0)
		    System.out.println("h="+h+"i="+i+": "+toString(a));
	    }    
	}
    }
    public static String toString(int[] a) {
	StringBuffer sb = new StringBuffer();
	for (int i=0; i<a.length; i++)
	    sb.append(a[i] + " ");
	return sb.toString();
    }
}

```
Tile Palette Windowの各ツールの名前

　Unity Tilemapの描画ツール(描画モード)の切り替えは、Tile Palette Windowの上部のアイコンを押す、もしくはショートカットキーを使うことで切り替えます。

　公式ドキュメント「[Painting Tilemaps](https://docs.unity3d.com/Manual/Tilemap-Painting.html)」によると、それぞれのツールには名前があるようです。公式ドキュメントは、各ツールの説明の合間に名前がかかれていて、名前が一覧しにくいため、まとめます。

# Select Tool

![icon0.PNG](https://qiita-image-store.s3.amazonaws.com/0/4125/ae24578f-c435-c78e-528a-8a9049de9963.png)

範囲選択を行うカーソルアイコンのツールは、「Select Tool」です。

# Move Tool

![icon1.PNG](https://qiita-image-store.s3.amazonaws.com/0/4125/8f893eb7-2168-9319-48f6-edb787004724.png)

移動を行う十字矢印のアイコンのツールは、「Move Tool」です。

# Paint Tool

![icon2.PNG](https://qiita-image-store.s3.amazonaws.com/0/4125/3317b523-be81-9e7c-8a15-ed33fa47f0e6.png)

Tileの描画を行う筆のアイコンのツールは、「Paint Tool」です。

# Rectangle Tool 

![icon3.PNG](https://qiita-image-store.s3.amazonaws.com/0/4125/59e3b5cf-a1d1-e687-bd91-2ac63a025cbb.png)

矩形描画を行う四角のアイコンは、「Rectangle Tool 」です。

# Picker Tool

![icon4.PNG](https://qiita-image-store.s3.amazonaws.com/0/4125/6dfb9864-c205-7e9d-fefe-08c722790450.png)

スポイト領域選択(抽出)を行うスポイトのアイコンは、「Picker Tool」です。

# Erase Tool

![icon5.PNG](https://qiita-image-store.s3.amazonaws.com/0/4125/45cd8625-dc58-4ceb-d240-38199ad782e9.png)

Tileの削除を行う消しゴムアイコンのツールは、「Erase Tool」です。

# Fill Tool

![icon6.PNG](https://qiita-image-store.s3.amazonaws.com/0/4125/96fb4384-c091-b1a7-e4d5-4813070a0bd1.png)

領域塗りつぶしを行うバケツのアイコンは、「Fill Tool」です。

# 関連

* [Tilemap Editorショートカットキーのメモ](https://qiita.com/RyotaMurohoshi/items/6fe23e65b18b818467e0)
* [Painting Tilemaps（公式）](https://docs.unity3d.com/Manual/Tilemap-Painting.html)
GitHubな環境でansible-vaultの暗号化パラメータをうまく管理するコツ

# はじめに
実際の現場では、AnsibleのPlaybookをGitHubやBitbucketなどで管理・共有していると思います。
その際気をつけなければならないのがパスワードなどの機密情報の管理です。
publicはもちろん、privateなリポジトリでもこれらの情報をアップロードすべきではありません。

そうした課題に応えるため、Ansibleには`ansible-vault`という機能があり、暗号化したファイルをPlaybook実行時に自動的に復号化してくれます。便利！

ただし、`ansible-vault`の暗号化はファイル単位となってしまうので、使い方によっては管理しづらくなるケースがあります。

# よくあるケース
テンプレートに下記のようにパスワードを埋め込みたいとき

```yaml:template.j2
password={{ password }}
```

上記`password`というパラメータを`secret.yml`に記載して暗号化

```yaml:secret.yml
password: XXXXXXXX

```

暗号化後

```secret.yml
$ANSIBLE_VAULT;1.1;AES256
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX...
```

# 上記の問題
新しいメンバは、templateを見て`password`というパラメータがあることを知りますが、リポジトリ内を検索してもkeyごと暗号化されているので当然見つかりません。

一人で開発している場合は作った本人が把握しているので問題ないでしょうが、チームで開発しており、新しいメンバがジョインしたときなどは混乱をきたすことになるかもしれません（私だ）。

# 解決策

**変数を階層化し、通常の変数と暗号化する変数の階層を分ける**

こうすると、valueに別階層の変数を指定できるため、valueのみを暗号化できます（`password`というパラメータ自体は検索できる）。

## sample

```yaml:template.j2
user={{ my_vars.user }}
password={{ my_vars.password }}
```

```yaml:vars.yml
---
my_vars:
  user: username
  password: "{{ secret.password }}"
```

```yaml:secret.yml
---
secret:
  password: XXXXXXX
```
暗号化後

```secret.yml
$ANSIBLE_VAULT;1.1;AES256
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX...
```
`password`というパラメータ自体は、`user`というパラメータと共に暗号化していない`vars.yml`に定義してあるため、検索も容易です。
そのvalueを見れば、値そのものはわからなくても`secret.password`に定義されているのだなとわかります。

あとは、暗号化ファイルはファイル名に`_secret`をつけるなどの命名規則を決めておけば新しいメンバも混乱することはないでしょう（私だ）。

# 参考
`ansible-playbook`実行時の復号はパスワード入力でも可能ですが、実際の運用を考えると現実的ではありません。
暗号化時のパスワードをファイルに記載しておき、`ansible-playbook`実行時にそれを参照するようにします。

```bash:
$ ansible-playbook -i hosts site.yml --vault-password-file /PATH/TO/.vault_password
```
これでもいいですが、`ansible.cfg`の`[defaults]`に下記のように設定すれば`--vault-password-file`オプションも不要になります。

```ini:ansible.cfg
[defaults]
vault_password_file = /PATH/TO/.vault_password
```

あとは`/PATH/TO/.vault_password`をメンバ間で共有しておけば、通常どおり`ansible-playbook`で実行できます。

##通常運用での暗号化ファイルの操作

###既存ファイルの暗号化
`ansible-vault create`で新規作成するのが本来かもしれませんが、私の場合、暗号化せずに開発を進めてリポジトリにpushするタイミングで暗号化することが多いです。

```bash:
$ ansible-vault --vault-password-file /PATH/TO/.vault_password encrypt secret.yml
```

###暗号化ファイルの編集
```bash:
$ ansible-vault --vault-password-file /PATH/TO/.vault_password edit secret.yml
```

###復号（個人的にあまり使わない）
```bash:
$ ansible-vault --vault-password-file /PATH/TO/.vault_password decrypt secret.yml
```
Laravel でAjax をデバッグする方法

最近はずっとJava 使っていたんですが、後輩の手伝いで1年ぶりにLaravel を触りました。
気づいたらversion 5.5 までいってたんですね。え、もっと先もあるんですか。

後輩に教えた事をまとめます。
タイトルではLaravel と書いてありますが、普遍的な内容もちょっとミックスしています。

## 環境
・Laravel 5.5
・Google Chrome
・jQuery (多分他のjs ライブラリでも似た感じになるかと)

## 実装例
```html:app.blade.php
<!-- head 内に追記 -->
<meta name="csrf-token" content="{{ csrf_token() }}">
```
```javascript:app.js
$.ajax({
  headers: {
    'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
  }
  type : "POST",
  data: {
    "id" : id,
    "name" : name
  },
  url : './doSomething' /* HogeController@doSomething に合わせる */
  dataType : "json",
);
```
```php:HogeController.php
namespace App\Http\Controllers;

use App\Hoge;
use App\Http\Controllers\Controller;
use Log;

class UserController extends Controller
{
    public function doSomething(Request $request)
    {
        Log::debug($request);
    }
}
```
# デバッグの方法
## Ajax で送信しているURI が正しいか知りたい
Google Developper tool を使いましょう。
・500番台→パスは合っているがphp の処理中にエラーが発生している
・400番台→パスが間違っている
・200→処理は成功している
`右クリック→検証→Network→XHR` からAjax の送信状況 (Request, Response 等)を見る事ができます。
ネットワーク送受信に関わる複雑なxml が出てきますが、頑張って読み解きましょう。

![network.PNG](https://qiita-image-store.s3.amazonaws.com/0/143161/c1194591-6a95-acc0-8c81-466cf3660966.png)

※出力される複雑なxml は<a href="https://www.amazon.co.jp/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%81%AF%E3%81%AA%E3%81%9C%E3%81%A4%E3%81%AA%E3%81%8C%E3%82%8B%E3%81%AE%E3%81%8B-%E7%AC%AC2%E7%89%88-%E7%9F%A5%E3%81%A3%E3%81%A6%E3%81%8A%E3%81%8D%E3%81%9F%E3%81%84TCP-IP%E3%80%81LAN%E3%80%81%E5%85%89%E3%83%95%E3%82%A1%E3%82%A4%E3%83%90%E3%81%AE%E5%9F%BA%E7%A4%8E%E7%9F%A5%E8%AD%98-%E6%88%B8%E6%A0%B9/dp/4822283119" target="_blank">『ネットワークはなぜつながるのか』</a>なんか読むと理解できるようになってきます。


## データがきちんと渡っているか知りたい
```php:log.php
/* 問題ないコード storage/log/laravel.log へ出力される */
Log::debug($request);
```
```php:log.php
/* 失敗するコード　原因は追っていない */
dd($request);
dd($request->all());
```
dd って便利ツールは今回初めて知りました。
大変便利な機能だと思いますが、ページ切り替わるみたいなのでAjax と相性悪いんですかね。
いろいろ試しても500 返ってきました。
ここは大人しくLaravel 標準のロガーを使って.log ファイル読み解きましょう。
Scala入門 備忘録 Option編

## 自己紹介
JavaからScalaへ転向してはや数年、上田です
結局はこれが凄かったねScalaちゃん、って所を纏めて行こうと思いました

## 対象者
Scala初学者
ゴリゴリ触っている人にはあたりまめな事しか書いてませんw

## ここで書く事
1. Option型は空の状態を持てる
1. Option型は未確定な未来の状態も表現できる

## Option型は空の状態を持てる
1. Option型は明示的に空の状態を持つ事が可能な型です
1. get, fold, map, flatMapで取りだす事が出来ます。 
1. Option型は未確定の状態、つまり未来に起こる事を入れる事もできる

```
val opStr1: Option[String] = Some("文字列だよ")
val opStr2: Option[String] = None
```

**getで文字列を取り出す**

```
println(s"get opStr1 = ${opStr1.get} ") 
//println(s"get opStr2 = ${opStr2.get} ") // getは中身が無いと落ちます
```

**foldは中身が無い場合の戻り値を指定出来ます**

```
println(s"get opStr1 = ${opStr1.fold("空っぽ")(x => x)} ") 
println(s"get opStr2 = ${opStr2.fold("空っぽ")(x => x)} ") 
```

**mapは中身がある場合だけ文字列を取り出せます**
一般的なmapの使い道は配列などをぶん回す場合に多用するが、Optionに対して使うとこうなります

```
println(s"get opStr1 = ${opStr1.map(_)}") 
println(s"get opStr2 = ${opStr2.map(_)}") // 中身が無い場合には空
```

**flatMapは中身がある場合だけ文字列を取り出せますが、Option型で返す必要があります**
よく見かける一般的なflatMapの使い道は多段構造の配列をぶん回して1段に展開する場合に多用するが、Optionに対して使うとこうなります

```
println(s"get opStr1 = ${opStr1.flatMap(x => Some(x))}") 
println(s"get opStr2 = ${opStr2.flatMap(x => Some(x))}") 
```

サンプルではStringを取扱ったが、FunctionやらEntityも同様に取り扱えます


## Option型は未確定な未来の状態も表現できる
未来を扱う非同期処理を書きたい時
魔法のImport文を書くと未来を簡単に扱かう事が出来ます。

```
import ExecutionContext.Implicits.global
```
ここで言う未来とは、タイムラグがある処理の事で、DB問合せや、ElasticSearch検索, ファイルダウンロードしてなど、時間の掛かる処理を非同期で処理して、処理が終わったら続きを処理するような場合の事です。

```
# このimportによりflatMapに未来の処理を詰める事ができます
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future

def fIf(flg: Boolean): Future[Option[String]] = Future.successful{
  if (flg) { Some("未来の文字列") }else{ None }
}    

def fFlatMap(): Future[String] = { 
  fIf(true).flatMap{ r => 
    Future.successful(r.fold("空っぽ")(x => x))
  }
}

fFlatMap().flatMap{ r => 
  println(s"未来の処理結果=${r}")
  Future.successful(Unit)
}
```
Fedora Media Writer を使用して Red Hat Enterprise Linux のインストール USB を作成する

![fedora-media-writer-home](https://qiita-image-store.s3.amazonaws.com/0/67627/35b2d04a-5199-029b-0a9e-ceaf8c45121b.png)

[Fedora Media Writer](https://github.com/MartinBriza/MediaWriter) を使用して Red Hat Enterprise Linux のインストール USB を作成する方法をメモっとく。[Red Hat Enterprise Linux Server を開発用に無償利用するために Red Hat Developer Program に参加する](https://qiita.com/takuya0301/items/e59fa07f87d8d6e97923)の続き。

今回は Windows で作成する。Linux や macOS での作成方法は [Red Hat Enterprise Linux 7 インストールガイド](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/installation_guide/)を参照すること。

# Fedora Media Writer をインストールする

[Fedora Media Writer のリリース](https://github.com/MartinBriza/MediaWriter/releases/)にアクセスして、FedoraMediaWriter-win32-x.y.z.exe をクリックしてダウンロードする。

![github-fedora-media-writer-releases](https://qiita-image-store.s3.amazonaws.com/0/67627/7a52d82f-075c-1e5e-ce47-62c1b2e4e8ca.png)

ダウンロードしたファイルを実行すると下記のようなウィザードが起動する。ウィザードどおりに進めるとインストールが完了する。

![fedora-media-writer-license-agreement](https://qiita-image-store.s3.amazonaws.com/0/67627/dc2d6ca1-722a-e8af-4be0-22640af13b68.png)

![fedora-media-writer-choose-install-location](https://qiita-image-store.s3.amazonaws.com/0/67627/27fc9fa0-f577-837b-20d2-ad2bb9cf5b3c.png)

![fedora-media-writer-installation-complete](https://qiita-image-store.s3.amazonaws.com/0/67627/bbf5993e-e20d-e735-0ffd-a7347362c55c.png)

![fedora-media-writer-completing-fedora-media-writer-setup](https://qiita-image-store.s3.amazonaws.com/0/67627/6eda4505-70b7-a93b-c878-64fb0008c8f0.png)

# インストール USB を作成する

Fedora Media Writer のインストールが完了したら、Fedora Media Writer を起動する。

Fedora Media Writer の起動画面で Custom Image を選択し、ダウンロード済みの Red Hat Enterprise Linux の ISO イメージを選択する。

![fedora-media-writer-home](https://qiita-image-store.s3.amazonaws.com/0/67627/35b2d04a-5199-029b-0a9e-ceaf8c45121b.png)

4.5 GB 以上の容量を持つ空の USB ドライブを接続し、接続した USB ドライブをリストから選択する。そして Write to Disk をクリックして書き込みを開始する。

書き込みを開始すると USB ドライブの内容はすべて消去されるので実行する前に、USB ドライブに何も入っていないことをきちんと確認すること。

![fedora-media-writer-write-custom-image](https://qiita-image-store.s3.amazonaws.com/0/67627/a553f48a-e950-e1b1-2a81-508ceeefccaa.png)

書き込みが完了したら Close をクリックして Fedora Media Writer を終了する。

![fedora-media-writer-write-custom-image-complete](https://qiita-image-store.s3.amazonaws.com/0/67627/e1155662-6e7a-bc5f-658c-76716a69ab97.png)

---

今回は Fedora Media Writer を使用して Red Hat Enterprise Linux のインストール USB を作成するところまで説明した。次回は ThinkPad X1 Carbon で Red Hat Enterprise Linux のインストーラーを起動する方法を説明する。

# 参考文献

https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/installation_guide/
Shapeless で固定長形式の行データをデコードする

固定長形式のテキストの一行を、shapeless でケースクラスにマッピングする方法を考えてみた。

## 動機
『[Think Stats-プログラマのための統計入門](http://greenteapress.com/thinkstats/)』では、第1章の分析対象が固定長形式のテキストデータとして書かれている([NSFG](https://www.cdc.gov/nchs/nsfg/nsfg_cycle6.htm)の'2002FemResp.dat'、ファイル形式は[ここ](ftp://ftp.cdc.gov/pub/Health_Statistics/NCHS/Dataset_Documentation/NSFG/Cycle6Codebook-Pregnancy.pdf))。

固定長形式とは、1レコードを1行とし、各フィールドのデータを固定の開始・終了桁で示した位置に書きこんだもの。

この形式のファイルを読み込む Python コードが、[書籍のサイト](http://greenteapress.com/thinkstats/survey.py)で提供されているが、同じことを Scala + shapeless で**宣言的**に書いてみたい。

## 方針
簡単のために、以下のようなシンプルなケースクラス`IceCream`で考えてみる（『[The Type Astronaut's Guide to shapeless](https://underscore.io/books/shapeless-guide/)』から借用）。

```scala
case class IceCream(name: String, numCherries: Int, inCone: Boolean)
```
このインスタンスを、以下のようなフォーマットのテキスト行をデコードして生成してみたい。

- name: 1桁~12桁
- numCherries: 13桁~14桁
- inCone: 15桁~17桁（yes または no）

(shapeless は 2.12の 2.3.3、ソースは[ここ](https://gist.github.com/yasuabe/4d542dc10aceee6aeef5959b6aa9dbef))

## やり方
まず行の指定の位置から、変換関数を用いて値を抽出する関数を返す高階関数`extract`を、以下のように定義する。

```scala
def extract[A](start: Int, end: Int, convert: String => A): String => A =
  line => convert(line.substring(start - 1, end).trim)
```
これを使ってフィールドごとに抽出関数を作って、関数の`HList`とする。

```scala
val extractors =
  extract(1,  12, identity)   ::
  extract(13, 14, _.toInt)    ::
  extract(15, 17, _ == "yes") ::
  HNil
```
これを行に適用して変換結果フィールド値の`HList`を得るには、同じ要素数だけ行を繰り返した`HList`を作って引数の`HList`とし、`extractors`とはり合わせる形で関数適用する。

指定数だけ行を繰り返して引数の`HList`とするには以下のような関数を使う。

```scala
def repeat[I <: HList, L <: Nat, O <: HList](in: I, s: String)(
  implicit
    len: Length.Aux[I, L],
    rep: Repeat.Aux[String :: HNil, L, O]
): O = rep(s :: HNil)
```
「関数の`HList`」を「引数の`HList`」に適用するには、`zipApply`を使い、最後に`Generic`を使って`IceCream`に変換する。まとめると次のような関数になる。

```scala
def lineToIceCream(line: String): IceCream =
  Generic[IceCream].from(extractors zipApply repeat(extractors, line))
```

以下のように確認できる。

```scala
val lines = List (
    "Sundae       1no ",  // IceCream(Sundae,       1,  false),
    "Cornetto    13yes",  // IceCream(Cornetto,     13, true),
    "Banana Split 0no ")  // IceCream(Banana Split, 0,  false)
  .map(lineToIceCream)
```

## 所感等
- 命令型のコーディングだと、フィールド定義をループしながら一個ずつ値を抽出・変換して、結果のオブジェクトに書き込んで更新する形になるが、Scala + shapeless だとかなり宣言的に書ける。

- `IceCream`と同様に NSFG のデータ 13593件も問題なくデコードできる。
- [FS2](https://github.com/functional-streams-for-scala/fs2)などを用いてStreaming I/O的にレコードの流れを扱う方法などは、別の機会にやってみたい。

## まとめ
型レベルプログラミングも宣言的なコーディングに役に立つ。
ドメイン駆動設計の基本原則

# 自己紹介
フルスタックエンジニアのk-okinaです。
最近DDDを学習しているのですが、ビジネスエキスパートである人へEric Evans氏のDDDのビデオを見せたらとてもわかりやすく解説してくれて感激したのでシェアします。

# ドメイン駆動設計の定義
Eric Evans氏は**DDD**とは以下4つの原則からなると説明しています。
その説明を**ソフトウェアエキスパートが理解し易い**よう訳します。

## 1. Focus on the core complexity and opportunity in the domain
訳： 複雑で解決すると利益のある問題の焦点に集中する。（問題の核心）

## 2. Explore models in a collaboration of domain experts and software experts
訳： 関連する専門家で協力して問題にアプローチするモデル(仕組み)を作る。

## 3. Write software that expresses those models explicitly
訳： モデルたちをうまく表現したソフトを作る

## 4. Speak ubiquitous language within a bounded context
訳： 境界付けられたコンテキストの中の共通言語で話す
#### 補足
例1. これがどういう意味かというと、例えば、ピカチュウと言うとピカチュウと認識します。それは互いに共通するポケモンのコンテキストがあるからです。
しかしポケモンを知らない==ピカチュウは何も意味しない==共通のコンテキストではない
もし相手がポケモンを知っているという前提でピカチュウと言ってしまってポケモンを知らなかった場合はミスコミュニケーション＝誤解が発生し、うん？？？？となります。
それを認識することはとても大切です。

#### 例2.
**前提**：X<Y, 結果：Y-X = +/-　はどっちですか？
と、この**前提**がなかった場合、Y-Xは+/-どっちですか？
Eric Evans氏はこの**前提**を制限と言っています。
要は前提が言葉の意味を制限しているということです。
それこそドメインにおける境界を決めるかのように。

#### 例3.
ポケモンという前提が、ピカチュウの一つの意味を作っている。
他の国ではピカチュウはあのピカチュウじゃないかもしれない。
あのピカチュウがピカチュウであるというドメインの領域がコンテキストによって定められてる。
この場合、境界＝前提＝コンテキスト
領域＝ドメイン
前提を認識していない＝ドメインのズレ、そしてプロジェクトのズレ
つまり、ピカチュウがピカチュウと意味を成す領域がドメインで、そのドメインが有効なのはそのコンテキスト内であると
ポケモンを知ってる人の集団があって、それは抽象的にドメインを構成している

#### 例4.
<img width="460" alt="スクリーンショット 2018-03-05 1.05.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/141711/2438c6f0-380d-9c71-ca5f-73f273820044.png">
これは日本のドメインです
この中で話されている言葉はこの外では通じません
前提==日本語==コンテキスト
日本語を知っているか知らないかでコンテキストは境界づけられています
しかし、沖縄弁は日本領域内ですが、沖縄でしか通じません
そこにもドメインはあります
しかし、共通のコンテキストがあるので、沖縄の人と大阪の人が一緒に問題解決をしようとした場合、東京弁で会話します
これがEric Evans氏の言う
**境界付けられたコンテキストの中の共通言語で話す**ことです

## つまりコンテキストとは
例4で出したように**大阪の人**と**沖縄の人**の**2つのドメインが1つのコンテキスト内にあった**ように、**コンテキストとは、ドメインの範囲を決めているもの**です
ものすごーく簡単に言うと、コンテキストは環境(日本)で、ドメインはその環境内の特定領域(大阪・沖縄など)の事です

# 最後に
いかがだったでしょうか？
もっとシンプルに説明・補足・追記出来る方いましたら、編集リクエストどしどしお願いします！
TableViewで一番下に行った時にロード中をだす。

##行いたいこと
Api通信時、待ち時間がある時にロード中の表示をだす。(今回はApiの代わりにタイマーで)

##動作の模様
![loadsample.gif](https://qiita-image-store.s3.amazonaws.com/0/133940/90870802-123a-c4c3-7229-94b95f90161c.gif)

##コード重要部分のみ

```ViewController.swift
import UIKit

class ViewController: UIViewController {
    
    var sampledatas = [1,2,3,4,5,6,7,8,9,10]
    let table = UITableView()
    let ViewFrame = UIScreen.main.bounds
    var isaddload:Bool = true

    override func viewDidLoad() {
        super.viewDidLoad()
        
        
        self.table.register(UITableViewCell.self, forCellReuseIdentifier: "MyCell")
        self.table.register(cellType: LoaddingTableViewCell.self)
        let footerCell: UITableViewCell = table.dequeueReusableCell(withIdentifier: "LoaddingTableViewCell")!
        (footerCell as! LoaddingTableViewCell).startAnimationg()
        let footerView: UIView = footerCell.contentView
        table.tableFooterView = footerView

        table.frame = ViewFrame
        self.view.addSubview(table)
        
        self.table.dataSource = self
        self.table.delegate = self
        
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        
    }
}

extension ViewController:UITableViewDataSource,UITableViewDelegate{
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
       return sampledatas.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath as IndexPath)
        cell.textLabel?.text = "\(sampledatas[indexPath.row])"
        return cell
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat{
        return 130
    }
    
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        if (self.table.contentOffset.y + self.table.frame.size.height > self.table.contentSize.height && self.table.isDragging && isaddload == true){
            self.isaddload = false
            self.addData()
        }
    }
    
    func addData(){
        DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
            for count in 0..<10{
                self.sampledatas.append(count)
            }
            if(self.sampledatas.count > 50){
                self.isaddload = false
                self.table.tableFooterView = UIView()
            }else{
                self.isaddload = true
            }
            self.table.reloadData()
        }
    }
}

```

##githubのurl

https://github.com/sachiko-kame/BotomLoadSample

##参考にさせていただいたurl
[てきとーにSwiftとマリオ64](http://swiftblog01.com/2017/04/27/post-318/)
[とりあえずphpとか](http://kimagureneet.hatenablog.com/entry/2017/01/05/061539)
[[iOS][Swift]UITableViewのヘッダーとフッターを設定する方法](https://qiita.com/nakamurau1@github/items/301b69522c32254617ad)
[UITableViewのデリゲートメソッドまとめ](https://qiita.com/kagemiku/items/22b74010365723c5c4fe)
ApnsPHPでタイトルつきPush通知を送るよ

# まえがき
タイトルの通りです。

タイトルつきPush通知は、どうもiOS8.2あたりから送信可能となったようです。

そもそも久しぶりにPush通知送信処理を書くことになったので、
どうしたものかと軽く悩んでみたのですが、大丈夫、ちゃんとApnsPHPが対応していました。

**ApnsPHPえらい**
**ApnsPHPすごい**

・・・・というための記事です。


# 実装
通常のメッセージのみを送信する処理はサンプルにあるとおりで、
`ApnsPHP_Message`を使用します。

タイトルつきの通知を送信する場合は、ApnsPHPに用意されている`ApnsPHP_Message_Custom`を使用します。
`ApnsPHP_Message_Custom`は名前の通り`ApnsPHP_Message`の改良版で、タイトルの対応がされています。
なので、そのまま処理を増やせば大丈夫。

```php
$apns_message = new ApnsPHP_Message_Custom($user_device_token);
$apns_message->setExpiry($expire);
$apns_message->setText($message);
$apns_message->setBadge($badge);
$apns_message->setTitle($title);    // ←NEW
```

別段特殊なことはしていないので、送信の実処理はサンプル見てどうぞ。


# あとがき
内容がうっすいけど、まぁそんなもんで。。

しかし、ApnsPHP、自分が最初に触ったのは5年くらい前のはずなんですが、
まだ同じライブラリが、それもちゃん新機能に対応されて利用できるというのはちょっと嬉しいですね(^^)


# おまけ
そんなApnsPHPですが、どうも2017/12に対応されたようなのでもう不要みたいですが、
自分が使用したソースではデバイストークンの桁数増加には対応されていませんでした。
なので、継承したクラスを用意して対応しています。

```php
/**
 * デバイストークンの桁数が変更となったため対応
 * タイトルのため、\ApnsPHP_Messageではなく\ApnsPHP_Message_Customを継承
 */
class My_ApnsPHP_Message extends ApnsPHP_Message_Custom
{
    /**
     * 桁数を32bytes(16進数で64文字)から100bytes(16進数で200文字)に変更
     *
     * @param  $sDeviceToken @type string Recipients device token.
     * @throws ApnsPHP_Message_Exception if the device token
     *         is not well formed.
     */
    public function addRecipient($sDeviceToken)
    {
        if (!preg_match('~^[a-f0-9]{64,200}$~i', $sDeviceToken)) {
            throw new ApnsPHP_Message_Exception(
                "Invalid device token '{$sDeviceToken}'"
            );
        }
        $this->_aDeviceTokens[] = $sDeviceToken;
    }
}
```

あと1ヶ月はやければ↑の対応いらなかったなぁ・・・・運が悪かったか。。('A`)
くやしいのでここに書いときます・・・・(-_-;)
solidityにおけるエラーハンドリング、assert()とrequire()

solidityでは状態を元に戻す例外が使われている。assert()もrequire()も
変更を元に戻して例外を返す。assert()は内部エラーの検証や不変量の確認に使われ、
require()はインプットやコントラクタの状態変数が有効かの確認に使われる。
下の例ではrequire()がインプット(msg.value)が偶数かチェックし、assert()はコントラクトの
の結果の正しさをチェックしている。

```solidity:exception.sol
contract Sharer {
    function sendHalf(address addr) public payable returns (uint balance) {
        require(msg.value % 2 == 0); 
        uint balanceBeforeTransfer = this.balance;
        addr.transfer(msg.value / 2);
        assert(this.balance == balanceBeforeTransfer - msg.value / 2);
        return this.balance;
    }
}
```

またassert()はすべてのGasを使い切るが、require()は残ったGasを返却する。

[参考](http://solidity.readthedocs.io/en/develop/control-structures.html?highlight=throw#error-handling-assert-require-revert-and-exceptions)
RSpec + Factory_botでテストする方法

RSpecとFactory_botを使用したテスト方法。要点のみ。

当記事の動作環境
OS: macOS High Sierra 10.13.3

Ruby 2.4.2p198
Rails 5.1.5

rspec (3.7.0)
rspec-core (3.7.1)
rspec-expectations (3.7.0)
rspec-mocks (3.7.0)
rspec-rails (3.7.2)
rspec-support (3.7.1)

factory_bot (4.8.2)
factory_bot_rails (4.8.2)

## RSpecとは
Ruby用のテスティングフレームワーク。
Ruby on railsには標準でminitestが搭載されているが、より多く使われているのはRSpec（主観）

## Factory_botとは
テストデータ作成ツール。
もともとはFactory_girlという名称だったが変更になった。

## 事前準備
RSpecを使用してテストを行うため以下の設定が必要。
今回の記事では使用しないGemもあるが、今後のために先に入れておく。

```ruby:Gemfile
group :development, :test do
  gem 'factory_bot_rails'
  gem "rspec-rails"
  gem "guard-rspec"
  gem "spring-commands-rspec"
end

group :test do
  gem "faker"
  gem "capybara"
  gem "database_cleaner"
  gem "launchy"
  gem "selenium-webdriver"
  gem "shoulda-matchers"
end
```

RSpecをインストール

```shell
$ bundle exec rails generate rspec:install
```

## テスト方法
### テストデータの準備

```ruby:spec/factories.rb
FactoryBot.define do
  factory :staff do
    staff_last_name  "名字"
    staff_first_name "名前"
    staff_short_name "名字"
    position_div "2"
    create_id "TEST01"
    update_id "TEST01"
    lock_version "1"
  end
end
```

```ruby:*_spec.rb
# テストコード内でのデータ生成方法

# DBへレコードを追加
FactoryBot.create :staff
# モデルのみの生成
FactoryBot.build :staff

# 生成したデータをコンソール出力する場合
@staff = create :staff
p @staff
```

### テストコードの作成

```ruby:spec/requests/staffs_controller_spec.rb
require "rails_helper"

describe StaffsController, :type => :request do

  describe "GET index" do
    before do
      FactoryBot.create :staff
    end

    it 'リクエストが成功すること' do
      get staffs_url
      expect(response.status).to eq 200
    end

    it '@staffが取得できていること' do
      get '/sales-system/staffs?position_div=2'
      expect(response.body).to include "レスポンスに含まれている名前"
    end

  end
end
```

### テスト実行

```shell
# spec/*/*_spec.rbを全て実行
$ rails spec
/Users/kodai/.rbenv/versions/2.4.2/bin/ruby -I/Users/kodai/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/rspec-core-3.7.1/lib:/Users/kodai/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/rspec-support-3.7.1/lib /Users/kodai/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/rspec-core-3.7.1/exe/rspec --pattern spec/\*\*\{,/\*/\*\*\}/\*_spec.rb

StaffsController
  GET index
I, [2018-03-05T00:40:04.626323 #38686]  INFO -- : Started GET "/sales-system/staffs" for 127.0.0.1 at 2018-03-05 00:40:04 +0900
    リクエストが成功すること
I, [2018-03-05T00:40:04.774848 #38686]  INFO -- : Started GET "/sales-system/staffs?position_div=2" for 127.0.0.1 at 2018-03-05 00:40:04 +0900
    @staffが取得できていること

Finished in 0.73985 seconds (files took 8.59 seconds to load)
2 examples, 0 failures
```

### 方針
modelのvalidateや、controllerのlogicが正しいことより
常にリクエストのレスポンスが200であることの方が重要だと思うのでmodelやコントローラのテストは端折ってしまいます。
reactjsを勉強してみた　第1回

#前提環境
OS:Windows7
nodejs:v8.9.4
npm:5.6.0

#reactjsを勉強する前に
早いとこreactjsを勉強したいのですが、nodejsとかnpmとかその辺の事をまだちゃんと勉強したことがなかったのでそこから触っていきます。
復習の為まとめていこうかと思います。

#npmコマンド
勉強したコマンド
<dl>
<dt>npm install ○○</dt>
 <dd>ライブラリ○○をローカルインストール。</dd>
<dt>npm install -g ○○</dt>
 <dd>ライブラリ○○をグローバルインストール。</dd>
<dt>npm root -g</dt>
 <dd>ライブラリをグローバルインストールした時の格納場所が表示される。</dd>
<dt>npm uninstall ○○</dt>
 <dd>ライブラリ○○をローカルアンインストール。</dd>
<dt>npm uninstall -g ○○</dt>
 <dd>ライブラリ○○をグローバルアンインストール。</dd>
<dt>npm init</dt>
 <dd>カレントディレクトリで使用する。使用するとpakage.jsonが作成されプロジェクトを管理することができる。特に設定することがなければEnter連打とかでもOK。</dd>
<dt>npm install ○○ --save</dt>
 <dd>ライブラリインストール時に--saveか-Sをつけるとpakage.jsonの依存モジュールとしてインストールされる。pakage.jsonにdependenciesという項目が増え、そこにモジュールとバージョンが記録される。

```json:pakage.json
{
  "name":"testProject",
  ...
  "dependencies": {
    "testLib": "^v1.1.0"
  }
}
```

</dd>
<dt>npm run ○○</dt>
 <dd>pakage.jsonの"scripts"に「コマンド名:コマンド」を任意に追加していく。追加したコマンドを○○に当てはめる事によって
任意で追加したコマンドを実行できる。

```json:pakage.json
{
  "name":"testProject",
  ...
  "scripts": {
    "start": "node index.js"
    "check": "node -v"
  }
}
```

</dd>
</dl>
php-fpmとRAMのお勉強メモ。KUSANAGIで試した。

kusanagiを非推奨の環境であるt2.microに
推奨RAMが4GB以上のところ、t2.microは1Gしかないので、すぐスワップアウトする。

良い機会なのでちょっと勉強してみた。

- kusanagi php7 のオプションでphp7にしているのと同じ状態
- 動作環境はWordPressの最新版
- 内容は実運用データを入れたもので、そこそこ重くなっているものでテスト

## 疑問だったこと

- nginxの同時接続数とFastCGI(fpm)の間の関係
  - Apacheのmoduleの時は理論上の最大RAMが[Apacheの同時接続数]x[php.iniのmemory_limit]だったが...？

## 同時接続数との関係

nginxはfpmをupstreamとして扱う。 Railsとかのプロセスとほとんど考え方は一緒。
nginxで受けてまだfpmに空きがなければ、あくまで待つっぽい。多分キュー。

これによって上記でApacheだと〜って問題がなくなってるし、メモリリークがあっても500回とか処理したらプロセス捨てて別なプロセスに任せるみたいな強引なやり口で、メモリ問題が解決出来る。たいへん賢い。

## php.iniでのメモリ上限

```/etc/php7.d/php.ini
# 1プロセスあたりの上限を128Mとする
memory_limit = 128M
```

## fpmの同時処理数の設定

```/etc/php7-fpm.d/www.conf
# ワーカーあたりの最大同時処理数っぽい。kusanagiのデフォは50っぽい。
pm.max_children = 50
# プロセスを自動で立ち上げといてくれるらしい
pm.min_spare_servers
pm.max_spare_servers
# ↑の初期値。未指定でデフォにしてもよさげ
pm.start_servers
```

ここから、理論上PHPだけで128Mx50 = 6.25G使う可能性があることが分かる。
ただし、現実的にはそれを食い尽くす事はないだろうし、スワップで間に合う範囲でもあるから、妥当な数字に思える。

逆に言えば、1GBだと、OS自体やnginx自体などのフットプリント的なRAM容量を考慮して `max_children=10` にするのが安定しそう。

## 実際落ちてたのが直った

実際、apache bench alternativeなboomってコマンドで以下のような事をして虐めると、あっという間に悪名高い「データベース接続エラー」になってたけど、max_childrenを10にしたら起きなくなった。時間はかかるけど。

```sh
boom -a staging:staging -n 100 -c 50 http://staging.example.com/hoge-fuga-piyo/
```

## kusanagiはDB落ちると復活しないっぽい

monitの仕事がダメなので、DBサーバーが落ちると勝手には復帰しないみたい。
monitの監視時間の問題かも。

## 結論

- fpmのチューニングしたいときは /etc/php7-fpm.d/www.conf みたいなファイルの pm オプション群で指定できる
- KUSANAGIは推奨環境を守れば速い（たぶん）ので、ちゃんと守ろう
【Javascript基本文法用語】オブジェクトってなんだっけ編

## はじめに
JSの基本で使用する言葉の定義をまとめています。
目次は[こちら](https://qiita.com/nabe_kurage/items/373adae38c0b6073b304)


## オブジェクト
データ（変数）と処理（関数、メソッド）をひとまとめにしたもの。
データを限られた範囲でのみ使用可能にすることで、誤って参照、変更される危険性を抑えられる。

オブジェクトの機能は連想配列の仕組みを使って実現できる。連想配列のバリューには関数を含めたどのような型も入れられるため。

```js
//これがオブジェクト

var object = {
  variable : 0,
  method : function(){
    .........
  }
};

console.log(object.variable): //0を表示
object.method(); //無名関数を実行
```

## 予約語this
オブジェクト内部から内部の関数や変数を使用するには、 予約語thisを使う。
### thisを使わない場合

```js
var object = {
  num : 0,
  method : function(){
    console.log(object.num);
    //これでも参照できるが、オブジェクト名を変えたら全て変更しないといけない
  }
};

```
### thisを使う場合

```js
var object = {
  num : 0,
  method : function(){
    console.log(this.num);
    //これで、オブジェクト名が変更されても参照されるようになった
  }
};

```

## インスタンス変数
オブジェクトに入れられた変数のこと。
thisを使って参照すれば、オブジェクト内からのみ読み書きできるので、意図的に指定しようとしない限り指定オブジェクトの外から上書いてしまう心配が少ない。
AWS ECS で awsvpc を便利に使う

# AWS ECS で awsvpc を便利に使う

## 概要
昨年末、 AWS ECS で コンテナに対して vpc が使えるようになりました。
しかしながら、サービスをみつけるには DNS か LB を使うしかないことは変わらないです。
ECS でサービスが起動されたときに、自動的に Route53 に ローカルIPアドレス を登録してくれればいいのに。

## 対応
サービス起動時に、Route53 に ローカルIPアドレス を登録する仕掛けを用意しました。

docker events でイベントを監視して、awsvpc なコンテナ起動をトリガに ローカルIPアドレス を調べます。

```bash:/sbin/docker_monitor.sh
#!/bin/bash
cluster=$1
zoneid=$2

while :; do
docker events --filter "event=start" | while read event; do

name=`echo $event | sed -r "s:.*container-name=([^,]*).*:\\1:"`
if [ $name = '~internal~ecs~pause' ]; then

arn=`echo $event | sed -r "s:.*task-arn=([^,]*).*:\\1:"`
ipv4=`aws ecs describe-tasks --cluster $cluster --tasks $arn \
 --q tasks[0].containers[0].networkInterfaces[0].privateIpv4Address \
 --o text`

family=`echo $event | sed -r "s:.*task-definition-family=([^,]*).*:\\1:"`
zone=`aws route53 get-hosted-zone --id $zoneid --q HostedZone.Name --o text`
record=$family.$zone

aws route53 change-resource-record-sets --hosted-zone-id $zoneid --change-batch \
 "{\"Changes\":[{\"Action\":\"UPSERT\",\"ResourceRecordSet\":{\"Name\":\"$record\",\"Type\":\"A\",\"TTL\":60,\"ResourceRecords\":[{\"Value\":\"$ipv4\"}]}}]}"

echo $arn
echo $ipv4
echo $family
echo $record

fi


done >> /var/log/docker_monitor.log
sleep 1
done
```


ホストには、以下の権限が必要です。

```
ecs:DescribeTasks
route53:GetHostedZone
route53:ChangeResourceRecordSets
```

使い方としては、こんな感じの upstart を仕込んでおくといいです。

```bash:/etc/init/docker_monitor.conf
start on runlevel [2345]
stop on runlevel [!2345]
respawn
exec /sbin/docker_monitor.sh <クラスタ名> <ゾーンID>
```

これで、コンテナを起動すると Route53 に ローカルIPアドレス が自動的に登録されるようになります。
Python3で整数の最大値や小数の無限大を扱いたい

Python3で整数型の最大値は`sys.maxsize`として定義されています(URL: https://docs.python.jp/3/library/sys.html#sys.maxsize )。たとえばC言語風のforループがサポートされている言語で、以下のように書く処理があるとします。

```java
for (int i = 1; ; i++) {
    if (isOK(i)) {
        break;
    }
    do_someting(i);
}
```

これと同じ処理をPython3で実装する、かつ`for`と`range`を利用する場合は、以下のようになるはずです。

```python
import sys

for i in range(1, sys.maxsize):
    if is_ok(i):
        break
    do_something(i)
```

`sys.maxsize`を利用しない場合は次のような書き方になりますが、__iのインクリメント(`i += 1`)を忘れて大変な目にあいがち__なので、個人的には好きではありません(´・ω・｀)

```python
i = 1
while not is_ok(i):
    do_something(i)
    i += 1
```

***

わたしの思いつく限り、Python3でよく利用される数値型としては以下のものがあげられます。

- `float`
- `decimal.Decimal`
- `fractions.Fraction`

`float`と`Decimal`については「無限大」がサポートされています。「最大値」も取得できなくはないようですが、基本的には「無限大」で事足りるように思います。

```python
import decimal

float('inf')
float('infinity')
decimal.Decimal('inf')
decimal.Decimal('infinity')
```

`fraction.Fractions`は有理数を扱うクラスです。その性質から「最大値」や「無限大」という概念はサポート外になっているようです(´・ω・｀)
ブラウザ不要。更地のWindows PC上に開発環境を整えるまで（e.g. vscodeでVue.js）

私用のPCを何年かぶりに新調したので久々に開発環境をゼロから構築しました。もうダウンロードサイトの巡回なんてのは過去の話になったのだなあとしみじみ感心したので、その手順をメモしておきます。

# まずは最低限

Scoopでも良いですが自分はChocolatey派です

```powershell:Win+X，Aで管理者権限のPSを起動して以下を打鍵。
PS C:\WINDOWS\system32>  Import-PackageProvider ChocolateyGet
PS C:\WINDOWS\system32> Install-PackageProvider ChocolateyGet
PS C:\WINDOWS\system32> Install-Package visualstudiocode
PS C:\WINDOWS\system32> Install-Package git
PS C:\WINDOWS\system32> install-package nodejs -MaximumVersion 8.9.4
```

* `Win+X` というホットキーはWindows 7時代にはWindowsモビリティセンターというユーティリティの呼び出しでした。8以降に現在の便利な管理系メニュー呼び出しに変わりました。
* 注意！パッケージプロバイダは「**ChocolateyGet**」、です。Windows 標準搭載の「Chocolatey」パッケージプロバイダは何かの間違いなので使わないように。一度使ってしまったが最後、ゴミが以後のInstall-Packageで一々邪魔してきます。一応ゴミを掃除する手段も無くは無いので別途追記します。
* 昔は `-Version` でバージョンを直接指定出来てたのと思うのですが今はそのオプションは `-RequiredVersion` という名前になったようです。 `-MaximumVersion` だと、試してませんが「8.999.999」とかも指定できそうですね。

# 後は気が向くまま

* `Install-Package` で `googlechrome` とか `winmerge` とか `jdk8` とか `screenpresso` とかも入れられますので適宜どうぞ。vlcやffmpeg、steamなんかも有ります。
* ひとしきり気が済むまでインストールしたらプロジェクトを作ってみます。最近 Vue.js のお世話になってるので下記はその流れです。

vscodeに拡張機能インストール。先にやらなくても後段の操作中にcodeがリコメンドしてくるのでそこでインストールしても良い。

```powershell
code --install-extension dbaeumer.vscode-eslint
code --install-extension octref.vetur
```

プロジェクト作成

```powershell:codeを起動してターミナルタブを開いて
PS %USERPROFILE%> mkdir vueapp
PS %USERPROFILE%> cd vueapp
PS %USERPROFILE%\vueapp> npm install -g @vue/cli
PS %USERPROFILE%\vueapp> npm install -g @vue/cli-init
PS %USERPROFILE%\vueapp> vue init webpack my-project
```

出来たmy-projectフォルダをvscodeで開いてESLintの準備

```js:.vscode/settings.json
// Ctrl+, でワークスペースの設定ファイルを開いて下記を追記。ESLint に *.vue ファイルも自動修正させる。
// eslint~ というキー名がエラー(赤下線)になったら、ESLint拡張機能が無効になっている。拡張機能サイドバーで有効化できる。
    "eslint.autoFixOnSave": true,
    "eslint.validate": [
        "javascript",
        {"autoFix": true, "language": "vue"}
    ]
```

```js:.eslintrc.js
  extends: [
    'plugin:vue/recommended', // essentialは緩すぎるのでrecommendedに変更
```

テスト実行、起動してみて、下準備が整った事を見届けたらgitのローカルリポジトリを作って初回コミット。

```powershell
PS %USERPROFILE%\vueapp\my-project> npm run unit
PS %USERPROFILE%\vueapp\my-project> npm run dev
PS %USERPROFILE%\vueapp\my-project> Invoke-WebRequest -Uri https://raw.githubusercontent.com/github/gitignore/master/Node.gitignore -OutFile .gitignore
PS %USERPROFILE%\vueapp\my-project> git config --global user.email "you@example.com"
PS %USERPROFILE%\vueapp\my-project> git config --global user.name  "your name"
PS %USERPROFILE%\vueapp\my-project> git init
PS %USERPROFILE%\vueapp\my-project> git add -A
PS %USERPROFILE%\vueapp\my-project> git commit -a -m "init"
```

何かをインストールするのにブラウザを開かなくて良い というお手軽さのおかげで、ものの数行で何もかも揃ったような気がしましたが、こうして書き出してみるとそこそこ打鍵してますね。

# ところで果たして本当にブラウザは不要だったのか

え、ええ。大体は。問題はパッケージ名ですね。vscodeを入れるべく `Install-Package vscode` と打ち込むと、お目当てとは違う何かが入ってしまったりします。パッケージ名を調べるのは結局Webで……。
ホワイトボード的なwebアプリ作ってみた

ホワイトボード的なwebアプリを作り、グーグルの無料サーバーで運用しているので、よかったら使ってください
（ただし保存はローカルです）
** **

**目的**
・考え事を整理するために、ホワイトボードみたいに「テキストを打ち込めて適当な絵をかける」アプリを作る
・2年ぶりにit業界に復帰するので勘を取り戻す

**使った技術**
・HTML canvas
・javascript（jquery）

**できあがったもの**
<img width="500" alt="スクリーンショット 2018-03-04 23.06.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/241937/059fa990-7e33-fb43-5050-0ae8510c8ef9.png">
https://fusen-196404.appspot.com/

**できること**
・テキストと絵を同じ画面に書き込むこと
・ローカルに保存

**できないこと（やらなかったこと）**
・サーバーのDBに保存
　　　→お金がかかる
・お絵かきチャットのような共有モード
　　　→CANVASの筆（getcontext 2d）は、一つのCANVASに対して一本しか使えないので、同時にお絵かきできないので断念（片方に反映するだけならできる）。

**やろうと思えばできること（今はやらない）**
・ローカルに複数のメモを保存できるようにする
・サーバーのDBに保存
　　　→node jsをサーバーとして使っているので後付けで保存機能は足せる

よかったらどうぞ
Web初心者がfirebaseでPWA入門してみる(ユーザ登録編)

# はじめに
前回の記事から随分経ってしまいましたが、今回はユーザ登録を実装してみます。

ログイン機能は前回実装した、Google Authorization機能を用いますが、一般に公開されるユーザ名を追加で設定できるようにします！

この記事の内容で、FirebaseDB(と呼びます)への書き込みが理解できました。

成果物はこちらになります。
https://github.com/tamalign/CheekyCat/tree/day3

# 設計と実装
どのようにユーザ管理をするかを考えます。
(あまりWebに詳しくないので間違っていることがあるかもしれませんがご容赦ください。)

今回はユーザの一意のIDをKeyとして、必要な情報をValueに保存するテーブルで管理を行いたいと思います。

FirebaseDBでは以下のようにしてuidを取得できます。[参考ページ](https://firebase.google.com/docs/auth/web/manage-users?hl=ja)

```javascript

var auth = firebase.auth().currentUser;
var uid = auth.uid;
```

ほかにも `User.getToken()`というメソッドでもトークンを取得できるようです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/79662/774ef358-f43d-44f8-6b09-9b4de92aaee1.png)

データを上記のように"users/$uid/"という形で保存しました。

javascriptから登録するコードは以下になります。

```javascript
function OnRegister()
{
  var nameField = document.getElementById('UserName');
  var database = firebase.database();
  var db = database.ref("users");
  var auth = firebase.auth().currentUser;
  var ref = db.child(auth.uid);
  ref.set(
    {
      name: nameField.value
    },function(error)
    {
      if(error)
      {
        console.log(error);
      }else
      {
        window.location.reload(true);
      }
    }
  );
}
```

簡単に書けますね:boy:

また、setするオブジェクトですが、次のようにも書けるみたいです。

```javascript

function Test()
{
  var object = {name: "hogehoge", number: "fugafuga", id: "piyopiyo"};
  var ref = firebase.database().ref("users/"+firebase.auth().currentUser.uid);
  ref.set(object);
}
```

これだけでDBの値が更新できるので、便利だと思う反面、ちょっと怖いですね。

さて、ほかのユーザにもuidがバレてしまうとそれ以下のデータを編集されてしまう危険があるので、データベースルールを編集します。

```database.rule.json
{
  "rules": {
    "users": {
      "$uid": {
        ".read": "$uid === auth.uid",
        ".write": "$uid === auth.uid"
      }
    },
    "cat_message":{
      ".read": true,
      ".write": false
    }
  }
}

```

`users`以下はuidが等しい(自分の)場合のみ読み書き可能、猫のセリフが入っている`cat_message`以下は読めるが書き込み不可というように修正しました。


# 初心者がcssでハマった件
firebase + chromeという環境で開発しているわけですが、新たにcssを記述したときにchromeで検証してみると、 `user agent stylesheet`でスタイルが上書きされている(本当は反映されていない)問題がありました。

**結論から言うと**、*cssがキャッシュされていて新たに追加したスタイルが反映されていませんでした。*

エンジニアなのでデベロッパーコンソールから得られる情報でひたすらググったのですが、有益な情報がなく、新規cssファイルを作成したところ反映されて気づいた次第です。。

次のようにしてキャッシュ回避をしました。

```html
<script>
    var rnd = Math.random().toString(36).slice(-8);
    document.write('<link rel="stylesheet" type="text/css" href="/main.css?'+rnd+'>""');
</script>
```

インラインでjavascriptコードを実行し、ランダムな文字列を生成してcssファイルの末尾に追加しました。

[参考: Javascriptでランダムな文字列を生成する方法](https://qiita.com/ryounagaoka/items/4736c225bdd86a74d59c)

# まとめ
今回はやりたかったこと以外のところ(cssのキャッシュ)で時間が取られてしまったので、あまり内容が書けませんでした・・・。
次回は、なまいきなねこに言葉を教えてみたいと思います(やっと)。
RDataのデータフレームをPythonで読み込む

Rで分析したデータを、Pythonから分析したい (パッケージがPythonにしかない、Pythonのコード資産を活用したい、など) 場合のメモ。

## 自分のケース
Rの{caret}で機械学習にかけたデータを、Tensorflow/kerasを使ったニューラルネットワークにかけたい。
RでもTensorflow/kerasは使えるが、Pythonに比べると使いづらい。
分析用のデータは一旦csvに吐き出した後、R内でデータ型など加工しており、RDataに保存している。
RDataは2種類あり、説明変数のデータと、複数の目的変数が格納されているデータ。
目的変数の番号を指定して、説明変数＋欲しい目的変数を取得したい。

## 使うもの
- データを保存しているRData
- pyper

## 自分が書いたコード

```py
def readR(i):
	r = pyper.R(use_numpy='True', use_pandas='True')
	r("load('data/train.RData')")
	r("train <- as.data.frame(train[,-1])") # 1列目はIDなので除外
	r.assign(obj="i", val=i)
	r("load('data/score.RData')")
	r("target <- score[,i+1]") # 1列目はIDなので除外
	r("name <- colnames(score[,-1])")
	r("name <- gsub(':', '', name)")
	r("name <- name[i]")

	# pyperからpandasへ引き渡し
	train = pd.DataFrame(r.get('train'))
	score = pd.DataFrame(r.get('target'))
	name = str(i).zfill(2) + "_" + r.get('name')

	return train, score, name
```

trainが説明変数のデータ、scoreが目的変数のデータ (今考えると名前が変だ)。
3つめの返り値のnameは、目的変数の名前がカラムに書いてあるので、それを使っている。
nameを取得するのは、出力ファイルのディレクトリ名にするため。
汎用性を考えると、

## 簡単な説明
Pythonのpyperパッケージを使う。
Rのdata.frame型を引き取る際に、pandasのpd.DataFrameとして受け取るので、インスタンス作成時のオプションの`use_pandas='True'`は必須。
`use_numpy='True'`はしなくても動くかもしれないが、別にしないメリットもあまりないので。
pyperの中は基本的にRのコマンドを書いていき、最後にr.get()でRのオブジェクトをPythonに引き渡すだけ。特に難しいことはないはず。

## やってみた感想
思ったよりもメモリを食う。r.get()でRからPythonにオブジェクトを引き渡す時に、恐らくオブジェクトをまるごとコピーするのだが、そのせいでRで読んでた時の2倍＋αのメモリを食う (+αどころか、元の3倍くらい食ってる気が……)。
巨大なデータのやり取りにpyperを使うのは避けた方が良さそう。

あと、scoreの方のデータフレームは、1列ずつ読み込んだが、全部一気に読み込もうとするとエラーで上手く行かなかった。
理由はよくわからないが、今思うとメモリが溢れていたのかもしれない……
単一責任の原則(SRP: Single Responsibility Principle)

## クラスを変更する理由は複数存在してはならない
- クラスの役割が複数あればクラスを変更する理由も複数になる
- クラスが複数の役割を背負うと、ある役割が変更を受けるとそのクラスが担っている他の役割にも影響を受け、不具合が生じる可能性がある
 - このようになってしまうと予想もしない形で壊れる脆い設計となる

## 役割とは？
- SRPでは「役割(責任)=変更理由」と定義している

## 永続性のあるシステムと単一責任の原則(SRP)
- 例えば頻繁に変化するビジネスルールとあまり変化しない永続性のあるシステムを混ぜてはいけない
  - 頻繁に変化するものとあまり変化しないものを結合することは自らトラブルを生んでいるようなものである
  - このような場合は役割を二つに分離する

## まとめ
- 単一責任の原則(SRP)は最もシンプルな原則の一つであるが、正しく適用するのが最も難しい原則の一つでもある
- 結合している役割を見つけそれらを分離する作業はソフトウェア設計の本質である

## 考察
- 1つのクラスに複数の役割を持たせない
- 複数の役割が同時に変更されるようなケースでは分離する必要はない
【SQL】テーブル作成/更新/削除

DBMS = Postgreを使用。

#テーブルの作成
テーブルを新規作成する際は、以下コマンドを実行する。

※デフォルト値を設定すると、Nullではなく指定した値を格納してくれる。
また、デフォルト値には指定したデータ型と合わせる必要がある。
例：integerの場合は、数値を指定。

```sql
create table テーブル名 (
カラム名 データ型,
カラム名 データ型,
カラム名 データ型 default 'デフォルト値',
カラム名 データ型 default デフォルト値
);
```
<img width="479" alt="スクリーンショット 2018-03-04 21.12.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/174494/1d0afe88-1b51-b91d-0dca-ba4d46a3dbfa.png">


#テーブルの更新

列を追加する際は、以下コマンドを実行する。

```sql
alter table テーブル名 add カラム名 データ型;
```

<img width="485" alt="スクリーンショット 2018-03-04 23.10.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/174494/072c61f1-1e8c-082f-a43c-8a546fc50fc9.png">

列を削除する際は、以下コマンドを実行する。

```sql
alter table テーブル名 drop カラム名;
```
<img width="362" alt="スクリーンショット 2018-03-04 23.14.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/174494/481cb238-9140-3de1-3adb-10fbffd82b13.png">

#テーブルの削除
テーブルを削除する際は、以下コマンドを実行する。

```sql
drop table テーブル名;
```

<img width="458" alt="スクリーンショット 2018-03-04 23.17.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/174494/f94ef124-d631-f4c2-28bc-1db83a071cf0.png">



以上！
Promiseとasync functionの書き換え

async修飾子をfunctionにつけるとPromiseを返す関数になる。

async修飾子の付いたfunctionで値をreturnするとpromiseでresolveしたときと同じ。
以下のコードのsuc1,2,3は同じ動作をする関数になる。

```js
function suc1() {
  return new Promise((resolve) => {
    resolve('suc1');
  })
}

function suc2() {
  return Promise.resolve('suc2');
}

async function suc3() {
  return 'suc3';
}

async function suc() {
  console.log(await suc1());
  console.log(await suc2());
  console.log(await suc3());
}

// suc()の実行結果
// suc1
// suc2
// suc3
```

async修飾子の付いたfunctionで例外を投げるとrejectしたときと同じ動作をする。

```js

function err1() {
  return new Promise((resolve, reject) => {
    reject('err1');
  })
}

function err2() {
  return Promise.reject('err2');
}

async function err3() {
  throw 'err3';
}

async function err() {
  try {await err1()} catch(e) {console.log(e)}
  try {await err2()} catch(e) {console.log(e)}
  try {await err3()} catch(e) {console.log(e)}
}

// err()の実行結果
// err1
// err2
// err3
```
Oracle APEX5で使われているCSS

#ここでは
Oracle APEX5はCSSを多用しているため、カスタマイズする場合、CSSの変更が必要な場合がある。
ここでは私の古い知識にないCSSを読み解くため、参考にしたサイトと簡単な説明を記載する。

#before&after
before,after疑似要素はCSS2.1でサポートされ、IE8でもサポートされる。
CSSはスタイルを指定するものと認識していたが、要素も追加できたのか。

http://coliss.com/articles/build-websites/operation/css/css-tutorial-pseudo-element-before-after-by-hongkiat.html
例えば、下の::before== $0の上の<span>から下の</span>まではCSSのbeforeで追加されたものである。
![before1.PNG](https://qiita-image-store.s3.amazonaws.com/0/241305/1e757069-27f0-869b-a96c-0d4eea8ef5f2.png)

#随時更新予定
　2018/3/2 作成。
後からブートローダーを設定しデュアルブート環境にしたい

デュアルブート環境を作りたくてUbuntu、Windows10の順にインストールしてみたが
オーケー、ブートローダーが無い。BIOSの起動設定画面からじゃないと起動OSが選択出来ない。
やっちまったなこりゃあ。
だもんでこっからデュアルブート出来るようにしたい。
# Ubuntuでの操作
Windowsのブートローダーが入ったHDDディレクトリを探す。
`sudo fdisk -l`
起動に「*」がついててタイプがNTFSのやつを探す
`デバイス   起動   Start 最後から セクタ  Size Id タイプ
/dev/sda1  *       2048   1126399   1124352  549M  7 HPFS/NTFS/exFAT`
あった、こいつだ。
次にブートローダーのUUIDを確認 
`sudo blkid /dev/sda`
を実行。
`/dev/sda: PTUUID="1234abcd" PTTYPE="dos"`
みたいな感じに出てくる。
`sudo vi /etc/grub.d/40_custom`
で下記のようにgrubのブートローダー一覧にWindows 10を追加する。
`menuentry “Microsoft Windows 10” {
  search –fs-uuid –no-floppy –set=root (さっきのUUID)
  chainloader (${root})/efi/Microsoft/Boot/bootmgfw.efi
}`

`sudo update-grub`
でgrubの設定を更新。
# BIOSで起動優先順位を設定
これは…ちょっとマシンによって異なるんで
ここではDellのマシンのやり方を記載

1. マシン起動時にF2キーを押し、セットアップを起動
2. Boot>LEGACY BOOTを選択
3. grubがインストールされたドライブを選択し、F5キーで優先順位を上げる
4. F10でSave and Exit

以上、目出度くgrubが優先的に起動され、Windows 10、Ubuntuの選択が可能になりました。
…なんか余計なのたくさんあるけどまた明日設定しよう…
Kotlinでジェネリクス、基本から応用-クラス定義からメソッド、多重実装まで-

# はじめに
Kotlinでアプリを作ろう！と思い開始したのですが、Utilやhelperを作るためにジェネリクスと戯れていたら一日が終わっていました。
まだあまりKotlinのジェネリクスの記事が無いようなので、調べたり試したりした内容を記そうと思います。
適当な感じでjavaとの例で比較します。
こういうのもあるよ！というのがあれば教えていただければと思います。

# 基本
## クラス・メソッドのジェネリクス
javaと変わらない

```java:java
public abstract class Sample<T> {
    abstract T create();
    
    abstract void parameter(List<T> list, T t);
}
```
```kotlin:kotlin
abstract class Sample<T> {
    abstract fun create(): T

    abstract fun parameter(list: List<T>, t: T)
}
```

## staticメソッド
companion objectのメソッドの中でジェネリクスを使う

```java:java
class Smaple{
    public static <T> void sampleMethod(List<T> tList) {
    }
}
```
```kotlin:kotlin
class Sample {
    companion object {
        fun <T> sampleMethod(tList: List<T>) {
        }
    }
}
```

##継承や実装制約を付ける場合

継承と同じように、「:」を利用する。
クラスとstaticメソッド両方一緒に記載。

```java:java
public class Sample<T extends View> {
    public static <L extends View.OnClickListener> void setListener(L l){
    } 
}

```
```kotlin:kotlin
class Sample<T : View> {
    companion object {
        fun <L : View.OnClickListener> setListener(l: L) {
        }
    }
}
```

# 応用
## 多重実装
where句を利用する

```java:java
public class Sample<T extends View & View.OnClickListener> {
    public static <L extends View & View.OnClickListener> void setListener(L l) {
    }
}
```
```kotlin:kotlin
class Sample<T> where T : View, T : View.OnClickListener {
    companion object {
        fun <L> setListener(l: L) where L : View, L : View.OnClickListener {
        }
    }
}
```

ちなみに、下のようにも書けるが、警告が出る

```kotlin:kotlin
class Sample<T : View> where T : View.OnClickListener {
    companion object {
        fun <L : View> setListener(l: L) where L : View.OnClickListener {
        }
    }
}
```
> if a type parameter has multiple constraints, they all need to be replaced in the 'where' clause.
型パラメータに複数の制約がある場合、それらはすべて 'where'句で置き換える必要があります。

## 一つの場合でもwhere句は利用可能
[継承や実装制約を付ける場合](#継承や実装制約を付ける場合)での例をwhereで書く。

```kotlin:kotlin
class Sample<T> where T: View {
    companion object {
        fun <L> setListener(l: L) where L : View.OnClickListener {
        }
    }
}
```
一つの場合は「:」の方が分かりやすそうだが、クラスやインターフェース名が長い場合はいいのかも。
Rubyでヒアドキュメントを使う


## 1.ヒアドキュメントとは
* ヒアドキュメント（別の呼び方としてヒア文字列、heredocなど）は、文字列リテラルを、シェルスクリプトやプログラミング言語の中に埋め込むための1つの方法である。ー　[ja.wikipedia.org](https://ja.wikipedia.org/wiki/%E3%83%92%E3%82%A2%E3%83%89%E3%82%AD%E3%83%A5%E3%83%A1%E3%83%B3%E3%83%88)
* 簡単に説明すると、長い文字列（SQLクエリ、JSONデータ）を作成するときインデントをつけて見やすく綺麗に書き方です　ーこれはただ自分の考えです。

## 2.ヒアドキュメント種類
###2.1 ``` <<EOS と <<-EOS ```

```ruby:eos.rb
name = "２行目"

str1 = <<EOS
  ダブルクォート文字列です。
  #{name}
EOS

str2 = <<-EOS
  ダブルクォート文字列です。
  #{name}
EOS

puts str1
puts str2
```

結果
<img width="459" alt="Screen Shot 2018-03-04 at 22.13.17.png" src="https://qiita-image-store.s3.amazonaws.com/0/201748/654906b5-d60c-3915-07aa-41adaecc4b34.png">
両方はダブルクォート文字列を返すので変数を渡せばちゃんと表示できます。

### 2.2　``` <<~EOS ```
```ruby:eos.rb
puts <<-EOS
  インデントあり。
EOS

puts <<~EOS
  インデントなし。
EOS
```
結果
<img width="455" alt="Screen Shot 2018-03-04 at 22.18.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/201748/ae9067de-6143-22e7-309d-7f93163534a6.png">
``` <<-EOS ```と同じいダブルクォート文字列を返しますが、インデントは使えないです。
### 2.2　``` <<~'EOS' ```
```ruby:eos.rb
name = "EOS"
puts <<'EOS'
  シングルクォート#{name}
EOS
```
結果
<img width="462" alt="Screen Shot 2018-03-04 at 22.24.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/201748/5c784be9-8096-cac3-4446-48efc968bc93.png">
 シングルクォートを返すので変数を渡しても文字列として表示されます。

### 2.2　```<<`EOS````
```ruby:eos.rb
system_command = <<`EOS`
  echo "current date is"
  date
EOS

puts system_command
```
結果
<img width="455" alt="Screen Shot 2018-03-04 at 22.26.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/201748/9e9b4c49-018b-1792-f88e-fa2df8cdf774.png">
OS（システム）のコマンドを実行できます。
2.5 ネストヒアドキュメント

```ruby:eos.rb
puts <<-'EOS1', <<-EOS2
  i am EOS1
EOS1
  i am EOS2
EOS2
```
結果
<img width="446" alt="Screen Shot 2018-03-04 at 22.30.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/201748/ae183100-960c-57fd-3f5c-0503232cb1ea.png">

## 3.おまけ
ヒアドキュメントは色々な種類があるので適当に使えばソースコードは見やすくなってると思います。
HTKを使って1つのwavファイルから時間分割して音響特徴量作成

## The Hidden Markov Model Toolkit (HTK)
一応軽くいっておきますとHTKとはThe Hidden Markov Model Toolkitの略で音声認識に用いられるGMM-HMMの音響モデル作成キットです。

HTKは非常に多機能なのですが、現状DNN-HMM音響モデルが出てきているためもっぱら音響特徴量作成、つまりは`HCopy`が主な使用コマンドとなります。

## 本題
さて`HCopy`を使う際に1つのwavファイルから音響特徴量作成(Log mel-scale filter bankやMFCCなど)を行うわけですがそのままでやると一つのファイルに書き出されてしまうことになります。

読み取った後に分割しても良いですが今回はファイルを分けてみましょう。

例えばサンプリング周波数が16000Hzの2秒の`sample.wav`があったとしましょう。これを1秒ごとの`sample_0-1.htk`と`sample_1-2.htk`にするとします。
結論からいきましょう。
以下の設定ファイルを用意してください。
```
sample.wav[0,16000] sample_0-1.htk
sample.wav[16000,32000] sample_1-2.htk
```

そしてこれを`sample.scp`とすると

`HCopy *** -S sample.scp`

という感じにすると良いわけですね。
`***`はその他の設定となります。

## 解説
もうお察しと思いますが`wavファイル[始まり,終わり] 保存先`を使うことで読み込む秒数を決めるわけですね。
ただし単位は秒ではなくサンプリング周波数基準なので気をつけてください。

多分HTK Bookには載ってます...があんなページ数あるものを読むなんてなかなか骨が折れます...