OmniAICreator/Qiita-1.07M huggingface dataset:
Macのタッチパッドの生データを取得する

# プロジェクトの準備
1. File -> New -> Project -> macOS -> Cocoa App でプロジェクトを作る
2. /System/Library/PrivateFrameworks/MultitouchSupport.framework を`Embedded Binaries`にCopy items if neededで追加する（同時に`Linked Frameworks and Libraries`に追加される）
3. [M5MultitouchSupport](https://github.com/mhuusko5/M5MultitouchSupport)をcloneしてビルドし，生成されたFrameworksをMultitouchSupport.frameworkと同様の手順でプロジェクトに追加する（podを使っても良い）
4. ~~TARGETS -> Capabilities -> App SandBox を`OFF`にする~~  
`~.entitlements`にKey`com.apple.security.temporary-exception.sbpl`を加えて，Valueに`(allow iokit-open)`を記入する

# コーディング（最低限）
```swift:ViewController.swift
import Cocoa
import M5MultitouchSupport

class ViewController: NSViewController {
    
    var manager: M5MultitouchManager! = nil
    var listener: M5MultitouchListener! = nil
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        manager = M5MultitouchManager.shared()
        listener = manager.addListener(callback: { [weak self] (event) in
            if let e = event, let touches = e.touches as NSArray as? [M5MultitouchTouch] {
                DispatchQueue.main.async {
                    self?.process(touches)
                }
            }
        })
    }
    
    override func viewWillDisappear() {
        super.viewWillDisappear()
        listener.listening = false
    }
    
    override var representedObject: Any? {
        didSet {
        }
    }
    
    func process(_ touches: [M5MultitouchTouch]) {
        var currentInfo: String = "["
        currentInfo += touches.map({ (touch) -> String in
            return String(format: "ID: %d, state: %@, Position(x, y) = (%0.4f, %0.4f), Velocity(x, y) = (%+0.4f, %+0.4f), Size: %0.4f, Axis(major, minor) = (%0.4f, %0.4f), Angle: %0.4f",
                          touch.identifier,
                          stateString(touch.state),
                          touch.posX,
                          touch.posY,
                          touch.velX,
                          touch.velY,
                          touch.size,
                          touch.majorAxis,
                          touch.minorAxis,
                          touch.angle)
        }).joined(separator: "\n ")
        currentInfo += "]"
        Swift.print(currentInfo)
    }
    
    func stateString(_ state: M5MultitouchTouchState) -> String {
        switch state {
        case .notTouching: return "notTouching"
        case .starting: return "starting"
        case .hovering: return "hovering"
        case .making: return "making"
        case .touching: return "touching"
        case .breaking: return "breaking"
        case .lingering: return "lingering"
        case .leaving: return "leaving"
        default: return "unknown"
        }
    }
    
}
```

## 取得できるデータ
11点までタッチ点を取得可能
また，タッチ点それぞれについて，
- ID
- 接触状態
- 絶対座標（範囲はタッチパッド領域の上下・左右それぞれに対して0~1)
- 移動速度
- 長径と短径（タッチ点を楕円とみなしている）
- 長軸の傾き
が取得可能

# サンプルプロジェクト（GitHub)
[TouchpadRawDataGetter](https://github.com/Kyome22/TouchpadRawDataGetter)
<img width="800" alt="touchpad_example.png" src="https://qiita-image-store.s3.amazonaws.com/0/67153/fdf88968-900b-6c99-9e81-64e26459064a.png">
ABC - 099- A&B&C

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

#A問題

 - 999回目が境目

```java
	private void solveA() {
		Scanner scanner = null;
		int numN = 0;

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

			if (numN > 999) {
				System.out.println("ABD");
			} else {
				System.out.println("ABC");
			}

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

```

#B問題

 - $(1+2+3+4+ ・・・+N)=N*(N+1) / 2$
 - 積雪量： $(B-A)=X$ として、$(1+2+3+4+ ・・・+X-1)$ となる

```java
	private void solveB() {
		Scanner scanner = null;
		int numA = 0;
		int numB = 0;

		try {
			scanner = new Scanner(System.in);
			numA = scanner.nextInt();
			numB = scanner.nextInt();

			int wk = numB - numA;

			int res = 0;
			for (int i = 1; i < wk; i++) {
				res += i;
			}

			System.out.println(res - numA);

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

#C問題：DPの勉強に良い

 - コードにコメントで記述している

|引き出す金額||1|2|3|4|5|6|7|8|9|10|11|12|-|N|
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|操作回数||1|2|3|4|5|1|2|3|1|2|3|2|-|X|

```java

	/**
	 * dp[0] = 0
	 * N = cash/yen
	 * dp[N] = 1 + dp[N-1]
	 *       = 1 + dp[N-6]
	 *       = 1 + dp[N-6^2]
	 *       = 1 + dp[N-6^3]
	 *
	 *       = 1 + dp[N-9^1]
	 */
	private void solveC() {

		try (Scanner scanner = new Scanner(System.in)) {

			int numN = scanner.nextInt();

			/*
			 * 1
			 * 6 , 6^2 , 6^3 , 6^4
			 * 9 , 9^2 , 9^3 , 9^4
			 * dp[N]
			 * dp[i] ----- dp[N-1]
			 * 1円を使うパターン
			 * dp[N]= 1 + dp[N-1]
			 *     　  = 1 + dp[N-6]
			 *       　= 1 + dp[N-6^2]
			 *       　= 1 + dp[N-6^3]
			 *
			 *　       = 1 + dp[N-9^1]
			 * 上記最小値
			 *
			 */

			/*
			 * N<=100000　なので、dp[N]は100000以上で取っておく
			 */
			int[] dp = new int[100010];

			/*
			 * dp[N]を求めていく。
			 * minを求めるので大きな値で初期化
			 */
			Arrays.fill(dp, 999999999);

			/*
			 * dpN円引き出すのに必要な操作回数
			 * 0-5は1円での操作
			 * 埋めておく
			 */
			dp[0] = 0;
			dp[1] = 1;
			dp[2] = 2;
			dp[3] = 3;
			dp[4] = 4;
			dp[5] = 5;
			/*
			 * 6円からN円までの操作回数最小
			 */
			for (int dpN = 6; dpN <= numN; dpN++) {

				/*
				 * 6べきのDP
				 */
				int power = 6;
				while (power <= dpN) {
					/*
					 * dpN円とdpN-power(6^?乗)円の比較
					 * dpN：初期値はINFで埋まっている
					 * dp[dpN - power] + 1とは、(dpN-power)円のときの"操作回数"に+1をしたのが今回の操作回数の予定という意味
					 */
					dp[dpN] = Math.min(dp[dpN], dp[dpN - power] + 1);
					power *= 6;
				}

				/*
				 * 9べきのDP
				 */
				power = 9;
				while (power <= dpN) {
					/*
					 * dpN円とdpN-power(9^?乗)円の比較
					 * dpN：初期値はINFまたは6^?での操作回数で埋まっている
					 * dp[dpN - power] + 1とは、(dpN-power)円のときの"操作回数"に+1をしたのが今回の操作回数の予定という意味
					 * 例：dpN=6の場合、現在の6円の操作回数と、(6-6^1)円の操作回数+1との比較
					 * なぜなら、6円とは0円+6^1円で表せるため、0円の時の操作回数に+1をすると6円の時の操作回数になる
					 *
					 */
					dp[dpN] = Math.min(dp[dpN], dp[dpN - power] + 1);
					power *= 9;
				}
			}

			System.out.println(dp[numN]);

		}

	}
```
[LaraDock]俺俺SSL化が楽すぎて感動した

# はじめに
LaraDockでLaravel開発した際に、HTTPS化したいと思ったら、想像以上に楽にできて感動したので共有します。

# 環境
Ubunts
PHP7
Docker version 18.09.2
Docker-compose version 1.17.1
Laravel Framework 5.8.10

# 前提条件
LaraDockのインストールは完了しているものとします。
インストール方法が分からない方は、別記事で確認をお願いします。

# 俺俺SSL化の設定
まずはlaradock環境へ移動して、nginxの設定ファイルを開きます。

```bash
$ cd laradock
$ vim nginx/sites/default.conf
```

ファイルを開いたら、以下のコメントを削除します。
事前に「For https」という枠が用意されており分かり易い！

```bash
# For https
listen 443 ssl default_server;
listen [::]:443 ssl default_server ipv6only=on;
ssl_certificate /etc/nginx/ssl/default.crt;
ssl_certificate_key /etc/nginx/ssl/default.key;
```

次に以下の箇所をコメントにします。
これでHTTPからの接続を塞ぎます。

```
#listen 80 default_server;
#listen [::]:80 default_server ipv6only=on;
```

ここまでできたらファイルを保存して、DockerをリビルドすればOKです。

```bash
$ docker-compose build --no-cache nginx
$ docker-compose up -d nginx
```

以上、これで俺俺SSL化の完了です！
とても簡単で感動ですね。

# 認証ファイルの作成ロジック

もう少し処理をみると、nginxのDockerファイルにこのような処理があります。

```bash
ADD ./startup.sh /opt/startup.sh
RUN sed -i 's/\r//g' /opt/startup.sh
CMD ["/bin/bash", "/opt/startup.sh"]
```

このstartup.shが何をしているのか見ると、こんな感じで俺俺SSLの認証ファイルを生成していい感じに配置してからnginxを起動していることが分かります。

```bash
#!/bin/bash

if [ ! -f /etc/nginx/ssl/default.crt ]; then
    openssl genrsa -out "/etc/nginx/ssl/default.key" 2048
    openssl req -new -key "/etc/nginx/ssl/default.key" -out "/etc/nginx/ssl/default.csr" -subj "/CN=default/O=default/C=UK"
    openssl x509 -req -days 365 -in "/etc/nginx/ssl/default.csr" -signkey "/etc/nginx/ssl/default.key" -out "/etc/nginx/ssl/default.crt"
fi

nginx
```

LaraDockはDocker-compose設計など、とても綺麗に書かれており勉強になります。
まだ利用実績は少ないようですが、今後利用者が増えると嬉しいです。
Laravel 5.8のStrやArrでphpstanが通らない

# TL;DR

_ide_helper.phpで多重宣言されてるので宣言を消すかエラーを無視しよう。

# 現象

``` php:index.php
<?php
require_once __DIR__ . '/vendor/autoload.php';

use Illuminate\Support\Str;

echo Str::random();
```

``` yaml:phpstan.neon
# 省略
```

``` sh
$ php artisan ide-helper:generate
A new helper file was written to _ide_helper.php
$ vendor/bin/phpstan analyze -l 1 index.php
Note: Using configuration file /var/www/html/phpstan.neon.
 1/1 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%

 ------ ---------------------------------------------------------------------- 
  Line   index.php                                                             
 ------ ---------------------------------------------------------------------- 
  6      Call to an undefined static method Illuminate\Support\Str::random().  
 ------ ---------------------------------------------------------------------- 

                                                                                                                        
 [ERROR] Found 1 error
```

:thinking: 

# 原因

_ide_helper.phpに空のStr/Arrヘルパークラスが書き出されていて、phpstanはこちらを参照しているっぽい。

``` php:_ide_helper.php
<?php
// ...
namespace Illuminate\Support {

    /**
     *
     *
     */
    class Arr {

    }

    /**
     *
     *
     */
    class Str {

    }

}
// ...
```

# Fix

- _ide_helper.phpの当該箇所を削除する。
- phpstanの設定で無視する。 [参考](https://qiita.com/ngmy/items/1a8ef21c76d74c1d4dfe#%E3%81%9D%E3%81%AE%E4%BB%96%E3%81%A9%E3%81%86%E3%81%97%E3%82%88%E3%81%86%E3%82%82%E3%81%AA%E3%81%84%E7%B3%BB%E3%81%AE%E3%82%A8%E3%83%A9%E3%83%BC%E3%81%AE%E5%AF%BE%E5%BF%9C)

CIを考えると後者かな…。ide-helper側で対応して欲しいところ。

# 参考URL

https://github.com/barryvdh/laravel-ide-helper/issues/784
ポートフォリオをGitHub で公開する

## ポートフォリオとは
ポートフォリオとは、いわゆる、**「クリエーターの履歴書」**です。クリエーター自身が、これまでに制作してきた作品をサイトを通じて紹介することで、同じクリエイターに自身の課題解決能力を示すためのものです。作るうえでは、「自己紹介」、「制作実績」、「連絡先」を掲載すればいいです。しかし、わざわざポートフォリオを公開するために、有料のレンタルサーバーを借りたりしたくないと考えている人もいます。そこで、この記事では, GitHubが無料で提供している**GitHub Pages** を利用してポートフォリオを作成していきたいと思います。

## GitHub の使い方
GitHub を初めて利用する人は、次のサイトを見ながら制作するといいです。
[GitHub 入門](https://qiita.com/ay3/items/8d758ebde41d256a32dc)

ここでは、公開するリポジトリ名は、"portfolio"とします。

GitHubで リポジトリ作成後、生成された

`https://github.com/[ユーザー名]/portfolio.git`

をコピーしてください。

次は、PC側 でのファイルを制作していきます。

```bash:
mkdir portfolio
cd portfolio
```
として、この ”portfolio” のファイルの中に、**index.html** を作成します。

HTML ファイルの中身は、以下の通りです。

```html:index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Example Portfolio</title>
</head>
<body>
    <h1>Hello GitHub.io !</h1>
</body>
</html>
```
作成後、コマンドライン上で、次のコマンドを打ちます。

```bash
git add .
git commit -m'FirstCommit'
git remote origin add https://github.com/[ユーザー名]/portfolio.git 
git push origin master
```
これにより、ファイルを portfolio リポジトリへ公開することができました。

## GitHub Pages で公開
いよいよ、ポートフォリオを公開していきたいと思います。このサイトのリポジトリへ移動し、Setting → GitHub Pages　で、Source の中を　master branch で選択します。下の写真のように、下線部分を選択してください。
![スクリーンショット (21).png](https://qiita-image-store.s3.amazonaws.com/0/271708/a561a59c-a02a-b69a-de16-62f0f4b959c9.png)

これにより、公開することができました。

`https://[ユーザー名].github.io/portfolio/` のURLで公開されているかどうか確認してください。
もし、エラーが発生した際は、`https://[ユーザー名].github.io/portfolio/index.html`のURLで公開されています。

成功していれば、次のように公開されています。
![スクリーンショット (24).png](https://qiita-image-store.s3.amazonaws.com/0/271708/5c50a458-3b5c-2dd1-ecbd-5fdd69a7fe72.png)


###　注意
- もし、リポジトリ内に、README.md が先にファイル内に存在したら、デフォルトのURLは**README.md**が優先されて公開されます。
- ポートフォリオを公開する際は、HTML.CSS,JavaScript を利用した方が各々の思い通りの記事を記述できると思います.
- 全く使ったことがない人でも、README.md を利用してMarkdown 形式で記述することもできます。 

## 最後に
以上で、GitHub.Pages を利用してポートフォリオを公開する手段を記述しました。GitHub Pages では、BootStrapだけでなく、Vue,JQuery も利用することができますが、Ruby on Rails や MySQL といったデータベースをGitHub Pages 内で公開することはできません。この場合、記事を公開したい場合は microCMS などの
外部APIを 利用して記事の管理を行ったり、Vue やReact ができるようになれば、[Gatsby.js](https://www.gatsbyjs.org/) や[Gridsome](https://gridsome.org/) といった静的サイトジェネレーターを利用してみるとよいでしょう。

以上の点を踏まえて、みなさんの思い描くポートフォリオを作成、公開していきましょう。


## 追記

現在、新しくポートフォリオを **Gridsome**というフレームワークで実装しました。詳しい内容についてもQiita にて公開していますので、興味ある人はこちらを参照してみてください。

https://qiita.com/0622okakyo/items/4e5d4a4d29e4cd2b1576
PlayFab データバックエンド機能強化！

PlayFab のデータバックエンドのシステム見直しして機能強化したよ！
という話
原文は[こちら](https://blog.playfab.com/blog/overhauling-the-playfab-data-backend)


### で、何を強化するの
そもそも今までS3へのログ送信やSnowflakeとの連携などの機能は提供していますが、AzureやAWSなど周りの機能が便利になってのでそれを有効活用する方向に転換
Azureに移行して機能強化を行うことで今後アップグレードを図っていきますよ
ということでどんな機能が実装されるかというご紹介

大きくは3つ

・データパイプライン
・データテナント
・分析とレポート

### データパイプライン
今までのPleyStreamは各イベントを個別に解析して処理していました。
ただリアルタイム分析時はそれも良いが、オフライン長期間解析を行う際には非効率的
そこでタグ付きのイベントはPlayStreamを回避させることでスループットを向上させることができる
またAzure Data Explorer と連携することでデータ分析をさらに効率化させることができます

### データテナント
今まではEvent HistoryページとPlayersページの両方から、プレーヤープロファイル内の列と過去30日間のイベントデータ間でクエリを実行できました。
さらに分析する場合にはSnowflakeを利用できましたが、単一インデックスでデータが流れ込んでいたのでクエリパフォーマンスがよろしくなかったでした。
今後はAzure Data Explorer に独自テーブルでデータが流れるため、クエリのパフォーマンスが向上します
PlayFab上で管理されたゲームスタジオはまとめて入れられるので相関分析もできるようになります。

### 分析とレポート
今までは読み込みを早くするためにいろいろやっていたり、cardinalityの上限に当たったりしていたが、バックエンドをAzure DataExplorerにしたことでこれらの懸念もなくなり、イベント履歴やプレイヤー検索などKQL言語を使ってリアルタイムに検索することができるようになりました。


これらはMicrosoftに買収されたことにより得られたメリットだとのこと
今後も進化してほしいですな
Qiitaの脚注は任意の文字列で指定できる。

# この記事よりもっといい記事があります。
現在では[脚注の書き方について公式からもっと詳しい記事](https://qiita.com/phigasui/items/010f4c79ff47bbaaebdd)が公開されていますので、そちらを読むことをお勧めします。[^あるある]


# 概要
* 完全に自分用記事です QiitaというよりMarkdownの仕様のはなしかも。
* Qiitaの記事に脚注を入れるとき、`[^1]`のように数字じゃなくても`[^foot-note]`のような文字列で指定できた。
* 他の記事でも出てるんですが
    * Markdownの他の記法と一緒に書いてあるので、辿り着きにくかった。
    * 単純に「Qiita 脚注」でぐぐった際のトップに出てくる「[この記事](https://blog.qiita.com/105484781374-2/)」だと数字の例しかないので気づけなかった。[^search-top]

## 脚注に対する勘違いと混乱
もう概要で書いちゃいましたね。
Qiitaで使うMarkdownにおいて、脚注を入れる際にこんなサンプルがよく見られます。

```: 脚注を入れたい
脚注についてのサンプルです。[^1]
記事中に余談を書くのは邪魔だから脚注で補足入れたい。時ありますよね。[^2]
[^1]: サンプルなので適当な文です
[^2]: 脚注が多い文章も困りものですが
```
しかし、この`\[^1]`と`\[^1]:`のような連番による注釈は記事をアップデートする際の管理が大変です。間に文章を差し込んだときにそこに入れる脚注の番号はどうすればいいでしょうか？こんな風にだんだん混乱して来ます。

```: 文を追加したいけど脚注どうしよう
脚注についてのサンプルです。[^1]
あとから文を差し込みたい時もありますよね。[^3]
記事中に余談を書くのは邪魔だから脚注で補足入れたい。時ありますよね。[^2]
[^1]: サンプルなので適当な文です
[^2]: 脚注が多い文章も困りものですが
[^3]: 差し込んだ脚注です
```

上のように書いても**表示上は数字に関係なく出現順に1、2、3の連番で並びます。** 見た目は不自然なく見えるんですが、管理はつらい。[^renban]
しかしこの脚注、実はこんな風に書けます。
```: 脚注に名前を付けて管理する
脚注についてのサンプルです。[^sample]
あとから文を差し込みたい時もありますよね。[^sashikomi]
記事中に余談を書くのは邪魔だから脚注を入れたい。時ありますよね。[^arimasu]
[^sample]: サンプルなので適当な文です
[^sashikomi]: 差し込んだ脚注です
[^arimasu]: 脚注が多い文章も困りものですが
```

このほうが解りやすくなりますね。この方法で積極的に使っていきたいです。
この記事でも使っているので、この記事のMarkdownも参考にしてもらえればと思います。
## それでも忘れちゃいけない大事なこと
**あまり長い記事を書かない。**
いわゆるTL;DRですが、読まれないだけじゃなくて記事をメンテしていくのも大変です。

[^search-top]: 現在はちゃんと記事あります。
[^renban]: 最低限、脚注の本体は出現順に並べた方が楽だと思います。
[^あるある]: 今となってはこの記事は意味がないんですが、それでも時々読まれているようなので、公式に誘導しつつ記事自体は残しておきます。
PHP Markdownを使ってMarkdownをHTMLに変換するバッチを作ってみた

環境はWindows10。

**PHP Markdown**
GitHub：https://github.com/michelf/php-markdown
Packagist：https://packagist.org/packages/michelf/php-markdown

# インストール

```
C:\xampp\htdocs\markdown>composer require michelf/php-markdown
Using version ^1.8 for michelf/php-markdown
./composer.json has been created
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
  - Installing michelf/php-markdown (1.8.0): Downloading (100%)
Writing lock file
Generating autoload files
```

# テスト実行

適当なMarkdownをHTMLに変換してみます。

```index.php
<?php
require_once __DIR__ . '/vendor/autoload.php';

use Michelf\Markdown;

$markdown = <<< EOF
# 見出し h1
## 見出し h2
### 見出し h3
#### 見出し h4
##### 見出し h5
###### 見出し h6

- リスト
- リスト
    - リスト

1. 番号付きリスト
2. 番号付きリスト
    1. 番号付きリスト

**text**

*text*

~~text~~

`code`

> text
>> text

[title](http://...)

---

EOF;

$html = Markdown::defaultTransform($markdown);
?>

<html>
<head>
	<link href="https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/3.0.1/github-markdown.min.css" rel="stylesheet">
</head>
<body>
	<div class="markdown-body">
		<?= $html ?>
	</div>
</body>
</html>
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/96507/ed300dde-7310-299c-ea49-b8e1cc72c26b.png)

CSSはGitHubのMarkdown CSSをCDN使って読み込んでいます。
効かない構文もあるけど、ちゃんと変換することができました。

# 変換バッチファイルを作成する

Markdownファイルを渡すとHTMLファイルに変換してくれるバッチファイルを作ってみます。

```md2html.bat
@echo off
cd /d %~dp0

set PhpCommand="C:\xampp\php\php-win.exe -f"
set MarkdownFile=%1
set HtmlFile=%2
if "%HtmlFile%" equ "" (
	set HtmlFile=%MarkdownFile%.html
)

%PhpPath% md2html.php %MarkdownFile% %HtmlFile%

set ReturnCd=%ERRORLEVEL%
exit /b %ReturnCd%
```

```php:md2html.php
<?php
require_once __DIR__ . '/vendor/autoload.php';

use Michelf\Markdown;

$markdownFile   = $argv[1];
$htmlFile       = $argv[2];

$markdown = file_get_contents($markdownFile);

$html = Markdown::defaultTransform($markdown);

$html = <<< EOF
<html>
<head>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/3.0.1/github-markdown.min.css" rel="stylesheet">
</head>
<body>
    <div class="markdown-body">
        ${html}
    </div>
</body>
</html>
EOF;

file_put_contents($htmlFile, $html);
```

`>md2html.bat test.md test.html`

こんな感じでMarkdownファイルを読み込ませるとHTMLファイルを作ってくれます。
遊戯王のカードゲームでオブジェクト指向を考える

#オブジェクト指向についてメモ
こんにちは。[未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)でインターンをしている梅原です。
つい最近、オブジェクト指向を学んだので、アウトプットします。

オブジェクトは命令を受けるものです（shiracamusさんありがとうございます、コメント欄参照）

それだけ聞いても、なにもわからないので、今回は

「もしも遊戯王のカードゲームをオブジェクト指向言語で書くとどうなるだろう」

という思考実験的なコンセプトで書きました。

###オブジェクト指向を構成する二つの要素(属性とメソッド)

モンスターカードの「ゴブリン突撃部隊」について考える。
ゴブリン突撃部隊に書かれている情報は
地属性
戦士族
ATP(攻撃力)=2300
DEF(守備力)=0
モンスター効果=「攻撃したら守備表示になり、次のターンまで攻撃表示にできない」
などである。


〇属性
上で上げたものはオブジェクト指向ではプロパティなどと呼ぶ。
ではこの情報を与えれば、ゲームをプログラムできるだろうか？


いや出来ないはずだ。
モンスターカードは召喚したり、攻撃したりせねばならぬではないか！



〇メソッド
そう、オブジェクト指向を構成する二つ目の要素はこのようなメソッドである。
「攻撃すると、攻撃表示のモンスターでは攻撃力の低いモンスターが破壊され。。。。。」
といった、メソッドが必要なのだ。

###なぜ、オブジェクト指向なのか
では、仮想の遊戯王ゲームをプログラムしていくことを想像してみよう。
いま、オブジェクト指向で遊戯王カードを記述するイメージはできただろう。
では、「ゴブリン突撃部隊」を書いて作り、「ブラックマジシャン」を作り、「死者蘇生」を作り、、、、、。一体いつこのゲームは完成するのだろう。
2017年の時点で、遊戯王カードの種類は8000種類を超えている。
え、無理じゃね？？？

安心してください。オブジェクト指向の利点を生かせば、そんな苦労をしないで済むのです！

###クラスを使う
そもそも、先ほどの例では何が問題なのだろう。
答えは同じ内容を何回も書いているからだ。
モンスターカードは召喚、攻撃するのだからその処理をカードごとに何回も書くのは非効率だ。
だから、モンスターカードクラスを考える。
このクラスは攻撃、召喚、攻撃力、守備力など、共通のものをまとめたものである。
このクラスに対して、個々のモンスターカードはインスタンスと呼ばれる。

車というクラスがあって、ポルシェというインスタンスが存在するという関係と同じだ。

「ゴブリン突撃部隊」はモンスターカードクラスのインスタンスとして作ればよい。
「ブラックマジシャン」はモンスターカードクラスのインスタンスとして作ればよい。
「ブルーアイズホワイトドラゴン」はモンスターカードクラスのインスタンスとして作ればよい。
攻撃力や守備力などを入力するだけで、カードのコードが作れる。

###継承とは
よし、これで作業が楽になった。めでたし、めでたし。。。。
そう、あなたは思ったかもしれない。
ところが、上司に「仕様変更でシンクロを追加するから、実装よろしく」と言われてしまった。
シンクロモンスターは普通のモンスターと違って、デッキ外から召喚するし、手続きも異なる。つまり、シンクロモンスターはモンスターカードクラスに属していながら、モンスターカードクラスにないプロパティやメソッドを持っている。

そんな、また、シンクロモンスタークラスを一から作らなければいけないのか。。。。。

安心してくれ、オブジェクト指向の「継承」を使えば一瞬だ。

親クラスがモンスターカードクラス。
子クラスがシンクロモンスターカードクラス。
という状況を考える。
ここで、継承を使えばモンスターカードクラスが持っている機能をシンクロモンスターカードクラスに引き継いで、残りの部分の機能だけ、追加すればいいのだ。

遊戯王には様々な神をモチーフにしたカードが存在するが、「オブジェクト指向」と名のついた、カードがあってもいいのではないか。
オブジェクト指向　Is 神

#最後に
実は、プログラミングも、遊戯王も初心者なので、いろいろ間違えていることもあるかもしれません。その時はご指摘ください。
この記事が、誰かの理解の助けになれば幸いです。

###参考
https://eng-entrance.com/what-oop
https://qiita.com/hirokidaichi/items/591ad96ab12938878fe1
Power9 CPUのUsers Manualを読んでいく(3)

ということで今日もPOWER9 CPUのUsers Manualを読んでいきます。

私事ですが、最近スタンディングデスク買いました。集中力とカロリー消費が増すようです。

ちなみに文面はコピペすると

>Upto24processorcores

なぜかこうなっちゃうので手打ちしてます。タイポしてるかもしれないので見つけたら言ってください。

Users Manualは以下からダウンロードできます。

https://openpowerfoundation.org/?resource_lib=power9-processor-users-manual

>20-deep primary and 96-deep secondary history buffer per slice

sliceって何なんだろうなとは思います。前も出てきたよな。ヒストリバッファって何？deepって何？ということでスルーしておきます。

>Core paire share
> 32KB per core(not shared) instruction cache(I-cache)

コアごとに32KBの（共有されてない）命令キャッシュ
命令キャッシュとは、CPUが実行するべき命令を一時的に保存するところのようです。

（https://kotobank.jp/word/%E5%91%BD%E4%BB%A4%E3%82%AD%E3%83%A3%E3%83%83%E3%82%B7%E3%83%A5-643282）

>32KB per core(not shared) data cache(D-cache)

コアごとに32KBの（共有されていない）データキャッシュ
データキャッシュとは、CPUの直接的な処理対象であるデータを保存するところのようです。
共有されていないとはどういうことなのかよくわからないですね。

>512KB private L2 cache

512KBのprivateなL2(レベル２）キャッシュ。

>10MB eDRAM L3 cache

eDRAMに関しては以下のサイトに詳しいです。プロセッサと同じダイまたはパッケージに統合された、キャパシタベースのDRAMのようですね。　

https://ja.wikipedia.org/wiki/EDRAM

> DDR4 memory controllers

DDRはDouble Data Rateの略で、規格の一つのようです。メモリコントローラについて記述してますね。

>Eight DDR4 ports, 1.2V, two DIMMs per port

８個の、DDR4ポート、１．２Vとは、電源が1.2Vのものを使えという意味かな？
DIMMとは、Dual Inline Memory Moduleの事のようです。
ポートごとに、２個のDIMMがあるようです。

> Support x4,x8,4 - 16Gb,R/LR,3D devices

うーむ、何がどう3Dデバイスなのかよくわからないです。3Dレンダリングに使うビデオボードとは関係ないですよね。

>DDR4 support: maximum 2667MHz, one DIMM per channel

DDR4という規格をサポート、チャンネルごとに一つのDIMM、2667MHzって何を指しているのかよくわからないです。

> DDR4 support: maximum 2400Mhz, two DIMM per channel

もう一つ上のと矛盾する気はします。何が2667MHzで、何が2400HMzなのか、何がチャンネルごとの一つのDIMMで、何がチャンネルごとに二つのDIMMなのかがよくわからないです。
うーん、もしかして、チャンネルごとに一つのDIMMだった場合は、2667MHzで駆動できて、チャンネルごとに二つのDIMMだった場合は、2400MHzで駆動できるという意味かな？2667MHz、2400MHzは、CPUのクロック数かもしれません。

> High-throughput atomic memory operations

スループットの高いアトミックなメモリー操作。アトミックってことは、「分割できない」という意味なのかなと思います。

>133+ GBps streaming bandwidth at 2667MHz

2667MHzのクロック数の場合は、133+GBpsのストリーミング帯域のようです。流れが連続した場合の帯域のことかな？

>128-byte line with 64-byte sectoring

128バイトのラインに、64バイトのセクタリング。メモリーコントローラについて触れられているところなので、メモリのフォーマットのことを言ってると思います。

>POWER9 SMP on-chip interconnect

SMPとは、Symmetric Multiprocessingのこと、複数のCPUに処理を分割することができる。SMPでは、複数のCPUでメモリを共有できるみたいですね。
on-chip interconnectってことは、チップ間の相互接続のようです。オンチップなので、チップ内の相互接続のようです。

> 1600-2400MHz frequency

1600MHzから2400MHzの周波数ということですね。CPUのクロック数のことを指しているようです。

>Eight 32-byte data buses

なぜ８がEightになっているかというと、こっちまでアラビア数字にすると、8 32-byte data busesになってしまうからのようです。参考になりますね。日本語だったら、「８個の３２バイトのデータバス」という表現ができます。
データバスとは、コンピュータ内部のデジタル信号の伝送路のようです。

>Four address snoop buses

バスすヌーピングという技術があるようですね。

>12 or 24 core ramps

core rampsって何だろう。ちょっと調べてもわからないですね。rampというものが存在するようです。

>Fifteen nest ramps

これもよくわからないですね。

>POWER9 SMP off-chip interconnect

SMPとは、前述の通り、Symmetric Multiprocessingのこと、チップ外部の相互接続について触れてます。

> Two 30-bit + 2 spare electrical X buses at 16 GHz

データの伝送経路の説明をしているようです。

> Maximum two socket SMP

最大二つのソケットのSMP、ソケット二つまでSMPはサポートしているのかな？

ということで、また次回
【Kaggle日記】 2019/04/09

# 概要

文系大学3年生が  
2019年度内までにKaggle Masterになる  
過程において、
その日学んだことをアウトプットしていきます。
間違いやご指摘などが御座いましたらご教示願います！

## バックグラウンド

春から文系の大学3年生です。
プログラミング・機械学習経験ゼロの状態から去年の夏頃fast.aiをきっかけに機械学習に触れ始めました。
ここ3ヶ月ほど、Kaggleに挑戦しようと試みたのですが、毎度のことhigh-scoring-kernelを模写して終わることが続きました。。。
そもそも、kernel模写してても分からないことだらけで手も足も出ず。。。
このままではマズイと思い、
一念発起して【Kaggle日記】始めます！

## モデル別得意領域

### 線形モデル

ex) Logistic Regression, SVM

それぞれの損失関数を用いて、線形の区域分けにより、グループ別に分類する

得意領域 高次元の過疎(sparse)なデータ
不得意領域 比較的簡易的な手法であるため、限界が存在する

### 樹木モデル

ex) GBDT, Random Forest

「木構造の条件分岐で分類・予測(回帰)を行う」

得意領域 精度が高く、目的変数が多くても作動する
不得意領域 条件分岐のため、線形的なの特徴を見い出すのが不正確な場合がある

### kNNモデル

ex) k-Nearest-Neighbors

近い距離ごとにグルーブ別に分類する

得意領域 シンプルな手法であるにも関わらず有用な情報が包容されている事が多い
不得意領域 意味的な(semantic)情報を抽出することができない

### ニューラルネットワークモデル

ex) 深層学習

人間のニューロンを模倣した数理モデル

得意領域 「情報空間内における予測や識別」
不得意領域 未知の情報に対する予測や識別

## 参考・引用文献

- [Coursera How to Win a Data Science Competition: Learn from Top Kagglers](https://www.coursera.org/learn/competitive-data-science)
- [「樹木モデルとランダムフォレスト－機械学習による分類・予測－」－データマイニングセミナー様のスライド](https://www.slideshare.net/hamadakoichi/tree-basedmodelsandrandomforests)
- [Random Forests explained intuitively](https://www.datasciencecentral.com/profiles/blogs/random-forests-explained-intuitively)
- [Gradient Boosting explained [demonstration]](http://arogozhnikov.github.io/2016/06/24/gradient_boosting_explained.html)
- [Introduction to k-Nearest Neighbors: Simplified (with implementation in Python)](https://www.analyticsvidhya.com/blog/2018/03/introduction-k-neighbours-algorithm-clustering/)
- [ディープラーニングの得意なこと、不得意なこと](https://cpoint-lab.co.jp/article/201804/2133/)

## 最後に

改めてこうしてMLの手法を学び直してみると再発見が多かったです。

1. スクラッチから手法を書けるようにする
2. LightGBMやXGBoost のソースコードのぞいてみる
3. Highest Scoring Kernel を何としてでも一度超える。。。

最後に  
間違いやご指摘などが御座いましたらご教示願います！
qiita 記事 投稿 書き方 初心者 まとめ

#はじめに:
Qiitaは、プログラミングのアウトプットをするのにも最適です。
そこで、記事投稿の書き方について初心者でもわかりやすいようにまとめました。
#目次:
1.見出しをつける
2.コードを挿入する
3.URLの挿入/画像の挿入
4.引用
5.リスト
6.Markdownの無効化
##■1.見出し
文頭に#をつけることで簡単に見出しができます。
\#の数で見出しのサイズも簡単にできます
HTMLでいうと\<h1>〜\<h6>ですね。

>\#見出しh1
>\##見出しh2
>\###見出しh3
>\####見出しh4
>\#####見出しh5

#見出しh1
##見出しh2
###見出しh3
####見出しh4
#####見出しh5
##■2.コードを挿入する
こちらもコードの記事を投稿する上では、使用頻度が多いと思います。
\```バッククォート3つでコードを囲むと簡単に挿入することができます。
MacならPの右となりのキーをshiftを押しながら。
※ちなみにシングルクォーテーションではありません。

```
<h1>ハローワールド</h1>
<p>こんにちは</p>
```

####シンタックスハイライトをつける
また、\```のすぐあとに言語名を入れるとシンタックスハイライトもつけることができます。

```php4
<h1>ハローワールド</h1>
<p>こんにちは</p>
```
今回は、\```php4　としています。

####ファイル名を挿入する
\```のあとに：ファイル名とします。

```:index.html
<h1>ハローワールド</h1>
```
今回は、\```:index.html　としているので上記のようになりました。

##■3.URLの挿入/画像の挿入
####URLの挿入
```
リンクの挿入は、[リンクテキスト](URL)と書きます。
例えば、、、
ここは[zozotown](https://zozo.jp/)に移動します。
```

ここは[zozotown](https://zozo.jp/)に移動します。
####画像の挿入
```
![代替テキスト](画像URL)
例えば、、、
![zozo](https://o.imgz.jp/shop/common/shop_1982/top_0s.jpg)
```
![zozo](https://o.imgz.jp/shop/common/shop_1982/top_0s.jpg)
##■4.引用
文頭に>をつければ簡単にできます。
こちらも見出しと同じように複数つけるだけで入れ子のうようにもできます。

\>引用１
\>>引用２
\>>>引用３
\>>>>引用4

>引用１
>>引用２
>>>引用３
>>>>引用4

##■5.リスト
文頭に「*」「+」「-」のいずれかを入れる。
文字との間に半角スペースを入れることを忘れずに。

* リスト1
* リスト2

##■6.Markdownの無効化
 \\ をMarkdownしたくない文字の前に書くことで無効化できます。

#最後に:
プログラミングをはじめた頃は、「覚えられない」「頭に入らない」等のお悩みをお持ちの方も多いと思いますが、スポーツと同じでとにかく打ち込むこととアウトプットが重要になってきます。
Qiitaで、どんどんアウトプットして身につけていきましょう！
Googleフォームをサイトに埋め込み、自動返信メールを送信する(2)

[Googleフォームの埋め込みとカスタマイズまではこちら](https://qiita.com/shiromegumi/items/8981b4bb7bcb3edd6e60)

##Googleフォームから自動返信メールを送信する
自動返信させるのは、Googleフォームの回答が保存されるスプレッドシートにスクリプトを書く方法とGoogleフォームにスクリプトを書く方法がありますが、ここではGoogleフォームに書く方を記します。

###自動返信のスクリプトを書く
1. Googleフォームの編集画面、右上のメニューから「スクリプトエディタ」を選択し、スクリプトエディタを開きます
2. スクリプトエディタに以下のように記述します。
 
```auto_reply.gs
function onFormSubmit(e) {
  var itemResponses = e.response.getItemResponses();
  var fullname = itemResponses[0].getResponse(); //申込者の氏名を取得
  var email = itemResponses[1].getResponse(); //申込者のメールアドレスを取得

  var subject = 'お菓子パーティーへの申込みが完了しました。';
  var body = fullname+'様\nお菓子パーティーへようこそ！\n下記の内容で申込みを受付けました。\n\n';

  for (var i = 0; i < itemResponses.length; i++) {
    var item = itemResponses[i];
    body += '【' + item.getItem().getTitle() + '】\n'
    body += item.getResponse() + '\n\n'
  }
    
  GmailApp.sendEmail(email, subject, body);

}
```
申込者の氏名、メールアドレスの取得は作成したGoogleフォームでの順番で指定していますので、フォーム毎に変える必要があります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/135373/80905b70-c800-3f99-84a7-fb711a1c6bff.png)

###トリガーを作成する
保存ボタン（フロッピーディスクみたいな）をクリックして保存後、トリガーボタン（時計みたいな）をクリックします。G Suite Developer Hubというページが開くので、「新しいトリガーを作成します」をクリック。追加の設定を行い、保存します。
- - -
実行する関数：先程書いたスクリプトのfunction名
実行するデプロイを選択:Head
イベントのソースを選択:フォームから
イベントの種類を選択:フォーム送信時
![image.png](https://qiita-image-store.s3.amazonaws.com/0/135373/e3c5b616-bde6-6d2b-6460-a152f3c86cc0.png)

###アクセスリクエストを許可する
Googleにログインを促すウインドウが開くので使用するアカウントを選択、その後アクセスリクエストを許可します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/135373/e833b260-db15-7764-e0e1-fb63462753eb.png)
許可後、先程のトリガー作成画面に戻るとトリガーが作成されていることを確認できます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/135373/297cbdf9-efd2-021a-c2e6-e58c4cf29100.png)

##自動返信のテストをする
自サイトに設置したフォームでテスト送信を行います。
フォームに入力したメールアドレスにメールが届いていれば成功。GmailApp.sendEmailのbodyにfromやnameを指定して差出人を変更することも可能。（認証が必要）

##今後の課題
今回は申込者の氏名・メールアドレスの取得に配列の番号で直接指定してしまっているので、汎用性...
他の方法で取得可能かを試したい。
DIフレームワーク Zenject と Spring を比べてみた

# DIフレームワーク Zenject と Spring を比べてみた

最近、Unity のDIフレームワーク **Zenject** に触れる機会がありました。過去に業務で、Java の DIフレームワーク **Spring** (厳密にはWeb開発向けの **Spring Boot** )を利用したことがあるので、その比較をしてみたいと思います。



DIとは何か？については、過去にこんな記事を書いたので、興味があればご覧ください。
[肥満な物語でDIを解説する](https://qiita.com/segur/items/14d1e6c712363afebfba)



# フィールドインジェクション

クラスのフィールドに注入の設定を記載することをフィールドインジェクションと呼びます。Zenjectでは `[Inject]` 、Spring では `@Autowired` を使います。記述方法がかなり似ていますね。

```C#:Unity&nbsp;Zenject
public class Sample
{
    [Inject]
    private Foo _foo;
    [Inject]
    private Bar _bar;
}
```

```java:Java&nbsp;Spring&nbsp;Boot
@Component
public class Sample {
    @Autowired
    private Foo _foo;
    @Autowired
    private Bar _bar;
}
```



# コンストラクタインジェクション

コンストラクタインジェクションについては、特に違いはありませんでした。

```C#:Unity&nbsp;Zenject
public class Sample
{
    private Foo _foo;
    private Bar _bar;
    
    public Sample(Foo foo, Bar bar)
    {
    	_foo = foo;
    	_bar = bar;
    }
}
```

```java:Java&nbsp;Spring&nbsp;Boot
public class Sample {
    private Foo _foo;
    private Bar _bar;
    
    public Sample(Foo foo, Bar bar) {
    	_foo = foo;
    	_bar = bar;
    }
}
```

Spring界隈では、フィールドインジェクションはなるべく使わずに、コンストラクタインジェクションを積極的に利用しよう！という声が多い気がしますが、Zenject界隈では特にそういう声はきかない気がします。



# シングルトン

インスタンスをコンテナに対して１つだけ作ることを、Springではシングルトンと呼びます。
Zenjectでは `AsSingle()` というメソッドがあります。

```C#:Unity&nbsp;Zenject
public class HogeInstaller : MonoInstaller
{
    public override void InstallBindings()
    {
        Container.Bind<Sample>().AsSingle();
    }
}
```

Springでは、 `@Scope("singleton")` というアノテーションを利用します。

```java:Java&nbsp;Spring&nbsp;Boot
@Configuration
public class AppConfig {
    @Bean
    @Scope("singleton")
    public Sample sample(){
        return new Sample();
    }
}
```

ただ、Springの場合、デフォルトでシングルトンなので、実は、 `@Scope("singleton")` は省略可能です。



# トランシェント / プロトタイプ

インスタンスを再利用せずに、注入要求があるたびに、別々のインスタンスを生成することを、Springではプロトタイプと呼び、Zenjectではトランシェントと呼ぶようです。

Zenjectでは `AsTransient()` を利用します。

```C#:Unity&nbsp;Zenject
public class HogeInstaller : MonoInstaller
{
    public override void InstallBindings()
    {
        Container.Bind<Sample>().AsTransient();
    }
}
```

Springでは、 `@Scope("prototype")` を利用します。

```java:Java&nbsp;Spring&nbsp;Boot
@Configuration
public class AppConfig {
    @Bean
    @Scope("prototype")
    public Sample sample(){
        return new Sample();
    }
}
```





# さいごに

C#とJavaが似ているからかもしれませんが、Zenject と Spring はかなり似ているなぁと思いました。
SpringはWebバックエンド開発、Zenjectはゲームシステム開発と、利用シーンが全然違いますが、そのどちらでも利用されるDIというアーキテクチャは本当にすごいなぁと改めて思いました。
Windows 10 + Burp Suite で Android 8.0 のアプリの通信を取得する方法

## 概要

Webアプリケーション脆弱性診断するときに困ったので、備忘録としてまとめました。

- Android 8.0 で動くアプリについて、 Windows 10 Pro + Burp Suite Pro で HTTPS 通信を取得する方法です。
- Mac をお使いの方は適宜読み替えてください。
- 対象の Android 端末の root 化が必要なのと、システムディレクトリ触るので注意が必要です。
- ご利用される際は自己責任でお願いします。

## 環境

- Nexus 5X(Android 8.0)
  - root 化済み
- Windows 10 Pro バージョン1803 (OSビルド 17134.407)
- OpenSSL Win64 v1.1.1b
- Android Debug Bridge version 1.0.40 Version 4986621
- Burp Suite Pro 1.7.37
  - Communityエディションでもいけると思いますが未検証…


## 通信のイメージ

Android <--無線LAN--> Win10(Burp:8080) <--無線LAN--> サーバー

## 前提

Burpの設定をしておきます。
Android端末の通信をプロキシできるようにします。

- Win10 を 無線LANに接続します。
  - 無線LANの接続方式をプライベートネットワークにしておきます。
    - 信頼できないネットワークでやらないようにしてください。
- 対象の Android 端末も Win10 と同じ無線LANに接続します。
  - 接続する際、Proxyを設定します。手動設定でWin10のIPアドレスと8080ポートを指定します。
- Burp を起動して、 `Proxy > Options > Proxy Listeners` と進み、デフォルトの8080ポートの設定を選択してEditします。
  - Proxy設定を変更していきます。
    - `Binding > Binding to address:` のラジオボタンで `All interfaces` にチェックをいれます。
      - 信頼できないネットワークでやらないようにしてください。
    - `Request handling > Invisible proxy support allows non-proxy-aware clients to connect directory to the listner > Support invisible proxying (enable only if needed)` にチェックをいれます。
  - 設定後 OK し、 Proxy 設定を反映させます。

これだけだと、https接続時に証明書エラーがおきるので、次のステップで証明書エラーが起きないようにします。

## 証明書の設定手順

- Burp Suite の `Proxy > Options > Proxy Listeners` の `Import/export CA certificate` をクリックします。
- `Export > Certificate in DER format` にチェックを入れて `Next` をクリックします。
- 任意のローカルフォルダを設定して、任意のファイル名で保存します。
  - 例） `c:\hoge.der`
- PowerShellなどを用いて、OpenSSLを使って、保存した hoge.der をpem形式に変換します。

```
PS C:\> openssl x509 -inform DER -in hoge.der -out hoge.pem
```

- 作成したpemファイルの `subject_hash_old` の1行目の値を取ります（下記だと9a5ba575）

```
PS C:\> openssl x509 -inform PEM -subject_hash_old -in hoge.pem
9a5ba575
-----BEGIN CERTIFICATE-----
～略～
-----END CERTIFICATE-----
```

- hoge.pem のファイル名を変更します。（hash + 拡張子が0）
  - 例）9a5ba575 の場合は 9a5ba575.0 にファイル名を変更

```
PS C:\> ren hoge.pem 9a5ba575.0
```

- adb を使って、Android端末に作成したファイルを保存します。

```
PS C:\> adb push 9a5ba575.0 /sdcard/
```

- adb shell を使ってAndroid端末を操作します。

```
PS C:\> adb shell 
```

- su を叩いて superuser になります。
  - もし Android 端末側で確認ダイアログが出たら許可します。

```
$ su
```

- 端末に保存した証明書ファイルをシステムにマウントします。

```
# mount -o rw,remount /system
# mv /sdcard/9a5ba575.0 /system/etc/security/cacerts/
# chmod 644 /system/etc/security/cacerts/9a5ba575.0
```

- 端末を再起動します。
- 再起動後、端末の設定内のセキュリティ項目で、「信頼できる認証情報」を確認して、 `PortSwigger CA` が設定されていることを確認します。

結果、 Burp Suite で通信が取れようになっていると思います。

## 参考サイト

[WindowsにOpenSSLをインストールして証明書を取り扱う（基本編）：Tech TIPS - ＠IT](https://www.atmarkit.co.jp/ait/articles/1601/29/news043.html)
[Configuring Burp Suite with Android Nougat](https://blog.ropnop.com/configuring-burp-suite-with-android-nougat/)
[AndroidのプレインストールされたCAにCAを追加する - 試運転ブログ](http://otameshi61.hatenablog.com/entry/2017/12/03/151706)
GLSurfaceViewメモ

#### GLSurfaceViewのサイズ変更
`LayoutParams`でサイズ指定して`GLSurfaceView.setLayoutParams()`で設定

```.java
public class MainActivity extends Activity {

    private GLSurfaceView mGLView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mGLView = new GLSurfaceView(this);
        ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(800,400);
        mGLView.setLayoutParams(params);
        setContentView(mGLView);
        
        ...
```


#### GLSurfaceViewの保存
`GLSurfaceView.Renderer`の継承クラスに新しくメソッドを作り、その中で別スレッド立てて行う

```.java
int pixels[] = new int[width * height];
IntBuffer buffer = IntBuffer.wrap(pixels);
buffer.position(0);

GLES20.glReadPixels(0, 0, width, height, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, buffer);

Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
bitmap.copyPixelsFromBuffer(buffer);

try {
    FileOutputStream fos = null;
    fos = new FileOutputStream(new File(DOWNLOAD + "/tmp.png"));
    bmp.compress(Bitmap.CompressFormat.PNG, 100, fos);
    fos.close();
    Log.d("Plug-in", "save: " + DOWNLOAD + "/tmp.png");
}catch (IOException ex) {
    Log.d("Plug-in", ex.toString());
}
```
Drone.io の plugins/docker で BuildKit を使う

Drone.io では [plugins/docker](http://plugins.drone.io/drone-plugins/drone-docker/) という CI の中で `docker build`, `docker push` を行ってくれる便利なプラグインがある。 

その plugins/docker で少し前に docker 18.09 が使えるようになっている。
https://github.com/drone-plugins/drone-docker/pull/227

PR の[コメント](https://github.com/drone-plugins/drone-docker/pull/227#issuecomment-477140599)にもあるとおり、`plugins/docker:latest`, `plugins/docker:18.09.0`, `plugins/docker:18.09`, `plugins/docker:18` のタグ指定すると docker 18.09 が使えるようになり、
environment で `DOCKER_BUILDKIT=1` を設定すると BuildKit を使った build ができるようになる。

http://plugins.drone.io/drone-plugins/drone-docker/#multi-stage-builds

```diff:.drone.yml(v0.8)
  build:
-   image: plugins/docker
+   image: plugins/docker:18.09
    repo: foo/bar
    tags: latest
+   target: production
+   environment:
+     - DOCKER_BUILDKIT=1
```
```diff:.drone.yml(v1.0)
kind: pipeline
name: default

steps:
 - name: build
-  image: plugins/docker
+  image: plugins/docker:18.09
+  environment:
+    DOCKER_BUILDKIT: 1
   settings:  
     repo: foo/bar
     tags: latest
+    target: production
```

すると、BuidKit が有効な状態で plugins/docker による build が行える :tada:

```
#1 [internal] load build definition from Dockerfile
#1       digest: sha256:174a08959d51507beac0d4f95d94024c127621ba7133f8eb737642389d05a66f
#1         name: "[internal] load build definition from Dockerfile"
#1      started: 2019-04-08 08:04:01.317228142 +0000 UTC
#1 transferring dockerfile: 2.16kB 0.2s done
#1    completed: 2019-04-08 08:04:01.72257637 +0000 UTC
#1     duration: 405.348228ms
```
新米エンジニアは「事実と解釈を見極めろ」

#■はじめに
とあるセミナーで「事実と解釈」というテーマを扱っていました。

その考え方がとてもためになったので、`事実とはなにか？`また`解釈とは何か？`を見極めることが物事の整理の手助けとなるよ、ということを伝えらればと思います。
余談ですが、エンジニアになりましたーという人の中にも「今研修中」という人や、「OJTで実業務やってまーす」という人もいると思います。
おそらくOJTが多いとは思いますが、業務が忙しいよーという人がこの記事を読んでる人の中にはいると思います。

上長から「これお願いね」と言われてよくわからん状況になって不安しかない人。
先輩の教え方が下手。
何をすればいいの？

いろいろ感じると思います。
そんな方はもしかしたら現在の状況整理ができていない可能性があります。

#■事実と解釈とは？
事実とは`実際に起こったこと`です。
当たり前ではありますが、事実とはそれ以上でもそれ以外のことでもありません。
プログラミングを例に挙げてみます。

例）`コードを追記したら、システムが止まってしまいとてもあせっている。`

上記の文章の「`コードを追記したら、システムが止まってしまい`」だけが**事実**にあたります。
では「`とてもあせっている。`」は何か？
これは事実ではなくその人の**解釈**になります。
では解釈とは何か？
解釈とは`事実をもとに意味を、受け手の側から理解すること`です。
要するに「事実を受け、どう感じた」ということが解釈に当たります。

#■おわりに
以上のことから、事実と解釈とはなにか？がわかってもらえたと思います。
人間なので、解釈に翻弄されがちですが、解釈はあくまで事実を受けてのリアクション、反応です。
そのため、いったん落ち着いて「事実はなんだ？」に注目してみると、問題解決がスムーズにいくと思います。

初めてはわからないことばかりです。
わからないことは質問をする。
質問を遠慮なくしていく。
でないと、わからないことだらけという問題がたまってしまいます。
一人でできないことは事実をうまくみつけて、先輩にその事実を伝えて問題解決を手伝ってもらうようにしましょう。

それでは、良いエンジニアライフを！
GitHub PagesのDNS設定でトラブった件

[cress-cc.github.io](https://cress-cc.github.io/) に独自ドメイン [cress.cc](https://cress.cc/) でアクセスできるように設定しようとしたところ、CNAMEの使い方を勘違いしていて壮大にトラブったのでご報告。

| タイプ | ホスト名 | コンテンツ           |
|:-----:|:-------:|:-------------------:|
| CNAME | @       | cress-cc.github.io. |

Aレコードだけでなく、MXレコードも cress-cc.github.io の設定で上書きされます。具体的に何が起きるかというと、メールが届かなくなります。ホスト名なし（@）のCNAMEレコードが非推奨とされるのはそういう理由。

もちろん正解はこちら。

| タイプ | ホスト名 | コンテンツ       |
|:-----:|:-------:|:---------------:|
| A     | @       | 185.199.108.153 |
| A     | @       | 185.199.109.153 |
| A     | @       | 185.199.110.153 |
| A     | @       | 185.199.111.153 |

IPアドレスは [GitHubのヘルプ](https://help.github.com/en/articles/setting-up-an-apex-domain) に載っています。
nginx-link-functionモジュールをC言語以外でも利用可能な説を検証！

[nginx-link-function](https://github.com/Taymindis/nginx-link-function)は、nginxの設定ファイルに共有ライブラリのパスと関数名を設定しておくと、
設定に応じて関数をコールしてくれる素敵なnginxのモジュールです。

C/C++でできるなら、Rustでもできんじゃね？と思ったので試してみました。

# RustとC/C++

1. crate-typeをdylibに設定すると、.soファイルを作成することが可能
2. [bindgen](https://github.com/rust-lang/rust-bindgen)を利用すると、ヘッダーファイルからRustのコードを生成できる。  
（生成されるコードはちょっと辛い・・・）
3. unsafeを使うとポインタが使える

上記の理由から、RustはC/C++との連携をしやすい言語かなと思っています。

# Docker

nginxとnginx-link-functionはREADME.mdの通り。
Rustはrustupを入れて、インストールしました。

```
$ git clone https://github.com/akatsuki-chan/nginx-rust-function.git
$ cd nginx-rust-function
$ docker build  -t nginx-link-function .
$ docker run --rm -p 8888:8888 -ti nginx-link-function
$ curl http://127.0.0.1:8888/testCFunGreeting
```

# まとめ

Rustとbindgenを使って、nginx-link-functionを利用することができました。

他にも共有メモリ機能や.soファイルのダウンロード（？）機能なんかあるらしいので、
ベンチマークとったりDBに接続したり遊んでみようかと思います。
iOSデバイスだけでYouTube動画をKeynoteに貼り込む方法（無料で）

# 問題設定
iOSデバイス（iPhoneやiPadなど）だけでYouTube動画をKeynoteに貼り込みたい．

# 動機

プレゼンテーション中にYouTube動画を紹介したいが，プレゼン中はネットに繋がっていない，アプリを切り替えるのが格好悪い，トリミングしたいなどの理由から，動画をローカルに持っておきたい．

# 用意するもの
* ウェブブラウザ
* Keynoteアプリ
* [Documentsアプリ](https://itunes.apple.com/jp/app/documents-by-readdle/id364901807?mt=8) (Readle)
* YouTubeアプリ (Google) ←無くても良い

# YouTube動画をKeynoteに貼り込む手順

## 貼り込みたい動画のURLを取得する

ウェブブラウザでもYouTubeアプリでも良いので，貼り込みたい動画を見つけてURLを取得する．

![IMG_0004.PNG](https://qiita-image-store.s3.amazonaws.com/0/15782/f5abd493-1bd7-69dd-44aa-c5715d70a472.png)

## 動画を再エンコードする

YouTube動画はそのままではダウンロードできないので，[VideoGrabber.net](videograbber.net) を使って再エンコードする．

![IMG_0005.PNG](https://qiita-image-store.s3.amazonaws.com/0/15782/3f272a28-a074-5d18-f6d1-e93f47efa3a5.png)

![IMG_0006.PNG](https://qiita-image-store.s3.amazonaws.com/0/15782/6cd4f58c-fbfe-a7ff-ba49-0b8e7242baae.png)

## 動画をローカルストレージにダウンロードする

iOS上のウェブブラウザからは動画を直接ファイルシステムに保存できないので，Documentsを使って保存する．

![IMG_0007.PNG](https://qiita-image-store.s3.amazonaws.com/0/15782/e1181f47-ad0a-264d-3db9-908d04f73e58.png)

![IMG_0009.PNG](https://qiita-image-store.s3.amazonaws.com/0/15782/b748e613-6cd7-87d0-bb10-ffe328056299.png)

![IMG_0008.PNG](https://qiita-image-store.s3.amazonaws.com/0/15782/377743a9-4595-d99f-f858-15b869f22e32.png)

## 動画をKeynoteから見える場所に移動させる

Documentsが管理するフォルダはKeynoteから見えないので，動画をカメラロールかiCloudドライブに移動させる．

![IMG_0010.PNG](https://qiita-image-store.s3.amazonaws.com/0/15782/59be983f-640b-3384-4720-230eacf586f9.png)

## Keynoteで動画を貼り付ける

Keynoteで動画を貼り付ける

![IMG_0011.PNG](https://qiita-image-store.s3.amazonaws.com/0/15782/1548e19e-14b5-07d9-1d50-ebae06fb0057.png)

（完了）
devise備忘録

:hand_splayed_tone2:初学者です。

#deviseの使い方の備忘録です。
よくdeviseを使うので、備忘録として書き留める事にしました。
一連の流れざっくりまとめてみます。


```ruby
gem 'devise'
```

```ターミナル
$ bundle install
$ rails g devise:install
```

##Userモデルの作成

```
$ rails g devise user
```
●新規作成されるファイル
・app/models/user.rb
・db/migrate/2014XXXXXXXXXX_devise_create_users.rb
・test/fixtures/users.yml
・test/models/user_test.rb

```
$ rails db:migrate
 #作成されたマイグレーションファイルの実行
```

##devise用のビューファイルの作成

```
$ rails g devise:views
 #ここでいつもviewsのsをつけ忘れます、、、
```
●新規作成されるファイル
app/views/devise以下のディレクトリにあるビューファイル


##カラムの追加

deviseのテーブルを作成した際に、基本的にemailカラムとpasswordカラム等しか作成されず、Nicknameを追加したい場合は

```
$ rails g migration AddNicnameToUsers nicname:string
```

上記で作成したマイグレーションファイルに下記追加


```ruby

class AddNameToUsers < ActiveRecord::Migration[5.2]
  def change
    add_column :users, :name, :string,    null: false,unique: true,index:true
  end
end
```
からの

```
$ rake db:migrate
```


また、deviseを用いると、初期状態ではサインアップ時にメールアドレスとパスワードのみ受け取るようにストロングパラメーターが設定してあるので、追加したパラメーターを許可するにはapplication_controllerにて

```ruby

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

 private
   def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
   end
end

```

##sign_upのviewを作成

```ruby
<div class="field">
        <%= f.label :nickname %> <em>(6 characters maximum)</em><br />
        <%= f.text_field :nickname, autofocus: true, maxlength: "6" %>
      </div>
```


これで、DBにニックネームも保存できるか試したら保存できていました！

間違っていたらコメントお願いします！！
マインドマップについてマインドマップでまとめてみた

## 1. はじめに

みなさんはマインドマップを活用していますでしょうか？
マインドマップは、21世紀のノート術と言われており、脳を整理する際にとても役に立ちます。
「学習」「仕事」「家庭」「人付き合い」等、幅広い用途で使われています。
マインドマップについて、マインドマップでまとめてみました。

※とりあえず自分にとって重要だなと思った点をまとめましたので、マインドマップについての情報を網羅しているわけではありません。予めご了承ください。

## 2. マインドマップのマインドマップ
![download.png](https://qiita-image-store.s3.amazonaws.com/0/247638/552fcd1b-4dd0-1510-8614-ea9e1b1003fe.png)

## 3. 参考
- [**マインドマップ超入門**](https://www.amazon.co.jp/マインドマップ超入門-トニー・ブザン天才養成講座-トニー・ブザン/dp/4887596766/)
【Jupyter Notebook】GUIで削除したファイルを復元する

JupyterではGUIで削除したファイルは復元不可能と以前どこかで見たことがあったのですが、実はOSのゴミ箱に行っている模様。
私はここにファイルが溜まってディスク容量を圧迫してました。

![スクリーンショット 2019-04-09 11.54.04.png](https://qiita-image-store.s3.amazonaws.com/0/262969/4b0348ab-0a3f-6047-2a6d-aebb8e5ef481.png)


以下、自分用メモも兼ねて。

## 環境
CentOS 7.6

## 削除先フォルダ（私の場合）
**/home/USER/.local/share/Trash/files** フォルダ内に削除したファイルがあるはず。
自身の環境でファイルが見当たらない場合は
```$ find ~ -name "Trash"```
で検索も出来るみたいです。

いつか、ディスク容量がいっぱいになったときにやることリストまとめたい。
数学・機械学習ビジュアルラーニングまとめ

## 目で数学を理解したい

※随時更新中。良サイトを知っていたらコメントで教えてください。
調べたら、[ここ](https://github.com/stared/interactive-machine-learning-list
)にまとめてあった

###[- Distill](https://distill.pub/)
機械学習に関する難しい概念をインタラクティブに説明する次世代のアカデミックプラットフォーム。
![Peek 2019-04-09 11-21.gif](https://qiita-image-store.s3.amazonaws.com/0/295666/4ac9531b-1ef6-c40e-a068-b8ad53095866.gif)

###[- 3Blue1Brown](https://www.youtube.com/channel/UCYO_jab_esuFRV4b17AJtAw)
見たら「数学はこれで学びたかった」と誰も思うはず。
![Peek 2019-04-09 11-24.gif](https://qiita-image-store.s3.amazonaws.com/0/295666/fb18c287-daae-0b92-ede1-a78bb7b927f9.gif)

###[- Physics Videos by Eugene Khutoryansky](https://www.youtube.com/channel/UCJ0yBou72Lz9fqeMXh9mkog)
オーバーに可視化しているところもありますが、イメージがつかめる
![Peek 2019-04-09 11-35.gif](https://qiita-image-store.s3.amazonaws.com/0/295666/055e18ea-cf9a-81bd-78bf-ed14b9f57c07.gif)

###[- An Interactive Introduction to Fourier Transforms](http://www.jezzamon.com/fourier/)
フーリエ変換をインタラクティブに説明。
![Peek 2019-04-09 11-46.gif](https://qiita-image-store.s3.amazonaws.com/0/295666/4df5609f-2d38-172f-585f-a63859e2c6a3.gif)

###[- A VISUAL INTRODUCTION TO MACHINE LEARNING](http://www.r2d3.us/)
スクロールとともにスムーズに可視化が進んでいく。
![Peek 2019-04-09 11-50.gif](https://qiita-image-store.s3.amazonaws.com/0/295666/f6723a1d-a32b-ec50-d661-5c9f30f8aca9.gif)


###[- A Neural Network Playgroud](https://playground.tensorflow.org)
ブラウザの中でニューラルネットワークを使った学習が体験できる。
![Peek 2019-04-09 11-56.gif](https://qiita-image-store.s3.amazonaws.com/0/295666/f7b2249c-e478-6c8f-6f14-03d89571af30.gif)

###[- Experiments with Google](https://experiments.withgoogle.com/collection/ai)
ウェブカメラのデータを使った識別を含めた、Googleの教育用おもしろ実験まとめサイト。
![Peek 2019-04-09 12-01.gif](https://qiita-image-store.s3.amazonaws.com/0/295666/ca192469-d1a3-f107-7d89-f0fd9ab84864.gif)

###[- Explained Visually](http://setosa.io/ev/)
線形回帰からマルコフ連鎖までをカバー。
![Peek 2019-04-09 12-09.gif](https://qiita-image-store.s3.amazonaws.com/0/295666/f708910a-2c46-ed5e-a31b-9a2035adb1ce.gif)

###[- GAN Lab](https://poloclub.github.io/ganlab/)
![Peek 2019-04-09 12-11.gif](https://qiita-image-store.s3.amazonaws.com/0/295666/88cf1714-8c87-32bb-d8e2-d7bd10ffc23f.gif)

###[- From Cells to Systems](https://spaciecat.github.io/cells/)
![Peek 2019-04-09 12-12.gif](https://qiita-image-store.s3.amazonaws.com/0/295666/df3af250-9c7a-9e9a-55fc-eb17eb7aa2d7.gif)
プライベート・リポジトリからのプロジェクト・インポート

Looker 6.8のリリースにおいて、プライベート・リポジトリに対してリモート・プロジェクト・インポートが可能になりました。以前のリリースにおいて、他のリポジトリにあるLookMLプロジェクトをインポートする機能はありましたが、今回のリリースにおいてプライベート・リポジトリに対応したことにより、企業内で「ハブ・アンド・スポーク」アーキテクチャによるLookMLの開発が可能になります。
こちらの[Importing Files from Other Projects](https://docs.looker.com/ja/data-modeling/learning-lookml/importing-projects)にて記載のインポート内容に、プライベート・リポジトリのインポート方法を追記したものになります。
##企業向けプロジェクトのインポート：「ハブ・アンド・スポーク」アーキテクチャ##
ご利用組織が大きくなってくると、開発チームがすべての部門のデータニーズを管理できなくなり、ある程度の委任が必要となってきます。各部署が管理できるようにプロジェクトを分割と同時に、一貫性を維持していく必要があります。
この場合、プロジェクトのインポートを使用して、一元化された、統制のとれたビジネスロジックを各部門のプロジェクトに展開できます。これを「ハブ・アンド・スポーク」アーキテクチャと呼びます。
ハブ・アンド・スポークアーキテクチャでは、データチームがコアプロジェクト（「ハブ」）を管理し、各部門が独自のプロジェクト（「スポーク」）を管理します。ハブにはユニバーサルビジネスロジックが含まれていますが、スポークにはドメイン固有のロジックが含まれています。プジェクトのインポートによってこのアーキテクチャが実現できます。
##設定手順##
このモデルで開発をするためには、以下が必要になります。
1. Git上でのハブおよびスポークそれぞれのリポジトリ
2. Lookerでインポート機能の有効化
3. ハブ側プロジェクトでのマニュフェストファイルの作成
4. インポート・リポジトリに対しての認証設定
5. リモートリポジトリのファイル参照
###Git上でのハブおよびスポークそれぞれのリポジトリ###
Lookerの開発でご利用いただいているGitリポジトリがあると思いますので、分割対象となるプロジェクトそれぞれでリポジトリを用意してください。
###インポート機能の有効化###
この機能は、現在ベータ版として提供されています。管理者パネルからLabsセクションを開いて頂き、Project ImportのトグルをONにしてください。
![Screen Shot 2019-04-09 at 10.19.48.png](https://qiita-image-store.s3.amazonaws.com/0/394509/0f2e470e-3962-506c-7cab-d7d4602ab929.png)
###ハブ側プロジェクトでのマニュフェストファイルの作成###
インポートをするプロジェクトで、マニュフェストファイルを追加します。
![Screen Shot 2019-04-09 at 10.28.39.png](https://qiita-image-store.s3.amazonaws.com/0/394509/15d061fe-1be4-fd5a-8fb4-a412daed9c13.png)
以下のようにコードを追加します。*バージョンを指定する必要があります*

```LookML:manifest.lkml
project_name:"プロジェクト名"

remote_dependency: 参照名 {
  url:"user@path.to.repository.git"
  ref:"参照するバージョンのSHAキー"
}
```

###インポート・リポジトリに対しての認証設定###
上記のマニフェストファイルを追加すると、プロジェクト設定画面において、以下のように**Import Credentials**というタブが表示されます。
![project_settings.png](https://qiita-image-store.s3.amazonaws.com/0/394509/f7cb6a11-1e74-0f20-69e3-7f9bed0211ae.png)
次に、Editアイコンをクリックすると以下のようにデプロイキーが表示されますので、コピーしてインポート元のGitリポジトリに追加します。（インポート元のプロジェクトを変更する必要が無いと思いますので、write_accessは不要です）
![deployKey.png](https://qiita-image-store.s3.amazonaws.com/0/394509/45655ab6-e8c6-01dc-4e79-8adfa0d04005.png)
デプロイキーの設定が完了後にLookerのプロジェクト設定画面に戻り、**Test**ボタンをクリックすると正常にファイルをインポートできるかを確認できます。
![Screen Shot 2019-04-09 at 10.47.47.png](https://qiita-image-store.s3.amazonaws.com/0/394509/1b5980f6-0c38-fb9c-57d4-2280edc13f6e.png)
###リモートリポジトリのファイル参照###
インポートの設定が完了したら、以下のようにViewを拡張したり

```LookML:extended_order.view.lkml
include: "//sample1/order_items.view.lkml"
view: extended_order {
  extends: [order_items]
  dimension: tax {
    type: number
    sql: ${sale_price} * 0.08 ;;
  }
  measure: total_tax {
    type: number
    sql: ${total_revenue} * 0.08 ;;
  }
  measure: total_revenue_with_tax {
    type: number
    sql: ${total_revenue} + ${total_tax} ;;
  }
}
```
modelを拡張することが可能です。

```
include: "*.view.lkml"                       # include all views in this project
include: "//sample1/*.view.lkml"
include: "//sample1/*.model.lkml"

explore: extended_order {
}
```

いかがでしたでしょうか。弊社では、[Looker Blocks](https://looker.com/platform/blocks/directory)という、分析パターンやデータソースがわかっている場合には、そのままお使いいただけるLookMLコードをご提供しておりますので、上記方法で参照していただくことも可能です。