OmniAICreator/Qiita-1.07M huggingface dataset:
JWT について調べた内容をまとめました。

# 概要
WEB アプリケーションの認証に JWT 利用を検討してるなかで、JWT について調査した内容をまとめます。

## JWT とは
JWT（ジョット）とは JSON Web Token の略で、電子署名付きの URL-safe（URLとして利用出来る文字だけ構成される）な JSONのことです。
電子署名により、**JSON** **の改ざんをチェックできる**ようになっています。

ざっくり言うと、改ざんできない JSON ということになります。

## 利用ケース
1. クライアントは、認証情報 (ログインID + パスワード) を送信する。
2. サーバは、認証情報を確認して ```user_id``` と ```exp``` (有効期限) を含む JSONを 秘密鍵で暗号化して JWT として返却する。
3. 以降クライアントは、認証済みリクエストとして JWT を利用して通信をおこなう。

クライアントからの送信される JWT はサーバで秘密鍵を利用して改ざん検証をおこなうため
```user_id``` や ```exp``` の改ざんを検知することができます。

## JWT の中身
JWT の文字列ははピリオド区切りで３つの役割にそれぞれ分かれています。

```
{Base64エンコードされたヘッダ}.{Base64エンコードされた JSON の中身}.{電子署名}
```

### ヘッダ情報（１つ目）
ヘッダ情報には、署名アルゴリズムの種類やメタ情報が記載されています。

|予約済項目名|役割|
|---|---|
|alg|署名アルゴリズム。```HS256``` など|
|typ|トークのタイプ。```JWT``` 指定が推奨|

※ なお、必須項目は ```alg``` のみとなっています。

ヘッダの中身が次の例の場合、```"typ": "JWT"``` これは JWT であり、```alg": "HS256``` HMAC SHA-256アルゴリズムを使ってMACが付与されていることを表しています。

```json

{
  "typ": "JWT",
  "alg": "HS256"
}
```

```alg``` に ```none``` や  ```HMAC-SHA*``` を指定して署名検証を回避する脆弱性があるため
ホワイトリスト形式で ```alg``` を検索する必要があります。

### クレーム情報（２つ目）
JSON 本体で、Base64デコードするだけで 通常の JSON と同様に内容を確認できます。

|予約項目名|役割|
|---|---|
|exp|期限切れ日時|
|ndf|期間開始日時|
|iat|JWT発行日時|
|iss|発行者(サーバ側)の識別子|
|aud|利用する側（クライアント側）の識別子|

### 電子署名（３つ目）
３つ目の署名情報については検証にしか利用されないため、特に意識する必要はありません。

## 注意点
### ヘッダ情報の脆弱性
ヘッダ情報の説明でも触れましたが、```alg``` の脆弱性が存在するため、必ず中身のチェックをしましょう。
### 重要な情報は設定しない
JWT の中身は Base64 エンコードされただけなので中身が簡単に確認できるので、クライアント側に見えてはいけない内容は回避しましょう。
### 一度発行した JWT の無効化は難しい
一度認可した JWT を無効化扱いすることはできません。
有効期限を短くしたり、即時無効化する必要がある場合は別途仕組みを用意するなどで対策しましょう。
Java8のお勉強(Collector/Collectors)

ということでCollector/Collectorsです。
Streamの結果を加工しつつ取り出したい場合なんかに使うみたいです。以下サンプル。

```
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * Collectorsのお勉強
 * @author komikcomik
 *
 */
public class CollectorsHello {

	public static void main(String[] args) {

		// 文字列のストリームを結合してStringにしている、その際に区切り文字と先頭文字、末尾文字を付与している
		Stream<String> s = Stream.of("1", "2", "3", "4", "5", "6", "7");
		String ss = s.collect(Collectors.joining("-", "先頭", "末尾"));
		System.out.println(ss);

	}
}
```

実行結果は以下の通り。
```
先頭1-2-3-4-5-6-7末尾
```
時間表示（strftime）


## 使い方

```
strftime(フォーマット)
```


```
time = Time.now # Thu Dec 24 00:00:00 +0900 2011
time.strftime('%Y年%m月%d日 %H:%M:%S') # 2011年12月24日 00:00:00
```


```
%A	曜日の名称(Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday)
%a	曜日の省略名(Sun, Mon, Tue, Wed, Thu, Fri, Sat)
%B	月の名称(January, February, March, April, May, June, July, August, September, October, November, December)
%b	月の省略名(Jan, Feb, Mar, Aprm May, Jun, Jul, Aug, Sep, Oct, Nov, Dec)
%c	日付と時刻
%d	日(01-31)
%H	24時間制の時(00-23)
%I	12時間制の時(01-12)
%j	年中の通算日(001-366)
%M	分(00-59)
%m	月を表す数字(01-12)
%p	午前または午後(AM,PM)
%S	秒(00-60) (60はうるう秒)
%U	週を表す数。最初の日曜日が第1週の始まり(00-53)
%W	週を表す数。最初の月曜日が第1週の始まり(00-53)
%w	曜日を表す数。日曜日が0(0-6)
%X	時刻
%x	日付
%Y	西暦を表す数
%y	西暦の下2桁(00-99)
%Z	タイムゾーン
%%	パーセント文字
```

## 補足

・Ruby の strftime で月日や時刻の 0 埋めを行わない書式指定

```
Time.now.strftime('%Y/%-m/%-d %-H:%-M:%-S') #=> 2012/8/14 9:4:10
```

・リファレンス　→　https://docs.ruby-lang.org/ja/1.9.3/method/Time/i/strftime.html
Java8のお勉強(Stream)

今回はStreamです。
早速サンプル。

```
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * Streamのお勉強。Intのストリーム。
 * @author komikcomik
 *
 */
public class StreamSample {
	public static void main(String[] args) {

		// ストリームを作って、中で一連の処理をやってもらうみたいな感じ
		IntStream is = IntStream.of(1000, 123, 456, 1001, 10000, 919, 561, 2000);
		// 1000以上のデータを抽出して、ソートする、その後標準出力
		is.filter(i -> i >= 1000).sorted().forEach(i -> System.out.println(i));

		// 1文字でないデータを除去→ソート→標準出力
		Stream<String> strStream = Stream.of("A", "b", "C", "d", "AAA", "BBB", "E");
		strStream.filter(s -> s.length() == 1).sorted().forEach(s -> System.out.println(s));
	}
}
```

実行結果

```
1000
1001
2000
10000
A
C
E
b
d
```

イメージは涌きやすかったですがこれをガンガン現場で使えるかって言ったら結構悩みそうですね。
JavaScriptじゃんけん

じゃんけんぷろぐらむをかいてみました。

```html:janken.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <title>じゃんけん</title>
</head>
<body>
    <div id="message1" >
        <h3>CPUの手: なにかな〜</h3>
    </div>
    <div id="message2" >
        <h3>結果: セレクトボックスから選択して決定ボタンを押してください。</h3>
    </div>
    <form>
        <select id="janken">
            <option>ぐー</option>
            <option>ちょき</option>
            <option>ぱー</option>
        </select>
        <input type="button" value="これでしょうぶ" onclick="myGame()">
    </form>
    <script>
    function myGame() {
        // 自分が選択したじゃんけんの手
        var myte = document.getElementById("janken").selectedIndex;
        // CPUのじゃんけんの手の番号
        var cpunum = Math.floor(Math.random()*3);
        // CPUのじゃんけんの手
        var cpuhand;
        // 判定
        var judge;

        if(cpunum == 0) {
            cpuhand = "ぐー";
        } else if(cpunum == 1) {
            cpuhand = "ちょき";
        } else if(cpunum == 2) {
            cpuhand = "ぱー";
        }

        if(myte == 0 && cpunum == 1) {
            judge = "あなたの勝ち";
        } else if(myte == 1 && cpunum == 2) {
            judge = "あなたの勝ち";
        } else if(myte == 2 && cpunum == 0) {
            judge = "あなたの勝ち";
        } else if(myte == cpunum) {
            judge = "ひきわけ";
        } else {
            judge = "あなたの負け";
        }

        document.getElementById("message1").innerHTML = "<h3>CPUの手: " + cpuhand + "</h3>";
        document.getElementById("message2").innerHTML = "<h3>結果: " + judge + "</h3>";
    }
    </script>
</body>
</html>

```
スプリントプランニングうまくやってる？

# スプリントプランニング(Sprint Planning)とは
スプリントプランニングとは、選択されたプロダクトバックログアイテムをこれから実行するスプリント内で実現するために、やるべきことをタスクに分解し、そのタスクを見える化するスクラムのセレモニーの１つです。スクラム全要素については[こちら](https://note.com/koki_jp/n/n6b72aa876e9f)。

プロダクトオーナー、開発チーム、スクラムマスターが基本的に参加しますが、プロダクトオーナーは、最初の30分ほどでも良いかも知れません。これから実行するスプリントで実現するプロダクトバックログアイテムをチームがサインアップしたものが何かを把握し、開発チームと合意するところまで。スクラムガイドでは、スプリントプランニング１と２と区別していますが、区別しないやり方もあるようです。

+ スプリントプランニング1 : 優先順位が高いプロダクトバックログアイテムをチームが選択する。選択したものをスプリントで実装することをプロダクトオーナー、開発チームで合意する。
+ スプリントプランニング2 : 選択されたプロダクトバックログアイテムを、開発チームがタスクに分解し、見える化する(=透明性を高める)。

スプリントプランニングの成果として、スプリントバックログが出来ることが必要です。

# プランニングの基本的な流れ
スプリントプランニング1

+ POとプロダクトバックログアイテムの選択

スプリントプランニング2

+ 開発チームの使える時間・カレンダーの確認
+ タスク分割
+ スプリントバックログ作成
+ POと最終合意

# 目安の時間
スプリントプランニング1は、30分程度、
スプリントプランニング2は、1週間スプリントだと、およそ2～8時間、2週間スプリントだと4～16時間かかると言われていますが、どれだけ時間がかかってもそのスプリントの計画をきっちり建てることが大切です。ここにタイムボックスはありません。

# 心構え
+ タスクは、30分～1時間、最大でも5時間程度(1日以内でやりきれる時間)の粒度まで分解し、計画をします。（よく、このタスクの時間をプランニングポーカーしているチームを見かけますが、見積もり時間はプランニングポーカーするレベルのものではないです。もっと厳密に見積もります。プランニングポーカーをするのは、もっと粒度が洗いもの、プロダクトバックログアイテムのポイント決めで使うことがあります）
+ 受け入れ基準の再確認をします。また、設計行為をしてしまいます。コードのどの部分をどう直す、まで決めるイメージです。クラス図やシーケンス図をホワイトボードに書きながら、アーキテクチャを見える化し、そのままそこにタスクの付箋を貼っているチームもありました。まさにプランニング！
+ 開発チームがこのスプリントで使える時間を計算し、全タスクがその時間内に収まっているかを把握します。もし溢れてしまった場合は、プロダクトオーナーと共有し、入りきらないリスクがあることを伝えます。それでもやってみるのか、プロダクトバックログアイテムをいくつか落とすのかを相談します。
+ DONEの定義を確認しながら進みます。
+ 一つのプランでうまくいかないリスクがある場合は、開発チームは複数プランを建てます。


# 効果的・効率的にやるには

これまでスクラムマスター・アジャイルコーチを数年やってきて、色々なチームを見させてもらっていますが、どこのチームも最初はプランニングが辛いと言っていました。辛くないチームは、結構属人化が進んでしまっている傾向があります。チームのあるメンバーしかそのタスクが取れない、という場合には、そのメンバーがタスク分解したら共有して終わりって感じなので辛くはないんです。時間も短く済みます。ただ、それが本当のチームなのかというと、そうではないですよね。

チーム全員で共有しながら、理想的には誰でもそのタスクが取れる状態になり、且つスプリントプランニングを効果的・効率的にやる方法はあります。

一言で言うと、全員の脳を常により動かしておく状態にすることです。
どうすれば、全員の脳を常に動かしておけるのでしょうか。

+ スプリントプランニングをワークショップ形式にする
+ デジタルツールを使わない
+ 常に対話が生まれる状態にする

などがありますが、実は他にもたくさんのアイディアや原則があります。
困ったらスクラムマスターに相談しましょう！

開発チームによって特有のやり方、事情があるでしょうから、一概にこの方法がベストプラクティスだとは言い切れません。
個別にご相談にも載れますので、[ご連絡](mailto:u2daijibrother@gmail.com)いただければと思います（笑
Amazon EC2にAnsibleのコマンド一発でWordPress環境を作った話

## 目的

最近AWSとAnsibleが楽しくなってきたので勉強がてらメモを残します。

インストールが簡単と噂のWordPressを更に簡単にAnsibleを使ってコマンド一発でやってしまおうということが狙いです。

## Ansibleとは？

サーバの構成管理ツールです。

大きな特徴は構成管理対象とするクライアント側にエージェントが不要というところで、sshさえ繋がれば初期状態からクライアント側の環境構築ができます。


Ansible自体の使い方についてはこちらの記事を参考にさせていただきました。

* [超ansible入門　/ ansible for beginer](https://qiita.com/Seisan0044/items/e8e9815a02d611b2e5b0)
* [Ansible 入門](https://qiita.com/ArimaRyunosuke/items/1f9d840311584d8160bc)


## Amazon EC2の構成

構成はシンプルにEC2だけを使用しています。MySQLも同EC2内に環境を構築しています。

<img src="https://qiita-image-store.s3.amazonaws.com/0/199081/fd72444f-1e88-f637-0ff9-a8cd932cfcfc.png" height=75% width=75%>

## Ansibleの実行

今回作成したAnsibleのPlaybookをGithubに置いています。
このPlaybookを使って以下の様にWordPress環境が構築できます。

https://github.com/rednes/ansible-sample


---

1. Amazon EC2でAmazon Linux AMIから環境作って。

    ![STEP01.png](https://qiita-image-store.s3.amazonaws.com/0/199081/d7e0abde-9b26-b6fd-848e-f607659d02c1.png "STEP01.png")

1. EC2ダッシュボードでインスタンスの状態がrunningになったことを確認して。

    ![STEP02.png](https://qiita-image-store.s3.amazonaws.com/0/199081/4b36e24c-6731-0dee-b1f7-eb17c090ecd6.png "STEP02.png")

1. EC2にssh接続するとためにssh_configのHostNameを書き換えて。

    ```
    Host aws-ec2
      HostName "XX.XX.XX.XX"    # set your environment
      User "user"　　　　　　 　 # set your environment
      IdentityFile "XXXXXX.pem" # set your environment
    ```

1. Ansibleのコマンドどーんと打って。

    ```
    $ ansible-playbook site.yml -v
    ```

1. 環境構築したEC2のURLからWordPreesのセットアップして。

    ![STEP05.png](https://qiita-image-store.s3.amazonaws.com/0/199081/379b5def-1b83-8cfe-ebfd-a2c3a1f5a1af.png "STEP05.png")


1. WordPressの環境ができました。Ansibleすごい。

    ![STEP06.png](https://qiita-image-store.s3.amazonaws.com/0/199081/d2ef2c65-50cc-9cdd-19b0-2bba0095ab2b.png "STEP06.png")
【PlayCanvas】1秒間にnドット移動したい

1.初期化時

```js
// speedというVec2型の変数を用意する。
this.speed = new pc.Vec2();
this.speed.set(10, 10);

// 移動量を計算する変数を用意する。
var tmp = new pc.Vec2();
```

2.update時

```js
// tmp変数に移動量を代入する。
this.tmp.set(this.speed.x, this.speed.y);

// Vec2のscaleメソッドにupdate変数の引数であるdtを引き渡す。
// dtは1フレームにかかった時間を示す。
// scaleメソッドにdtを指定することで1フレームで移動する値を算出する。
this.tmp.scale(dt);

// tmp変数に1フレームでの移動量が格納されているので、移動対象のpositionに加算する。
```
pry on Windowsでページャーにlessを使う

# 問題

pryをwindowsで使うとなぜか最初の出力時に
`情報: 与えられたパターンのファイルが見つかりませんでした。`
というエラーメッセージ？が出るのが煩わしかったので調べたところ
`where less`をエラーメッセージ抑制せずに使っていました。

pryのデフォルト(文字通り失敗)ページャーの挙動の横幅の広い文字列を上手くページングできない挙動にストレス溜まってた事もあり詳しく調べてみると
どうも、初期設定的な意味でのデフォルトページャーは`less`で
それがないからとりあえずコレでも使っとけなのが内蔵ページャーらしいです
（たぶん開発者はlessなしの挙動をまともにテストしてないんじゃないかなぁ）

そんな訳でlessならMSYS2に入ってるだろうって事でなんとかしてみました

# ~/.pryrcを編集

```rb:.pryrc
# Windowsの場合
if /mswin(?!ce)|mingw|cygwin|bccwin/ === RUBY_PLATFORM
  #微妙に不便な1行目の出力を消す
  puts

  # PAGER
  ENV['PATH'] = 'C:\Program Files\Git\usr\bin;' + ENV['PATH']
end
```

# 解説
最初の`puts`は
  ![](https://i.gyazo.com/f0970ec8998efae35893da874c8654a2.gif)]
の抑制
Git for WindowsのMSYS2(の`less`)をPATHに登録することで`less`をページャーとして利用している

ちなみに

```rb:pryrc
ENV['PAGER'] = 'more'
```

で`more`をページャーとして利用できるがあまり利点はない
WindowsでTensorFlowを使う

GPU無しWindowsしか手元にない。
でもTensorFlowを使いたい。
そんなときには。

# Docker for Windowsをインストール

お約束です。
see https://docs.docker.com/docker-for-windows/install/

# Dockerでtensorflowコンテナを起動する

```
docker run -it -p 8888:8888 tensorflow/tensorflow
```

by https://hub.docker.com/r/tensorflow/tensorflow/

## docker compose版

docker-compose.ymlを作っておくのもよいです。

```
version: '2'
services:
  tensorflow:
    image: tensorflow/tensorflow
    ports:
     - "8888:8888"
```

起動。

```
docker-compose up -d
```

終了。

```
docker-compose down
```

# tensorflowコンテナにログインする

コンテナ名は、docker psとかで調べます。

```
docker exec -it コンテナ名 bash
```

# テストする

pythonを実行し、tensorflowが使えることを確認します。

```
$ python
```

以下を入力します。

```
>>> import tensorflow as tf
>>> hello = tf.constant('Hello, TensorFlow!')
>>> sess = tf.Session()
>>> print(sess.run(hello))
```

以下が表示されます。

```
Hello, TensorFlow!
```

by https://www.tensorflow.org/install/install_windows

おしまい。

# gitをインストールする

tensorflowコンテナにはgitが入っていないので入れておきます。

```
$ apt-get update
$ apt-get install git
```

# 必要なライブラリをインストールする

ライブラリもいろいろ入れておきます。

```
$ apt install python-tk tk-dev
$ pip install opencv-python
```
Rustで競プロに使えそうな入力取得用マクロ

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">Rustでやったけど普通に as usizeとか.unwrapとかにまみれてめんどいことになってしまったなあ。そこまで言うほどでもないケド。あとcinほど楽に入力出来ないのがアレっすなあscanf相当のマクロとかﾃﾞｯﾌｫで有ると良いんだが…(´･_･`)</p>&mdash; Hideyuki Tanaka (@tanakh) <a href="https://twitter.com/tanakh/status/919185493702582274?ref_src=twsrc%5Etfw">2017年10月14日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

つらみがある。デフォでは1行取ってくるだけでも面倒くさいんですよね。
趣旨からずれるかもしれないですが、マクロ書けば、scanfやcinほど簡単じゃないんですが多少はマシなものが作れました。

競技プログラミングガチ勢じゃないので「これじゃ○○のときに使えねぇ！」とかありましたらコメント欄まで。

```rust
#![allow(unused_macros, unused_imports, dead_code)]

use std::io;

fn read_line() -> String {
    let mut s = String::new();
    io::stdin().read_line(&mut s).unwrap();
    s
}

macro_rules! from_line {
    ($($a:ident : $t:ty),+) => {
        $(let $a: $t;)+
        {
            let _line = read_line();
            let mut _it = _line.trim().split_whitespace();
            $($a = _it.next().unwrap().parse().unwrap();)+
            assert!(_it.next().is_none());
        }
    };
}
```

##使い方
`from_line!(変数名: 型, ...);`
のようにすると、`let 変数名: 型;`されて、値が代入されます。
`mut`はつけられないので、必要なら後で`let mut x = x;`のようにしてください。

例題:
https://yukicoder.me/problems/no/431

>3つの死亡フラグの状態と、1つの生存フラグの状態が与えられるので、
死亡か生存か判定してください。判定方法は次の通りです。

> - 死亡フラグが2本以上立っていれば死亡、2本未満なら生存
> - 生存フラグが立っていれば、死亡フラグの状態に関わらず生存 

> ## 入力
> > $D_1\ D_2\ D_3\ S$

> $D_i$ は死亡フラグiの状態、Sは生存フラグの状態で、1か0が与えられます。
1はON(フラグが立っている)、0はOFF(フラグが立っていない)を表します。
##出力
死亡なら"DEAD"、生存なら"SURVIVED"と出力してください。
最後に改行してください。

これが、こんな感じになります。

```rust
fn main() {
    from_line!(d1: u32, d2: u32, d3: u32, s: u32);
    println!("{}",
             if s > 0 || d1 + d2 + d3 < 2 {
                 "SURVIVED"
             } else {
                 "DEAD"
             });
}
```
Java8のお勉強(repeatable)

今回はrepeatableです。
同一のアノテーションを同じ場所に複数書ける用になるらしいです。
早速サンプル

```
/**
 * 適当な自作アノテーション。
 * SakeListってところで繰り返し登場するよって宣言する意味で@Repeatableをつけている。
 * @author komikcomik
 *
 */
@Repeatable(SakeList.class)
public @interface Sake {
	String name();

}
```

```
/**
 * 適当な自作アノテーション。
 * Sakeの配列を持っていて、これで繰り返しsakeアノテーションが使える。
 * @author komikcomik
 *
 */
@Retention(RetentionPolicy.RUNTIME)
public @interface SakeList {
	Sake[] value();
}
```

コメントに書いたとおりですが、Sake側で@Repeatable(SakeList.class)って書くことでSakeList側でSakeが複数登場することを宣言しているイメージです。
SakeList側でもそれに対応してSakeの配列を持っている感じです。あとメソッド名はvalueじゃないとコンパイルエラーが出ました。

で、これらを使ってみた例。

```
import java.lang.annotation.Annotation;

@Sake(name = "翠露")
@Sake(name = "一吟")
@Sake(name = "龍泉八重桜")
/**
 * repeatableの勉強。
 * @author komikcomik
 *
 */
public class SakeListUser {

	public static void main(String[] args) {
		Annotation[] anoList = SakeListUser.class.getAnnotationsByType(Sake.class);
		for (int i = 0; i < anoList.length; i++) {
			System.out.println(anoList[i]);
		}
	}

}
```
実行結果

```
@java8.repeatable.Sake(name=翠露)
@java8.repeatable.Sake(name=一吟)
@java8.repeatable.Sake(name=龍泉八重桜)
```
name=の後ろだけきれいに取り出したいんだけどどうやるんだろうか、よくわからなかったです・・・。

2017/10/16追記 そのままコメント欄で教えていただいた内容になりますが以下のようにすると取れるみたいです。

```
		Sake[] Sakes = SakeListUser.class.getAnnotationsByType(Sake.class);
		for (int i = 0; i < Sakes.length; i++) {
		    // Sake#name() はメソッドとして呼べる
		    System.out.println(Sakes[i].name());
		}
```

実行すると以下のようになります。素敵！

```
翠露
一吟
龍泉八重桜
```
【SEO対策】Googleペナルティについて

ほぼ個人メモ用

#ペナルティとは？
[Googleペナルティの原因と確認・解除方法](https://digital-marketing.jp/seo/reconsideration-request/)が理解しやすかったです。

>Googleペナルティとは、Googleが定める品質に関するガイドラインに準拠していない・違反しているWebサイトに対して、Googleが課すペナルティのことを指します。Google自身は「ペナルティ」という言葉は使わずに、「対策」「アルゴリズム」という表現を使いますが、一般的に「ペナルティ」と呼ばれています。
Webサイトがこのペナルティの対象になると、検索結果の掲載順位が極端に下がったり、インデックス削除され、検索結果から完全に表示されなくなったりします。
場合によっては検索エンジンからの流入が全くなくなってしまうこともありますので、Webサイトへの集客、ひいては申し込みやお問い合わせ、売り上げにも影響が出てしまうでしょう。
Webサイト運営者にとって、Googleペナルティは必ず避けなければいけないものなのです。

Google検索だけ？と思いがちですが、yahoo検索エンジンの順位もGoogleのシステムを利用しているのでGoogleペナルティを科せられると集客性が大きく落ちる可能性が高いので注意ですね。

#え？大変じゃん！
そんなに神経質になる必要はないです。悪意をもって悪いことをしないとペナルティにはならないようです。ウィルス仕込むとか何十万と外部からの被リンクを仕掛けるとか。

#ペナルティになるかもしれない注意点（外部編）
- 被リンク用サイトからリンク 
- IPが同じサーバーからたくさんリンク
- 似たようなサイトばかりからリンク
- 相互リンクサイトに登録

#ペナルティになるかもしれない注意点（技術編）
- サイト内リンクがたくさん切れている
- 画像が表示されない
- 文字が見えづらい（白背景に白文字とか）
- HTMLソースが複雑
- ディスクリプションが全てのページで同じ

>ディスクリプションって？
このページの概要説明のこと。文字数は100文字以上書いた方がいいけどスマホは50文字以内の表示なので重要な部分は50文字以内に検索キーワードを含めた方がよい。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/178016/61f91816-2053-40c9-88ca-7fd9009ae059.png)

#ペナルティになるかもしれない注意点（コンテンツ編）
- コピペした記事を投稿
- リライトした記事を投稿
- ツールで作った意味不明の記事を投稿
- サイトの存在意義がない
- 誘導目的のサイトになってる

コピペは完全コピペだけでなく、語尾を変えたり主語つけたりなど表現を変えても無駄とのこと。
論理パズル解答(続)

新しい論理パズルも解いてみました。
問題->https://twitter.com/puzzlegiver_bot  (2017.10.15)

論理パズル３
  複数解が出ますが正解はどうなんでしょう。

```prolog
solve:-permutation([_:(1,1),_:(1,2),_:(1,3),_:(2,1),_:(2,2),_:(2,3)],L),
       L=[a:(AX,AY),e:(EX,EY),h:(HX,HY),k:(KX,KY),r:(RX,RY),y:(YX,YY)], % (人:階,並び)
       HY<KY,(EX=\=RX;(abs(EY-RY,N1),N1=\=1)),AX=:=HX,RY>EY,YY=1,(RX=\=HX;(abs(RY-HY,N2),N2=\=1)),
       write(L),write("\n"),fail.

%solve.

```
論理パズル８

```prolog
cal([],N,N).
cal([H|T],N,R):-H=_:G,(G==t->N1 is N+1;N1=N),cal(T,N1,R).

res:-L=[a:A,b:B,c:C,d:D,e:E,f:F],maplist(g,L),
      not((D==t,E==t)),not((C==f,A==f)),cal(L,0,N),not(N=:=4),
      not((D==f;C==f)),not((B==t,D==t)),not(N=:=2),not((A==t;B==t)),
      disp(L,[],[]),!.

disp([],T,F):-write("good"),write(T),write("bad"),write(F).
disp([H|L],T,F):-H=P:G,(G==t->(T1=[P|T],F1=F);(T1=T,F1=[P|F])),disp(L,T1,F1).

g(_:t).
g(_:f).

%res.

```
2017.10.17追加
%虫食い算１

```prolog
ans1:-L=[V,X,Y,Z],maplist(between(0,9),L),Y=\=0,A1 is V*100+V*10+Z,A1=:=(30+V)*X,
      A2 is Y*10*(30+V),A2=:=V*1000+560,A1+A2=:=V*1000+X*100+Y*10+Z,
      write(L),!.        %丸、三角、四角、星の順
```
%論理パズル７

```prolog
count(_,[],0).
count(X,[H|T],N):-count(X,T,N1),(H=:=X->N is N1+1;N=N1).

ans2:-L0=[X1,X2,X3,X4,X5,X6],L1=[1,1,2,3,4,5,5],maplist(between(1,5),L0),X6=:=X1-X5,
      append(L0,L1,L2),findall(N,(between(1,5,X),count(X,L2,N)),L3),
      reverse(L0,[H|T]),reverse(T,L4),L4==L3,
      write(L0).     % 1の数から順に

```
Java8のお勉強(コンストラクタ参照)

今度はコンストラクタ参照です。
感覚的には１つ前の記事のメソッド参照では関数型IFの抽象メソッドの実装を特定のメソッドにするように指定していたけど、
特定としてメソッドをコンストラクタも指定できるみたいなイメージでしょうか。

前回同様適当に関数型IFを幾つか用意します。
SampleBeanはSampleFunctionalIF3のmethodA用に用意した専用の戻り値Beanで、SampleBeanExtはそれをextendsしてデフォルトコンストラクタをつくっただけのBeanです。getter、setterは省略してます。

```
@FunctionalInterface
public interface SampleFunctionalIF<T> {
	String methodA(T object);
}
```

```
@FunctionalInterface
public interface SampleFunctionalIF2 {
	String methodA();
}

```

```
@FunctionalInterface
public interface SampleFunctionalIF3 {
	SampleBean methodA(String A, String B);
}
```

```
public class SampleBean {

	private String val1;
	private String val2;
}
```
```
public class SampleBeanExt extends SampleBean {

	SampleBeanExt(String param1, String param2) {
		this.setVal1(param1);
		this.setVal2(param2);
		System.out.println("SampleBeanExtのコンストラクタが呼ばれました");
	}
}
```

で、これらを実行してみているのが下記。

```
public class ConstructorRef {
	public static void main(String[] args) {

		// 引数有（String)の場合
		// 関数型IFで規定された抽象メソッドmethodAが呼ばれたタイミングでnew String("xyz")が呼ばれている
		System.out.println("-----例1-----");
		SampleFunctionalIF<String> sample = String::new;
		System.out.println(sample.methodA("xyz"));

		// 引数なし（String)の場合
		// 関数型IFで規定された抽象メソッドmethodAが呼ばれたタイミングでnew String()が呼ばれている
		// 空文字になってるからサイズは０
		System.out.println("-----例2-----");
		SampleFunctionalIF2 sample2 = String::new;
		String s2 = sample2.methodA();
		System.out.println(s2.length());

		// 引数２個の場合
		// 関数型IFで規定された抽象メソッドmethodAが呼ばれたタイミングで
		// new SampleBeanExt("hello","world")が呼ばれている
		System.out.println("-----例3-----");
		SampleFunctionalIF3 sample3 = SampleBeanExt::new;
		SampleBean bean = sample3.methodA("hello", "world");
		System.out.println("1:" + bean.getVal1());
		System.out.println("2:" + bean.getVal2());
	}
}

```

で、実行結果

```
-----例1-----
xyz
-----例2-----
0
-----例3-----
SampleBeanExtのコンストラクタが呼ばれました
1:hello
2:world
```

メソッド参照をやったあとならなるほどねって思えますね。
しかしこれはあまり使いどころが思い浮かばないぞ。
Rubyバージョンアップに伴うGem Update手順

# はじめに

　Rubyバージョンアップや、古いGemのバージョンアップなどを行う中で、自分なりの手順というものができてきたので、その手順をここに書きたいと思います[^1]。古くから使用されていたGemは、メンテナンスされていなかったり、バージョンアップしたRubyで動くかが不明でした。そのため、Gemのテストコード実行なども行ったので合わせて書いていきます。

[^1]: 自分なりの手順なので、これが正解というものではないです。

# Gem情報の確認

Githubのリポジトリにアクセスして下記の情報を中心にアップデート情報を確認していきます。
確認する部分は下記のとおりです。

- Gemのバージョンの差異が、大きくサービスに影響を及ぼすか？
    - READEME
    - CHANGELOG/CommitLog
    - MIGRATING.md/UPGRADING.md
- 対象のRubyバージョンが対応している・テストコードが実行されているか？
    - gemspec
    - circle.yml/.travis.yml
- リポジトリがメンテナンスされていなかったり、Gemが他のGemにマージされていないか？
    - README

これらの情報を確認して、現在のGemのバージョンアップ、代替Gemの導入、使用Gemの廃止などを行います。

## README.md

基本中の基本。こちらをざっと眺めて、気になる情報があるかを確認します。
リポジトリによりますが大きな変更がある場合は、下記に記載するMIGRATING.md/UPGRADING.md
などへのリンクが貼ってあったり、ここにそのままバージョンアップに関する注意点が書いてあったりします。

## CHANGELOG.md

変更履歴です。リポジトリによってはReleases部分に変更履歴が記載されている場合があります。
GemによってはCHANGELOGがない場合もあります。その場合は、、、面倒ですがCommitLog
を確認して履歴を追ったりします。


## MIGRATING.md/UPGRADING.md

バージョンアップによって使用するメソッドのインターフェースが大きく変わる場合は、
MIGRATING/UPGRADINGなどの名前でガイドが作成されていたりします。それに従って
使用するメソッド名や引数を変えます。ただ、ここに書かれていない変更などもあるので
実際は、irb/rails consoleで動かしてみたり、サービスのテストコードを実行して動作確認を行いました。

## gemspec

Gemに関する依存関係、バージョン情報が記載されています。
Gemによりますが、記載されている情報がマチマチ(Rubyのバージョンなどが未記載)なので、
これ以外にも他の情報をチェックするようにしました。

## circle.yml/.travis.yml

継続的インテグレーション(CI)ツールの設定ファイルです。

- CircleCI
- TravisCI

CIツールで、どのRubyバージョンでテストコードが実行されているかを確認します。
全面的に信頼できるわけではありませんが、対象のRubyバージョンがここに書かれていているようであれば、ある程度安心です。


## Wiki/専用Webページ

大きなリポジトリだとWikiや専用Webページに様々な情報が記載されています。
リポジトリによっては上記で書かれている情報がそのままWiki/専用Webページに書かれていたりするので、必ずチェックします。


# Gemのテストコードの実行

情報が少なく、アップデート後のRubyバージョンで動くか微妙だったGemもありました。いくつかのGemはGem自身のテストコードを実行しました。

1. ローカル環境に対象のRubyバージョンをインストール
2. Githubのリポジトリからダウンロード
3. テスト対象のGemを動かすためのGemをインストール
4. テスト対象のGemのテストコードを実行

CONTRIBUTING.mdなど、開発者向けの情報を確認しつつ実施しました。ただ、リポジトリによってはCONTRIBUTINGなどの開発情報ないものもあるので、その場合は、、、まあなるようになります。

動作確認ができたら、対象のRailsプロジェクト内で

```
$ gem update [gem名]
```
これをひたすら繰り返します。

# 最後に

まめなGemアップデートは大事です。一気にやるもんじゃないです。しっかりとテストコードを書いておけば楽ですが、テストコードだけでチェックしきれない部分もあるので、細かくチェックしたいときはやはり手を動かす必要があるかと思います。チーム内で持ち回りして、まめにアップデートしましょう。
ソフトウェアテストにおけるテストの自動化

## 自動化の前提条件
自動化への投資は、実務の業務の推敲を支援するものでなければ意味がない。
テスト設計の不十分な状態での自動化は、まるで効果が上がらなく、自動化の得意分野をよく理解してテストを設計しないと、自動化の恩恵をうけれない。

また、テスト要件、アーキテクチャ、担当者の能力などの状況によって、自動化の戦略を考える必要もある。


## 目的はコストダウンではなく、開発プロセスの迅速化
テストの自動化によって迅速に情報が得られるようになれば、開発者へのフィードバックを早めることができる。
自動化による目的は、主に次のようなものになる。

- 不完全なプログラム修正の早期発見
- 回帰テストによるバグの早期発見
- 問題点の早期報告

よく使うテスト手法としては、自動スモークテスト（ビルド確認テスト）と自動単体テストとがある。

自動スモークテスト　では、製品の全機能について基本的な部分のテストを実施し、もし主要部分が動かないなどの致命的なバグがあれば、動作を安定させるためにビルドを差戻す。

自動単体テストでは、製品の低レベルの関数やクラスの集合についてテストを行う。
このテストの最大の利点は、いつでも誰でもが実行できることにある。

## テストによっては自動化をした方が有効なものがある

- 負荷テスト
- 性能ベンチマーク
- 構成テスト
- 耐久性テスト
- 競合状態
- 複合バグ

## 自動化は「銀の弾丸」にならない
自動テストを導入するだけで良いテストが常に行えるなんてことはない。
100%の自動化を達成しているような場合でも、それは複数のテスト手法を組み合わせることによって成功している。
ボタンを押すだけで自動的にバグを見つけてくれて報告してくれるようなものを作ったとしても、人手によるエラー調査は必須である。

## テストツールに使われないこと
テスト作業において、ツールがやり方を教えてくれるわけではないし、混乱した事態を収集してくれるわけではない。
テストの自動化は、まずテストプロセスを安定させてから行うべき。
また、作業者が自分が行なっているテストの目的を理解せずにテストを行なっていたとしても、全く意味がない。

## 手動テストと自動テストは別格
人間が行うテストを自動化すればいいということではない。
テストの自動化とは、人がやるようなテストを単純にCPにやらせることではなく、明示的に手順化された固定的なテストを行うことであり、手動テストでできないことを実行させることである。

自動テストは、常に同じスピードで、同じ手順で、同じ操作によって実行される。これに対し、人手においては実施のたびに内容に差異が生じることから、このおかげで新しいバグが見つかることもある。
また、自動テストでは、通常テストにおいては特に指示をしなくても気づいて報告するような問題に気づくことはできない。

## 同じテストをなんども繰り返すだけでは元は取れない
よく比較される方法として、自動テストと手動テストにおいて実行回数などから実際にかかるコストを比べ、投資することでどれほどの利益があるのかを考えるというものがある。
ここでは、「手動テストと自動テストは別格」ということや、そもそも実際に同じテストを繰り返す必要があるのかを考えなくてはいけない点に気をつける必要がある。

## 自動化で埋もれてしまうバグはないか
自動化の作業中に行うべきことはないか、実行できるテストはないか、発見できなくなるバグはないか等、コストやリスクを考えることが大切。
また、既に完成されている自動テストにも十分注意が必要であり、本当にテストできているのか、役に立つのか、ガバレッジは大丈夫か、正しくチェックされているかを常に注意する必要がある。

## GUI関係のテスト自動化
UIの変更に追随する必要があり、そのためにはインターフェース部分を抽出し、それを抽象化して自動化テストに取り組む必要がある。

## 自動化した回帰テストはすぐに使えなくなる
UIや出力形式の変更、環境の問題、メンテナンスの問題などの可能性を考慮し、自動化するテストの選定は慎重に行うべき。
どんなテストでも自動化を行えば、それはメンテナンスをし続けるか、捨てるしかなくなってしまう。

## テストの自動化はソフトウェア開発そのものであり、決して安くない投資である
一つの手動テストをきちんと設計し自動化するものなら、手動テストを行う10倍もの時間がかかるだろう。
もちろん、ソフトウェア開発の工程のように、プログラミング、テスト、レビューやプロジェクト管理が必要となり、幅広いスキルが求められる。
このことからも、自動化計画はプロジェクトの早い段階で立てるべきである。

## 自動化テスト設計で注意すべき事項

- テスト環境の確認
- 期待する結果は何か
- 潜在的エラーと副作用の確認
- 潜在的なエラーから復旧する方法
- 他のテストの邪魔をすることはないか

## テスト変数が多い時は
データ駆動型自動テストや、キーワード駆動型自動テストを使う。
データ駆動型自動テストとは、入力値と期待値を表計算ソフトなどの表に記入し、それを読み込むことでテストと結果の合否を評価する方法。
テストデータと実行コードとを分離することで、繰り返し使うことができるだけでなく、テスト用プログラミングの簡略化やレビューが行いやすい等のメリットがある。
キーワード駆動型テストとは、表に登録できるものがデータだけでなく、項目の組み合わせ（キーワード）であるという点が異なる。

## 自動単体テスト
単体テストとは、関数、クラス、メソッドなどのソフトウェアを構成する採用単位の機能をテストするものである。
本来、単体テストでは、一つの機能を完全に独立させた状態でテストを行うが、いくつかの単体テストを処理経路に沿って行うことで、スタブ（テスト対象から他のモジュールを擬似的に呼び出す）を作る必要をなくす自動単体テストには人気がある。

## 「テスト容易性」とは可視性と操作性である
ソフトウェアの動作を監視したり、状態を操作したりする機能を組み込めば、よりテストが容易になる。

- ソースコードの確認
- ログ出力
- 診断コード
- エラーシミュレーション
- テストポイント
- イベント鳥が
- 古いデータフォーマットとの互換
- カスタムコントロールサポート（GUIのテストツールが持っているインターフェースを操作する機能）

## 即効性のある自動化から始めよ
効率の改善という面から自動化の対象を選択するべき。

- システムセットアップと準備
- 診断支援
- セッション記録
- テスト生成など
Git Submodule内の変更をプッシュする手順


## Submodule
サブモジュール内のファイルを変更する

* cd submodule/xxx
* git add .
* git commit -m 'hogehoge'
* git push origin HEAD

## 本体側
`modified:   submodules/xxx`と出ている

* git add submodules/xxx
* git commit -m 'xxx'
* git push origin HEAD

これでsubmodule側でプッシュしたコミットIDに本体側の参照が切り替わる
JavaScriptでreduceを使う時の注意事項

reduceは複数の引数を取る関数をコールバックに取るメソッドでfilterやmapに比べて使うときに気をつけなければならない点が多いのでよくやるエラーについて解説します。

## コールバックの返リ値とinitialValueは配列と同じ形式
reduceでは左から右（右から左）に処理をし返り値は新たな引数として再利用する。
そのため返り値は新たな引数(配列要素）と同様の振る舞いをしないとエラーになる。
initialValueも与えた最初の配列要素としてみなされるのでまた配列要素と同じ形式でないとならない。
例えばObjectのある要素の合計を求めたいとき

```js:sum.js
const arr=[ { num: 1}, {num:2}, .... {num: } ];

// NG 返り値が num属性をもったObjectでない NaN
arr.reduce((previous, current)=>{ return previous.num+current.num; });
// OK 最終結果は { num: 1+2+3+...+n }
arr.reduce((previous, current)=>{ return { num: previous.num+current.num }; });
// NG initialValueが　num属性をもったObjectでない { num: NaN }
arr.reduce((previous, current)=>{ return { num: previous.num+current.num }; }, 0);
```
タチが悪いことにこれらはundefinedと数字の演算でNaNとなり例外を出さずどこかにNaNを返す。

## initialValueを渡す時と渡さない時の挙動
ではinitialValueを渡さなければどうなるか?
2乗和を求めるプログラムの以下の例を見てもらおう。

```js:sum_squares.js
const arr=[ 3 ];
const arr=[ 3, 4 ];

console.log(arr.reduce((a,b)=>{ return a+b*b; }));  // 3
console.log(arr.reduce((a,b)=>{ return a+b*b; }, 0));  // 9

console.log(arr2.reduce((a,b)=>{ return a+b*b; }));  // 19
console.log(arr2.reduce((a,b)=>{ return a+b*b; }, 0));  // 25
```
コールバックがない場合はひとつ目の要素の2乗部分が呼ばれず正しい値にならない。
からの配列を渡すとどうなるか？

```js:empty.js
const arr=[];
console.log(arr.reduce((a,b)=>{ return a+b*b; })); // TypeError
console.log(arr.reduce((a,b)=>{ return a+b*b; }, 0)); // 0
```
TypeErrorの例外が投げられる。initialValueを与えればinitialValueが返ってくる。
これは単にinitialValueを返しているので`{ num: 0 }`とか与えるとそのまま返ってくる（もちろん要素があれば変な値になる)。

# まとめ
安全にreduceを使うためにはinitialValueは与えコールバック関数の返り値とinitialValueは配列要素と形式を合わせるべきです（使うものだけで多分動きます）。
数字などを扱っているときは便利ですがちょっと複雑なオブジェクトを扱うときは注意が必要です。
GameMaker Studioを一ヶ月触って

__前置き__

Qiita 初投稿です。タイトル通り GameMaker Studio というゲームエンジンを使って一ヶ月目の感想です。
Qiitaの下書きにいくつか溜まっていますが、どの記事書いていくと後半でだんだん疲れてきていつも投稿しないのでとりあえず、投稿します。


##概要

GameMaker Studioとはゲームエンジンである。

日本ではほとんどシェアがないが、世界ではunityにつぐ第二位のシェアである。

イベントベースでかつ、GUIプログラミングが可能である。
(自分はコードで書いたほうが楽なので、最初の慣れないとき以外はコードで書いている。)

GameMaker Studioに使用される言語はいわゆる独自言語でGameMakerLanguage(GML)と呼ばれる。



##環境
OS: macOS sierra
version:　2.1.0 (GameMaker Studio 2)
2Dゲームを作成



##GameMaker Studioの簡単な紹介

Sprite, Object, Room などを作成してゲームを作っていく

+ Sprite:  画像を設定。
  (tips: 一つの画像から分割して取り込みたい(スプライトのシートをとりこみたい)場合は、 画像を編集 ->  選択するとアプリケーションメニューバーに Image, View, Effectというのが現れる → Image を選択 → Import Strip Image でOK)

+ Script: メソッド。GMLで独自のメソッドを定義するにはこれを使う必要がある。 argumentというbuilt-in変数で引数を指定できる。

+ Object: Create, Stepなどのイベントを持ったもの。また、spriteなど設定できる。

+ Room: Unityでいうところのシーンである。レイヤーがあり、そこにObjectを配置していく。


##イベントとは
インスタンスが何かしら動作をトリガーにして何を実行するかを定義できる。

- Create: インスタンスができたとき 
- Step: 毎フレームごとに実行
- Mouse: マウスでクリック(など)したとき
- Draw: 描写に関係する
 (Tips: スクリプトでdraw系のメソッド呼ぶ場合、drawというイベントに定義しないと描写できない)





##言語の簡易の紹介
○変数のスコープ

- local変数(黄色[^1]):  var キーワードをつける。　ひとつのスクリプト内

+ インスタンス変数(青): あるインスタンスが持つ変数(インスタンスとはオブジェクトが顕現したもの)

+ グローバル変数(紫):　gloval.nameで定義できる。　
 + (tips: Arrayも使える。が、なぜか青で表示される)
 + キーワード glovalvar でもグローバル変数になるが今は非推奨

+ built-in変数(緑): 各インスタンスがもとから持つ特別な変数

○タイプ(よく使うもの)

+ 数字、文字、真偽値、enum (それぞれオレンジ)
+ 真偽値はtrueという名前の1を返す定数
+ enum はよくある列挙型で指定しなければ、0,1,…の値を返す。整数だけ可能
定数は、enumを使うのがよい。(tips:キーワードconstがあったりしない)

(tips: オレンジは定数を返す。スプライトやスクリプト、すべて定数値を返す、値はリソースの上から順に0, 1…となる)


  

○演算子
  だいたいお馴染みのが使える。三項演算子も使用可能 (ver2.0)

○他

+ \#macroというのが使える、c言語などのdefineと同じである(赤) 
  (tips: 同じ名前のマクロを複数定義してもコンパイルエラーはでない)

+ エクステンションで外部スクリプト(例えばjs)が使用可能。また外部のjsからgmlのスクリプトを呼ぶこともできる

+ httpリクエストのメソッドも用意されている


##エディターのおすすめショートカット
- 定数にカーソルを合わしてFn1:
定義に飛べる。sprite, script, enum, macroなど（要するにオレンジ文字）が可能。
- コマンド+t: Resourcesを検索
- コマンド+f: 1script内の文字列検索
- コマンド+shift+f:プロジェクト全体からの文字列検索

(tips: IDEのショートカットの変更はできない)

##実際の実装において

+ ゲームの固定値(ちまたではマスターデータとか呼ばれているもの)は定数で管理したいのでenumを利用。
また、arrayを使いたかったので、変更可能だが仕方なくグローバル変数で定義。 



+ 変数名にはかなり気を使う必要がある。 
最近の言語では非推奨なことが多いがハンガリアン記法を使うしかない。
接頭辞のscr, spr, rm, obj。定数は大文字など。
(色や命名規則でどうにかやっていく必要がある。)


+ イベントはすべてスクリプトで書きやすいようにした。
createイベントなら obj_hoge_create という名前のスクリプトを作って一行それを呼ぶ。
他同様に、stepイベントは obj_hoge_step を作って呼ぶ。

+ データストラクチャで連想配列やリスト、スタックが使えるが、今回作っているプロジェクトでは2次元配列などでやりくりし、使わないことにした。

##GMLの大雑把な感想

+ 型無しのお手軽に書ける言語である。クラスはない。ネームスペースなどもなし。

+ ファンクションが気軽に定義できず、必ずscript(一つのファイル)を作る必要がある(だるい)。（1ファイルに1メソッドということである。）

+ Unityでいうところのコルーチンが書きたくなるがあまりうまくできない。timelineで似たようなふうに書けるかもしれないが、まぁだるい。

+ 機能は多くなく、覚えることは少ない。




##GMS全体の感想
guiでプログラミングができるというのは、ゲーム作り初心者にはありがたいかもしれないが、込み入ったことがしたくなると、どうしてもコードで書く必要になってくるかと思う。
言語自体の仕様は多くなく、覚えることは少ない。その点も初心者がとっつきやすいのかなと思う。
型がないということで、スピーディにシンプルな（あまり大きくない）ゲーム作りたいという場合に選ぶ動機になる…？
実はもともと画像編集ソフトだったらしく、画像編集ができる。

---

[^1]: 色が書いてある場合はIDEの表示色です
ns3におけるL２スイッチの作り方まとめ


ns3では明示的にスイッチノードが用意されているわけではないので、ノードと CSMAの組み合わせによってスイッチを作り上げる必要がある．その方法のメモ．

# 方法
スイッチを作成するためにはノード同士を1対1でつなぐリンクを接続ホストの数だけ作成することになる．
具体的には以下のコードのようになる．

```cc
for (uint32_t i = 0;i<lan1.GetN();i++){
  NetDeviceContainer link = csmaHelper.Install(NodeContainer(lan.Get(i),swNode));
  swDevs.Add(link.Get(1));
}
```
 
 `lan`は`NodeContainer`クラスのオブジェクト、`swNode`は`Ptr<Node>`のオブジェクトである．
 
 そして`swNode`内にある複数のNetDeviceをブリッジできるようにするためには`BridgeHelper`を利用する．
 
 
 ```cc
 BridgeHelper switchHelper;
 switchHelper.Install(swNode,swDevs);
 ```
 
 これによりNode内のNetDevice間でのブリッジができるようになった．
 
 **BridgeHelperを利用する際には，インストールするノードにIPアドレスが割り振られていないのが前提条件にあるので注意**
 
 他にもAP作成時にもこのBridgeHelperは利用する.
Java8のお勉強(メソッド参照)

今回はメソッド参照のお勉強です。
関数型IFの変数にメソッドを代入することが出来るらしいです。
関数型IFの(唯一の）抽象メソッド呼ばれたらこの代入（指定した）メソッド実行してね言ってるイメージだと思います。
関数型IF忘れた人は[前回の記事参照](https://qiita.com/komikcomik/items/c4de939775af87e5037e)

とりあえず以下のように関数型IFを２つ用意します。

```
@FunctionalInterface
public interface SampleFunctionalIF {

	String methodA();

}
```

```
@FunctionalInterface
public interface SampleFunctionalIF2 {

	String methodA(String A, String B);

}
```

で、これらを呼び出すクラスを用意したのがこちら

```
/**
 * メソッド参照のお勉強。
 * 関数型IFの変数にメソッドを代入することが出来る。
 * 関数型IFの(唯一の）抽象メソッド呼ばれたらこの代入（指定した）メソッド実行してね言ってるイメージだと思います。
 * @author komikcomik
 *
 */
public class MethodRef {

	public static void main(String[] args) {
		/* 引数なしの場合 */
		// SampleFunctionalIFの抽象IFであるmethodAが呼ばれたら代わりにこのクラスのメソッドhelloを実行してねといっているイメージ
		System.out.println("-----例1-----");
		SampleFunctionalIF if1 = MethodRef::hello;
		System.out.println(if1.methodA());

		/* 引数１個の場合 */
		// この辺はリストに適当に値詰めてるだけ
		System.out.println("-----例2-----");
		List<String> l = new ArrayList<>();
		l.add("hoge");
		l.add("hogehoge");
		l.forEach(System.out::println); // 関数型IFであるListの抽象メソッドの実装をSystem.out.println(s)と指定しているイメージ
		l.forEach(MethodRef::echo); // 1つ上と似たような感じだけど自作メソッドも当然代入できる


		/* 引数２個の場合 */
		System.out.println("-----例3-----");
		SampleFunctionalIF2 if2 = MethodRef::join;
		System.out.println(if2.methodA("Hello", "World"));

	}

	public static String hello() {
		System.out.println("helloメソッド呼ばれたよ");
		return "hello";

	}

	public static String join(String A, String B) {
		return A + B;

	}

	public static void echo(String s) {
		System.out.println(s);
	}
}
```

実行結果は以下のようになります。

```
-----例1-----
helloメソッド呼ばれたよ
hello
-----例2-----
hoge
hogehoge
hoge
hogehoge
-----例3-----
HelloWorld
```

まあ想定通りですね。ただやっぱりラムダ式の書き方とか今回の::みたいな書き方に慣れていないのでなんとなく身構えてしまう・・・。
ラムダ式は<b>引数 -> 処理</b> って書いていて今回の例2相当をラムダ式で書いたら

```
		l.forEach(s -> {
			System.out.println(s);
		});
```

となるので、似たような効果が得られるみたいですね。バリバリ使っている人はどうやって使い分けているのだろうか。
Ubuntuに新しくAndroid開発環境構築しようとしてハマった

## env
- Ubuntu 17.04
- Intellij 2017.2

## おきたこと

- エミュレータ起動しようとしたのにしない

```
16:52	Error Opening Emulator
			libGL error: unable to load driver: i965_dri.so
			libGL error: driver pointer missing
			libGL error: failed to load driver: i965
			libGL error: unable to load driver: i965_dri.so
			libGL error: driver pointer missing
			libGL error: failed to load driver: i965
			libGL error: unable to load driver: swrast_dri.so
			libGL error: failed to load driver: swrast
			X Error of failed request:  BadValue (integer parameter out of range for operation)
			Major opcode of failed request:  155 (GLX)
			Minor opcode of failed request:  24 (X_GLXCreateNewContext)
			Value in failed request:  0x0
			Serial number of failed request:  39
			Current serial number in output stream:  40
```

## ググってわかったこと

```
ln -sf /usr/lib32/libstdc++.so.6 ~/Android/sdk/tools/lib64/libstdc++/libstdc++.so.6
```

みたいにしようね

## こまったこと

`~/Android/sdk/tools/lib64/libstdc++` ディレクトリがそもそもない

## 解決法

`~/Android/Sdk/emulator/lib/libstdc++` ディレクトリがあったのでそこにsymlinkを貼る

```bash
$ cd ~/Android/Sdk/emulator/lib/libstdc++
$ mv libstdc++.so.6 libstdc++.so.6_
$ ln -s /usr/lib32/libstdc++.so.6 .
```

## 感想

バージョンアップで何か変わったんかな。
ようわからんけどとりまこれで動いた気がする。


## 参考

- https://developer.android.com/studio/install.html
- https://qiita.com/yasuBrosK/items/6632ce383feb215c9682
- https://askubuntu.com/questions/867081/android-studio-buggy-after-upgrade-to-16-10
CozmoSDKを使ってCozmoを操作する

Cozmoをゲットした。

![IMG_20171005_213130.jpg](https://qiita-image-store.s3.amazonaws.com/0/141310/37c51fba-bd1f-c1b8-fd3c-d84a479bb46f.jpeg)

Cozmoは「やんちゃでかしこいあいぼう」という成長型のペットみたいなロボット。
http://www.takaratomy.co.jp/products/cozmo/

AndroidやiPhoneなど(※)のスマートフォンと連携させて動かす。
専用アプリがあり、そのアプリが起動していないとCozmoは動かない。
※一応Fire OSにも対応しているみたい

専用アプリ上でブロックベースでプログラミングして、Cozmoを操作することができる。
また、CozmoSDKを使うと、Pythonでプログラミングして、Cozmoを操作することができる。
CozmoSDKならIFTTT連携もできるみたい。

今回は、CozmoSDKを使ってCozmoを操作する方法を説明する。
スマートフォンはAndroidを使っている。

# 環境
環境はいつも通り。
Win10を使っているが、Bash on Ubuntu on Windowsを使っている。

|対象|OS、バージョン等|
|:--|:--|
|PC|Ubuntu 16.04.3 LTS(Win10のBoW使用)|
|Android|Nexus6P(Android8)|

# 概要
基本的には以下の通り。
http://cozmosdk.anki.com/docs/index.html

CozmoSDKはスマートフォン経由で実行される。
こんなイメージ。
[PC] <-> [Android] <-> [Cozmo]

PCとAndroid端末はUSBケーブルで接続し、adb経由で通信する。
Android端末とCozmoはCozmoアプリのCozmoSDKを有効にして通信する。

# 環境構築
Android端末にはCozmoアプリ、PCにはAndroidSDKとPython 3.5.1以上が必要になる。

## Android端末(Cozmoアプリ)
Android端末に[Cozmoアプリ](https://play.google.com/store/apps/details?id=com.anki.cozmo&hl=ja)を入れておく。

Cozmoのセットアップが終わっていないならセットアップしておく。
ついでにCozmoと遊んでおくといいと思う。

## AndroidSDK(adb)
AndroidSDKでコマンドラインツールのみの場合、sdkmanager(sdk-tools-linux/tools/bin以下)でplatform-toolsを取得しておく。
sdkmanagerのパスを通した状態で、下記コマンドを実行する。

```bash
sdkmanager "platform-tools" "platforms;android-26"
```

adb(sdk-tools-linux/platform-tools以下)のパスを通しておく。
Android端末をPCに接続し、下記コマンドを実行する。
※Android端末では予め開発者モードを有効にし、adbデバッグも有効にしておくこと。

```bash
adb devices
```

以下のように「device」が表示されていればOK。

```
List of devices attached
XXXXXXXXXX        device
```

## Python3
下記コマンドでPython3をインストールする。

```bash
sudo apt-get update
sudo apt-get install python3
```

pip3をインストールする。

```bash
sudo apt install python3-pip
```

Tkinter(PythonのGUIツールキット)もいるらしいのでインストールする。

```bash
sudo apt-get install python3-pil.imagetk
```

## CozmoSDK
下記コマンドでPCにCozmoSDKをインストールする。
[camera]はオプションみたい。

```bash
pip3 install --user 'cozmo[camera]'
```

CozmoSDKをアップグレードする必要がある場合は、下記コマンドを実行すればいいみたい。

```bash
pip3 install --user --upgrade cozmo
```

# チュートリアルの実行
CozmoSDK Examplesを取得する。
下記からLinux版を取得できる。
http://cozmosdk.anki.com/1.0.1/cozmo_sdk_examples_1.0.1.tar.gz

格納したディレクトリに移動し、解凍する。

```bash
tar -zxvf cozmo_sdk_examples_1.0.1.tar.gz
```

Cozmoアプリを起動し、Cozmoに接続する。
アプリの設定(上部右側のアイコン)の中にある「SDKを有効にする」ボタンを押下する。

PC側で下記コマンドを実行する。

```bash
cd cozmo_sdk_examples_1.0.1/tutorials/01_basics
./01_hello_world.py
```

Cozmoが「hello world」と言ってくれる。

# Cozmoの発話処理
01_hello_world.pyの中身はこんな感じになっている。

```py
import cozmo

def cozmo_program(robot: cozmo.robot.Robot):
    robot.say_text("Hello World").wait_for_completed()

cozmo.run_program(cozmo_program)
```

cozmo.robot.Robotクラスのsay_textメソッドで発話処理をする。
wait_for_completedメソッドでは発話処理の完了待ちをしている。
デフォルトで最大5秒待つようになっている。それ以上かかる場合は引数に秒単位で指定する。
cozmo.run_programメソッドで実行する。

発話内容は日本語でも大丈夫だった。
以下のようにsay_textメソッドに「オヤスミ」を渡すと発話してくれた。

```py
def cozmo_program(robot: cozmo.robot.Robot):
    robot.say_text("オヤスミ").wait_for_completed()
```

カタカナでなくても「おやすみ」「お休み」でも発話していた。
Twitterとかメールとか、日本語の文章を読み上げさせることができるみたい。
IFTTT連携のサンプル(if_this_then_thatディレクトリ以下)もあるので、色々連携させるのも面白そう。
UnityEngine.UI.Textをフェードイン・アウトする時のメモリ消費

#概要
Unityで文字をフェードイン・アウトする方法についてです。
![bandicam-2017-10-15-16-05-37-911.gif](https://qiita-image-store.s3.amazonaws.com/0/183870/7b6464c4-1e43-c1f0-8673-125d8d83d748.gif)

#環境
Windows 10
Unity 2017.1.1f1

#方法1
一番最初に試した方法がこちらです。

```csharp
using UnityEngine;
using UnityEngine.UI;

public class Sample : MonoBehaviour
{
    public Text text;

    void Update()
    {
        Color color = text.color;
        color.a = color.a <= 0 ? 1 : color.a - 0.01f;
        text.color = color;
    }
}
```

これでもやりたい事はできましたが、メモリ消費がどんどん増えます。
※秒間200Kbyte程度

#方法2
長時間この効果を連続させたく、メモリ消費を抑えたかったので以下の方法にしました。

![01.png](https://qiita-image-store.s3.amazonaws.com/0/183870/3684f69b-d89b-3aff-8a4a-6944d88e9750.png)

![00.png](https://qiita-image-store.s3.amazonaws.com/0/183870/9413a6fd-2030-de30-6b7f-8bec7aea16c7.png)

```csharp
using UnityEngine;
using UnityEngine.UI;

public class Sample : MonoBehaviour
{
    public Text text;

    void Update()
    {
        Color color = text.material.GetColor("_Color");
        color.a = color.a <= 0 ? 1 : color.a - 0.01f;
        text.material.SetColor("_Color", color);
    }
}
```

マテリアルを作成し、ShaderをUI/Unlit/Textを設定します。
作成したマテリアルをTextのMaterialに設定します。
スクリプトではText.colorの代わりにマテリアルの"_Color"を変更します。

#備考
実行形式については未確認です。

#参考
http://tsubakit1.hateblo.jp/entry/2015/03/24/062102
http://kan-kikuchi.hatenablog.com/entry/Material
Docker 17.09 からADD/COPY --chownでファイルのオーナーを変更できるようになった

# はじめに
Docker 17.09から ADD/COPY --chownでファイルのオーナーを変更できるようになったようです。
root以外でコンテナを動かしたりするときに地味にうれしい機能。

まぁなくても追加でRUN chownすればいいだけで困りはしないが、あるとDockerイメージのレイヤが1枚減るので地味にうれしい。

[moby/moby: Add --chown flag to ADD/COPY commands](https://github.com/moby/moby/pull/34263)

というわけで、さっそく試してみた。

# 稼働確認
稼働確認したバージョンは以下のとおり。

```
$ docker version
Client:
 Version:      17.09.0-ce
 API version:  1.32
 Go version:   go1.9
 Git commit:   afdb6d4
 Built:        unknown-buildtime
 OS/Arch:      darwin/amd64

Server:
 Version:      17.09.0-ce
 API version:  1.32 (minimum version 1.12)
 Go version:   go1.8.3
 Git commit:   afdb6d4
 Built:        Tue Sep 26 22:45:38 2017
 OS/Arch:      linux/amd64
 Experimental: false
```

サンプルで適当なDockerfileを準備する。

```
FROM alpine

RUN addgroup -S app && adduser -S -g app app
COPY --chown=app:app test.txt /tmp/test.txt
```

ここでは、alpineベースでappというグループとユーザを追加し、`test.txt` をCOPYしている。
`COPY --chown=app:app` でオーナーのユーザとグループを指定するのがポイント。

稼働確認のためコピーしている `text.txt` を適当にローカルに作る。

```
$ echo "chown test" > test.txt
```

ビルドしてみる。

```
$ docker build -t chown-test ./
Sending build context to Docker daemon  3.072kB
Step 1/3 : FROM alpine
 ---> 4a415e366388
Step 2/3 : RUN addgroup -S app && adduser -S -g app app
 ---> Running in 81e187e57527
 ---> 8db2e92a0c06
Removing intermediate container 81e187e57527
Step 3/3 : COPY --chown=app:app test.txt /tmp/test.txt
 ---> d5e26892a07e
Successfully built d5e26892a07e
Successfully tagged chown-test:latest
```

コンテナを実行してオーナーを確認してみる。

```
$ docker run -it chown-test ls -la /tmp
total 12
drwxrwxrwt    2 root     root          4096 Oct 15 06:34 .
drwxr-xr-x   27 root     root          4096 Oct 15 06:35 ..
-rw-r--r--    1 app      app             11 Oct 15 06:34 test.txt
```

ちゃんとオーナー設定されてる。よさげ。
上の例は `COPY` だけど試してみたところ `ADD` でも動いた。
あと試してみたところディレクトリがある場合も、 `chown -R` 相当で再帰的にサブディレクトリのファイルのオーナーも変わってたので、大量のファイルをまとめてCOPYする場合でも大丈夫。

# おわりに
COPYと同時にchownできるとイメージのレイヤが1枚減って地味にうれしい。

ちなみにchmodもないの？って思って調べたらIssueは立ってて、

[moby/moby: Proposal: Add --chmod flag to ADD/COPY commands (analogous to --chown)](https://github.com/moby/moby/issues/34819)

これを書いてる現在(2017/10/15)は検討中のようです。chmodもそのうち追加されるかもしれないですね。
Jetpack の全機能が有効/無効にできる隠しページの開き方

##全機能が有効/無効にできるページ
サイト統計情報などの通常は無効化できない機能も無効にできる隠しページ

```:URL
/wp-admin/admin.php?page=jetpack_modules
```

![jetpack modules page](http://qiita.halpas.com/img/jetpack-modules-page.jpg)

##開き方
WordPressにログイン。サイドバーからJetpackの「設定」を開き、画面下部にある「Debug」をクリック
![jetpack debug](http://qiita.halpas.com/img/jetpack-debug.jpg)

「お使いのサイトで使用可能な Jetpack モジュールの全一覧にアクセスします。」リンクをクリック
![jetpack modules page link](http://qiita.halpas.com/img/jetpack-modules-page-link.jpg)

以上
![jetpack modules page](http://qiita.halpas.com/img/jetpack-modules-page.jpg)
KotlinとSparkでWebアプリケーション①（準備とHello World!編）

# 検証環境
この記事の内容は、以下の環境で検証しました。

* Intellij IDEA ULTIMATE 2017.2
* Kotlin 1.1.4-3
* Spark 2.6.0
* Gradle Projectで作成

# 目標
Spark Framework(以降、『Spark』と表記)を使用して最も簡単なWebアプリケーションをKotlinで作成する事

# 今回の流れ
* Sparkの簡単な概要
* 事前準備
* 実装
* 実行
* まとめと次回の予定

# Sparkの簡単な概要

http://sparkjava.com/

今回紹介するSparkは上記のwebアプリケーション構築用のmicro frameworkです。
似たものでApache Sparkがあるが、それとは全くの別物です。名前が似てるだけ！

Webアプリケーションを構築すると、サーバはどーしようとか、設定ファイルはどーやって書くんだろうと覚えることが多くて、すこーしハードルが高い気がする。

このフレームワークはmainメソッドやmain関数だけで構築出来ちゃう。
フレームワークにサーバも組み込まれているので、実行も簡単！サーバは「Jetty(https://www.eclipse.org/jetty/ )」が組み込まれている。
サイトのトップに「最小限の努力で作れちゃう」と謳っているとおり、簡単に作成できる！

# 事前準備
準備はいたって簡単。ライブラリを１つ追加するだけ。

gradleの場合は以下を追記

```groovy
compile 'com.sparkjava:spark-core:2.6.0'
```

Mavenの場合は以下を追記

```xml
<dependency>
    <groupId>com.sparkjava</groupId>
    <artifactId>spark-core</artifactId>
    <version>2.6.0</version>
</dependency>
```

# 実装
Sparkのライブラリを追加出来てたら、実装してみる。
実装例は以下の通り。

```kotlin:SparkSample.kt
package jp.co.casareal.kotlin_spark

import spark.Spark.get

fun main(args: Array<String>) {
    get("/hello") { request, response -> "Hello World!" }
    get("/bye") { request, response -> "Bye!" }
}
```

## spark.Spark.getメソッドの説明
内容はすごく単純。
第一引数の文字列でしているURLにHTTPのGETメソッドでアクセスすると、第二引数の処理を行い。文字列をレスポンスとして返す。引数のrequestはHttpServletRequest、responseはHttpServletResponseのオブジェクト。

今回は、「/hello」にアクセスすると「Hello World!」、「/bye」にアクセスすると「Bye!」がレスポンスとして返る。

## その他のメソッド
getの他にもpost、put、deleteなども用意されている。

# 実行

実行するとサーバが起動して、デプロイします。

アクセスするURLは以下の通りです。
URLをみてわかるようにデフォルトのポートは4567。

```text
http://localhost:4567/hello
```
![スクリーンショット 2017-09-29 14.25.25.png](https://qiita-image-store.s3.amazonaws.com/0/99960/b8fddfa3-9ac9-f198-24c5-4e7dbd3674b4.png)


```text
http://localhost:4567/bye
```
![スクリーンショット 2017-09-29 14.25.34.png](https://qiita-image-store.s3.amazonaws.com/0/99960/6c6eb32f-5d6d-488b-6cf6-08a8b7102671.png)


# まとめと次回の予定
SparkでWebアプリケーションを構築すると簡単に作れちゃいます。
しかもmain関数（メソッド）だけで完結するので、プログラミングを初めて行う人にもとっつきやすい気がする。

次回は、パラメータを取得する方法でも書く。
かなり古い論理パズル

Qiita内を逍遥していましたら、論理パズルをrubyで解かれていました。
論理といえばprologですので、挑戦してみました。
問題->https://twitter.com/puzzlegiver_bot/status/220508689981902849/photo/1
rubyの解->https://qiita.com/nidouchi/items/92f351731858ddbba931

```prolog
cal([],N,N).
cal([H|T],N,R):-H=_:G,(G==t->N1 is N+1;N1=N),cal(T,N1,R).

res:-L=[red:R,blue:B,yellow:Y,brown:BR,green:G,violet:V,black:BL],maplist(g,L),
      (R==V->R==f;R==t),(Y==G->B==f;B==t),(Y==G->Y==t;Y==f),(BR==Y->BR==t;BR==f),
      (V==BR->BL==f;BL==t),cal(L,0,N),(N==3->G==t;G==f),
      disp(L,[],[]),!.

disp([],T,F):-write("honest"),write(T),write("liar"),write(F).
disp([H|L],T,F):-H=P:G,(G==t->(T1=[P|T],F1=F);(T1=T,F1=[P|F])),disp(L,T1,F1).

g(_:t).
g(_:f).

%res.
```
登場人物（とその状態）を並べてそのあとに条件を連ねれば、バックトラックのおかげで解が出ます。
dangerでPull Requestに自動でラベルをつける

[danger](https://github.com/danger/danger)を使うことでPR駆動開発を推し進めていきたいなと考えており、いろいろな記事を参考にしました。

- [Dangerで効率よくPR駆動開発 | Recruit Jobs TECHBLOG](https://techblog.recruitjobs.net/development/danger_driven_development)
- [Dangerで始めるPull Requestチェック自動化｜コネヒト開発者ブログ](http://tech.connehito.com/entry/danger)
- [Android開発のコードレビューbotを乗り換えた話｜クックパッド開発者ブログ](http://techlife.cookpad.com/entry/2017/06/28/190000)

とっても便利ですね。一つ気になったのは、 dangerは名前の通り警告したりするのが主な目的なのでコメントを残す、warnを出すなどの機能に絞って作成されたため、今一つ自動化のかゆい部分に手が届きません。

公式にもある通り、[プラグインの作成が非常に簡単です](http://danger.systems/guides/creating_your_first_plugin.html)。

どのプロジェクトでも**「WIP」タイトルを見つけてコメントする**まではやってるんですが、どうせならラベルつけてくれた方が楽だしもっと自動化できてるんじゃ無いかな？と考えて作ってみました。

## danger-auto_label

非常に単純ですが、PRのタイトルにWIPをつけるとプロジェクトにあるWIPラベルをつけてくれます。

![sample.gif](https://qiita-image-store.s3.amazonaws.com/0/26883/2141082d-e095-c080-5cdd-57bcf4bc2571.gif)

WIPラベルが無い場合は自動で作成するようにしました。gemで公開済みです。
これだけだと単純すぎたので、ラベル名と色を指定すれば自由なラベルをつけれるようにもしてあります。

- [danger-auto_label](https://github.com/kaelaela/danger-auto_label)

すでにdangerを導入済みの場合以下の数行で導入できます。

```:Gemfile
gem 'danger'
gem 'danger-auto_label' #追加
```

```:Dangerfile
if github.pr_title.include? "[WIP]"
    auto_label.set_wip(github.pr_json["number"])
end
```

---

簡単ですね。dangerのプラグイン開発はおろか、Rubyを書いてるのも初めてなので多少コードは汚いかもしれません。開発の際にはこのへんを参考にしました。

- [Dangerプラグインを作ろう｜量産型エンジニアの憂鬱](http://blog.duck8823.com/entry/2017/07/11/155714)
- [danger-findbugsを作った｜kazy no blog](http://kazy.hatenablog.com/entry/2017/05/14/211925)

OctokitというRubyのGithubAPIクライアント的なものが存在するので、こちらは必読です。

- [octokit.rb](http://octokit.github.io/octokit.rb/)
JRubyでクロスプラットフォームなアプリを作ってみる(jarファイル生成編)

#「WindowsでもMacでも動くアプリを作ってほしい」
まぁ、きっかけはなんであれ、このような要件をいただいたので、Javaアプリを作ることになった。
ただ、今までJavaでアプリを作ったこともなく、どうしようかと思っていたところJRubyなるものがあるのでそれを使ったほうが良い、とのことだったのでそうしてみることに。
##JRuby?
JRubyは、名前からわかるようにJava + Rubyの言語らしい（詳しいことは知らん）

##何をすべきだったか
最終的にアイコンをダブルクリックしたら動く（jarファイル）ものを作れとのことらしい。

##JRubyでjarファイルを作る
https://dev.classmethod.jp/etc/jruby_warbler_ruby_source_create_jar/
とりあえず、この手順通りやればいけるはず。

やってみたところ、無事に行けた
【勉強メモ】deviseとscaffoldを組み合わせてプチSNSをつくる①【挫折しない！】

##今回したいこと
・CRUDを自動的につくってくれるscaffoldと、ログイン機能をつくってくれるdeviseの2つを合わせてプチSNSをつくる。
・ログインしたユーザーと投稿した文とを紐付けする。
・投稿した文をログインユーザーのみが編集できるようにする。

##１．scaffoldで骨格をつくる。
scaffoldはCRUDを自動的につくってくれるやつだからな。
便利なやつだからな。
タイトルをいれるtitleカラムと本文を入れるbodyをつくる。

```
$ rails g scaffold Post titile:string body:text
```

##２．deviseを追加する。
次に、ログイン機能を実装するためにdeviseを実装させる。


```gemfile.rb
#コメントアウトを外す
    gem 'therubyracer', platforms: :ruby
#追加する
    gem 'devise'
```

``gem 'therubyracer', platforms: :ruby``のコメントアウトを何故外すのかは分からなかった。調べたけど、難しくて理解できなかった。もう、ここは割り切って「そういうもんだ！」ってことにしておこう。

そして、保存をしてインストールコマンドを入力するやつ。

```
$ bundle install
$ rails g devise:install
```

##３．トップページでdeviseのログイン画面になるようにルーティングをいじる。

```config/routes.rb
root "posts#index"
```

よく見たら、ターミナルに使い方が書いてあるね。
<img width="786" alt="スクリーンショット 2017-10-15 14.25.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/205578/4a37ed80-9556-7d15-2a76-a945de98a9da.png">


##４．deviseにUserモデルをもたせる
今、deviseをインストールしたけど、まだテーブルが出来ていない。
そこでUserモデルを追加させる。

```
$ rails g devise User
```

そしてここで、いつものアレを入力してマイグレートする！！

```
$ rails db:migrate
```

##５．postsテーブルにuser_idカラムを追加する
###ここまでしたことは
・scaffoldでPostテーブルを作成した。
→Postテーブルはタイトルと本文の２つの投稿内容を記録するためのテーブル。
・deviseでUserテーブルを作成した。
→Userテーブルはユーザーを記録するテーブル。

###これからしたいこと
・どのUserがどの投稿(Post)したのかを紐付ける。
・投稿記事(Post)に投稿者(User)のidを紐付けさせたい。
・postsテーブルにuser_idカラムを追加させたい

###実際の実装

```
$ rails g migration add_user_id_to_posts user_id:integer
```

そして

```
$ rails db:migrate
```

##６．ログイン機能を表示させるためにviewに記録する。


```app/views/layouts/application.html.erb

    <%= csrf_meta_tags %>
    <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
    
      <% if user_signed_in? %>
      Logged in as <%= current_user.email %>
      <%= link_to "ログアウト", destroy_user_session_path, method: :delete %>
    <% else %>
      <%= link_to "新規登録", new_user_registration_path %> |
      <%= link_to "ログイン", new_user_session_path %>
    <% end %>
```
Userオブジェクトを扱うので、routesに記述する。

```config/routes.rb
resources :users
```

よく分からん。よく分からないけど、これを記述しておこう。

##７．サーバー起動後に確認

<img width="250" alt="スクリーンショット 2017-10-15 15.10.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/205578/cc6e984d-361e-dfef-e609-33b29e46eda0.png">

おぉ、新規登録とログインが実装されたscaffoldが現れた！！
実際に記述してみる。

<img width="424" alt="スクリーンショット 2017-10-15 15.14.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/205578/a56cca41-43cc-7859-ef6d-aa0646a2ff3a.png">

できた。ログイン機能＋投稿＆編集機能がついた。
だがしかし、これだと誰でも投稿を編集したりできてしまう状態。ログイン機能を実装する意味が皆無。

今度はログインしたユーザーの投稿が表示され、それをいじくれるシステムをつくらないといけない。

##過去のやつ
【勉強メモ】scaffoldを使う【挫折しない！】
https://qiita.com/takatoshi0905/items/208363abd07b849cf5f4
【勉強メモ】deviseを実装させる①【挫折しない！】
https://qiita.com/takatoshi0905/items/d39832df81f3c6550b42
【勉強メモ】deviseを実装させる②【挫折しない！】
https://qiita.com/takatoshi0905/items/dbb303900f79f1208585
【勉強メモ】deviseを実装させる③【挫折しない！】
https://qiita.com/takatoshi0905/items/6f7e73ada9307657d679
【勉強メモ】deviseを実装させる④【挫折しない！】
https://qiita.com/takatoshi0905/items/25e490eba35ce495739f
【勉強メモ】アソシエーションできるようにする！【挫折しない！】
https://qiita.com/takatoshi0905/items/1ffca5b4a5fad4b7e7a2