OmniAICreator/Qiita-1.07M huggingface dataset:
#python の #正規表現 のあの r でパターンを囲ってるやつ‥あいつ‥なんだよ‥ふざけるなよ‥答えは？ ( raw string 記法 )

主にバックスラッシュ対策のようだ。もっと特別なことをしているのかと思っていたぜ。

[Pythonでの正規表現の使い方 - Qiita](https://qiita.com/wanwanland/items/ce272419dde2f95cdabc)

>それから、パターンの最初にrを付けることをを勧めします、付けなくても基本的には大丈夫ですが、付けることによって文字列中のバックスラッシュ文字をそのままバックスラッシュとして扱えるので、パターンの書き方が分かりやすくなります。

[re — Regular expression operations — Python 3.7.3 documentation](https://docs.python.org/3/library/re.html)

>Regular expressions use the backslash character ('\') to indicate special forms or to allow special characters to be used without invoking their special meaning. This collides with Python’s usage of the same character for the same purpose in string literals; for example, to match a literal backslash, one might have to write '\\\\' as the pattern string, because the regular expression must be \\, and each backslash must be expressed as \\ inside a regular Python string literal.

>The solution is to use Python’s raw string notation for regular expression patterns; backslashes are not handled in any special way in a string literal prefixed with 'r'. So r"\n" is a two-character string containing '\' and 'n', while "\n" is a one-character string containing a newline. Usually patterns will be expressed in Python code using this raw string notation.


# e.g

```py
>>> re.search('\\\\',  "A\\B\\C")[0]
'\\'
>>> re.search(r'\\',  "A\\B\\C")[0]
'\\'
```

# raw string とは

![image](https://user-images.githubusercontent.com/13635059/56463755-23400600-6415-11e9-94a3-46a0fc5733eb.png)


# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/1366








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
テスト駆動マークアップのすゝめ

## はじめに
本記事は、Heydon Pickering（ヘイドン・ピカリング）によって提唱された開発手法であるテスト駆動マークアップの解説と運用のベストプラクティスを紹介します。今回のサンプルコードは [GitHub](https://github.com/toshifumiimanishi/Test-Driven-Markup) で公開しています。

- 2019/12/29 追記
  - 新しいモジュールシステムの [`meta.load-css()`](https://sass-lang.com/documentation/modules/meta#load-css) を利用したテスト駆動マークアップ用スタイルシートの読み込み方法を変更しました。

## テスト駆動マークアップとは
プログラムのテストは、機能の実装後に書くのが一般的です。逆にプログラムを実装する前にテストを書く手法が **テスト駆動開発（Test Driven Development; TDD）** です。CSS にテスト駆動開発を適用すれば、HTML マークアップの構造の正しさをテストできます。

### CSS のロジック
CSS のセレクタは、HTML の構造にマッチさせるための条件式です。たとえば、disabled 属性がない button 要素に対してスタイルを当てる場合、以下のように書きます。

```css
button:not(:disabled) {
  /* disabled 属性がない button 要素にあたるスタイル */
}
```

通常、CSS は HTML の要素をどのように修飾するかを指示するために宣言を書きます。しかし、誤ったパターンを対象にエラースタイルを適用して問題を可視化ができます。

```css:test.css
img:not([alt]) {
  outline: 5px solid red;
}
```

あとは、その要素がどのような問題があるのかをエラーメッセージで伝わるようにすればよいのです。

### ERROR プロパティ
問題のある要素にエラーメッセージを通知するには ERROR プロパティを使います。ご存知の通り、CSS には **ERROR プロパティはありません。**無効な CSS プロパティは無視されます。

```css:test.css
img:not([alt]) {
  outline: 5px solid red;
  ERROR: img 要素には、alt 属性が必須です。;
}
```

このエラーメッセージは、各ブラウザの開発ツールで確認できます。Chrome の開発ツールでエラーメッセージを確認した場合、以下のように警告マークをつけてくれます。

<img width="" alt="Screen Shot 2019-04-21 at 17.43.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88525/8092bd16-5d7a-41f7-f9c7-b767078ace35.png">

## 運用のベストプラクティス
テスト駆動マークアップは、gulp + Sass の運用で開発モードにテスト駆動マークアップの制御を行えます。Node.js の環境変数を Sass の変数に渡すには [gulp-sass-variables](https://www.npmjs.com/package/gulp-sass-variables) を使います。gulp のバージョンは最新版の 4.0 になります。（2019/04/21 現在）

```js:gulpfile.js
const gulp = require('gulp');
const sassVariables = require('gulp-sass-variables');
const sass = require('gulp-sass');
sass.compiler = require('sass');
process.env.NODE_ENV = process.env.NODE_ENV || 'development';

function styles() {
  return gulp.src('src/sass/**/*.scss')
    .pipe(sassVariables({
      $mode: process.env.NODE_ENV
    }))
    .pipe(sass())
    .pipe(gulp.dest('dist/'));
}

exports.styles = styles;
```

また、package.json に環境変数を渡す npm-scripts を登録します。

```js:package.json
  "scripts": {
    "dev": "NODE_ENV=development gulp styles",
    "build": "NODE_ENV=production gulp styles"
  }
```

Sass の組み込みモジュールの [`meta.load-css()`](https://sass-lang.com/documentation/modules/meta#load-css) で動的にテスト駆動マークアップ用スタイルシートを読み込ませましょう。

```scss:main.scss
@use "sass:meta";

:root {
  @if $mode == "development" {
    @include meta.load-css("test");
  }
}
```

これで Node.js の環境変数が development の場合、テスト駆動マークアップ用スタイルシートの読み込みが行われます。

## さいごに
テスト駆動マークアップは、HTML マークアップの構造の正しさだけでなく、アイデア次第でプロジェクトの規約に沿ったソースコードを担保できます。たとえば、YouTube 動画の埋め込みで関連動画を同じチャンネル内に制御するようなケースがあります。

```css
iframe[src^="https://www.youtube.com/embed/"]:not([src*="rel=0"]) {
  outline: 5px solid red;
  ERROR: YouTube の関連動画を同じチャンネル内に制御されてまいせん。;
}
```

まずは、テスト駆動マークアップの活用事例として [REVENGE.CSS](https://github.com/Heydon/REVENGE.CSS) をヒントに作成してみましょう！

## 参考文献
インクルーシブHTML+CSS & JavaScript 多様なユーザーニーズに応えるフロントエンドデザインパターン
https://amazon.jp/dp/4862463878/
俺的順列の生成

# 問題

```javascript
const combine = [1, 2, 4, 5, 6];
const define = {
  1: [1],
  2: [2],
  3: [3],
  4: [1, 2, 4],
  5: [5],
  6: [0, 6]
}
```

このデータから

```javacript
[
  [1, 2, 1, 5, 0],
  [1, 2, 2, 5, 0],
  [1, 2, 4, 5, 0],
  [1, 2, 1, 5, 6],
  [1, 2, 2, 5, 6],
  [1, 2, 4, 5, 6]
]
```

この配列を生成する(順不問)

## ルール

### combine は define の key を AND で接続するという意味の配列

### define は 自身の番号を OR で 接続するという意味の配列

### 簡単な例1

```javascript
const combine = [1, 2];
const define = {
  1: [1],
  2: [2]
}
```

このデータなら

```javacript
[
  [1, 2]
]
```

### 簡単な例2

```javascript
const combine = [1, 2];
const define = {
  1: [1],
  2: [2, 3]
}
```

このデータなら

```javacript
[
  [1, 2],
  [1, 3]
]
```

# 俺的順列の生成

```javascript

const combine = [1, 2, 4, 5, 6];
const define = {
  1: [1],
  2: [2],
  3: [3],
  4: [1, 2, 4],
  5: [5],
  6: [0, 6]
}

let result = new Array([]);

for (let i = 0; i < combine.length; i++) {
  let defNo = combine[i];
  if (!(defNo in define)) continue; //なければ飛ばす
  let def = define[defNo];
  let defKeys = Object.keys(def);
  // defineNo が複数あった場合に配列を複製する
  if (defKeys.length > 1) {
    let count: number = result.length;
    for (let i = 0; i < count; i++) {
      let base = result[i];
      for (let j = 1; j < defKeys.length; j++) {
        result.push(base.slice(0, base.length));
      }
    }
  }
  // 組み合わせにケース番号を登録する
  let j: number = 0;
  for (let i = 0; i < result.length; i++) {
    let caseNo: string = def[defKeys[j]];
    result[i].push(caseNo);
    j++;
    if (j == defKeys.length) j = 0;
  }
}

console.log(result);
```

いろいろ 気に入らない

特にここ

```javascript
  let j: number = 0;
  for (let i = 0; i < result.length; i++) {
    let caseNo: string = def[defKeys[j]];
    result[i].push(caseNo);
    j++;
    if (j == defKeys.length) j = 0;
  }
```

j をつかった defKeys[j] は 
`0 6 0 6 0 6 0 6` というふうに defineの数列を 繰り返してほしいのだが、もっとうまい方法があると思う

# メモ

とりあえずこれで実装した

メモ代わりに ここに残した
WordPressかんたん移行でエラーが出た時の対処方法

Conoha のレンタルサーバーの「かんたん移行」でエラーが出た時の対処方法です。

移行元のデータベースのテーブルに 100Mb 以上のものがあると失敗します。

エラーメッセージ

```text
予期せぬエラー
```

又は

```text
テーブル容量・行数エラー（エラーが発生したTable: wpa1234dposts）
```

対応の手順

１）ごく小さい WordPress のサイトを移行してみます。
　　インストールした直後の投稿数が数個のものを VPS に構築して確認すると良いです。
　　これは、「かんたん移行」の操作手順に間違いがないことを確認する為です。

２）phpMyAdmin で　移行元のテーブルのサイズを調べます。
　　テーブルのサイズでソートすればすぐに分かります。
　　100 MB を越えるものがあれば、それを削除するか、小さくする必要があります。

３）移行元の　WordPress にログインして、使ってない、または不要の Plugin を停止して削除します。
　この時、関連するテーブルも削除されます。
> WordPress Popular Posts という Plugin はかなり大きいテーブルを作成します。

４）再び、phpMyAdmin でテーブルのサイズを確認します。
　　これで、100MB　以下になっていれば、また移行作業をします。

５）なっていない時は、テーブルの縮小を行います。
さくらのレンタルサーバーは、ftp のアカウントで ssh 接続が
できるので、私は、ssh で接続して、縮小しました。
ssh で接続すると、次のようになります。

```text
FreeBSD 9.1-RELEASE-p24 (SAKURA17) #0: Thu Feb  5 10:03:29 JST 2015

Welcome to FreeBSD!
```

ここで、mysql コマンドを使います。
対象のテーブルを wpa1234dposts とします。

5-1) テーブルのバックアップ
縮小するテーブルをバックアップします。

```bash
mysqldump -hmysql123.db.sakura.ne.jp -uabc123 -psecret123 database123 wpa1234dposts > wpa1234dposts
```

5-2) テーブルの縮小
縮小する為の SQL

```sql:delete.sql 
select count(*) from wpa1234dposts;
delete from wpa1234dposts where post_date < '2018-01-01';
select count(*) from wpa1234dposts;
quit
```

SQL の実行

```bash
mysql -hmysql123.db.sakura.ne.jp -uabc123 -psecret123 database123 < delete.sql
```

６）再び、phpMyAdmin でテーブルのサイズを確認します。
　100 MB  以下ならば、移行、以上ならばもっと縮小します。
Pythonのエラー対処法

#対処法
1. 一番下を見る
2. 行を見る
3. 対処

##コード
- ImportError: No module named
 - もしかしたらpip内にあるからインストールしましょう． バージョンに注意 
- IndexError: list index out of range
 - 存在しないから， どこかで誤作動起こしてるかも. 
- TypeError: takes exactly (x) arguments ((?) given) (x=必要な引数の数 ?=与えた引数の数)
 - 引数が足りない.
- NameError: name '-' is not defined
 - 関数内だったら global - などをやって見るのもいいかも. [globalの使い方](https://www.sejuku.net/blog/58897)
- ValueError: invalid literal for int() with base 10
 - 変数でやってるなら中身が文字かも. プログラムの流れをよく見てみよう
- SyntaxError: invalid syntax
 - しっかり文を見てみよう
- AttributeError: --- instance has no attribute
 - クラスの中に， その関数はないよと言っている． 
- AttributeError: class --- has no attribute '---'
 - 上のエラーとほぼ同じ
- IndentationError: expected an indented block
 - スペースとタブの併用は無理. OK?
- TypeError: can only concatenate list (not "int") to list
 - str+int, list+str などをやってないか?
- KeyError
　- IndexErrorと同じように存在しないやつ

## 公式ドキュメント
https://docs.python.org/ja/3/library/exceptions.html
synergyで入力デバイスを共有する

`synergy`は一つのキーボード・マウスで複数のPCを操作できるソフトウェアです。
サーバを中心として各クライアントの画面を上下左右のいずれかに配置し、ポインティングデバイスが存在しているPCへのキーボード入力を可能にします。


# サーバ

キーボードとマウスを操作するPC。
設定ファイルでSynergy全体の設定を行う。
クライアントの画面の位置を指定する。

起動コマンドは`synergys [--config CONFIG_FILE] [-f]`。
設定ファイルのデフォルトは`/etc/synergy.conf`。
`-f`オプションでバックグラウンド起動。


# クライアント

サーバから操作するPCs。
起動コマンドは`synergyc SERVER_IP [-f]`。
`-f`オプションでバックグラウンド起動なのはサーバと同様。


# 設定ファイル例

```:/etc/synergy.conf
section: screens
  server:
  client:
end

section: links
  server:
    left = client
  client:
    right  = server
end
```
Windows Server 2016のDatadog用ホスト名を設定する

# やりたい事
Datadogが認識するWindows Server 2016のホスト名（hostname）を変更する。

# やってみた環境
- EC2 (Windows Server 2016)
    - AMI（Windows_Server-2016-Japanese-Full-Base-2019.02.13 (ami-0071141e8929a58d5)）
- Datadog Agent V6

# やってみる前のお話
DatadogのAgentインストール時にホスト名が指定できますが、コンピュータ名をそのまま使えばいいやと思って、下記のコマンドでエージェントのインストールを行っていたのですが、その後に変える必要が出てきたので今回の方法で設定を行いました。

```
msiexec /qn /i datadog-agent-6-latest.amd64.msi APIKEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
```

# やってみた
- 監視対象のサーバにリモートデスクトップで接続します。
- 隠しフォルダを表示させます。
    - エクスプローラーの表示メニューから「隠しファイル」をチェック
- 下記設定ファイルを開きます。
    - C:\ProgramData\Datadog\datadog.yaml
- 設定ファイル内の「hostname: ""」部分にホスト名を記述します。
    - 例：hostname: "hogehogehoge"
- Datadog Agent Manager（windowsメニュー → Datadog）から「Restart Agent」を実行します。
- Datadogの監視コンソールで認識されているホスト名が変わっている事を確認します。
    - Infrastructure → Infurastrucre ListからEC2のインスタンスIDで検索

# おわりに
Windowsのコンピュータ名は文字数制限があるので制限文字数以上のホスト名を使いたい場合や、コンピューター名とDatadogで使用するホスト名は別にしたい（お客さんがコンピューター名を変更する）場合などが今回のホスト名の設定を使うシチュエーションかなと思います。
同じシチュに遭遇した人にこの記事が参考になれば嬉しいです。

最後まで読んで頂きありがとうございました。　(・ω・)ノシ
nuxt+html2canvasで画面キャプチャのメモ

# やりたいこと

nuxtをベースにhtml2canvasにて画面キャプチャをする

html2canvas
https://html2canvas.hertzen.com/

# つまづいたところ

## 発火タイミング

html2canvasはDOMが描画されたあとに発火させないといけない。methodで定義しておいて、mountedで発火させる。

```javascript
  mounted: function () {
    this.capturecanvas()
  },
  methods: {
    capturecanvas: function () {
      html2canvas(document.body).then(function (canvas) {
        var imgData = canvas.toDataURL()
        document.getElementById('result').src = imgData
      })
    }
  }
```

## エラー

```
Syntax Error: Unexpected token, expected {
```

参照
https://qiita.com/you8/items/e8a2631b615ef4ff5685#syntax-error-unexpected-token-expected-

上記のエラーが出たのでfunction()を追記。

# コード

```javascript
<template>
<img src="" id="result" />
</template>
<script>
export default {
  mounted: function () {
    this.capturecanvas()
  },
  methods: {
    capturecanvas: function () {
      html2canvas(document.body).then(function (canvas) {
        var imgData = canvas.toDataURL()
        document.getElementById('result').src = imgData
      })
    }
  }
}
</script>
```

次がこのキャプチャをcloudstoreに保存。
Leetcode #771 Jewels and stones

```swift
func numJewelsInStones(_ J: String, _ S: String) -> Int {
    var dict = [Character: Int]()
    for char in S {
        if let value = dict[char] {
            dict[char] = value + 1
        } else {
            dict[char] = 1
        }
    }
    let array = Array(J)
    var count = 0
    for key in dict.keys {
        if array.contains(key) {
            count = count + dict[key]!
        }
    }
    return count
}
```
[CSS] 待機時間に表示すると少しだけおしゃれになるかも？なCSSアニメーション

# 概要

Webアプリのデザインをほんの少しだけでもおしゃれにできないかな...？
という気持ちから生まれた、効率度外視な努力の成果を紹介する記事です。

## デモ
[かめさんのIT実験室: 波打つ背景](https://siruku6-lab.herokuapp.com/labs/exp54)
このデモが気に入った人は、以下のソースコードをご利用くださいー

## ソースコード

以下のcssをコピー&ペーストしたら、

```css:xxx.scss
.gradient-wave {
  position: relative;
  animation: shade-wave 3000ms cubic-bezier(0.545, 0.080, 0.520, 0.975) infinite;
  overflow: hidden;

  /* 疑似要素 before を生成 */
  &:before{
    position: absolute;
    top: 0; /* 2019/04/24 追記しました ｍ（_ _）ｍ*/
    animation: slide-wave 1000ms cubic-bezier(0.545, 0.080, 0.520, 0.975) infinite;
    background: linear-gradient(90deg, rgba(255, 255, 255, 0.0), rgba(120, 255, 161, .2));
    content: '';
    height: 100%;
    width: 100%;
  }

  @keyframes slide-wave {
    0%   { left: -100%; }
    40%  { left: -100%; }
    100% { left:   70%; }
  }
  @keyframes shade-wave {
    0%   { box-shadow: inset 0px 0px 2px 2px rgba( 0, 255, 220, 0.3); }
    50%  { box-shadow: inset 0px 0px 2px 2px rgba(50, 255, 200, 0.2); }
    100% { box-shadow: inset 0px 0px 2px 2px rgba( 0, 255, 220, 0.3); }
  }
}
```

あとは適用したい要素に `gradient-wave`という`class`を付加するだけ！

```html:xxx.html
<div class='gradient-wave'>
  ...
</div>
```

## 必要な条件
- 適用対象要素には `width` と `heigth` が設定されていること
高さ又は幅が存在しない要素に適用しても、アニメーションは発生しません

- 適用対象要素は、`position: relative;` にすることが可能であること
`position:` を変更すると見た目が崩れるような要素や、`relative以外`でなければならない要素には、上手く適用できないことがあります

- scssが使用可能なアプリであること
railsなど（それ以外は申し訳ないですが知りません）

# 補足
影の厚さとか、流れるスピードとか、色とかは自由に調整してやってください。

- 影
`box-shadow`の後ろの数値や色をいじることで修正できます。
`inset`を消せば影が要素の外に表示されます。

- 流れるスピード
`1000ms`と書いてあるところを修正して下さい。
1000msだと、1秒に1ローテーションさせることになります。
スピードを早くしたかったら数値を小さくするとよいです。

- アニメーション毎の間隔をもう少し空けたい場合
アニメーションの間隔を開けたい場合は、`40%`の部分を50%や60%へとあげてみてください。

- 色
`rgba( , , , )`の中の値をいじれば色が変わります。
4つ目の引数は色の濃さ（透明度）で、`0.0`で完全な透明、`1.0`で一切透けないようになります。
Leetcode: #811 Subdomain visit count

Time complexity: O(N), N is the length of cpdomains
Space complexity: O(N)

```swift
func subdomainVisits(_ cpdomains: [String]) -> [String] {
    var dict = [String: Int]()
    for cpdomain in cpdomains {
        let array = cpdomain.components(separatedBy: " ")
        let count = (Int(array.first!))!
        let domains = array.last!.components(separatedBy: ".")
        var temp = ""
        for domain in domains.reversed() {
            temp = temp.isEmpty ? domain : domain + "." + temp
            if let value = dict[temp] {
                dict[temp] = value + count
            } else {
                dict[temp] = count
            }
        }
    }
    return dict.keys.map { String(dict[$0]!) + " " + $0 }
}
```
Visual Studio 2019 WindowsでGitコミット時にGPG署名出来なかった件[解決]

#問題
環境をまっさらにしてからVS 2019 (Win)をセットアップしたところ、Gitコミット時にGPG署名できなかった。
ほとんど情報がなかったので、需要があるかわからないけれど、書いておく。
(多分みんなパス通すか何かしてる。あと参考情報古い)

##環境
 - Windows 10 (1809)
 - Visutal Studio 2019
 - git version 2.21.0.windows.1
 - コマンドラインでのコミットには問題なし。

#エラー内容
次のようなメッセージが表示される
![VSGitError.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402677/794796e3-07ec-d711-c917-414eba5cf080.png)
>ご使用の Git フック 'gpg' はサポートされていません。最初の行が \"#!/bin/sh\" ではない可能性があります。\r\n詳細については、管理者に連絡してください。

英語だと
>Your git-hook, 'gpg', is not supported, likely because the first line is not \"#!/bin/sh\".\r\nSee your administrator for additional assistance.

#解決策
PATH環境変数に以下追加。
`C:\Program Files\Git\usr\bin`


#参照サイト
[MS Developer Community: "git commit failed with git-hook error"](https://developercommunity.visualstudio.com/content/problem/139363/git-commit-failed-with-git-hook-error.html)
Visual Studio Codeでプレビューを見ながらPlantUMLを書ける環境をDockerで作る

# Visual Studio Codeでプレビューを見ながらPlantUMLを書ける環境をDockerで作る

## はじめに

PlantUMLを使える環境を構築しようとするとJavaや[Graphviz software](http://plantuml.com/graphviz-dot)のインストールが必要でちょっと手間です。
Docker HubでPlantUML Serverの[公式イメージ](https://hub.docker.com/r/plantuml/plantuml-server/)を使うとPlantUMLを描画する環境をわりと楽に構築できたので紹介します。また、Visual Studio Codeとその拡張機能を組み合わせるとplantUMLを書きやすい環境ができたので合わせて紹介します。

構築後のイメージ

![plantuml_preview_sample.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18485/7e2ffe20-6b7e-9d8c-3e68-efebe5832b34.gif)

## 試した環境

mac OS 10.14.3
Visual Studio Code 1.33.1
Docker 18.09.2

## インストールするもの

- [Visual StudioCode](https://code.visualstudio.com/) 
- [PlantUML](https://marketplace.visualstudio.com/items?itemName=jebbs.plantuml) Visual Studio Codeの拡張機能
- [docker](https://www.docker.com/get-started)

それぞれのインストール手順は省略します。

## 構築手順

### PlantUML Server を起動する

```bash
docker run -d -p 8080:8080 plantuml/plantuml-server:jetty
```

ここはこれだけです。
ブラウザで http:localhost:8080 を開いてください。この画面がでれば期待通り動いていることになります。

<img width="1223" alt="plantumlserver.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18485/fc0bb5f3-4b1a-a99e-8d6f-4f06ac523df0.png">

### Visual Studio CodeのPlantUMLの設定

PlantUMLのレンダリングはPlantUML Serverでやるように設定します。

設定画面を開いて以下の設定をします。（windowsなら"ctrl + ,",  macなら"⌘ + ,"で開きます）
plantumlと検索キーワードを入れると設定項目が表示されます。

- Plantuml: previewAutoUpdateにチェック
- Plantuml: RenderをPlantUMLServerに選択
- Plantuml: Serverをhttp://localhost:8080に設定

<img width="827" alt="plantuml_setting.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18485/47277eaf-44a3-96b2-c723-bf3b8d5141c1.png">

以上で構築は完了です。

## 使い方

試しにtest.pumlというファイルを作成してください。
ファイルには以下の内容を入力してください。

```text
@startuml test
@enduml
```

ファイルを開いた状態で、Visual Studio Codeのコマンドパレット（windowsなら"ctrl + shift + p", macなら"⌘ + shift + p"）を開き、
PlantUMLと打ってみてください。
"PlantUML: カーソル位置のダイアグラムをプレビュー"というのが一覧にでるので選択してください。
プレビュー画面がでます。

<img width="1044" alt="plantuml_preview.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18485/30877f2e-2050-2567-fbdb-6521ae7f3f6f.png">

テキストを更新するとそれに合わせて、プレビューの内容も更新されます。

![plantuml_preview_sample.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18485/7e2ffe20-6b7e-9d8c-3e68-efebe5832b34.gif)

PlantUMLの文法かなにかあやまりがあったりエラーがあったときは、
赤いマークが出ます。カーソルをマークに合わせると何でエラーになっているのかがわかります。

<img width="1044" alt="plantuml_error.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18485/161372b4-2a19-1636-4e36-07e6ac45c445.png">

以上です。
dockerのおかげでツールのインストールが楽でいいなと思いました。（小並感）
【BigQuery】UDFと文字列関数を使ってGETパラメータを切り出す

https://qiita.com?hoge=111&fuga=222&moge=333

のページパスから「111」「222」「333」を切り出す

## 結論

``` SQL
CREATE TEMPORARY FUNCTION get_value(keyword STRING, pagepath STRING)
AS (
  REGEXP_REPLACE(
    REGEXP_REPLACE(
      pagepath, 
      CONCAT(r'.*(\?|&)', keyword, '='), 
      ''), -- 前半文字列を削除
    r'&.*', 
    '') -- 後半文字列を削除
  END
);

SELECT
  get_value('hoge', pagepath) AS hoge_value,
  get_value('fuga', pagepath) AS fuga_value,
  get_value('moge', pagepath) AS moge_value
FROM
  `project_name.dataset_name.table_name`  
```

## 処理の流れ

①REGEXP_REPLACE関数で値の前半部分を削除
②REGEXP_REPLACE関数で値の後半部分を削除
③UDF(ユーザー定義関数)で①と②を関数化し、SELECT句で呼び出し

## REGEXP_REPLACE関数

[公式リファレンス](
https://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators?hl=ja#regexp_replace)

## CONCAT関数

[公式リファレンス](https://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators?hl=ja#concat)

``` SQL
REGEXP_REPLACE(
  置換元文字列, 
  CONCAT(r'正規表現', ユーザー定義関数の引数), 
  置換先文字列
)
```

とすることで、正規表現にユーザー定義関数の引数を結合させることが可能

## UDF(ユーザー定義関数)

``` SQL
CREATE TEMPORARY FUNCTION 関数名(第一引数名 データ型, 第二引数名 データ型, ...)
AS (
  処理
);
```
Tenka1 Programmer Beginner Contest 2019 - A&B&C

#Tenka1 Programmer Beginner Contest 2019 A&B&C
[Tenka1 Programmer Beginner Contest 2019](https://atcoder.jp/contests/tenka1-2019-beginner)

[【解説放送：Tenka1 Programmer Contest 2019 解説配信】](https://www.youtube.com/watch?v=uQvc7k2xamY)
 - サイトにリンクがないためここに貼っておく

#A問題

 - 「CがAとBの間にある」なので比較する

```java
	private void solveA() {
		int numA = nextInt();
		int numB = nextInt();
		int numC = nextInt();

		if (numA <= numC && numC <= numB) {
			out.println("Yes");
		} else if (numB <= numC && numC <= numA) {
			out.println("Yes");
		} else {
			out.println("No");
		}

		out.println("");
	}
```

#B問題

 - SのK番目を抜き出しておいて、新しい文字列を作成する

```java
	private void solveB() {
		int numN = nextInt();
		String sS = next();
		int numK = nextInt();

		char tmp = sS.charAt(numK - 1);

		StringBuilder builder = new StringBuilder();

		for (int i = 0; i < sS.length(); i++) {
			if (sS.charAt(i) != tmp) {
				builder.append('*');
			} else {
				builder.append(tmp);
			}
		}

		out.println(builder.toString());
	}
```

#C問題

 - 解説はインライン

```java
	/*
	 * ●○
	 * この組を作らない
	 *
	 * ○●●●●●●●
	 * これはOK
	 * つまり、
	 * ●の位置を決定したらそれ以降全て●
	 * ●の位置決定前までは○が許可される
	 * ※出現したらではなく、位置決定したらが正確かと思う
	 *
	 * 例えばこんなの
	 * ○●●●○●○●
	 *
	 * 取りうるパターンは以下になる
	 * ●●●●●●●●
	 * ○●●●●●●●
	 * ○○○○○●●●
	 * ○○○○○○○●
	 * ○○○○○○○○
	 *
	 * 例えばこんなの
	 * ●○●●○●○●
	 *
	 * ●●●●●●●●
	 * ○○●●●●●●
	 * ○○○○●●●●
	 * ○○○○○○●●
	 * ○○○○○○○●
	 * ○○○○○○○○
	 *
	 * つまり、
	 * ある位置を決めたら左はすべて白、右はすべて黒になる
	 * １：左に黒があったら白にする
	 * ２：右に白があったら黒にする
	 * 上記を実装すればよい
	 *
	 */
	private void solveC() {
		int numN = nextInt();
		String sS = next();
		char[] tmp = sS.toCharArray();

		int black = 0;
		int white = 0;
		for (int i = 0; i < tmp.length; i++) {
			if (tmp[i] == '.') {
				white++;
			}
		}
		/*
		 * ○●●●○●○●
		 * 上記の遷移として
		 *
		 * 下記のようにするためには何個置き換える？というカウントをする。
		 * start ○=3  ●=0
		 * i
		 * 0 ○●●●●●●● ○-1     =  ○2個 ●0個置き換え = 合計2個
		 * 1 ○○●●●●●● ○-1 ●+1 =  ○2個 ●1個置き換え = 合計3個
		 * 2 ○○○●●●●● ○-1 ●+2 =  ○2個 ●2個置き換え = 合計4個
		 * 3 ○○○○●●●● ○-1 ●+3 =  ○2個 ●3個置き換え = 合計5個
		 * 4 ○○○○○●●● ○-2 ●+3 =  ○1個 ●3個置き換え = 合計4個
		 * 5 ○○○○○○●● ○-2 ●+4 =  ○1個 ●4個置き換え = 合計5個
		 * 6 ○○○○○○○● ○-3 ●+4 =  ○0個 ●4個置き換え = 合計4個
		 * 7 ○○○○○○○○ ○-3 ●+5 =  ○0個 ●5個置き換え = 合計5個
		 *
		 */
		int res = white;
		for (int i = 0; i < tmp.length; i++) {
			if (tmp[i] == '.') {
				white--;
			} else {
				black++;
			}
			res = Math.min(res, white + black);
		}
		out.print(res);

	}
```
node.jsを使っての写真共有ソフト作成

# 目的
　ある時男は思った。写真をみんなに見せたい。
　そして男は思った。アプリを使って共有しようと調べた結果
　googleフォト⇒　googleアカウント必須（いちいち知り合いのアカウント聞いて権限つけたはめんどい）
　amazonフォト⇒ アマゾンアカウント必須
　30days Album⇒150枚限定
　インスタ⇒やっぱアカウント問題が・・・

　んー色々制限がめんどい。見せたい人にご年配の人もいるのでできるならブラウザベースでアカウント等がなく合言葉で共有できるものが欲しい。
　って事で、お好みのものがなかったので自前でサーバを立てることにしました。

# 使用ツール
　サーバ：node.js 
　クライアント:vie.js

自分のお勉強もかねてサーバ作成から外部公開までできたらと思っています


# 環境作成
 node.jsのダウンロート＆インストールは以下を参照
  https://qiita.com/Masayuki-M/items/840a997a824e18f576d8

# サーバ作成

```Javascript
// ①HTTPサーバを作成するための必要
const http = require('http');

// ②サーバーを生成
const myServer = http.createServer(requestListener = (req, res) => {
    // どこからアクセスがあったか判定
    console.log(`url:${req.url}`);
    console.log(`method:${req.method}`);
    // ③HTTPレスポンスは必ず正常（200）を返すようにする
    res.writeHead(statusCode = 200, headers = {
        'Content-Type': 'text/html'
    });
    // ④表示するHTMLをレスポンス本体に設定
    res.end(data = '<!DOCTYPE html><html lang="ja"><head><meta charset="UTF-8"><title>写真共有</title></head><body>nodeのお勉強もかねて頑張るぞ！</body>\n')
});

// ⑤ポート番号:8081で受け付け開始
myServer.listen(port = 8081);

```

・サーバー起動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402093/8ba8e36d-8793-4ab2-bec4-de0cc3c778b7.png)


・アクセス

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402093/fb42bb0f-b9b1-1019-9698-821a3e2e94c3.png)


って事で無事にnodeでサーバ作成が完了しました。

次はテンプレートかな。。。
Craft CMS でテンプレートの処理時間を計測する

これらのプラグインを使えば計測できそう。

nystudio107/craft-templatecomments: Adds a HTML comment with performance timings to demarcate `{% block %}`s and each Twig template that is included or extended.
https://github.com/nystudio107/craft-templatecomments

mildlygeeky/craft-kint: Adds Kint, an in-app PHP debugger, to Craft CMS 3.x for use in Twig and PHP.
https://github.com/mildlygeeky/craft-kint

とりあえず前者を使って試してみる。
Node.js にて Promise オブジェクトの中で例外が発生したときの挙動を確認する

## 概要

- Promise オブジェクトの中で例外が発生したときの挙動を確認する
- await を付けて呼び出して try catch で捕捉するパターンを試す
- Promise.catch で捕捉するパターンを試す

## サンプルコード

```p.js
// Promise オブジェクトを返す関数
function foo() {
  // Promise を返す
  return new Promise(function(resolve, reject) {
    // Promise の中で例外を発生させる
    throw new Error('例外発生');
  });
}

async function bar() {

  try {
    await foo();
  } catch (e) {
    console.log('await つけて呼び出して try catch で捕捉');
    console.log(e);
  }
  console.log('');

  foo()
  .then(function(r){
  })
  .catch(function(e){
    console.log('Promise.catch で捕捉');
    console.log(e);
  });
  console.log('');
}

bar();
```

## 実行結果

Proimise 関数内で例外が発生した場合、呼び出し元で捕捉する必要があることがわかる。

```
$ node p.js 
await つけて呼び出して try catch で捕捉
Error: 例外発生
    at /Users/me/hoge/p.js:6:11
    at new Promise (<anonymous>)
    at foo (/Users/me/hoge/p.js:4:10)
    at bar (/Users/me/hoge/p.js:13:11)
    at Object.<anonymous> (/Users/me/hoge/p.js:30:1)
    at Module._compile (internal/modules/cjs/loader.js:701:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:712:10)
    at Module.load (internal/modules/cjs/loader.js:600:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:539:12)
    at Function.Module._load (internal/modules/cjs/loader.js:531:3)


Promise.catch で捕捉
Error: 例外発生
    at /Users/me/hoge/p.js:6:11
    at new Promise (<anonymous>)
    at foo (/Users/me/hoge/p.js:4:10)
    at bar (/Users/me/hoge/p.js:20:3)
    at process._tickCallback (internal/process/next_tick.js:68:7)
    at Function.Module.runMain (internal/modules/cjs/loader.js:757:11)
    at startup (internal/bootstrap/node.js:283:19)
    at bootstrapNodeJSCore (internal/bootstrap/node.js:622:3)
```

## 今回の環境

```
$ node --version
v10.15.3

$ sw_vers
ProductName:	Mac OS X
ProductVersion:	10.14.4
BuildVersion:	18E226
```

## 参考資料
- [Promiseを使う \- JavaScript \| MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Using_promises)
- [Promise\.prototype\.catch\(\) \- JavaScript \| MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch)
- [Node\.js にて await を付けて呼び出した関数が例外を投げた場合の挙動を見る \- Qiita](https://qiita.com/niwasawa/items/345f875c71927487cf6d)
【Visual Studio Code】拡張機能開発のハンズオンを成功させるためのTips

皆さん、こんにちは。戸倉彩です。

今回は、**Visual Studio Code の拡張機能の開発** に関する**「ハンズオン」**をコミュニティなどで開催する場合の **Tips** をまとめみました。皆さんのお役に立てればと思います。

# 事前準備
## 1. ゴール設定
**「VS Code 拡張機能」** は、自分でも手軽に開発できることが人気の一つです。**「ハンズオンを通じて開発を体験してもらう」** ということを **目的** にした場合、主催者側では具体的な **ゴール** を設定しておくと、ハンズオンの内容を決める時にも役立つと思います。
✅ 対象者 (コーディング経験/エディタ利用経験/VSCode利用経験の有無)
✅ どこまで何を体験してもらうか (デバッグ実行まで/パッケージ化まで/公開まで)  

## 2. 当日の流れ
**タイムテーブル(時間表)** を作成し、何にどのくらいの時間を利用するのか、あらかじめ時間配分を決めておきましょう。イベント告知の際に公開しておくと、途中から参加で良かったら参加する！という人もいるかもしれません。
✅ VS Code 概要
✅ VS Code Marketplace 紹介
✅ VS Code 拡張機能開発 について解説
✅ ハンズオン  

## 3. コンテンツ決め
VS Code 拡張機能開発に関する公式チュートリアル(英語)を活用するか、オリジナルで用意するかを考えましょう。
✅ [Visual Studio Code - Your First Extension](https://code.visualstudio.com/api/get-started/your-first-extension)
✅ [Visual Studio Code - Extension Guide](https://code.visualstudio.com/api/extension-guides/overview)
✅ [VSCode API](https://code.visualstudio.com/api/references/vscode-api)

## 4. ハンズオン資料の作成と公開
VS Code 公式サイトで公開されているチュートリアルは英語になります。ハンズオンをスムーズに進めるためには、日本語に翻訳されたステップバイステップで手順が解説されたハンズオン資料が用意されているのが望ましいですが、準備するのが困難な場合には、Qiitaで公開されている記事などを活用するなど、工夫しながら乗り切りましょう。ハンズオン資料は事前または当日に公開できるかたちにしておくと、参加者が個人個人のペースで手を動かすことができるので有用です。
✅ Qiitaで公開する。
✅ サンプルコードやReadmeと一緒にGitHubで公開する。
✅ PowerPointやWordで作成した場合にはpdfファイル形式にしてSpeakerDeckやSlideShareなどで公開する。

## 5. 事前準備の案内
ハンズオンを「マシン持ち込み」で行う場合、各自が持ち寄る環境が大幅に異なる可能があるため、ハンズオンに最低必要限に実行環境を事前に案内し、準備しておいてもらうことをお勧めします。初心者向けには、事前に準備内容を案内した上で、一人で準備が困難な場合にはハンズオン開始前などに環境を一緒に準備する時間を設ける等、フォローすることができると初めての参加者にとっては心強いです。
✅ VS Code (最新版が望ましい)
✅ Node.js
✅ Git
✅ Yoman
✅ Microsoft Azure DevOps アカウント (公開する場合)

# ハンズオン当日
## 6. インターネット環境
会場で Wi-Fi によるインターネットアクセスが提供できる場合には、参加者に分かりやすいようにアクセスポイントを案内しましょう。
✅ 見えるところにアクセスポイントに関する案内を貼っておく。
✅ ハンズオンが始まる前にスライドに表示しておく。
✅ 同時アクセスができる数に制限がある場合には運用でカバーする。

## 7. テクニカルメンター
ハンズオンの際には、参加人数や参加する人のITリテラシーによっても異なりますが、講師1人で進めるよりはメンターさんが存在しているのが望ましいです。
✅ 参加者にとっては、講師が他の参加者の質問を受けている時でも他にメンターさんがいると質問することができ、ハンズオンを効率よく進められます。
✅ 運営側にとっても、同時に複数の質問が寄せられた時に、対応を分散できるだけでなく、得意不得意分野を講師とメンターさんとでうまく補完しあって参加者をサポートすることができます。
✅ Slack や Facebook グループなどを用意し、質問をそこに投稿してもらうことで参加者同士で助け合ったり、遠隔地からもメンターさんの協力を得るなど、他にも工夫してみると良いかもしれません。　　

## 8. トラブルシューティング
ハンズオンにトラブルはつきものです。
✅ まずは冷静になって、手順を一つ一つ丁寧に確認してみましょう。
✅ 最新版の VS Code を利用してみましょう。VS Code のバージョンアップしたくない場合には、[Insiders版 (ベータ版)](https://code.visualstudio.com/insiders/) をインストールして同じ操作を試してみましょう。
✅ VS Code に関するよくある質問[「Visual Studio Code FAQ」](https://code.visualstudio.com/docs/supporting/FAQ)サイト (英語) を確認してみましょう。
✅ VS Code に関する既知の問題や他のユーザーから報告されている問題について GitHubリポジトリ の [「Issue」](https://github.com/Microsoft/vscode/issues) でチェックしてみましょう。

他にも追加で気づいた点がありましたら、随時追記していきたいと思います。「Visual Studio Code拡張機能開発」を一緒に楽しみましょう。

Have a nice Geek Life♪

※Twitterで最新情報配信中 [@ayatokura](https://twitter.com/ayatokura)
ORB_SLAM2のROSビルドがコケるときの対処法

ORB_SLAM2: https://github.com/raulmur/ORB_SLAM2

# 症状
```
/usr/lib/x86_64-linux-gnu/libboost_system.so: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
```
みたいなエラーが出てROSプログラムのビルドができない．

# 対処
`ORB_SLAM2/Examples/ROS/ORB_SLAM2/CMakeLists.txt`を開いて，

```:CMakeLists.txt
set(LIBS
${OpenCV_LIBS}
${EIGEN3_LIBS}
${Pangolin_LIBRARIES}
${PROJECT_SOURCE_DIR}/../../../Thirdparty/DBoW2/lib/libDBoW2.so
${PROJECT_SOURCE_DIR}/../../../Thirdparty/g2o/lib/libg2o.so
${PROJECT_SOURCE_DIR}/../../../lib/libORB_SLAM2.so
)
```
の部分を編集し，`-lboost_system`の行を追加する．

```:CMakeLists.txt
set(LIBS
${OpenCV_LIBS}
${EIGEN3_LIBS}
${Pangolin_LIBRARIES}
${PROJECT_SOURCE_DIR}/../../../Thirdparty/DBoW2/lib/libDBoW2.so
${PROJECT_SOURCE_DIR}/../../../Thirdparty/g2o/lib/libg2o.so
${PROJECT_SOURCE_DIR}/../../../lib/libORB_SLAM2.so
-lboost_system
)
```
Ubuntu18.04にCUDAをインストールする

# はじめに
UbuntuにCUDAをインストールする際にちょくちょく詰まったのでメモ．
研究室向けWikiに書いた内容とほぼ同一です．

# 実行時のシステム構成
- ThinkPad T450 20BV001LJP
    - CPU: Intel Core i7 5500U
    - RAM: 16GB
    - GPU: NVIDIA GeForce GTX940M
    - OS: Ubuntu 18.04 LTS

# 手順
## NVIDIA Driverのインストール
nvidiaのドライバを入れてない(nvidia-smiコマンドが無い)場合は，ドライバのインストールを行う．インストールされている場合はこの項目を飛ばしてCUDAのインストールへ．

まず，PCの電源を切り，UEFI画面を開いてセキュアブートを無効にする．方法はPCの型番によるので都度調べる．その後，再び起動させてから以下のコマンドを実行し，UbuntuがGPUを認識しているかどうかを確認する．

```bash
$ sudo ubuntu-drivers devices
```

搭載されているGPUの型番が正しく表示されたら，以下のコマンドを実行してドライバのインストールを行う．

```bash
$ sudo ubuntu-drivers autoinstall
```

インストールが終了したら再び`nvidia-smi`コマンドを実行し，ドライバのバージョンやGPUの詳細が表示されたらCUDAのインストールに進む．

### nvidia-smiが動かない場合
もし`nvidia-smi`を実行して以下のような表示が出た場合，Ubuntuにデフォルトで搭載されているグラフィックドライバ`Nouveau`と競合している可能性がある．

```
$ nvidia-smi
NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver. Make sure that the latest NVIDIA driver is installed and running.
```

> nvidia-smiはnvidiaのドライバを確認することができなかったよ．最新のドライバが入ってるかどうか確認してね．

この場合，Nouveauを無効化することで解決する．まず，`/etc/modprobe.d/blacklist-nouveau.conf`を作成し，以下のように編集する．

```bash
$ sudo vim /etc/modprobe.d/blacklist-nouveau.conf
```

```:blacklist-nouveau.conf
blacklist nouveau
options nouveau modeset=0
```

次に以下のコマンドを実行し，カーネルモジュールを再読込する．

```bash
$ sudo update-initramfs -u
```

PCを再起動し，`nvidia-smi`が実行できればCUDAのインストールに進む．

## CUDAのインストール
[CUDAダウンロードページ](https://developer.nvidia.com/cuda-downloads)から自分の環境に合わせたdebパッケージをダウンロードする．

ダウンロードが終了したら該当ディレクトリへ移動し，ダウンロードページに示されているようにインストールを行う．

```bash
$ cd ~/Downloads
$ sudo dpkg -i cuda-repo-ubuntu1804-10-1-local-10.1.105-418.39_1.0-1_amd64.deb #ダウンロードしたファイル
$ sudo apt-key add /var/cuda-repo-<version>/7fa2af80.pub #上のコマンド実行時に表示されるやつを入力
$ sudo apt update
$ sudo apt install cuda
```

インストールが終了したらPCを再起動し，`nvidia-smi`を実行してCUDAのバージョンが表示されたら終了．
ターミナル上で体重を記録するアプリを作成。skillhacks学習記録。

<h1>skillhacksのRubyメモアプリを自分で改造 </h1>
今回は迫さんが提供している「Skill Hacks」の学習記録です。
とりあえずコーポレートサイト以外の章を一周したので、第6章で課題にされているターミナル上で動くメモアプリをほぼ何も見ないで再現し、かつちょっと改造しました。

<h1>ソースコードはこちら</h1>

```
     def write_log
        puts "日付を入力してください"
        day = gets.chomp
        puts "体重を入力して"
        weight = gets.chomp
        
        date = {"日付"=>day,"体重"=>weight}
    end
    
    def show(dates)
        puts "記録を確認する"
        dates.each do |date|
            puts date["日付"] +":"+ date["体重"]
        end
    end
    

dates = []

puts "---------------"

while true

puts "モードを選択して"
puts "【add】で新規作成"
puts "【show】で全記録をみる"

mode = gets.chomp

    if mode == "add"
    dates.push(write_log)
    
    elsif mode == "show"
    show(dates)
    
    else
    puts "エラーです"
    end
end
```
<h1>感想</h1>
制作時間は15分くらいです。ruby基礎と情報発信をかねて今回の記事を作ったので全く良い作品ではないと思います(笑)
showの引数を設定するのは、難しかったですが勉強になりました。
Pythonでｔ検定をする練習

# はじめに

ｔ検定とは
>　帰無仮説が正しいと仮定した場合に、統計量がt分布に従うことを利用する統計学的検定法の総称である。母集団が**正規分布に従う**と仮定するパラメトリック検定法であり、t分布が直接、もとの平均や標準偏差にはよらない（ただし自由度による）ことを利用している。2組の標本について平均に有意差があるかどうかの検定などに用いられる。(wikipediaより) 
>>帰無仮説とは
　・研究で主張したい(採択したい)内容とは逆の仮設を帰無仮説と呼びます。
　・「差がない」とか「処理の効果がない」といった内容になります。
　・検定は、この仮説の反証を試みることになります。
栗原伸一『統計学図鑑』(2017)

>>パラメトリックとノンパラメトリック
(https://toukeigaku-jouhou.info/2018/02/24/parametric-nonparametric/)

>詳細は参考文献を参照のこと。

次の表のように項目１と２についてN数、平均値、分散が得られたとき、項目１と２に統計的な有意差があると言えるかを判定する。計算には元データを使用する。

|　|N数|平均値|分散|
|:---|:---:|:---:|:---:|
|項目１|22.0|24.1|16.5|
|項目２|24.0|26.1|20.0|


# 結果
　ｔ（の絶対値）は1.6となり、帰無仮説を棄却する（有意差はない）。

>ｔが「-2より小さい」もしくは「+2より大きい」ならば、平均値の差は統計的に有意といえます。
Newton2004年4月号『統計と確率』(2019)

# 計算方法
　次の式によりｔの値を求める。

- ｔ＝(項目１の平均値 - 項目２の平均値) / (((1/項目１のN数) + (1/項目２のN数)) × 合併分散)^1/2

- 合併分散＝((項目１- 1) × 項目１の分散 + (項目２のN数 - 1) × 項目２の分散)/自由度

- 自由度＝項目１のN数 + 項目２のN数 - 2

# Pythonによる実装
１．まず、元データをnumpy配列として登録する。
２．次に関数を設定する。３つの関数は自由度、合併分散、ｔを求めるもの。
３．３つ目の関数に項目１と項目２の元データを代入してｔを算出する。

```python
from statistics import mean,variance
import numpy as np

a = np.array([20.7,27.1,32.5,25.7,21.6,22.7,24.8,18.3,23.2,20.9,21.3,20.6,31.1,19.8,22.1,27.1,28.3,26.6,24.7,18.7,30.4,21.9])
b = np.array([31.4,26.4,20.7,19.3,30.4,18.0,23.4,26.0,28.5,24.3,27.4,25.4,22.1,30.1,28.6,22.0,34.5,25.8,18.1,25.1,31.5,29.0,28.0,30.9])

print(f'項目１のN数：{len(a):.0f}')
print(f'項目２のN数：{len(b):.0f}')

print(f'項目１の平均：{mean(a):.1f}')
print(f'項目２の平均：{mean(b):.1f}')

print(f'項目１の分散：{variance(a):.1f}')
print(f'項目２の分散：{variance(b):.1f}')

def free(n,m):
    x = len(n) + len(m) - 2
    print(f'自由度：{x:.1f}')
    return x

def marg(n,m):
    y = ((len(n) - 1) * variance(n) + (len(m) - 1) * variance(m))/free(n,m)
    print(f'合併分散：{y:.1f}')
    return y

def t_test(n,m):
    t = (mean(n) - mean(m))/(((1/len(n) + 1/len(m)) * marg(n,m))**0.5)
    print(f'ｔ：{t:.1f}')
t_test(a,b)
```

出力

```
項目１のN数：22
項目２のN数：24
項目１の平均：24.1
項目２の平均：26.1
項目１の分散：16.5
項目２の分散：20.0

自由度：44.0
合併分散：18.3
ｔ：-1.6
```

# 参考文献

- 栗原伸一『統計学図鑑』(2017)
- Newton2004年4月号『統計と確率』(2019)
GitLabで任意の拡張子にシンタックスハイライトをつける

# はじめに
GitLabのマージリクエストでレビューを行う際などに、特殊な拡張子のファイルはシンタックスハイライトがかからない場合があります。
ハイライトされていない状態ではコードレビューがつらいです。
設定ファイルでこの拡張子のファイルにはこの言語であると認識させることができます。

# 設定方法
## 任意の拡張子のファイルを作成する
まず、.hogeファイルというJavaで書かれたファイルをコミットしたブランチのマージリクエストを作成してみます。
![スクリーンショット 2019-04-21 3.13.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402550/63ac1919-b978-a954-4bba-ed8e966f0a91.png)

このように、Javaであると認識されていないため、ハイライトが効いていません。

## .gitattributesに設定を書く
```:.gitattributes
*.hoge gitlab-language=java
```
これで任意の.hogeファイルをJavaで書かれていると認識させることができます。
**※このファイルがデフォルトブランチ(masterなど)にマージされていないと反映されません。**

## ハイライトされているか確認する
.gitattributesをデフォルトブランチにマージしたら再度.hogeファイルを確認してみます。
![スクリーンショット 2019-04-21 3.18.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402550/80421f38-c5d1-9bcb-cf34-a506624c6429.png)

今度はJavaと認識されてちゃんとシンタックスハイライトが効いています。

# おわりに
あまり使う機会はないかもしれませんが、必要になった際には便利な機能だと思います。
特殊な拡張子のファイルを使っている際には、ぜひ試してみてください。
参考：[Syntax Highlighting | GitLab](https://docs.gitlab.com/ee/user/project/highlighting.html)
Laravel+Homestead+Vagrantでブラウザに"No input file specified."と表示される


##症状
Laravel+Homestead+Vagrantで新しくプロジェクトを作り、welcomeページを表示（Homestead.yamlに書かれているipにアクセス）したところ、ブラウザに"No input file specified."と表示される。
そもそもipが間違っている時とはエラーメッセージが異なるので、どうやら接続はできているらしいことがわかる。
###ホスト側のプロジェクトのディレクトリ構成
```
~/Laravel/Sample/laravelapp
```
##仮想マシンのエラーの探し方
仮想マシンのエラーログを見るには、vagrant sshでログインし、下記を入力。

```
vim /var/log/nginx/homestead.test-error.log
```

下記のエラーが出ていた。

```
2019/04/20 17:20:36 [error] 3616#3616: *1 FastCGI sent in stderr: "Unable to open primary script: /home/vagrant/code/public/index.php (No such file or directory)" while reading response header from upstream, client: 192.168.10.1, server: homestead.test, request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/var/run/php/php7.3-fpm.sock:", host: "homestead.test"
```
見に行っているフォルダにindex.phpがないということらしい。
index.phpはpublicディレクトリの下に配置されている。
vagrant sshでログインし、仮想マシンのディレクトリ構成を見てみると、publicフォルダは下記のパスに配置されていた。

```
code/laravelapp/public
```
一方、Homested.yamlのsitesの設定を見てみると、

```bash:Homestead.yaml
sites:
    - map: homestead.test
      to: /home/vagrant/code/public //間違っている！
```
下記のように直したところ、welcomeページに繋がるようになった。

```bash:Homestead.yaml
sites:
    - map: homestead.test
     to: /home/vagrant/code/laravelapp/public
```
【書きかけ】階層型、ネットワーク型のデータベースは、リレーショナル型データベースで再現できます。

#※この記事は書きかけです。まだ完成していません。
#Abstract
この記事での主張は、以下の3点である：
**１、リレーショナル型（関係型）データベースとは、思い切っていえば、どんなデータ構造でも作れる万能装置である。**
**２、つまり、階層型・ネットワーク型のデータ構造も、リレーショナル型データ構造を使って作れる**
**３、実際に階層型、ネットワーク型のデータ構造を、リレーショナル型データ構造を使って設計する方法**

具体的な方法のみを知りたい方は、次の見出しは飛ばし、３を参照されたし。
#１、２、
初心者向けのデータベースの説明として、以下のものがある：

データベースのデータ構造のタイプには、主に、階層型、ネットワーク型、リレーショナル型、の三種がある。
→大雑把にいって、階層型はツリー構造、ネットワーク型はクモの巣型、そしてリレーショナル型は表のような形式である。
→現在使われているデータベースのほとんどは、リレーショナル型を採用しており、階層型、ネットワーク型は前時代の産物である。


この使い古された説明からは、
「現代社会のほとんどのシステムはリレーショナル型が採用されている」
「MySQLなど"一般的"なDBMSは基本的にリレーショナル型である」
ということは読み取れる。

しかし、リレーショナル型はその抽象度故、いったい何ができるのか、俄かにはわかりにくい。

よく使われる概念図をみると、
階層型はツリー構造、ネットワーク型はクモの巣構造、と想像は付きやすいが、
リレーショナル型は、
「表形式のようなもの？」「何がどうリレーショナル（関係）なのか？」「Excelに毛が生えたようなもの？」「いったい何ができるのか」
という程度の理解にとどまってしまう諸君も少なくないのではなかろうか？

リレーショナル型は、概念図と少しの説明では、その全容どころか概要すら把握するのが困難である。


リレーショナル型データ構造とは、データ構造というよりも、
**集合論・論理学における『関係』という概念を用いて作られたデータ論理体系**
といえる。
現代数学的な見地から生み出された抽象的な概念なので、説明や概念図をパッとみただけではそのシステムの全様を理解するのは難しいが、その抽象性の高さは汎用性の高さをもたらしてくれる。

思い切っていうならば、
**リレーショナル型データ構造とは、考え次第でどんなデータ構造でも再現可能な万能装置**
といっても言い過ぎではない。

そして、私がこの記事で最も強調したいのは、以下のことである：
**階層型・ネットワーク型のデータ構造は、リレーショナル型データ構造を使って（比較的簡単に）再現できる**

#３
具体的な方法は以下のとおりである：

###階層型の再現（書きかけ）
ポイントは、
**・『ひとつのツリー』に『ひとつのデータベース』を、『ひとつの階層』に『ひとつのテーブル』を対応させる。**
**・階層間の親子関係を定義する**


例えばデータベース「山田家～我が家の家系図～」をつくることを考えよう。
ここでは「親を二つ以上もてない」という階層型データ構造の定義に忠実に従って、
あえて以下のような不自然な仮定を置くことにする：
「山田一族は無性生殖のみを行う（つまり、一人の親から子が生まれる）」

すると、流れとしては以下のようになる：

①テーブル「ルート」をつくり、カラム「名前」を作成し、そこに「山田太郎」を登録する。これが家系図のルートディレクトリとなる。
②テーブル「山田太郎C」を作る。CはChildrenの頭文字である。カラム「名前」を作成し、そこに山田太郎の子供たちの名前を登録する。「山田隼人」「山田龍」「山田梨花」とする。
③テーブル「山田隼人C」「山田龍C」「山田梨花C」をつくり、それぞれにカラム「名前」を作成し、それぞれの子供たちの名前を登録する。
④以下、全ての人物を記入し終えるまで、同様に繰り返す。
⑤子供を持たない人物（家系図が途切れている部分に相当）の数を数える。その数をnとすると、各人物にn個の値1,2,...,nを割り当てる。そしてn個のテーブル「グループ1」「グループ2」…「グループn」を作り、そこに対応する数値の人物を登録する。
⑥

###親を二つ以上もつ階層型
ここで、リレーショナル型の威力の一つを垣間見ることができる。
上の流れを少し変えると、「親を一つまでしか持てない」という階層型データ構造の基本制約を外し、より幅をもった階層型データ構造を作ることができる。

これで、「山田一族は無性生殖のみを行う」という不自然な仮定を取り払うことができる：

①テーブル「ルート」を作る。カラム「名前」を作成し、そこに「山田太郎」「藤田恵美」を登録する。これが家系図のルートディレクトリとなる。
②テーブル「山田太郎×藤田恵美」を作り、カラム「名前」を作成し、そこに子供たちの名前「山田隼人」「山田龍」「山田梨花」および、それぞれの配偶者（義理の子供たち）の名前「西木野真姫」「ヘレン・ケラー」「唐澤貴洋」を登録する。
③テーブル「山田隼人×西木野真姫」「山田龍×ヘレン・ケラー」「山田梨花×唐澤貴洋」を作り、カラム「名前」を作成し、そこに子供たちの名前、およびそれぞれの配偶者（義理の子供たち）の名前を登録する。

以下同様に繰り返せば、まっとうな家系図が出来上がる。

#ネットワーク型の再現
Widnwosの開発環境を整える：WSL＋Linuxbrewの導入

# 目的
Homebrewが2.0.0からWSLの正式サポートがはじまったらしいので導入してみる。
備忘録として書く。

# 環境
- Windows 10
- WSL: Ubuntu 18.04
- Linuxbrew 2.1.0

# 初期設定
Homebrewを使っても前提としてaptでいれなきゃいけないパッケージがあったりもするらしいので一応やっておく。

```
# aptのリポジトリを日本国内に変更
# backupを作る
$ cp /etc/apt/sources.list /etc/apt/sources.list.bak

# "http://archive.ubuntu.com" を "http://jp.archive.ubuntu.com" に変える
$ vim /etc/apt/sources.list

# 既にインストールされてるパッケージの更新
$ sudo apt update
$ sudo apt upgrade
```

英語は苦手なので日本語に変えておく

```
$ sudo apt install language-pack-ja
$ sudo update-locale LANG=ja_JP.UTF-8

# Ubuntuを再起動
$ echo $LANG
# "ja_JP.UTF-8"になってれば変更できている

# Manも日本語化する
$ sudo apt install manpages-ja manpages-ja-dev

# タイムゾーンの確認
$ date
# "yyyy年 mm月 dd日 曜日 hh:mm:ss JST" になっていれば変更はいらない

# タイムゾーンの変更
$ sudo dpkg-reconfigure tzdata
# アジア→東京と変更し、確認する
```

# Linuxbrewを導入する
[公式サイト](https://docs.brew.sh/Homebrew-on-Linux)の通りにインストールしていく

```
$ sh -c "$(curl -fsSL https://raw.githubusercontent.com/Linuxbrew/install/master/install.sh)"
```
`Warning: /home/linuxbrew/.linuxbrew/bin is not in your PATH.`
というようにWarningメッセージが出てきたが、下記で`~/.bashrc`に追記

```
test -d ~/.linuxbrew && eval $(~/.linuxbrew/bin/brew shellenv)
test -d /home/linuxbrew/.linuxbrew && eval $(/home/linuxbrew/.linuxbrew/bin/brew shellenv)
test -r ~/.bash_profile && echo "eval \$($(brew --prefix)/bin/brew shellenv)" >>~/.bash_profile
echo "eval \$($(brew --prefix)/bin/brew shellenv)" >>~/.profile
```
`source ~/.bashrc`なりWSL再起動なりして、.bashrcファイルを読み込んだらbrewコマンドは使えたのでとりあえず公式サイトの続きをしてみる

```
$ brew install hello
$ hello
# 世界よ、こんにちは！
$ which hello
# /home/linuxbrew/.linuxbrew/bin/hello
```
Homebrewでインストールはできているようなので`brew doctor`で出てきたメッセージの解決だけする

```
$ brew doctor
# Warning: umask is currently set to 000. Directories created by Homebrew cannot
be world-writable. This issue can be resolved by adding umask 002 to
your ~/.bash_profile
  echo 'umask 002' >> ~/.bash_profile

$ echo 'umask 002' >> ~/.bash_profile
$ source ~/.bash_profile
$ brew doctor
# Your system is ready to brew.
```

というわけで一応WSLにLinuxbrewを導入することに成功した。
特に大きな問題もなく導入できて安心。

# 今後について
普段使用しているzshの導入とpyenv+pipenvによるPythonの仮想開発環境を整える。
それらをVSCodeから操作予定。
3歳娘「パパ、もう参照渡しの話はやめて？」

[**【JS】いかがでしたか！？値渡しと参照渡しの使い分け！？**](https://qiita.com/Yametaro/items/21f7b1a4ae09f16f323e)
↑の続編やで。↑の記事は別に読まんでええけどな！

## 休日のワイ
ワイ「お、そろそろ**15時**やから**酒でも**飲もか・・・」

娘（**3歳**）「パパー」

ワイ「ん、なんや娘ちゃん？」

娘「この`false`っていうのは何て読むの？」
娘「**ファルス**？それとも**フォルス**？」

ワイ「なんや、お勉強してんのか？えらいなぁ」
ワイ「そんで何やったっけ？」
ワイ「あー、`false`な」
ワイ「これは・・・」

ワイ「**バルス**や」

娘「そっかー」
娘「**バルス！**」

ワイ「おお、ええ発音や」
ワイ「でもあんまりパパに向かって言わんといてな」

よめ太郎「（誰に向かって言うても**アカン**わ）」
よめ太郎「（むちゃくちゃ教えんなや）」
よめ太郎「（**お前をバルスすんで**）」

ワイ「ちょっとパパは[**参照渡しの記事**](https://qiita.com/Yametaro/items/21f7b1a4ae09f16f323e)を書いたら怖い人達に**総叩き**・・・いや**沢山の有り難いご指摘**をされてもうてな」
ワイ「お勉強し直してるところやから」
ワイ「娘ちゃんは**アンパンパーソン**でも見とき」

娘「うん！」
娘「**バルス！**」

よめ太郎「（**バルス**を訂正せえや！）」

## お勉強再開
ワイ「なるほどな。JSでは結局、変数に保存されるのは参照型の値なんやな」
ワイ「ほな変数から変数にコピーするときも全部**参照渡し**いうことやな」

娘「**パパ、違うよ？**」

ワイ「**ファッ！？**」

娘「そもそも**変数**に代入するときは**渡し**って呼ばないんだよ」

ワイ「おお、せやな（**まじか**）」

娘「**値渡し**とか**参照渡し**っていうのは」
娘「**関数**に対して**引数**を**渡す**ときの言葉なの」

ワイ「せやな〜（**なるほど・・・**）」

娘「**せやな**じゃないの」
娘「**そんなんだから叩かれるの**」

ワイ「**ぐぬぬ**」
ワイ「あんまり**エグらんといて**や・・・」

## 娘ちゃんの講習開始
娘「例えばJavaScriptで、配列を作って`a`という変数に代入するとするでしょ？」

```javascript
let a = [1, 2, 3];
```

ワイ「うんうん」

娘「配列が入ったその`a`を、関数`f`の**引数**として**渡す**の」
娘「そしてその関数`f`の中で、引数として`a`を受け取って、それを**新しい配列**で上書きするの」

```javascript
function f(a) {
  a = ["上書き"];
}

f(a);
```

ワイ「ほうほう」

娘「関数`f`を実行したあと、関数の外の**元々の変数`a`**の中身はどうなってると思う？」

ワイ「それは何も変わらんやろ」
ワイ「元のまま、**外の`a`**には`[1, 2, 3]`が入ったままや」
ワイ「関数の中で配列`a`に**要素を追加**したり、**一部を編集**したりした場合は**外の`a`にも**変更が反映されるけど」
ワイ「丸ごと**上書き**してもうた場合は別もんになるから、外の`a`には**影響なし**や」

娘「そう」
娘「そして、それは**値渡し**だからそうなるの」
娘「もし、今回みたいに引数で受け取ったものを関数の中で**上書き**した場合に」
娘「それでも**外側の`a`が変わるとしたら**」
娘「それが**参照渡し**なの」

ワイ「ほおお、なるほどなぁ・・・！」

娘「ちなみにJavaScriptでは参照渡しは**できない**の」
娘「ぜんぶ**値渡し**なの」
娘「C#とかだと値渡しと参照渡しを使い分けられるんだけどね」

ワイ「あー、せやから**袋叩き**に・・・いや**有り難いご指摘を沢山いただいた**んか〜」

娘「そうなの」

ワイ「（ぐぬぬ）」
ワイ「（っていうか何でそんなに詳しいねん）」
ワイ「（**薬で小さくなってしまった天才高校生探偵**か）」

## 値型と参照型
娘「ちなみに、C#とかだと**値型**と**参照型**って言葉があるんだよ」

ワイ「それはどう違うん？」

娘「例えば、新しいオブジェクトを生成して、変数`a`に代入したとして」
娘「その変数`a`を、変数`b`や変数`c`にも代入してコピーするの」
娘「そのあと`a`のhogeプロパティを変更しても、`b`や`c`のhogeプロパティは変わらない」
娘「**値型のオブジェクト**の場合はそうなるの」
娘「**値がコピーされる**からね」

娘「逆に**参照型のオブジェクト**の場合は」
娘「`a`のhogeプロパティを変更したら`b`や`c`のhogeプロパティも変わっちゃうの」
娘「値そのものがコピーされるんじゃなくて、**参照先の情報がコピーされる**だけだからね」
娘「構造体を使うか、クラスを使うか、とかで使い分けるの」

ワイ「はー、ワイは何も知らんかったんやなー」

娘「そうなの」

ワイ「はぁ・・・・」

娘「でも、JavaScriptのオブジェクトや配列の**一部を変えるだけ**なら**コピー元の変数にも反映される**ってことと」
娘「**代入し直しちゃう**と**コピー元の変数とは別物になっちゃう**っていう挙動が分かってれば」
娘「とりあえず**実務**では問題ないんじゃない？」

ワイ「（また**実務**の話かいな）」
ワイ「（義務教育も始まってへんのに**実務を視野に**入れなはんなや）」

## そんなこんなで晩御飯タイム
ワイ「おお！今日の晩御飯は、よめ太郎特製の**担々麺**かいな」
ワイ「ワイの好きなやつや〜」
ワイ「あ、ちょっと山椒かけたいから取ってや〜」
ワイ「これが本当の**山椒渡し**、言うてな〜」

よめ太郎「言うと思ったわ」
よめ太郎「ネットでもリアルでもオヤジギャグばっか言うてんな」

ワイ「せ、せやな・・・」
ワイ「はあ、しょうもない記事かいて恥かいて」
ワイ「明日会社行ったら笑われるんちゃうか」
ワイ「いや、そんな嫌な人はおらんな・・・」
ワイ「いや、でも、もしかしたら一人くらいおるかも・・・」
ワイ「あー、どうなんやろ」
ワイ「心配や・・・心配や・・・」
ワイ「明日どんな感じになるんやろ・・・」

娘（**3歳**）「パパ」
娘「どんな明日が来るか分からないのは、パパだけじゃないの」
娘「どんな明日が来るか、みんな分からないの」
娘「だから怖くないよ？」
娘「いつだって、パパにできる事をやるだけだよ」

ワイ「（何や、不思議な説得力・・・）」

娘「でも」
娘「あんまり変な記事は書かないでね」
娘「**私も恥ずかしいから**」

ワイ「**やっぱり恥ずかしい思てたんかい！**」

〜**おしまい**〜


## さらに続編書いたで

[**パパ、APIってなあに？ 〜3歳娘がインターンに来た話〜**](https://qiita.com/Yametaro/items/46f134f0ac31b751ee6a)
【Swift5】Buttonの表示/非表示・有効/無効を切り替えてみる

# 実行環境
【Xcode】10.2
【Swift】5.0

# 実現したいこと
1. UIButtonの表示/非表示を切り替える
2. UIButtonの有効/無効を切り替える

1は非表示の場合は、ボタンが言葉通り見えなくなる。
2は無効の場合は少し灰色っぽくなって、ボタン自体は見えてるけど押下できなくなる。

# 使える場面
・条件分岐で、このボタンを押した時は表示（非表示）するor有効（無効）にするといったことをしたい時

# 方法
#### 1.UIButtonの表示/非表示を切り替える
```ViewController.swift
@IBOutlet weak var button: UIImageView!
//UIButtonを表示
button.isHidden = false
//UIButtonを非表示
button.isHidden = true
```

#### 2.UIButtonの有効/無効を切り替える
```ViewController.swift
@IBOutlet weak var button: UIImageView!
//UIButtonを有効化
button.isEnabled = true
//UIButtonを無効化
button.isEnabled = false
```

# その他あれこれ
他にも`alpha`というのを使った方法もあるみたい。それについてはまた後日に。
自分用勉強メモ3日目

# 面白いと思った記事

- [Pythonのコードをきれいに書くコツ](https://qiita.com/yinawekuky/items/28d973a653e9825ed582)
    - zip関数を使えば，複数のリストから要素をまとめて取得することができる．  
Pythonを使用する機会は多いので，この言語特有の書き方を覚えておくと非常に便利．

# 調べた知識

## [スライディングコード](https://www.atmarkit.co.jp/ait/articles/1107/19/news123.html)

参照したら，実行したいシェルコードの先頭アドレスに飛ぶコード．
これをシェルコードの直前に配置して，コード内のどこかを参照させればシェルコードを実行させるようにする事ができる．

## Homebrew

- formula: ソースコードの状態からビルドする
- cask: ビルド済みのものがzipとかapp形式で配布される

で解釈あってるのでしょうか．

## [ランサムウェア](https://cybersecurity-jp.com/security-measures/22689#10_2018)

データを暗号化したりロックをかけたりして，ユーザに対して解除するためのお金(身代金)を要求するマルウェア．

# tips

## VirtualBoxのインストールに失敗した

[Solving VirtualBox “kernel driver not installed (rc=-1908)” Error on macOS](https://medium.com/@Aenon/mac-virtualbox-kernel-driver-error-df39e7e10cd8)
「システム環境設定」→「セキュリティとプライバシー」→「一般」で開発元のスクリプト実行を許可すればよい．

## Ubuntu19.04のインストールに手間取った

インストールの設定を行う最初のセットアップ画面で，ボタンを押そうとするとマウスがくるくるして何も反応しなくなった．
ゲストOSの設定で，メモリを1GB→2GBに変更したら止まることなくインストールが成功した．
メモリが小さくて失敗した？

# 修正
2019/04/21 一部文言を削除しました．
【Android】USBケーブルを使用せず、Wi-Fi経由でadb接続する

# 用途
- Android TVなど、PCとUSB接続が出来ないデバイスでのデバック
- Android端末のUSB端子をUSBメモリ等で使用しつつデバック

# 手順
- Android端末とPCを同じWi-Fi APに接続しておく
- Android端末のIPアドレスを設定アプリ等から確認する
- 以下のコマンドを実行

```
$ adb connect <Android端末のIPアドレス>
```

- この状態でUSBケーブルでadb接続している場合と同様に操作できる
- 接続解除する場合は以下のコマンドを実行

```
$ adb disconnect
```

以上です。
CocoaPods経由でreact-native-configを使うとビルドエラーになる問題の対応方法

半分個人用のメモ代わりに残しておく

# 経緯
Podfileがある時に`react-native-link`した時はPodfileにpodspecが自動的に追記される。
そして[react-native-config](https://github.com/luggit/react-native-config)をCocoaPod経由で使おうとするとビルドエラーになった。

issue的にはここらへん
https://github.com/luggit/react-native-config/issues/125

色々思考錯誤した結果以下の方法でいけた。

# 対応方法
こちらのPRの手順でビルドできるようになった
https://github.com/luggit/react-native-config/pull/329

## react-native-configのインストール
```shell
$ yarn add react-native-config
$ react-native link react-native-config
```

## Podfileに以下を追記

```ruby
post_install do |installer|
  installer.pods_project.targets.each do |target|
    if target.name == 'react-native-config'
      phase = target.project.new(Xcodeproj::Project::Object::PBXShellScriptBuildPhase)
      phase.shell_script = "cd ../../"\
                           " && RNC_ROOT=./node_modules/react-native-config/"\
                           " && export SYMROOT=$RNC_ROOT/ios/ReactNativeConfig"\
                           " && export BUILD_DIR=$RNC_ROOT/ios/ReactNativeConfig"\
                           " && ruby $RNC_ROOT/ios/ReactNativeConfig/BuildDotenvConfig.ruby"

      target.build_phases << phase
      target.build_phases.move(phase,0)
    end
  end
end
```

## react-native-configの設定を追加
- `project -> Build Settings -> All`の検索欄に「preprocess」を入れて絞り込む
- `Preprocess Info.plist File`を`Yes`にする
- `Info.plist Other Preprocessor Flags`に`-traditional`を入れる
- `Info.plist Preprocessor Prefix File`を以下のパスにする
    - `$(SRCROOT)/../node_modules/react-native-config/ios/ReactNativeConfig/GeneratedInfoPlistDotEnv.h`
    - CococaPods経由かどうかでここのパス変わるのだろうか :thinking: