OmniAICreator/Qiita-1.07M huggingface dataset:
GitLab の Error Tracking を試してみる

## はじめに

[GitLab 11.8](https://about.gitlab.com/2019/02/22/gitlab-11-8-released/) で導入された [Error Tracking](https://about.gitlab.com/2019/02/22/gitlab-11-8-released/#error-tracking-with-sentry) 機能を試してみました。
Error Tracking は、アプリケーションで発生したエラーを発見しやすく・確認しやすくするための機能で、 OSS のエラートラッキングシステムである [Sentry](https://sentry.io/) と GitLab を連携させることで実現できます。

### 前提となる環境

- GitLab → https://gitlab.com/ (GitLab.com / Free)
- Sentry → https://sentry.io
    - ユーザ登録するところは割愛
- 導入する対象は Rails アプリ
	- https://gitlab.com/omae-app/unlock
	- (よかったらアプリも遊んでください :smile:  )

## Sentry にプロジェクトを作成

ここはさらっと。

1. `Create Project` > `Rails` を選択します
2. プロジェクト名とチームを入力して `Create Project`

## Rails アプリに Sentry をインストール

`Gemfile` に `sentry-raven` を追加します。

```ruby:Gemfile
gem "sentry-raven"
```

```
$ bundle
```

`config/application.rb` にデータソース名を設定します。
実際には [dotenv](https://github.com/bkeepers/dotenv) とかを使って環境変数として設定するのがよいと思います。

```ruby:config/application.rb
Raven.configure do |config|
  config.dsn = 'https://xxx@sentry.io/xxx'
end
```

パラメータとセッション情報を取得するための設定をします。

```ruby:app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  before_action :set_raven_context

  private

  def set_raven_context
    Raven.user_context(id: session[:user_id])
    Raven.extra_context(params: params.to_unsafe_h, url: request.url)
  end
end
```

## Sentry の Auth Token 取得

1. `Settings` > `Account` > `API` > `Auth Tokens` > `Create New Token`
2. `event:read` と `project:read` にチェックを入れて `Create Token`

生成された Token は次で使います。

![スクリーンショット 2019-06-18 21.12.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222294/2dbf7c26-2b80-fc10-ee10-adbf1c37237a.png)

## GitLab から Sentry へ接続

1. `Settings` > `Operations` > `Error Tracking` > `Expand`
2. `Active` にチェックを入れます
3. 各項目を入力して、 `Connect`
	- Sentry API URL : `https://sentry.io`
	- Auth Token : 先ほど取得した Auth Token
4. 接続に成功したら、 `Project` のドロップダウンから作成したプロジェクトを選択して `Save`

これで、 GitLab の `Operations` > `Error Tracking` からエラーのリストを確認できるようになります。
試しに Sentry から sample event を発生させてみると ↓ の感じになりました。
GitLab で確認できるのはエラーのリストまでで、各エラーの詳細を確認するには Sentry で見る必要があるようです。

<img width="1789" alt="スクリーンショット 2019-06-18 22.15.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222294/d007a8fe-bd84-1d0d-1fe0-f4c7c417df44.png">

Sentry で見てみると ↓ な感じです。 

<img width="1570" alt="スクリーンショット 2019-06-18 21.26.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222294/1406df19-9c74-c26d-500d-d3b95c58dce6.png">

## 参考文献

- [GitLab Help | Error Tracking](https://gitlab.com/help/user/project/operations/error_tracking)
More than one file was found with OS independent path 'lib/x86/libflutter.so'

# 解決策
android/app/build.gradleファイルに、pickFirst 'lib/x86/libflutter.soを追加する。

例)build.gradle

```gradle
android {
  defaultConfig {
    packagingOptions {
        pickFirst 'lib/x86/libflutter.so'
    }
  }
}
```

# 背景
2019年6月18日現在
Flutterのバージョンをアップデートしたら、以下のようなエラーが出るようになった

![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130026/31371830-fc81-bdda-c3cd-a34408787dc5.png)

```text
Flutter 1.7.5-pre.21 • channel master • https://github.com/flutter/flutter.git
Framework • revision 217890685b (9 hours ago) • 2019-06-18 00:07:55 -0400
Engine • revision 20d3861ac8
Tools • Dart 2.4.0
```

# 最後に
僕はNativeエンジニアでもないので、対処法が間違っている可能性があります。
何か気になる点などがあれば、ご指摘いただけると幸いです。
pythonでパスワード付きのzipファイルを展開する


[Pythonでパスワード付きのzipファイルを解凍する \- 珠玉の誤訳](http://hiron.hatenablog.jp/entry/2014/12/15/115357)
のpython3版

```py
import zipfile

def unzip_with_pwd(filename, path='.', pwd=b''):
    with zipfile.ZipFile(filename, 'r') as zip_file:
        try:
            zip_file.extractall(path=path, pwd=pwd)
            print('extraction is successful!')
        except RuntimeError:
            print('{} is wrong password!'.format(pwd))

if __name__ == "__main__":
    unzip_with_pwd(filename="test.zip", pwd=b'nya')
```


Windowsで圧縮していると展開したファイルがLinux上で化けるので変換が必要

```py
import zipfile

def unzip_with_pwd_ja(filename, path='.', pwd=b''):
    with zipfile.ZipFile(filename, 'r') as zip_file:
        try:
            for info in zip_file.infolist():
                info.filename = info.filename.encode('cp437').decode('cp932')
                zip_file.extract(info, path=path, pwd=pwd)
            print('extraction is successful!')
        except RuntimeError:
            print('{} is wrong password!'.format(pwd))

if __name__ == "__main__":
    unzip_with_pwd_ja(filename="test.zip", pwd=b'nya')
```
flexboxを使ってheaderメニューを作る【学習メモ】

#はじめに
headerでメニューを作る時、いつもはfloatを使って作成していましたが、今回はflexboxを使って作成してみたいと思います。

#flexboxとは？
CSS3から使えるようになった機能の一つで、flexboxを使うと要素の配置を簡単に揃えることができます。
子要素の配置を変える時、親要素に**display: flex;**を置くと使えるようになります。

今回はheader要素(親)の中央にメニュー（子）を置きたいので、垂直方向に中央揃えにすることができる**align-items: center;**を使用していきます。
また子要素を両端に分けることができる**justify-content: space-between;**を使い、headerのタイトルとメニューを分けています。
他にも配置方法はたくさんあるので[こちら](https://creive.me/archives/15427/)を参考にしてください。

#コード
```HTML:index.html
<body>
    <header>
        <h1 class="title">header!!</h1>
        <nav class="nav-menu">
            <ul class="menu">
                <li class="menu-item"><a class="menu-link" href="">メニュー１</a></li>
                <li class="menu-item"><a class="menu-link" href="">メニュー２</a></li>
                <li class="menu-item"><a class="menu-link" href="">メニュー３</a></li>
                <li class="menu-item"><a class="menu-link" href="">メニュー４</a></li>
            </ul>
        </nav>
    </header>
</body>
```

```CSS:style.css
body {
    margin: 0;
    padding: 0;
}

header {
    box-sizing: border-box;
    background: #c1ff0a;
    width: 100%;
    height: 80px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 50px;
}
.menu {
    display: flex;
    list-style: none;
}
.menu-item {
    margin-right: 20px;
}
.menu-link {
    text-decoration: none;
}
```

#画面
<img width="1125" alt="スクリーンショット 2019-06-18 22.09.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269337/cfae8b5d-467b-f8da-c1b9-8e564fd52590.png">
Leetcode #241: Different Ways to Add Parentheses

```swift
func diffWaysToCompute(_ input: String) -> [Int] {
    var answer = [Int]()
    var str = Array(input)
    for i in stride(from: 0, to: str.count, by: 1) {
        if str[i] == "*" || str[i] == "+" || str[i] == "-" {
            let before = diffWaysToCompute(String(str[0..<i]))
            let after = diffWaysToCompute(String(str[(i+1)...]))
            for x in before {
                for y in after {
                    if str[i] == "*" {
                        answer.append(x * y)
                    } else if str[i] == "+" {
                        answer.append(x + y)
                    } else {
                        answer.append(x - y)
                    }
                }
            }
        }
    }
    return answer.isEmpty ? [Int(input)!] : answer
}
```
Leetcode #238: Product of Array Except Self

```swift
func productExceptSelf(_ nums: [Int]) -> [Int] {
    var left = Array(repeating: 1, count: nums.count)
    var right = Array(repeating: 1, count: nums.count)
    for i in stride(from: 1, to: nums.count, by: 1) {
        left[i] = left[i-1] * nums[i-1]
    }

    for i in stride(from: nums.count-2, through: 0, by: -1) {
        right[i] = right[i+1] * nums[i+1]
        left[i] *= right[i]
    }
    return left
}
```
差分法によるPoisson方程式の離散化とJacobi法で用いる漸化式

# 概要
Poisson方程式を差分法で離散化したときの離散化形式と，Jacobi法で反復計算を行うときの式を導出する．
実装の必要が生じたときには忘れていることが多いので，取り急ぎ記しておく．

そのうち導出とかを加筆する．

# Poisson方程式
数値計算において，Poisson方程式は様々な場面で現れてくる．

- 1次元

```math
\frac{\partial^2 f}{\partial x^2} = g
```

- 2次元

```math
\frac{\partial^2 p}{\partial x^2}+\frac{\partial^2 p}{\partial y^2} = \frac{\rho}{\Delta t}\theta^*
```
- 3次元

```math
\frac{\partial^2 \psi}{\partial x^2}+\frac{\partial^2 \psi}{\partial y^2}+\frac{\partial^2 \psi}{\partial z^2} = -\omega
```

## 離散化

- 1次元

```math
\frac{f_{i+1}-2f_{i}+f_{i-1}}{\Delta x^2} = g_i
```

- 2次元

```math
\frac{p_{i+1,j}-2p_{i,j}+p_{i-1,j}}{\Delta x^2}+\frac{p_{i,j+1}-2p_{i,j}+p_{i,j-1}}{\Delta y^2}  = \frac{\rho}{\Delta t}\theta^*_{i,j}
```

- 3次元

```math
\frac{\psi_{i+1,j,z}-2\psi_{i,j,z}+\psi_{i-1,j,z}}{\Delta x^2}+\frac{\psi_{i,j+1,z}-2\psi_{i,j,z}+\psi_{i,j-1,z}}{\Delta y^2}+\frac{\psi_{i,j,z+1}-2\psi_{i,j,z}+\psi_{i,j,z-1}}{\Delta z^2} = -\omega_{i,j,k}
```

# 漸化式

- 1次元

```math
f_{i}^{(m+1)} = \frac{f_{i+1}^{(m)}+f_{i-1}^{(m)}}{2} - \frac{\Delta x^2}{2}g_i
```

- 2次元

```math
p_{i,j}^{(m+1)} = \frac{\Delta y^2(p_{i+1,j}^{(m)}+p_{i-1,j}^{(m)}) +\Delta x^2(p_{i,j+1}^{(m)}+p_{i,j-1}^{(m)})-\frac{\rho}{\Delta t}\theta^*_{i,j}\Delta x^2\Delta y^2}{2(\Delta x^2+\Delta y^2)}
```

- 3次元

```math
\psi_{i,j,k}^{(m+1)} = \left.\left[\Delta y^2\Delta z^2(\psi_{i+1,j,k}^{(m)}+\psi_{i-1,j,k}^{(m)}) +\Delta x^2\Delta z^2(\psi_{i,j+1,k}^{(m)}+\psi_{i,j-1,k}^{(m)})+\Delta y^2\Delta z^2(\psi_{i,j,k+1}^{(m)}+\psi_{i,j,k-1}^{(m)})-(-\omega_{i,j,k})\Delta x^2\Delta y^2\Delta z^2\right] \middle/ 2(\Delta y^2\Delta z^2+\Delta x^2\Delta z^2+\Delta x^2\Delta y^2)\right.
```

# 準調和方程式

```math
\nabla\cdot\left(\frac{1}{\rho}\nabla p\right) = \frac{1}{\Delta t}\theta^*
```

## 離散化
```math
\frac{1}{\Delta x}\left(\frac{2}{\rho_{i+1,j}+\rho_{i,j}}\frac{p_{i+1,j}-p_{i,j}}{\Delta x}-\frac{2}{\rho_{i,j}+\rho_{i-1,j}}\frac{p_{i,j}-p_{i-1,j}}{\Delta x}\right)+\frac{1}{\Delta y}\left(\frac{2}{\rho_{i,j+1}+\rho_{i,j}}\frac{p_{i,j+1}-p_{i,j}}{\Delta y}-\frac{2}{\rho_{i,j}+\rho_{i,j-1}}\frac{p_{i,j}-p_{i,j-1}}{\Delta y}\right) = \frac{1}{\Delta t}\theta^*_{i,j}
```

## 漸化式

```math
p_{i,j}^{(m+1)} = \frac{ \frac{1}{\Delta x^2} \left(\frac{p_{i+1,j}^{(m)}}{\rho_{i+\frac{1}{2},j}}+\frac{p_{i-1,j}^{(m)}}{\rho_{i-\frac{1}{2},j}}\right) + \frac{1}{\Delta y^2} \left( \frac{p_{i,j+1}^{(m)}}{\rho_{i,j+\frac{1}{2}}}+\frac{p_{i,j-1}^{(m)}}{\rho_{i,j-\frac{1}{2}}} \right) -\frac{\theta^*_{i,j}}{\Delta t}}{\frac{1}{\Delta x^2} \left(\frac{1}{\rho_{i+\frac{1}{2},j}}+\frac{1}{\rho_{i-\frac{1}{2},j}}\right) + \frac{1}{\Delta y^2} \left( \frac{1}{\rho_{i,j+\frac{1}{2}}}+\frac{1}{\rho_{i,j-\frac{1}{2}}} \right)}
```

```math
\begin{eqnarray}
\rho_{i+\frac{1}{2},j} &=& \frac{\rho_{i+1,j}+\rho_{i,j}}{2}\\
\rho_{i-\frac{1}{2},j} &=& \frac{\rho_{i,j}+\rho_{i-1,j}}{2}\\
\rho_{i,j+\frac{1}{2}} &=& \frac{\rho_{i,j+1}+\rho_{i,j}}{2}\\
\rho_{i,j-\frac{1}{2}} &=& \frac{\rho_{i,j}+\rho_{i,j-1}}{2}
\end{eqnarray}
```
Leetcode #154: Find Minimum in Rotated Sorted Array II

```swift
func findMin(_ nums: [Int]) -> Int {
    var start = 0
    var end = nums.count - 1
    while start < end {
        let middle = start + (end - start)/2
        if nums[middle] > nums[end] {
            start = middle + 1
        } else if nums[middle] < nums[end] {
            end = middle
        } else {
            end-=1
        }
    }
    return nums[start]
}
```
Leetcode #153: Find Minimum in Rotated Sorted Array

```swift
func findMin(_ nums: [Int]) -> Int {
    var start = 0
    var end = nums.count - 1
    while start < end {
        let middle = start + (end - start)/2
        if nums[middle] > nums[end] {
            start = middle + 1
        } else {
            end = middle
        }
    }
    return nums[start]
}
```
【製作進捗】BlackJack：01

#始めに
何がBlackJackなのかというと、[こちらの記事](https://qiita.com/hirossyi73/items/cf8648c31898216312e5)で「初心者卒業にBlackJackを作ってみては」という課題（?）があったので、Progate終わりたてで丁度いいのではと軽い気持ちで始めて見ました。

##できたところ
- 簡単に仕様が決まった
- トランプ1枚を表す配列（["ダイヤ","A"],["ダイヤ","2"]……["クローバー","K"]）を作った

```Java:BlackJack.java
	String[] strMark={"ダイヤ","ハート","スペード","クローバー"};
	String[] strNumber={"A","2","3","4","5","6","7","8","9","10","J","Q","K"};

	for (int i=0;i<strMark.length;i++){
		for (int i2=0;i2<strNumber.length;i2++){
			String[] card = {strMark[i],strNumber[i2]};
			System.out.println(Arrays.deepToString(card));
		}
	}
```

##今後
- ↑で作った配列を山札配列に52枚分入れたい

```Java:BlackJack.java
    ArrayList<String[]> bills = new ArrayList<String[]>();
```

bills(山札)配列を定義しておいて、

```Java:BlackJack.java
    bills.add(card);
```
上記のfor文の中でcardをbillsに追加してます。

どうやら入ってはいるような感じはあるんだけれど、出力したときに、
>[Ljava.lang.String;@5c8da962,

と表示されちゃうので、なんとかしたい。

##終わりに
まだまだ初歩の初歩の状態ではありますが、焦らずゆっくりと進めていこうかなと思います。
少しずつでも進捗をここにアップしようかなと思うので、生暖かい目で見守ってください。
plunkerでsimcirjs その11

#概要

plunkerでsimcirjsやってみた。
式から回路作ってみた。
nand,nor実装してみた。

#写真

![image](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/2025bbe6-8a2a-e400-99f1-00f154e2c461.png)

#成果物

https://embed.plnkr.co/xsZLNPtEbzNsxJVkPCDT/

以上。
c++/構造体のソート

c++で構造体をソートしようとしてハマったのでメモ.

~~構造体を配列でまとめてソートするのではなく,~~
~~vectorに突っ込んでからソートするといい.~~

```c++:struct_sort.cpp
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

//構造体の定義
struct monkey {
    int w; //サルの体重
    int s; //サルのIQ
};

bool w_cmp(const struct monkey& p, const struct monkey& q) {
    return p.w < q.w;
}

bool s_cmp(const struct monkey& p, const struct monkey& q) {
    return p.s > q.s;
}

int main(void) {
    struct monkey mky[1005];
    int w, s;
    int m=0;

    std::vector<struct monkey> v;
    struct monkey temp;

    //ソートするためにvectorに突っ込む
    while(cin >> w >> s) {
        if(s == EOF) { break; }
        temp.w = w;
        temp.s = s;
        v.push_back(temp);
        m++;
    }

    //ソート(値が等しい要素の順序が維持されない)
    sort(v.begin(), v.end(), s_cmp);

    //ソート(値が等しい要素の順序が維持される)
    stable_sort(v.begin(), v.end(), w_cmp);

    //vectorの内容をすべて表示
    for(auto itr = v.begin(); itr != v.end(); ++itr) {
        cout << (*itr).w << " " << (*itr).s <<endl; 
    }
}

```

このプログラムに以下のような入力を与えてみる.

```text:ipt.txt
6008 1300
6000 2100
500 2000
1000 4000
1100 3000
6000 2000
8000 1400
6000 1200
2000 1900
```

結果は以下のようになる.
同じ値の要素の順序が維持されている(6000の行)
(wとsをどちらもstd::sortでソートした場合は,同じ値の要素の順序が維持されず,
 w=6000の要素において対応するsが降順にならない)

```text:out.txt
500 2000
1000 4000
1100 3000
2000 1900
6000 2100
6000 2000
6000 1200
6008 1300
8000 1400
```
React NativeでAndroidXに関する変更でAndroidのビルドができなくなったのに対応した

# はじめに
2019/6/17までAndroidのビルドができていましたが、2019/6/18にAndroidのみエラーが出るようなりました。
(`react-native: "0.59.8"`, `react-native: "0.59.9"` の環境で発生を確認しています。)

※ プルリクがマージされれば問題なくなると思いますが、ここ数日でリリースなどがあって困っている方もいるかもと思い記事にまとめておきます。

## エラー内容
```
> Task :app:processDebugManifest FAILED
/Users/XXX/android/app/src/debug/AndroidManifest.xml:22:18-91 Error:
        Attribute application@appComponentFactory value=(android.support.v4.app.CoreComponentFactory) from [com.android.support:support-compat:28.0.0] AndroidManifest.xml:22:18-91
        is also present at [androidx.core:core:1.0.0] AndroidManifest.xml:22:18-86 value=(androidx.core.app.CoreComponentFactory).
        Suggestion: add 'tools:replace="android:appComponentFactory"' to <application> element at AndroidManifest.xml:7:5-117 to override.

See http://g.co/androidstudio/manifest-merger for more information about the manifest merger.


FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:processDebugManifest'.
> Manifest merger failed : Attribute application@appComponentFactory value=(android.support.v4.app.CoreComponentFactory) from [com.android.support:support-compat:28.0.0] AndroidManifest.xml:22:18-91
        is also present at [androidx.core:core:1.0.0] AndroidManifest.xml:22:18-86 value=(androidx.core.app.CoreComponentFactory).
        Suggestion: add 'tools:replace="android:appComponentFactory"' to <application> element at AndroidManifest.xml:7:5-117 to override.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 1s
155 actionable tasks: 3 executed, 152 up-to-date
error Could not install the app on the device, read the error above for details.
Make sure you have an Android emulator running or a device connected and have
set up your Android development environment:
https://facebook.github.io/react-native/docs/getting-started.html
error Command failed: ./gradlew app:installDebug. 
```

## 原因
`react-native-push-notification`

下記のAndroidXに関するリリースが原因の様子でした。
https://developers.google.com/android/guides/releases

上記以外にも`react-native-device-info`も該当している様子でしたが、こちらは既にAndroidXに対応して修正されていました。

▼ react-native-device-infoの該当変更箇所
https://github.com/react-native-community/react-native-device-info/commit/ec930b3f61da83e46cd70ecd108e0fe7a873fcb0

## 解決方法
プルリクされているものがまだマージされていない為、`react-native-push-notification
` をreact-native-device-infoの該当変更箇所を参考にforkして対応しました。

▼ Issue
https://github.com/zo0r/react-native-push-notification/issues/1091#issuecomment-502992413


▼プルリクはすでに投げてくれていました。感謝…!
https://github.com/zo0r/react-native-push-notification/pull/1092
中心極限定理をパラメータと組み合せ数でグラフ化して理解する

## グラスを作成するプログラム
Nを増やしていくと、正規分布に近くことがわかります。
parameter を減らしても、Nを増やすと正規分布に近くことがわかります。


```python
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import math

parameter = [1,2,3,4,5,6] # 組み合わせを行うパラメータ
N = 2 # 組み合わせ数

instance = []
q = [0] * N

# パラメータのN組み合わせを作成する
def comb(n):
    n = n -1
    for v in parameter:
        q[n] = v
        if(n == 0):
            val = 0
            for c in range(N):
                val += q[c]
            instance.append(val)
            continue
        comb(n)
    return instance

#期待値, パラメータ, ヒストグラムの算出
def expectedValue(darray):
    cnt = len(darray)
    
    params = [darray[0]]
    
    for v in darray:
        if(not(v in params)):
            params.append(v)
            
    hist = [0] * len(params)
    cnt_h = 0
    for p in params:
        for v in darray:
            if(p == v):
               hist[cnt_h]+=1
        cnt_h+=1
    e = 0
    for i in range(len(params)):
        e += params[i] * hist[i] / cnt
        
    return e, params, hist


comb(N)

print(instance)

expectedValue, params , hist = expectedValue(instance)

plt.plot(params, hist)
plt.show()
```
## パラメータ毎の例
1. parameter = [1,2,3,4,5,6], N=2
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172499/af75b17d-080a-7a45-bccc-ae6f0134a511.png)

2. parameter = [1,2,3,4,5,6], N=3
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172499/5fc7b447-4369-5cd0-3e8b-e60c2cc90708.png)

3. parameter = [1,2,3,4,5,6], N=6
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172499/dc529fe5-8563-3ba8-053a-9c0902685b77.png)
【crontab】Macで定期的に自動でスクショを撮る方法

## こんなことを思ったことありませんか？
- 🤔< そういえば、１時間前・・何やってたっけ？ PCで何の作業してたんだろう
- 🤔< 定期的に自動ログみたいに、スクリーンショット撮ってくれないかな・・・

## 色々な解決策がありますが・・今回はcrontab使います
### 理由
- crontab使ってみたかったから
- シェルスクリプトを書いてみたかったから
- 簡単だったから
- mac標準のやつが思うように動いてくれなかったから


## 準備するもの
- mac
- エディタ（何でもいいです。メモ帳でもいいです）
- ターミナル（macにはじめっから入ってます）

## 手順

### 1.シェルスクリプトを用意する
- 好きな場所に（今回はデスクトップ）にフォルダを作ります
- そのフォルダの中に「auto_capture.sh」というシェルスクリプトを作成します
- 今回の場合、指定したURLを開いて、そのあと10待って、スクリーンショットを撮るという動作にしています

　

```sh
#!/bin/bash

#1個目のサイトを開いて
open https://www.yahoo.co.jp/
#10秒待って
sleep 10s
#スクリーンショット撮る
/usr/sbin/screencapture -m -C -T0 -x ~/pictures/capture_`date +%Y%m%d%H%M`.png

#2個目のサイト
open https://www.google.com/
sleep 10s
/usr/sbin/screencapture -m -C -T0 -x ~/pictures/capture_`date +%Y%m%d%H%M`.png

#3個目のサイト
open https://www.facebook.com/
sleep 10s
/usr/sbin/screencapture -m -C -T0 -x ~/pictures/capture_`date +%Y%m%d%H%M`.png

#4個目以降のサイトも、URLだけ変えればコピペでいけます

```
　

- ターミナルを開いて、「auto_capture.sh」ファイルが置いてあるディレクトリに移動する


```sh
$ cd /Users/yourname(登録している名前に変えてください)/Desktop/capture
```
　

- スクリプトに実行権限をつける


```sh
chmod +x auto_capture.sh
```

### 2.crontabを編集する
- ここで自動的にシェルスクリプトが発火してくれます
- そのタイマー設定みたいなことをします
　

- 下のコマンドでcrontabの編集に入ります

```sh
$ crontab -e
```
　

- ここでVimでの編集になります
- Vimの使い方がわからない場合は、[こちら]()を参考にしてくださいね

 
 
| コマンドの意味 | 入力するコマンド |
|:--|:--|
| 編集モードに移行(挿入) | i |
| ファイルを上書き保存後終了 | !wq |
　

- 以下を追加(iで追加)して、保存（!wq）します

```sh
00 * * * * ~/capture/auto_capture.sh
```

↑これで１時間に１回、「auto_capture.sh」が発動することになります。

他の時間指定が知りたい！という場合は、[こちら](https://www.server-memo.net/tips/crontab.html)を参考にしてくださいね


## まとめ
- 大したコードは書いてないですが、これで自動でスクリーンショットを撮ってくれるようになりました
- 開きたいURLなどはお好きに変えていただくことで、そのサイトが開くようになります

## 参考サイト
- [Mac のスクリーンショットを定期的に自動撮影する](http://shu223.hatenablog.com/entry/20130314/1363342442)
- [crontabの書き方](https://www.server-memo.net/tips/crontab.html)
- [Vim超入門](https://www.hpc.co.jp/support/hello_vi_06/)
rentrezでNCBI Geneの情報を取得

[Ensemblが返すNCBI Gene IDが一意じゃなかった件について](https://qiita.com/antiplastics/items/1e2a7e88ecca94d4ecff)
でまとめた通り、NCBI Gene IDは、Ensemblを経由すると一意なIDではなくなってしまう。

ただし、これは管理している組織も国もポリシーも違うのでしょうがないのかもしれない。

BiomartやbiomaRtパッケージが便利すぎるから使っていたが、
NCBI側が作ったIDを使う以上は、NCBIに検索をかけるのが筋だとも思い直したので、
rentrezパッケージを使って、NCBI Gene IDからGene Symbolの取得を試みた。

ただし、biomaRtほど便利ではなく、数年ぶりにXMLのパースなんてことをやった。
以下のように、Xpath式で階層を下っていけば、目的のGene Symbolにたどり着けた。

```r
install.packages("rentrez", repos="http://cran.r-project.org")
install.packages("XML", repos="http://cran.r-project.org")
library("rentrez")
library("XML")

geneid <- c("6013", "6019")
rln <- entrez_fetch(db="gene", id=geneid, rettype="xml")
rln <- xmlInternalTreeParse(rln)
symbol <- xpathSApply(rln, "//Entrezgene-Set/Entrezgene/Entrezgene_gene/Gene-ref/Gene-ref_locus", xmlValue)

data.frame(
	external_gene_name=symbol,
	entrezgene=geneid)
#   external_gene_name entrezgene
# 1               RLN1       6013
# 2               RLN2       6019
```

これにより、少なくとも同じNCBI Gene IDに、複数のGene Symbolが着くなんて事はなさそう。
コマンドライン/プログラムからPS4をつけてモンハンワールドを起動する

npmライブラリにどうやらPS4操作ができるライブラリがあるらしいので、とりあえず軽く使ってみました。

[ps4-waker - npm](https://www.npmjs.com/package/ps4-waker)

## 必要なもの
- PS4と同じネットワークに繋がったPC
- ネットワークの繋がったPS4
- PS4 Second Screenアプリの入った同じネットワークに繋がったスマホ

## セットアップ

### PCで `ps4-waker` をインストールし叩く

```bash
npm install -g ps4-waker

ps4-waker
```

最初に起動すると `No Credentials` とか出てくるので、コマンドラインからどのPS4を操作するのか、情報を登録する必要があります。

とりあえずコマンドラインはこの状態のまま待機です。

### スマホでSecond Screenアプリを起動し、ps4-wakerに接続する

スマホでSecond Screenアプリを起動し、うまくいくと画面上にps4-wakerが出てくるので、それをタップします。

すると、コマンドライン上でPINコードを求められますので次の手順へ。

### 使用するPS4で認証コードを発行する

- [設定]→[モバイルアプリの接続]→[機器を登録する]を押下すると8桁のPINコードがでてくる。
- PINコードをコマンドラインにうちこむ。(スペースはなしでOK)

うまくいくと `Logged into device! Future uses should succeed` とかでてきます

作業おつかれさまでした

## CLIコマンド一部紹介

注意事項としてですが、PS4の電源が落ちていると使えません。

起動コマンドはスタンバイモード時のみ可能です。

### 起動する

```bash
ps4-waker
```

### 状態確認

```bash
ps4-waker check
```

### スタンバイモードにする

```bash
ps4-waker standby
```

### ゲームを起動する

```bash
ps4-waker start [title id]
```

- モンスターハンター:ワールドを起動したい場合

ゲームのtitle idは起動中にcheckコマンド打ったら見れました。

```bash
ps4-waker start CUSA06027
```

### ボタン押下

> Key names:
  Button names are case insensitive, and can be one of:
    **up, down, left, right, enter, back, option, ps**
  You cannot send the actual x, square, etc. buttons.
  A string of key presses may be provided, separated by spaces, and they
   will be sent sequentially.
  In addition, a key name may be followed by a colon and a duration in
   milliseconds to hold that key, eg: ps4-waker remote ps:1000

ホーム画面しか操作できないのか、ゲーム中だと反応しないようです。

上下左右とenterとback(?)とoption、psボタンしか動かせないらしい

- 右に移動

```bash
ps4-waker remote right
```

## プログラム内から操作する

公式のサンプルだとこんな感じ。

```javascript
const {Device} = require('ps4-waker');
 
var ps4 = new Device();
ps4.turnOn().then(() => ps4.close());
```

ただ、これだけだと接続して起動して終わりになっちゃいます。

なので、ひとつサンプルコードを書いてみました。

### PS4を起動してモンハンワールドを起動

```javascript
const main = async () => {
  const { Device } = require('ps4-waker');

  let ps4 = new Device();

  await ps4.turnOn();

  await ps4.startTitle('CUSA06027');

  ps4.close();
}

main();
```

ええやん

## 備考

iPhoneからでも PS4 Second Screenアプリを使えば電源操作などはできるらしいンゴねぇ

## 参考記事

[PS4 を Google Home から音声で操作してみた - Qiita](https://qiita.com/eup42/items/98c2c3df55211d5b0202)

[Google Homeに話しかけてPS4を操作してみる - Qiita](https://qiita.com/miso_develop/items/0175c5f45a1e90464234)
TypeScript(JavaScript)のイベントハンドラで実行される非同期処理の完了を待つ

余計な非同期処理してくれるサードパーティの関数を同期的に実行する必要があったのでメモ。

## 解決したい問題
フォームのsubmitの直前に処理を挿入できるようにするため、カスタムイベント `beforeSubmit` を発火するようにした。

```TypeScript
window.dispatchEvent(new Event('beforeSubmit'));
$form.trigger('submit');
```

しかし、イベントリスナ側でサードパーティの非同期関数（つまり同期処理にできない）を呼び出す必要があった。

```TypeScript
window.addEventListener('beforeOderSubmit', function (event: Event) {
    thirdPartyAsyncFunction(callback);
});
```

わざわざ`beforeSubmit`イベントを作っているわけなんで、submit前までにこの非同期関数の処理は終わっていて欲しい。

問題の非同期関数がコールバック関数を受け付けるなら、イベント発火側からなんとかコールバックを渡せば良いと考えたが、イベントリスナが複数登録された場合はそれらの処理が終わるたびに呼び出されてしまう。コールバックでsubmitするようにしていたら、全てのイベントリスナの処理が終わる前にsubmitされてしまう可能性がある。


## 解決した方法
リスナでの非同期処理は全てPromiseにラップしてイベント発火側に渡して、イベント発火側でそれらの非同期処理を`Promise.all()`で処理して、`then`でsubmitすることで解決できた。

#### イベント発火側

```TypeScript
public someMethod() {
    let asyncFunctions: Promise<void>[] = [];
    window.dispatchEvent(new CustomEvent('beforeSubmit', {
        "detail": {
            "asyncFunctions": asyncFunctions,
        }
    }));

    Promise.all(asyncFunctions).then(function () {
        ...
        $form.trigger('submit');
    });
}
```
リスナに`Promise`オブジェクトを返してもらえるように、`CustomEvent`でパラメータとして`Promise`オブジェクトを入れる用の配列をリスナに渡している。

#### リスナ側

```TypeScript
window.addEventListener('beforeOderSubmit', function (event: CustomEvent) {
    event.detail.asyncFunctions.push(
        new Promise<void>((resolve) => {
            thirdPartyAsyncFunction(resolve);
        })
    );
});
```
渡してもらった配列に非同期関数の呼び出しをラップした`Promise`オブジェクトを入れている。
`resolve`は非同期処理が終わった時点で呼び出してやる必要がある。上記の例では`thirdPartyAsyncFunction`がコールバック関数を引数としてとると仮定している。

書いてて思ったが、リスナ側では単純に非同期関数を配列に入れて返して、イベント発火側で`Promise`にラップしても良かったかも。

もっとシンプルな方法を知っている人がいたら教えて下さい。
本当は怖いDocker for Windows のExpose daemon on tcp://localhost:2375 without TLS

# これは何？

- Docker for Windows + WSLでWindowsのDocker環境を構築している人が増えていそう
  - https://qiita.com/search?q=docker+for+windows+wsl&sort=rel
  - いっぱいいる
- 軒並みみなさん、`Expose daemon on tcp://localhost:2375 without TLS`にチェックを入れるとか言っている
  - <font color="Red"><b>It also makes yourself vulnerable to remote code execution attacks.</b></font> って書いてるのに！！そのケアもなしに。
  - <font color="Red"><b>遠隔コード実行が可能な攻撃を可能にすることにもなる</b></font>って書いてるのに
- あんまりどんなリスクがあるか、すぐに出てこなかったので記事にします

# 本当は怖い？UIに書いてるままのリスクじゃん

まったくもっておっしゃる通りです。
が、localにしかport公開しないのにどんなリスクがあるかすぐわからなくないですか？私はわかりませんでした。
同じLANにさらしてしまうならまだしも、なぜローカルにポートを開放するのがそんなに危険なのか、想定脅威をすぐ想像できませんでした。

# 一番具体的な想定脅威はなんだったの？

悪意あるWebページからのdockerデーモンのAPI利用でした。
REST APIに悪意あるWebページから到達可能になってしまいます。
SOPとかあるので一定は守られるのですが、「任意のコンテナイメージをビルドする」といった行為が、
遠隔の攻撃者がWebページを踏ませるだけでできてしまいます。
結果として(コンテナ内ですが)任意コード実行のような状態になります。

詳細は下記で解説されています:
https://www.blackhat.com/docs/us-17/thursday/us-17-Cherny-Well-That-Escalated-Quickly-How-Abusing-The-Docker-API-Led-To-Remote-Code-Execution-Same-Origin-Bypass-And-Persistence_wp.pdf

# 悪用されそう？

上記のシナリオではないですが、dockerdのAPIが利用できることによる攻撃は、過去観測されています。
https://blog.trendmicro.co.jp/archives/19773

# こんなリスクDocker以外にもあるんじゃない？

たしかに。
Chromeでは一部dstポートは下記のように塞がれてます。
https://superuser.com/questions/188058/which-ports-are-considered-unsafe-by-chrome

# 結局どう解決したの？

docker for windowsでLinuxコンテナを運用する際、認証(本来dockerdのAPIはクライアント証明書で認証できます)を付ける方法は私にはわかりませんでした。
tcpソケットを使わない方法は、名前付きパイプですが、WSLと名前付きパイプでやり取りするのは結構大変そうです。
参考: https://qiita.com/gentaro/items/22b0757d5be0c36ecd17

私はもうHyper−Vの活用を諦めて、無難にdocker-machine(with Virtualbox)にしました。。。
Ruby on Rails [学習記録-第2章-]


1. リクエストとレスポンス
2. ルーティング
3. コントローラ
4. ビュー

#リクエストとレスポンス
* ウェブサイトにアクセスした時、PCからはリクエストというものが送信される。
* それに対して、リクエストを受け取ったサーバーはリクエストに対して適切なレスポンスを返す。
![リクエストとレスポンス](http://si.comp.ae.keio.ac.jp/web_app_dev_material/simple/about_webapp/img/about_webapp.png)
出典：[WEBアプリケーションの概要](http://si.comp.ae.keio.ac.jp/web_app_dev_material/simple/about_webapp/index.html)
レスポンスを返す際には、ルーティング、コントローラ、ビューという3つのパートがそれぞれ異なる役割を持って処理を行う。

#ルーティング
* リクエストに対してどのコントローラのどのアクションを動かすのかを設定。
* Railsではルーティングをconfig/routes.rbに記述。
*ルーティングは`get 'apps' => 'apps#index'`のように書く。`get apps`の`apps`はURLのパスと呼ばれる部分を示す。
* ルーティングはパスに対応してどのコントローラのアクションを動かすかを設定するもの。
* `apps#index`は`コントローラ名#アクション名`となっている。

````rb:
Rails.application.routes.draw do
  get 'apps' => 'apps#index'
end
```

#コントローラ
* コントローラの作成には`rails g controller` コマンドというものを使用。このコマンドでコントローラに関するファイルが自動で作成される。

```
$ rails g controller コントローラ名
# コントローラを作成
```
コントローラを間違えて作成した場合は以下のコマンドで削除する。

```
$ rails d controller コントローラ名
# 作成したコントローラを削除
```
コントローラクラスはファイル名(appss_controller.rb)から、単語の先頭を大文字にしてアンダーバーをとった形になる。

```rb:
class AppsController < ApplicationController
  def index
  end
end
```

###アクション
* アクションとはコントローラクラスにおけるインスタンスメソッドのことを示す。
先のプログラムではAppsControllerクラスにindexアクションを作成したことになる。
アクションは複数記載することが可能。

##ビュー
* レスポンスによって返されるのがビューファイルである。
* ビューファイルには拡張子が`.html.erb`のものを作成する。
* コントローラのメソッド１つにつきビューファイルが１つ存在することになる。
* ビューファイルはコントローラと同じフォルダ内にあり、アクション名と同じファイル名のものが適用される。

###レイアウトファイル
* app/views/layouts以下にあるファイルはレイアウトファイルと呼ばれるビューファイル。
* レイアウトファイルは、それぞれのビューファイルが読み込まれる前に読み込まれる。
* つまり、このファイルにそれぞれのビューの共通部分(ヘッダーやフッターなど)を定義しておくことで、同じコードを省略可能。
* レイアウトフォルだ内にある、`application.html.erb`のbodyタグ内には`<%= yield %>`と書かれている。これはこの部分をそれぞれのビューファイルに置き換えるということ。

```rb:
<!-- yieldの部分がそれぞれのビューファイルに置き換わる -->

  <!DOCTYPE html>
  <html>
    <head>
      <title>App</title>
      <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track' => true %>
      <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
      <%= csrf_meta_tags %>
    </head>
    <body>

    <%= yield %>

    </body>
  </html>
```
Ruby on Rails [学習記録-第1章-]

#アプリケーション開発
* 本章からアプリケーション開発において必要となる知識を整理、記録していく。

#ターミナルコマンド

```bash:
$ cd　　　 #ディレクトリの移動
$ pwd　　　#ディレクトリの参照
$ rails s #テストサーバー起動、テストサーバー終了は"controll + c"
```

#新規アプリケーションの作成
* Railsで新規アプリケーションを作る際は、`rails new`コマンドを使用する。
コマンドは`rails new アプリケーション名`で実行する。オプションをつけるには`- オプション名`と追記する。

```bash:
$ rails new アプリケーション名 - オプション名

$ rails _5.2.2.1_ new Application -d mysql
```
* `Rails new`コマンドを実行するとアプリケーション名のディレクトリが作成される。
場合によっては実行時に以下のエラーが表示される。

```bash:
Installing mysql2 0.5.2 with native extensions

Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
current directory: /Users/user_name/Programs/web/foobar-repo/vendor/bundle/ruby/2.5.1/gems/mysql2-0.5.2/ext/mysql2
/Users/user_name/.rbenv/versions/2.5.1/bin/ruby -r (以下略)
```
* 上記エラーが表示された場合は以下のコマンドを入力する。

```bash:
$ gem install mysql2 -v '0.5.2' --source 'https://rubygems.org/' -- --with-cppflags=-I/usr/local/opt/openssl/include --with-ldflags=-L/usr/local/opt/openssl/lib
$ cd ファイルの保存場所
$ bundle install
```
* RailsでGemを追加するには*Gemファイル*に`gem 'gem名'`と追記して、`bundle install`コマンド を実行する。

```bash:
$ gem 'gem名'
$ bundle install
```

#運用環境
運用環境は３種類ある。
ローカルでの開発では基本的にdevelopment環境と呼ばれる開発用の環境しか使用しない。

| 運用環境 |                  概要                    |
|:------------|:-----------------------------------:| 
| development | 本番環境。アプリケーションをリリースする際に使用。 |
| poduction | 本番環境。アプリケーションをリリースする際に使用。 |
| test | テスト環境。アプリケーションの動作をテストする際に使用。 |

#データベースの作成
* データベースを作成するには`rake db:create`コマンド を使用する。
`data base.yml`というファイルにもとづいてデータベースを作成される。

```bash:
$ rake db:create
```
* 以下のエラーが表示されることがある。

```bash:
rake aborted!
Mysql2::Error::ConnectionError: Access denied for user 'root'@'localhost' (using password: NO)
```
* これは単純にパスワードが設定されていないために起こるエラー。
config/database.ymlにあるファイルにあるパスワードの欄が空白なので自分で値を入れて設定する。参考：[railsのapp作成でmysqlを使用する時の導入とハマるところ](https://qiita.com/Kaisyou/items/17142ff2d080d565fedc)

###データベースの確認
* Sequel Proを使用すればデータベースの中身をわかりやすく視覚化できる。
[Sequel Pro](https://sequelpro.com/download#auto-start)
接続時はソケット接続、名前：localhost、ユーザー名：rootで接続。
サポーターズの生放送勉強会に参加しました。

#アウトプットを始められない人への処方箋とは？
内容としてはYoutubeライブで登壇者方がアウトプットについてお話をしてくれました。
登壇者のういろうさんは毎日、ブログを書くと言うことを継続していてアウトプットするコツを教えてくれました。
まず最初に**「アウトプットするべき理由を」明らかにする**ここをしっかり軸を定めてからスタートする事が大事

自分はアウトプットする目的を学習の整理として現在、始めていますが今後は目的をその都度修正しようと思いました。
    
- アウトプットのコツ
    - 思い立ったらすぐ！
    - 無料・簡単に作る（こだわらない）
    - とりあえず、動くものを作る
    - 無理しない

>RPG感覚で自分の短い時間で無理ない範囲でやっていくとだんだんアウトプットのクオリティをあげていく
継続するのが難しいので、自分がアウトプットする事を楽しむ環境作りを行うことも大事!
自分のアウトプットする目的以外にもご褒美みたいなのを用意する。

毎日、アウトプットするのを習慣ずけするのは難しいと感じてたので意識的に楽しむ環境作りをする事は凄く大事だなと思いました。自分がやる理由、楽しむ事も意識していきます。

- 記事を書く際に意識する事
    - この記事を読む人は何が嬉しいか（概要）
    - その問題を解決するためにどうしたか（内容・詳細）
    - 誰向けか（ターゲット）
    
>論文の構成を参考にするのが結構良い

- アウトプットのメリット
    - 自信
    - 仲間
    - 転職
    - 他者貢献
    - 知名度（ブランディング）
    - あとで振り返る事ができる

今回の登壇者のういろうさんのブログです。
[【登壇資料】『アウトプットを始められない人 への処方箋』【612日目】](https://www.nyamucoro.com/entry/2019/06/17/204548)

#振り返り
プログラムを書いていてぶつかった課題があり、それを解決した際にしっかりアウトプットを習慣にしていなかったので、現状は自分用に解決した方法をしっかり振り返る事ができるようにアウトプットを習慣にして技術力をあげていきたいと思います。
"tidylog"でtidyverseを泳ぎきれ！ R初心者への浮き輪とか補助輪とかなんかそういう感じのやつ

# やぁみんな！dplyrしてるかい！
皆さまおはこんばんちは。「データサイエンスの90%はデータラングリングやで」だそうで。
まぁ色んなデータを毎日こねこねしてる方、いらっしゃるのではと思います。

で、ある程度出来てくると同僚とかも面白がって触ってみたがってくれたりするのですが
（みんなもっとR叩け―）
慣れてしまうとこんなに快適なdplyrパイプも、本当に始めてのひとには中々ワカランようで...

そんな時はこの一行！！

```R
pacman::p_load(tidylog)
```
初見殺しに見えるdplyrの各関数を、ヒューマンレダブルな文章で説明してくれちゃうのです。
（出力はRの標準コンソールに出ます）

## たとえばこんなコードを
```R:no_comments.R
uniwide <- unisales %>% 
  mutate(title_search = regtitle(title)) %>%
  select(-title, -inter_id) %>%
  left_join(manga2id, by = "title_search") %>%
  left_join(id2manga, by = "inter_id") %>%
  select(-title_search, title) %>%
  filter(dist == "pubridge") %>% 
  mutate(yearmon = floor_date(date, "1 month")) %>%
  group_by(yearmon, coa_id) %>%
  summarise(montotal = sum(sales)) %>%
  left_join(id2manga) %>%
  spread(yearmon, montotal)
```

## 「コメント付けたからわかるでしょ？」
つってもコメント書いたひとも勘違いしてたかもだし...
そもそもコード直した後コメント直し忘れとかしょっちゅうやし...(アカンけど)

```R:with_comments.R
uniwide <- unisales %>% 
  # manga2id でのサーチ用にtitleを変換
  mutate(title_search = regtitle(title)) %>%
  # 一度古いデータを排除
  select(-title, -inter_id) %>%
  # manga2idでcoa_idに名寄せ
  left_join(manga2id, by = "title_search") %>%
  # coa_id から正規タイトルを付け直す
  left_join(id2manga, by = "inter_id") %>%
  # search用カラム、元々のtitleを削除
  select(-title_search, title) %>%
  # 取次を一社だけに絞る
  filter(dist == "pubridge") %>% 
  # 日付データを一ヶ月単位にラウンド処理
  mutate(yearmon = floor_date(date, "1 month")) %>%
  # 日付単位・coa_id 別にグループ化 <- 月単位なのにコメント直して無い例
  group_by(yearmon, coa_id) %>%
  # 売上金額のグループ別集計
  summarise(montotal = sum(sales)) %>%
  # coa_id からタイトルを付け直す
  left_join(id2manga) %>%
  # WIDEデータに変換
  spread(yearmon, montotal)
```
で、実行しても割りと乾いた、メッセージ程度だけの出力。
初学者にはこれが怖いらしい。冷たいらしい。人間味を感じないらし...

```
Joining, by = "coa_id"
```


# tidylog を ON!!!!
 
```txt
mutate: new variable 'title_search' with 228 unique values and 0% NA
select: dropped 2 variables (coa_id, title)
left_join: added 13687 rows and added one column (coa_id)
left_join: added 0 rows and added one column (title)
select: dropped one variable (title_search)
filter: removed 178644 out of 987799 rows (18%)
mutate: new variable 'yearmon' with 64 unique values and 0% NA
group_by: 2 grouping variables (yearmon, coa_id)
summarise: now 6550 rows and 3 columns, one group variable remaining (yearmon)
Joining, by = "coa_id"
left_join: added 0 rows and added one column (title)
```
あらやだ丁寧。
慣れてる人でもうっかりミスとか、NA出来てないか手動でチェックしてる方も居ると思うんですが、
こんな感じで出してくれると一々個別に見なくて良いんで楽だなーと思います。

自分は毎回有効にするために.Rprofileに入れちゃいました。


## で、プログラミング未経験者の同僚に自分でデータ出ししてもらう
うわーい一瞬で数十万件のデータがWide集計出来たよ〜
<img width="320" alt="Screenshot 2019-06-18 at 20.36.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255842/8372aabb-39e0-af98-704f-7ae6a02e178c.png">

ってわけで部内の誰でも触れる用にrocker/tidyverseを立てました。
(廃棄PCの有効活用)

こんな数行のコードで100万件規模のデータが一瞬で集計出来るんだもんな〜
Excelでピボピボ言う生活にはもう戻れませんね。

ノンコーダーほどRを触るべきだと思う筆者であります。
初学者（ええ自分の事ですとも）の皆さまも、人にR叩かせたい手練れのの皆さまも、
#ぜひtidylog、覚えていって下さい。
ニートの自然言語処理100本ノック:35

頭使わなくなってコードに無理矢理感が出てきた。
またリファクタリングしようっと...
後『の』とか『ん』とか謎に入ってきているのを取り除かないとなあ

```python
"""
35. 名詞の連接
名詞の連接（連続して出現する名詞）を最長一致で抽出せよ．
"""

import MeCab
from pprint import pprint
from n30_execise import maping_morphology
from n31_execise import load_mecab_file,extract_verb_type_all



def extract_noun_continuos(analyzed_list):
    '''
    最長一致で名詞を連接したリストを出力する
    HACK:動詞の連結や助詞の連結なども作成できる?
    '''
    noun_join_list = []
    join_box = ""

    for mapped_morphology in analyzed_list:
        if mapped_morphology['pos'] == "名詞":
            join_box += mapped_morphology['Surface']
        elif join_box == "":
            continue
        else:
            noun_join_list.append(join_box)
            join_box = ""
            continue
            
    return noun_join_list


if __name__ == "__main__":
    
    # ファイルパス
    mecab_file = "neko.txt.mecab"

    # neko.txt.mecabを読み込む
    mecab_text = load_mecab_file(mecab_file)

    # 形態解析後のマッピングリスト
    analyzed_list = maping_morphology(mecab_text)
    # 連続する名刺をリスト格納
    noun_join_list = extract_noun_continuos(analyzed_list)
    print( noun_join_list)
```

# 出力結果
```
', '寿命', '金田君', '愚', '事', 'の', '天道公平君', 'おいで', '方', '鑑定', 'たんび', '余裕', '金田君', '近所', 'ゴロツキ', '今戸焼', 'たび', '八', 'ん', 'の', '主人', '判然', 'うち', 'もの', '予想', '手廻し', '八', 'ん', 'の', '主人', '八', 'ん', '八', 'ん', '主人', '判然', '主人', '手数', '八', 'ん', '剣突', '何', '苦', '主人', '横っ面', '訳', '昔', '西洋', '犯罪者', '所刑', '時', '本人', '国境外', '逃亡', '時', '偶像', '人間', '代り', '火あぶり', '彼等', 'うち', '西洋', '故事', '通暁', '軍師', '計略', 'もの', '落雲館', '八', 'ん', '袋', '腕', '主人', '苦手', 'ほか苦手', '町内中', '苦手', 'いま', '関係', '崩し', '紹介', '事', '八', 'ん', '泣き声', '主人', '朝っぱら', '癇癪', '布団', '上', '精神修養', '八木独仙', '何', 'もの', '両方', '手', 'ゴシゴシゴシ', '表皮', '頭中', '一ヵ月', 'フケ', '頸筋', '寝巻', '襟', '非常', '壮観', '髯', 'これ', '驚ろ', 'ぴん', '持主', '髯', 'もの', '一本一本', '癇癪', '勝手次第', '方角', '猛烈', '勢', '突進', 'これ', '見物', '昨日', '鏡', '手前', '事', '独乙皇帝陛下', '真似', '整列', 'の', '一晩', '訓練', '何', '者', '本来', '面目', '出', '立', 'の', '主人', '一夜作り', '精神修養', '�^C, '主人', '昔', '所', '寺', '下宿', '時', '襖一', '重', '尼', '五六人', '尼', 'もの', '元来意地', '女', 'うち', '意地', 'もの', '尼', '主人', '性質', 'もの', '自炊', '鍋', '今', '烏', '今', '烏', '拍子', 'そう', '主人', '尼', '嫌', 'の', '時', '尼', '嫌', 'それ', '違', '主人', '人一倍', '代り', 'いずれ', '事', '執着', '心機', 'むやみ', 'の', 'これ', '俗語', '翻訳', '奥行', '片', '鼻', '張', 'だだっ子', 'だだっ子', '以上', '喧嘩', '勢', '刎', '主人', '急', '気', '袋戸', '腸', 
```
[windows]リモートデスクトップにユーザー名/パスワードなしで接続するバッチ

#リモートデスクトップにユーザー名/パスワードなしで接続したい。
LAN内のサーバにリモート接続をする際、いちいちユーザー名とパスワードを入力するのが面倒なので、バッチを作成。


```cmd:リモート接続.bat
@Echo off
Set SERVER=IPアドレス
Set USERNAME=ユーザ名
Set PASSWORD=パスワード

Cmdkey /generic:TERMSRV/%SERVER% /user:%USERNAME% /pass:%PASSWORD%
Start mstsc /v:%SERVER%
Timeout 5
Cmdkey /delete:TERMSRV/%SERVER%
```


上記の内容をメモ帳等に貼り付けます。

「IPアドレス」、「ユーザ名」、「パスワード」を自分の接続先の情報に変更します。

あとは、拡張子を.batにして保存します。


保存したファイルをダブルクリックしたらユーザ名、パスワードの入力なしにリモートに接続できます。

ちなみにtimeoutを1とかにすると、接続する前にバッチが終了してしまい、ユーザー名・パスワードの情報が正しく接続先に渡されないときがあります。5秒くらいならOKな印象です。

※ユーザー名とパスワードがこのファイル内にベタ打ちで入力されることになるため、セキュリティ上問題があります。作成したバッチが流出しないように管理するのがよいかと思います。
PowerShellでインストール済みプログラムの一覧を取得する

# 方法1: レジストリから取得
```powershell
$base = "\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
$wow64 = "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
$path = @(("HKLM:" + $base), ("HKCU:" + $base))
if(Test-Path $wow64){
    $path += $wow64
}

# Get-ChildItemのままだとPSChildNameで名前しか取り出せないので、一旦PSPathを手に入れる。
# そのPathからGet-ItemPropertyを使用してプロパティを覗くと、そこにはDisplayNameやPublisherなどの情報が入っている
Get-ChildItem -Path $path |
    ForEach-Object {Get-ItemProperty -Path $_.PsPath} |
    #プログラムと機能に表示しないものを除外
    Where-Object {$_.systemcomponent -ne 1} |
    #更新インストールのものを除外
    Where-Object {$_.parentkeyname -eq $null} |
    #空白行を除外
    Where-Object {$_.DisplayName -ne $null} |
    Select-Object DisplayName, Publisher, Version |
    Sort-Object DisplayName 
```

# 方法2: WMIから取得（ただし不完全）
この方法だと「このユーザーに対してインストール」したプログラムが取得できないようで、「プログラムと機能」の一覧と差が出ます。
WMIからなんとか取得できないか調べたのですが分からなかったので、ご指摘頂けたらとても嬉しいです。

```powershell
Get-WmiObject Win32_InstalledWin32Program | 
Select-Object Name, Vendor, Version |
Sort-Object Name
```
plunkerで真理値表 その7

#概要

plunkerで真理値表やってみた。
nandで、なんでも作ってみる。

#not

![image](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/3bc7f0e4-527c-e658-eb00-8191170df385.png)

#and

![image](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/d8ed4445-e5d1-3c69-c6a1-5f4ace00b5f0.png)

#or

![image](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/f3c79705-f262-7f6e-fef8-5a9d4af73b68.png)

#xor

![image](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/8e9924f9-6df7-83b0-1c84-a3b91e029c20.png)

#成果物

https://embed.plnkr.co/ruqtjXnvT7O95qnvGCF9/

以上。
エンジニアでなくても、SQLの集計結果をダウンロードできるようにする。


Wordpressで動いているサイトのデータベースの集計結果を
エンジニアでない管理者でもダウンロードできるようにしたいなと考えています。
WordPressは詳しくないので、WPに依存しない方法を検討しています。

目標としては、クリックすると予め作っておいたSQLを実行しその結果をcsvなりExcelなどにしてダウンロードできるようにしたい。

(1)方法１
SELECT文の最後に

```SQL
INTO OUTFILE '保存先'　FIELDS TERMINATED BY ','　OPTIONALLY ENCLOSED BY '"';
```

を突っ込む。(上記でSQL実行時に保存先にSelectした内容のCsvが生成されます)
これをクリック時で実行できるようにする。。生成したファイルをレスポンスにいれてダウンロードさせる。
一番てっとり早く実装できるかなと思われます。


(2)方法２
PHP側で生成　こちらの記事が参考になりました。
https://qiita.com/hgsgtk/items/7782e81ccee8386bbc0b

翌日実装してあれこれ書いてみます。

<<翌日>>
とくに大きく嵌るポイントはありませんでした。

SQLを実行するPHPのファイル権限によっては、

```
\nWarning: touch(): Unable to create file utada.csv because Permission denied
```
と怒られるぐらいでした。
chmod & chown で適切な権限及びグループにすればなんてことはなかった。


```PHP
       $filepath = $generate_file_path;
       $filename = 'aggregate_data_student.csv';
        header('Content-Type: application/csv');
        header('Content-Length: '.filesize($filepath));
        header('Content-Disposition: attachment; filename="'.$filename.'"');
        readfile($filepath);
        unlink($filepath);
```

生成したcsvをディレクトリ上に残さない＆他者のアクセスをはじくようにするため
generate_file_pathとして、適当な乱数で一時ファイルを生成しました。
セキュリティ上おきっぱなしにしておくのはよくないので
httpレスポンスheaderに生成したcsvを入れ込んだのち、即削除する仕様にしてあります。
マイグレーションに関する知識！

こんにちは！:smiley:

チーム開発をしていく中で、マイグレーションに関するコンフリクトが多発したので、マイグレーションの知識を深掘りするためにも記事を書きました！

## 未実行のmigrationを知りたい...
そんな時に、便利なコマンドがこちらです！

```terminal
bundle exec rake db:migrate:status
```

Railsのマイグレーションファイルは、ファイルの作成後、マイグレートを実行して初めてデータベースに変更が反映されます！（***rake db:migrate***)

開発を進めていく中で、マイグレーションファイルが増えて、どのファイルまでがマイグレートを実行し終えているかターミナルで確認することができます！

## マイグレートを実行した後に、修正する手順！
(マイグレートを実行した後に、内容の誤りがあることが分かりました....):frowning2:

(どのように修正すれば良いでしょうか...?):frowning2:

(ほほう、2つの方法をご紹介しよう！):older_man_tone1:

### ➀
・***bundle exec rake db:rollback***を実行して、一度マイグレートされていない状態に戻す。
・マイグレーションファイルを修正する。
・再び***rake db:migrate***を実行する！

### ➁
・***rails g migration***で新たなマイグレーションファイルを作成する。
・修正箇所を正しい内容に変更するためのマイグレーションファイルを作成する。
・***rake db:migrate***を実行する！

(これら２つの方法で、修正することが可能じゃ):older_man_tone1:

## マイグレーションファイルによる禁止事項！

(一度実行されたマイグレーションファイルは、次のマイグレートに影響は及ぼさないんですよね？):frowning2:

(そうじゃ):older_man_tone1:

(それじゃあ、マイグレート後にファイルを変更したり削除したとしても今のDBに悪影響を及ぼすことはないから、変更したり削除したりしてもいいんですか？):frowning2:

(それは、けしからん！):older_man_tone1:

(チーム開発において致命的な不具合が出てしまうんじゃ...):older_man_tone1:

(どういうことでしょうか？）:frowning2:

(アプリケーションのファイルをデプロイ先にpushし、マイグレートを行なった時に、ローカル環境と違ったDBが出来上がったり、エラーになってしまうんじゃ...):older_man_tone1:

(コンフリクトなどの原因にもなりかねんから、やってはいけないぞ！):older_man_tone1:

(分かりました！ありがとうございます！）:relaxed:

---

以上となります！

最後の章は会話形式でまとめてみました！

その他、マイグレーションに関する見知など教えて頂けると幸いでございます！

コメントお待ちしております！

ご静聴ありがとうございました:relaxed:
Pythonのprint内での変数の扱い方

[未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)でインターンをしている山田です。

Pythonについて学習のアウトプットとして投稿します。

プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし、誤りがあれば修正するのでどんどん指摘してください。

#print内で変数を扱う方法

pythonで定義した変数をprintで表示する方法をご紹介します。

そもそも、私はインターン先のカリキュラムの課題に取り組んでいた時にこの壁にぶつかりました。
print内で複数行のHTMLを書いている際に、pythonで定義した変数をどのように表示すればいいのか分からず初めは非常に戸惑いました。
そこで、私のような初心者の方もたくさんいるのではないかと思い今回このテーマについてまとめることにしました。

私が調べた中で初心者向けにオススメできるという点で、print内で変数を扱う方法を4つ紹介します。

1.「変数+文字列」を使う
2.printf形式の文字列書式化を使う
3.format関数を使う
4.f文字列(f-strings)を使う

3については、以前Qiitaに投稿させていただきまして、4についてコメントをいただいたので、今回は１と2について紹介していきます。

以前の記事▼
[Pythonで複数行のHTMLを書く際のformat関数の使い方](https://qiita.com/kento_y/items/fb7944084e410a607679)

#「変数+文字列」を使った方法

これはもっとも単純な方法であると言えますが、**Hello,World!** と出力したいときを想定すると以下のようになります。

```hello.py
aisatsu = 'Hello'
sekai = 'World!'

print(aisatsu + ',' + sekai)
```

ただし、数字を使う場合はstring関数を使って数字を文字列に変換する必要があります。

```age.py

age = 20

print('私は' + str(age) + '歳です')

```

```実行結果.
私は20歳です
```

「変数+文字列」は、非常に簡単ですが、単純な場合にのみ向いている方法です。

#printf形式の文字列書式化を使う方法

sprintfは%演算子を使って変数で置き換える方法です。
具体的には、%dや%sなどの変換指定文字を利用して文字列と変数を出力します。
「変数+文字列」の際に用いた年齢の例を今回も使うと、以下のようになります。

```age.py

age = 20

print('私は%d歳です' % age)

```
```実行結果.
私は20歳です
```

変数の中身が数値(整数)のときは「%d」
変数の中身が文字列のときは「%s」を使います。

これを応用すると、print内でHTMLを使って複数の文字列を表示する場合など、もう少し複雑な場合でも使用できます。

```index.py
#変数の定義
age=20
height=170
weight=60

datalist = "あなたは、年齢:" + str(age) + "歳,身長:" + str(height) + "cm,体重:" + str(weight) + "kgでよろしいですか？"

# 以下のコードを書かないと、htmlとして読み込んでもらえない。
print("Content-type: text/html; charset=utf-8")

# printでHTMLコードを表示させることで、ブラウザがHTMLコードとして認識してくれる。
print(
  ( 
   """
     <html>
      <head> 
      <meta http-equiv=\"Content-Type\" content=\"text/html
           charset=utf-8\" / >
      </head>
      <body>
   　　確認してください。<br>

　    %s

      </body>
      </html>
     """
  )
  % datalist
)


```
```実行結果.
確認してください。
あなたは、年齢:20歳,身長170cm,体重:60kgでよろしいですか？
```
このように、sprintfを使えば、複数の数値を文字列にまとめた変数を定義した上で、HTMLとして表示することができます。

※コメントでご指摘を受け、一部修正させていただきました。(2019/6/19)
Shema小話

# その1: スキーマの意味
---

## schema の意味(一般)

1. 図式、図表、図解
2. 概要、大要

---
## schema (データベース関連)
1. 構造
    1. 「三層スキーマ」等
<details>外部スキーマ・概念スキーマ・内部スキーマ、概念スキーマ・内部スキーマ・物理スキーマのような使われ方</details>
    
    2. 「DBスキーマ」
<details>テーブル定義やインデックス定義など、データベースのメタ情報を指す</details> 

2. スキーマオブジェクト
<details>「CREATE SCHEMA」で作られるDBのオブジェクトをまとめるオブジェクト</details>

---

## 意味の識別方法

- 前後の文脈から判断する
- 会話等でわからない場合は相手に聞きましょう。

---

# その2: schema の複数形

---

## 問題: schema の複数形は？

1. schemas
2. schemata

---

## 正解: 両方使われている

---

## 不規則変化名詞の例

- phenomenon - phenomena
- automaton - automata
- antenna - antennae
- datum - data

---

## 問題: SQL Server では schema の複数形としてどちらが使われている？

1. schemas
2. schemata

---

- SELECT * FROM sys.schemas
- SELECT * FROM INFORMATION_SCHEMA.schemata

## 正解： 両方
HTMLアンケートの作成方法

こんにちは。職業です。

#⃣今回はアンケートです！
![フォーム１　アンケート.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427747/44a716ab-a609-e8c1-0bf2-58d72f70a674.png)
ポイントとなるタブ
**[form]**
**[text]**
**[submit]**
**[textarea]**
それぞれについて説明していきます。

まずは**[form]**フォームからです。
フォームとは、情報を入力、選択することです。
組み合わせが効く使い勝手が良いものになります。

action→データの飛ばし先を指定
method=[post]or[get]今回は何も書かないので[post]
value→ボタンに表示されるテキスト部分


**テキストフィールド**
inputタグを使い、typeで[text]を指定します。
今回はnameを使用します。

**送信ボタン**
送信ボタン→typeで[sumit]を指定します。
ボタンのテキストは[value]で指定します。

**テキストエリア**
テキストフィールドは複数行書くことができるフォームを作成することが出来ます。

![フォーム1 あんけーと０.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427747/ac30e556-8ca0-2b9c-c4f6-5f30c71d9a49.png)

参考になって頂けたら幸いです！
CodeIgniter の DB_Driver (save_queries) にご注意【vol.1】

株式会社オズビジョンのユッコ (@terra_yucco) です。
CodeIgniter の DB_Driver 及び config/database.php をデフォルト設定のまま使っていたので、DB オブジェクトを引き回しすぎてバッチ処理がメモリ不足で乙りました。というお話。

# CodeIgniter

PHP の軽量フレームワークです。


## DB_Driver

名前の通り、DB に接続するためのあれこれが詰まったクラスです。
この中の `save_queries` で今回嵌りました。

### 定義部分

https://github.com/bcit-ci/CodeIgniter/blob/9ffd233ba6b890ff034e985d1d87969c8dc755a7/system/database/DB_driver.php#L200-L207

```php
	/**
	 * Save queries flag
	 *
	 * Whether to keep an in-memory history of queries for debugging purposes.
	 *
	 * @var	bool
	 */
	public $save_queries		= TRUE;
```

### 利用箇所

上記コードから抜粋

この処理の少し前で SQL を作って `$sql` に入れている。
作成した `$sql` はこのインスタンスの寿命がある限りどんどん追加されていく。

```php
		if ($this->save_queries === TRUE)
		{
			$this->queries[] = $sql;
		}
```

その他、実行時間も以下のような 2 箇所で保存。

クエリ発行失敗時。

```php
		// Run the Query
		if (FALSE === ($this->result_id = $this->simple_query($sql)))
		{
			if ($this->save_queries === TRUE)
			{
				$this->query_times[] = 0;
			}
```

クエリ発行成功時。

```php
		if ($this->save_queries === TRUE)
		{
			$this->query_times[] = $time_end - $time_start;
		}
```

これもどんどん領域に追加されます。

## 対処するには

以下のようにすればよいと思われます。最後のところだけ、オリジナルのコードは `TRUE` ですが `false` にしています。

https://github.com/bcit-ci/CodeIgniter/blob/9ffd233ba6b890ff034e985d1d87969c8dc755a7/application/config/database.php#L76-L96

```php
$db['default'] = array(
	'dsn'	=> '',
	'hostname' => 'localhost',
	'username' => '',
	'password' => '',
	'database' => '',
	'dbdriver' => 'mysqli',
	'dbprefix' => '',
	'pconnect' => FALSE,
	'db_debug' => (ENVIRONMENT !== 'production'),
	'cache_on' => FALSE,
	'cachedir' => '',
	'char_set' => 'utf8',
	'dbcollat' => 'utf8_general_ci',
	'swap_pre' => '',
	'encrypt' => FALSE,
	'compress' => FALSE,
	'stricton' => FALSE,
	'failover' => array(),
	'save_queries' => false, #TRUE
);
```

## 実は注意書きもあった

https://github.com/bcit-ci/CodeIgniter/blob/9ffd233ba6b890ff034e985d1d87969c8dc755a7/application/config/database.php#L59-L65

>['save_queries'] TRUE/FALSE - Whether to "save" all executed queries.
NOTE: Disabling this will also effectively disable both
$this->db->last_query() and profiling of DB queries.
When you run a query, with this setting set to TRUE (default),
CodeIgniter will store the SQL statement for debugging purposes.
However, this may cause high memory usage, especially if you run
a lot of SQL queries ... disable this to avoid that problem.

['save_queries'] true または false
実行されたすべてのクエリを保存するかどうか。
メモ：これを false にすると `last_query()` が使えなくなり、またクエリのプロファイリングも使えなくなる。
この設定が true の状態でクエリを走らせると CodeIgniter は SQL ステートメントを debug のために保管する。しかし、特に実行クエリが多い場合、メモリ使用量の高騰の原因になるので、その場合はこの項目を無効にしてその問題を回避してください。

# Conclusion

`last_query()` が使えなくなるのは地味に痛いので、環境によって変更したり、接続単位で変更してあげるなどの工夫は必要そうです。
ただ、本番環境でデバッグ情報を大量に保持する必要はないので、基本的には設定を切っていきたいなと思った次第…。