OmniAICreator/Qiita-1.07M huggingface dataset:
FireStoreでページングを試してみたメモ

## 概要

FireBaseのバージョンは6.3.5。
FireStoreを使ったページングについて試したメモ。
最初に件数を取得する以外に何か方法がないか探している。

## ソース

保存の頻度は高くなく、createdAtにnanosecondsまで同じデータはなく、ユニークな値となっている想定。
nextPageTokenが空白のときは次のページはないという仕様にしている。
以下のソースだと、limitと、保存されているデータの総数が同じときに、
次のデータがないのに「次へ」というボタンが表示されるバグがある。

```ts
import * as firebase from 'firebase';
const { Timestamp } = firebase.firestore;

export async function readEnemies(storeUserId, limit, pageToken) {
  const db = firebase.firestore();
  let query = db.collection("users").doc(storeUserId).collection('enemies').orderBy('createdAt', 'desc').limit(limit);
  const splitter = ':';

  if (pageToken !== "") {
    const [seconds, nanoseconds] = pageToken.split(splitter);
    const timestamp = new Timestamp(seconds, nanoseconds);
    query = query.startAfter(timestamp);
  }

  const querySnapshot = await query.get();
  const enemies: any[] = [];
  await querySnapshot.forEach((doc) => {
    const enemy = doc.data();
    enemies.push(enemy);
  });

  if (querySnapshot.docs.length < limit) {
    // limitより少なければ、次のデータはないとする ... limitと同値の時は次へが表示されてしまう
    return { enemies, nextPageToken: "" };
  }

  const last = querySnapshot.docs[querySnapshot.docs.length - 1];
  const lastData = last.data();
  const time = lastData.createdAt;
  let nextToken = `${time.seconds}${splitter}${time.nanoseconds}`;

  return { enemies, "nextPageToken": nextToken };
}
```

### 参考ソース
[ts](https://github.com/hibohiboo/garden/blob/9efb71c8f8b0be85a76ff18059c089b55c06ea0e/src/assets/js/src_ts/crud.ts#L225)
[index](https://github.com/hibohiboo/garden/blob/9efb71c8f8b0be85a76ff18059c089b55c06ea0e/src/index.pug#L42)

## 参考

[Firestore で いいね順（Score順）Sort + Paging するポイント](https://qiita.com/MasanobuAkiba/items/6a0f4e3007816dd54bec)
[クエリカーソルを使用したデータのページ設定](https://firebase.google.com/docs/firestore/query-data/query-cursors)
[firebase. firestore. Timestamp](https://firebase.google.com/docs/reference/js/firebase.firestore.Timestamp)
[Firestoreを試してみた](https://qiita.com/miyae/items/6988c1b61b76b4938ae6)
[Firebase Cloud Firestoreの使い方](https://qiita.com/subaru44k/items/a88e638333b8d5cc29f2)
[TypeScriptからFirestoreを使いやすくするfirestore-simple v4をリリースしました](https://qiita.com/Kesin11/items/c2a52e4e33d6f8e83723)
[Firestoreお役立ちリンク](https://qiita.com/teramo3033/items/d24925f47840baa02c32)
チートシートまとめ


yum コマンド チートシート
https://access.redhat.com/sites/default/files/attachments/rh_yum_cheatsheet_1214_jcs_print-ja.pdf

ip コマンド　チートシート
https://access.redhat.com/sites/default/files/attachments/rh_ip_command_cheatsheet_1214_jcs_print_ja4.pdf

systemd コマンド　チートシート
https://access.redhat.com/sites/default/files/attachments/12052018_systemd_6.pdf
Ruby プログラミングノート Part1

## はじめに
[Ruby on Rails チュートリアル](https://railstutorial.jp/ "Ruby on Rails チュートリアル")の実施と並行してRubyの学習を行い
自身の記憶定着のためプログラミングノートとして書き起こす。

[Progate](https://prog-8.com/languages/ruby)および[チェリー本の1～3章](https://www.amazon.co.jp/dp/B077Q8BXHC/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)での学習結果の書き起こしになる

## RubyとRuby on Railsとの違い
|Ruby|Rails|
|:--|:--|
|プログラミング言語<br>（Python等と同様）|Rubyを用いたWebアプリケーションの<br>開発用のフレームワーク| 
|文字列、数値、true/false、nilのすべてがオブジェクト<br>(オブジェクトに対してメソッドが呼べる)|MVCモデルの提供<br>M＝Model(モデル)　データの処理<br>V＝View(ビュー)　見た目の処理<br>C＝Controller(コントローラ)　ModelとViewを制御する| 

## Rubyの基本文法
### Rubyファイルの実行
```bash
$ ruby ファイル名（～.rb）

Ex.
$ ruby sample.rb
```
### ライブラリの種類
- インストール不要  
   - 標準ライブラリ（date,csvなど　https://docs.ruby-lang.org/ja/latest/library/index.html）
   - 組込みライブラリ（Array,Hashなど　https://docs.ruby-lang.org/ja/latest/library/_builtin.html）

- インストール必要 
    - gem(外部ライブラリ)

### ライブラリのインポート
- インストール不要

```ruby
# ファイル名指定時に拡張子の「.rb」は不要
require "ライブラリ名"
require "ファイルパス"

Ex.
  require "date"         (Dateクラス)
  require "./home/start" (home/start.rbファイル)
```      

### 変数宣言
```ruby
# 変数名のみの定義は不可能
  変数名 = 値（型の宣言が不要）
```

### コンソールへの入出力(putsとgets)
- コンソールへの表示  

```ruby
puts 文字列
puts 変数
```
  
- コンソールへの入力    

```ruby
# 改行付きの入力
  変数名 = gets       

# 改行を外した入力
  変数名 = gets.chomp
```

### 文字列

```ruby
# 定義
  クオーテーション「""」と「''」
   
# 変数の埋め込み
  "・・・#{変数名}・・・"
   
# 文字列の連結（数値 + 文字列は使えない）
  文字列 + 文字列

# 文字列 ⇔ 数値の変換
 （→文字列）変数.to_s
 （→数値）  変数.to_i
　数値でも整数（.to_i）、小数（.to_f）など種類がある


Ex. 
   num_age = 19
   str_age = '19'
   puts num_age + "歳"  　→ エラー
   puts "#{num_age}歳"  　→ 19歳
   puts 'str_age' + '歳'　→ 19歳
```

###「""」と「''」の違い
- 文字列に埋め込んだ変数を展開する・・・「""」
- 文字列に埋め込んだ変数を展開しない・・・「''」

```ruby
Ex. 
  name = "田中"
  puts "やあ#{name}さん"　→　やあ田中さん
  puts 'やあ#{name}さん'　→　やあ#{name}さん
```

### if文の使い方
```ruby
# 年号からうるう年を判別する
  year = 2019

  if year % 4 != 0 
    puts "うるう年ではありません"
  elsif year % 100 == 0 && year % 400 != 0
    puts "うるう年ではありません"
  elsif year % 100 == 0 || year % 4 == 0
    puts "うるう年です"
  end
  	
# if文の判定結果をTrue,false
  if shipping_free?(3000)
    puts "3000以上の数"
  else
    puts "3000より小さい"
  end
```

## テストの自動化
### Minitestの利用
- メソッドから出力される値が期待通りかを検証できる
- Fizzbuzzのテスト例にして作成する

```ruby:FizzBuzz.rb
def fizzbuzz(input_num)
  if input_num % 15 == 0
    'Fizz Buzz'
  elsif input_num % 5 == 0
    'Buzz'
  elsif input_num % 3 == 0
    'Fizz'
  else 
    input_num.to_s
  end
end
```
```ruby:FizzBuzz_test.rb
require 'minitest/autorun'
require 'FizzBuzz'

class FizzBuzzTest < Minitest::Test
  def test_fizz_buzz
    assert_equal '1', fizzbuzz(1)      
    assert_equal 'Fizz', fizzbuzz(3)
    assert_equal 'Buzz', fizzbuzz(5)
    assert_equal 'Fizz Buzz', fizzbuzz(15)
  end
end
```
```bash
$ ruby FizzBuzz_test.rb
-> テスト実施時間や、テスト結果（runs, assertions, failures, errors）がでる
openFrameworks上での行列演算メモ

# はじめに
CGなどを勉強しているとどうしてもさけて通れない分野の中の１つとして線形代数があるかと思いますが、今回はそのうちの行列演算などにスポットを当ててメモを残しておきたいと思います．
oF上での行列を扱うには```ofMatrix3x3```, ```ofMatrix4x4```などと言ったクラスが存在しており、それらを扱って変換行列など用意し行列演算を行っていきます．

# 行列データの保存形式
## 行優先、列優先
行列の保存形式には行優先形式と列優先形式というものが存在します．

```math
data = [a_{1}, a_{2}, a_{3}, a_{4}]
```

- 列優先(Column-Major)

```math
matrix_{col} = 
\left(
\begin{matrix}
a_{1} & a_{3} \\
a_{2} & a_{4} 
\end{matrix}
\right)
```
- 行優先(Row-Major)

```math
matrix_{row} = 
\left(
\begin{matrix}
a_{1} & a_{2} \\
a_{3} & a_{4} 
\end{matrix}
\right)
```

## APIごとでの保存形式の違い
このうちopenFrameworksでは<font color="MediumBlue">行優先形式</font>、GLSLでは<font color="MediumBlue">列優先形式</font>が採用されています．
こちらはofMatrix4x4.hに書かれているドキュメントです．
> /// oF uses row-vector style by default, meaning that when transforming a vector
/// by multiplying with a matrix, you should put the vector on the left side and
/// the matrix (or matrices) to its right. When multiplying by multiple matrices,
/// the order of application of the transforms is left-to-right. This means that
/// the standard order of manipulation operations is 
/// vector * scale * rotate * translate.
///
/// Note that in GLSL, this convention is reversed, and column-vector style is
/// used. oF uploads the matrices to the GL context correctly, but you should
/// reverse the order of your vertex manipulations to right-to-left style, e.g.
/// translate * rotate * scale * vector.

上に記されているように、<font color="MediumBlue">行優先形式</font>ではベクトルに対して<font color="MediumBlue">後</font>から変換行列を掛け、<font color="MediumBlue">列優先形式</font>ではベクトルに対して<font color="MediumBlue">前</font>から変換行列を掛けることに注意してください．(行列は掛け算の順序によって計算結果が変わってしまいます．)

# サンプルコード
全てではありませんが参考になりそうなコードを貼っておきます．

```sample.cpp
void ofApp::setup(){
    scaleMatrix.set(scale->x, 0.0, 0.0, 0.0,
                    0.0 , scale->y, 0.0, 0.0,
                    0.0, 0.0, scale->z, 0.0,
                    0.0, 0.0, 0.0, 1.0);
    
    translateMatrix.set(1.0, 0.0, 0.0, 0.0,
                        0.0 , 1.0, 0.0, 0.0,
                        0.0, 0., 1.0, 0.0,
                        translate->x, translate->y, translate->z, 1.0);
    
    modelMatrix = ofMatrix4x4::newIdentityMatrix();
    modelMatrix.preMult(scaleMatrix);
    modelMatrix.preMult(translateMatrix);
}

void ofApp::draw(){
    cam.begin();
    ofMatrix4x4 viewMatrix;
    viewMatrix = ofGetCurrentViewMatrix();
    ofMatrix4x4 projMatrix = cam.getProjectionMatrix();
  
    ofDrawAxis(1000.0);
    shader.begin();
    shader.setUniformMatrix4f("modelMatrix",  translateMatrix);
    shader.setUniformMatrix4f("viewMatrix",  viewMatrix);
    shader.setUniformMatrix4f("projMatrix",  projMatrix);
    cam.getProjectionMatrix();
    ofDrawRectangle(0.0, 0.0, 300.0, 300.0);
    shader.end();
    
    cam.end();
}
```

```sample.vert
uniform mat4 modelViewProjectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 projMatrix;
uniform mat4 modelMatrix;
in vec4 position;
void main()
{
  vec4 p = projMatrix * viewMatrix * modelMatrix * position;
  gl_Position = p;
}

```
ターミナルについての備忘録

#1. はじめに
- Mac環境の勉強がてらTerminal（ターミナル）について調べたので自分用の備忘録としてまとめました。

#2. Terminal（ターミナル）とは
- 端末エミュレータのこと。
- MacOSに標準で搭載されている`Terminal.app`や、`iTerm2`が該当する。
- Terminal.appを起動すると、CLI（Command Line Interface：コマンドラインインターフェイス）のShell（シェル）であるBash（Bourne Again Shell：ボーンアゲインシェル）が起動する。

##2-1. 端末エミュレータとは
- キャラクタ端末（テキストの入力と表示を行う端末）を画面（ウインドウシステム）上で擬似的にエミュレートしたもの。

##2-2. Shell（シェル）とは
- ユーザがOS内部（Kernel：カーネル）とやりとりするためのソフトウェア。
- カーネル自身はユーザと対話することができないため、ユーザがターミナルで入力したコマンドや入力操作をシェルが解釈し、カーネルに処理を依頼する。その後カーネルから出力された結果やメッセージをユーザに返す。

##2-3.ターミナル上でのコマンド入力、解釈、実行までの流れ
- 例として`ls`コマンド実行までの流れ
 
1. ターミナル上で`ls`コマンドを入力。
2. シェルがコマンドを解釈し、カーネルに処理（**ディレクトリ、ファイルのリスト出力**）を依頼。
3. カーネルが依頼された処理を実行。
4. シェルがカーネルの処理結果を解釈し、ターミナルに結果（**ファイル、ディレクトリのリスト**）を返す。
5. ターミナル上に結果（**ファイル、ディレクトリのリスト**）が表示される。

#3. （よく使いそうな）コマンド一覧
## pwd コマンド
- print working directoryの略。
- カレントディレクトリのパスを表示する。

```sh:pwd
$ pwd #カレントディレクトリのパスを表示
```

## ls コマンド
- listの略。
- カレントディレクトリにあるファイルを表示する。

```sh:ls
$ ls #カレントディレクトリにあるファイルとディレクトリを表示
$ ls -a #隠しファイルも含めたファイルとディレクトリを表示
$ ls -l #ファイルやディレクトリの詳細も表示
```

## cd コマンド
- change directoryの略。
- カレントディレクトリを移動する。

```sh:cd
$ cd Desktop #カレントディレクトリをDesktopフォルダに移動
$ cd ~ #ホームディレクトリに移動
$ cd .. #カレントディレクトリを1階層上のディレクトリに移動
```

## touch コマンド
- ファイルのタイムスタンプを変更する。
- 存在しないファイル名を指定するとファイルを新規作成する。

```sh:touch
$ touch hoge.md #hoge.mdを新規作成
$ touch hoge.md #hoge.mdのタイムスタンプを現在日時に設定
$ touch -d "2019-8-11 20:30" hoge.md #hoge.mdのタイムスタンプを2019/8/11 20:30に設定
```

## mkdir コマンド
- make directoryの略。
- カレントディレクトリに指定フォルダ（ディレクトリ）を作成する。

```sh:mkdir
$ mkdir hoge #hogeフォルダを作成
$ mkdir -m 666 hogehoge #パーミッション（666：全ユーザに読み書き許可、実行許可なし）のhogehogeフォルダを作成
```
## mv コマンド
- moveの略。
- ファイルを移動またはファイル名をリネームする。

```sh:mv
$ mv hoge.md Desktop/ #hoge.mdをDesktopに移動
$ mv hoge.md hoge1.md #hoge.mdをhoge1.mdにリネーム
```

## cp コマンド
- copyの略。
- ファイルまたはフォルダ（ディレクトリ）をコピーする。

```sh:cp
$ cp hoge.md hoge1.md #hoge.mdをhoge1.mdとしてコピー
$ cp -r test test1 # testフォルダをtest1フォルダとしてコピー
```

## rm コマンド
- removeの略。
- ファイルまたはフォルダ（ディレクトリ）を削除する。

```sh:rm
$ rm hoge.md #hoge.mdを削除
$ rm hoge* #ファイル名にhogeを含むファイルを削除
$ rm -r test #testフォルダを削除
```

## openコマンド
- ファイルまたはフォルダ（ディレクトリ）を開く。

```sh:open
$ open . #カレントディレクトリをFinderで開く
$ open ~ #ホームディレクトリをFinderで開く
$ open hoge.md #関連付けられているアプリでhoge.mdを開く
```
## source コマンド
- ファイルを再読み込みする。

```sh:source
$ source .bash_profile #.bash_profileを再読み込みし、設定を有効にする
```
## findコマンド
- ファイルを検索する。

``` sh:find
$ find ~/ -name *.md # ホームディレクトリ配下の.mdファイルを検索
```

## grepコマンド
- ファイル内の文字列に対して検索する。

```sh:grep
$ grep hoge *.md # カレントディレクトリに存在する.mdファイルについて、hogeを検索
$ grep hoge ./DEV # DEVディレクトリに存在するファイルについて、hogeを検索

# findコマンドと組み合わせて指定ディレクトリ配下を再帰的に検索する
$ find ./DEV -name "*.md" | xargs grep hoge # DEVディレクトリ配下の.mdファイルについて、hogeを検索
```
Google Apps Scriptのトリガーで実行されるバージョンについて

# はじめに
Google Apps Script（GAS）において、運用しながら開発をするために、指定したバージョンの関数をトリガーで実行する必要がありました。

そのときに調べてわかったことを備忘録として記事にします。

# 「実行するデプロイを選択」でHEADが実行されると困る
トリガーの設定画面で「実行するデプロイを選択」することができます。
![Screenshot from 2019-08-10 17-58-55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356779/a8cad319-f893-2d0d-6be4-28087d0b0c21.png)
運用しながら開発したいときに、「HEAD」がトリガー実行されると困りますよね。保存されている最新のコードがHEADバージョンなので、開発途中に実行されてもちゃんと動かないことが多い。

そんなときにはGASのバージョン管理とデプロイメント機能を利用することで、望ましいコードをトリガー実行できるようにできます。

流れとしてはこんな感じです。
1. 実行したいソースコードのバージョンを作成
2. デプロイ
3. 「実行するデプロイを選択」で自分で作成したデプロイを選択

## 1. バージョン管理
コードのスナップショットを保存しておくことができます。
プロジェクト画面で「ファイル」→「版を管理」→説明文を追加→「新しいバージョンを保存」
とすることで、現時点のコードを保存しておくことができます。

注意：ソースコードの変更履歴の管理をしたい場合は、別途Gitなどで管理すること。GASの変更履歴機能は使いづらいので。

## 2. デプロイメント機能
WEBアプリケーションやAPIとして公開することができます。今回はこの機能で指定バージョンをデプロイし、それをトリガーで実行するように設定します。

「公開」→「マニフェストから配置」を押すと以下の画面になります。現在はLatest VersionというDeploymentのみ存在します。
![Screenshot from 2019-08-10 18-24-32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356779/e3fd2c1f-7c9d-7680-72a4-d8305a673667.png)

「Create」→Development nameとVersionを設定→「Save」
この画面で新しいバージョンを作成することもできます。
![Screenshot from 2019-08-10 18-27-11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356779/57c1e424-f384-70c4-c460-6a7dff8948b4.png)

新しいDeploymentを作成できました。「Edit」からデプロイするバージョンの変更もできます。
![Screenshot from 2019-08-10 18-31-25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356779/6576d644-0d27-a657-dd26-442ca70d1ae3.png)

## 3. トリガーの設定
「編集」→「現在のプロジェクトのトリガー」→「トリガーを追加」→「実行するデプロイを選択」から先程のデプロイを選択できるようになります！デプロイの名前やIDではなく、デプロイされているバージョンが表示されているのがややこしい、、。
![Screenshot from 2019-08-10 18-34-41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356779/a580f602-b42c-490a-a9a6-9fbda5ef6794.png)

これで、開発しながらも正しく動くバージョンをトリガーで実行することができるようになりました。
注意点としては、デプロイしているバージョンNo.が変更されると、トリガーで実行されるバージョンも変更されます。トリガーの作成時に、バージョンではなくどのデプロイを実行するか指定しているからです。

# スクリプトでトリガーを作成した場合
手動ではなく、[Script service](https://developers.google.com/apps-script/reference/script/)を利用することによってトリガーを作成・削除することができます（[参考](https://developers.google.com/apps-script/guides/triggers/installable#managing_triggers_programmatically)）。

```javascript
function createTimeDrivenTriggers() {
  // Trigger every 6 hours.
  ScriptApp.newTrigger('myFunction')
      .timeBased()
      .everyHours(6)
      .create();
}
```
`create()`で作成されたトリガーで実行されるバージョンは、`create()`が実行されたコードとバージョンと同じです。つまり、バージョン1の`createTimeDrivenTriggers`関数で作成されたトリガーは、バージョン1の`myFunction`関数を実行します。
共発現解析（相関分析） 応用編

#前回までの内容
1. [R初心者のための共発現解析（相関分析） イントロ編](https://qiita.com/Ykeito/items/a7554397943c2168fb17)
2. [R初心者のための共発現解析（相関分析） 実践編](https://qiita.com/Ykeito/items/38191088a1edd2ba4979)

#目的
簡便かつ迅速に相関分析をすること。

#対象
ある程度自力でデータ処理できる方（corrrを使えば簡便かつ迅速に相関分析ができますが、その後、自分でデータ処理できなかったら宝の持ち腐れだと感じているので、ある程度自力でデータ処理ができる方といった表現になっています）。

#簡便かつ迅速に相関分析ができるスクリプト
##corrrのインストール
```
install.packages("corrr")
```

##corrrの読み込み
```
library(corrr)
```

##corrrの実装
```
T.data <- iris[, 1:4]
temp <- correlate(T.data)
temp <- shave(temp)
temp <- stretch(temp, na.rm=T)
```

#番外編：より見えやすいスクリプトを書く
参考サイト1でも使っているが、dplyrパッケージを入れているとパイプ（ %>% ）が使えるようになります。ちなみにパイプはctrl + shift + Mで入れることができます。
##dplyrのインストール
```
install.packages("dplyr")
```

##dplyrのインストール
```
library(dplyr)
```

##より見えやすいスクリプト
```
temp <- T.data %>% 
  correlate() %>% 
  shave() %>% 
  stretch(na.rm=T)
```
#次回の内容
[共発現解析（相関分析） 応用編+α](https://qiita.com/Ykeito/items/23d5f99287852c4be5b0)
#参考サイト
下の2つのサイトに使い方が丁寧に書かれています。
>1. https://drsimonj.svbtle.com/exploring-correlations-in-r-with-corrr
>2. https://kazutan.github.io/kazutanR/corrr_test.html
OpneJDK8 ビルド on CentOS7_x86_64

#OpenJDK8 をソースコードからビルド

参考：http://hg.openjdk.java.net/jdk/jdk/file/tip/doc/building.md

#必要パッケージ導入

"開発者ツール"をグループインストール
(*) OSインストール時に"開発者ツール"にチェックをいれた場合は作業不要

```
# yum groupinstall -y "Development Tools"
```

openjdkビルドに必要な依存パッケージ導入
ブートストラップJDKは以前のメジャーリリースのJDKを使用する(OpenJDK7)
(参考)http://hg.openjdk.java.net/jdk8/jdk8/raw-file/tip/README-builds.html#setup

```
# yum install -y java-1.7.0-openjdk-devel
# yum install -y libXtst-devel libXrender-devel cups-devel freetype-devel alsa-lib-devel libXt-devel fontconfig-devel
```



#ソースコードDL

バージョン管理ツール Mercurial インストール

```
# yum install -y mercurial

### バージョンが 2.6.3 より古い場合は 本家 Mercurial から rpm 直 DL ＆インストール
# curl -OL https://www.mercurial-scm.org/release/centos7/RPMS/x86_64/mercurial-4.9-1.x86_64.rpm
# rpm -Uvh mercurial-4.9-1.x86_64.rpm

```

ビルド用のホームディレクトリを /usr/local/src/openjdk8 とする場合

```
# cd /usr/local/src
# hg clone http://hg.openjdk.java.net/jdk8u/jdk8u openjdk8u
# cd openjdk8u
# chmod +x get_source.sh
# ./get_source.sh
```

#configureスクリプト実行

```
# cd /usr/local/src/openjdk8u
# chmod +x configure
# ./configure
```

#makeスクリプト実行

```
# cd /usr/local/src/openjdk8u
# make images
```

#ビルドされたJDKの検証

build/linux-x86_64-normal-server-release/images/j2sdk-image 配下にビルド成果物が生成される（JREは j2jre-image 配下）
生成された新たなjavaコマンドバイナリでバージョン確認して検証する

```
# cd /usr/local/src/openjdk8u
# cd ./build/linux-x86_64-normal-server-release/images/j2sdk-image
# ./bin/java -version
```
返信一覧開閉

<img width="671" alt="スクリーンショット 2019-08-11 21.37.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265805/7cc24d36-a2ba-6bb8-299c-f0487257bc03.png">


```ruby

<div class = "user_icon" id = "comment_user_<%= i %>"><%= fa_icon("user") %></div>


    <script>
      $(function () {

    // <!-- リプ一覧欄開閉 -->
      $('#reply_lists_id_<%= i %>').hide();
      <% if comment.replies.present? %>
        $('#comment_user_<%= i %>').click(function () {
          $('#reply_lists_id_<%= i %>').toggle();
    // <!-- リプフォーム閉 -->
          $('#reply_form_id_<%= i %>').hide();

      <% else %>
        $('#comment_user_<%= i %>').click(function () {
          window.alert('リプライがありません。');
      <% end %>
      });
     });
   </script>
```
UE4エディタで起こるAndroidビルド時のJavaの文字化けエラーの解読

# UE4エディタのコンソール（アウトプットログ）を確認すると、日本語が文字化けをしている。

Java（UPL/APL）のエラーの内容が確認できない。

## gradleが文字化けを起こしていた。

VisualStudioの言語を英語だけにしてもダメ
UE4の言語設定を英語設定にしてもダメ

## 前置き　（追記 22.10.18）

https://docs.unrealengine.com/4.27/en-US/SharingAndReleasing/Mobile/UnrealPluginLanguage/

基本的にGradleの設定はプロジェクト単位では、出来る限りUPLの
```
<gradleParameters> </gradleParameters>
<buildGradleAdditions>  </buildGradleAdditions>
<gradleProperties> </gradleProperties>
```


などに書き込んだ方が良さそうです。プラグイン化するとか色々あるとは思いますが。
（こちらの方法で、エンコーディングがちょっと上手く行ってない状態なので、引き続き調査が必要ですが）
その上で、エンジンの方のバッチファイルを修正すれば解決するので、今回はそれで対応します。

## エンジンのbatファイルに加筆

Engine¥Build¥Android¥Java¥gradle¥gradlew.batにコメントがありました。
> Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.

``` Engine¥Build¥Android¥Java¥gradle¥gradlew.bat
set GRADLE_OPTS="-Dfile.encoding=utf-8"
```

そのコメントの下に変数を追加すれば、日本語のアウトプットログが出力されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128851/67b54103-2231-5d4e-eda6-781b29253915.png)

ちなみに、C:¥Users¥(User)¥.gradle¥gradle.properties
を配置しても、色々設定できそうです・・・が、どの範囲で設定したいか考えて、どういう方法をとるか選んだ方がいいみたいです。
上記のエンジンのbatファイルを書き換える行為も、エンジン自体のバックアップがとれていなければ、消失してしまうリスクとかもありますので。


## 編集前の本文

~~エディタの直接的な問題の解決にはならないが、
（面倒だったので見つけられなかった。。。）
IntermidiateのAPK内にあるgradlewを探す。
コマンドプロンプト（ShiftJIS）上で~~

```
gradlew compileDebug
```

~~か何かで、同じエラーの日本語が確認できる。
文字コードが違ったら、gradlewをテキストファイルで開き、「Java（gradle）＞コンソール」のエンコードが一致するように設定する。
必要があればEngineのテンプレートのgradlewを修正する。~~

~~根本的な解決法ないですかね。~~
Vuetifyが2.0にアップデートして、ようやくgridsome.jsへの導入方法が分かったので共有してみたり

# 参考
https://github.com/gridsome/gridsome.org/pull/225/commits/96442da8cd154ae19d1eb6cabb9ee20cfad978fd

まもなく、公式にアップされそう
とりあえず、半分は自分用のメモという事で

めちゃくちゃ迷走したが、結局何の事は無い

appOptionsに追加するだけだった

```javascript:main.js

import DefaultLayout from '~/layouts/Default.type1.vue'
import Vuetify from 'vuetify'
import 'vuetify/dist/vuetify.min.css'
import colors from 'vuetify/es5/util/colors'



export default function (Vue, { router, head, isClient, appOptions }) {

  // use
  Vue.use(Vuetify)

  appOptions.vuetify = new Vuetify({
    customVariables: ['~/assets/css/variables.scss'],
    theme: {
      dark: false,
      themes: {
        dark: {
          primary: colors.grey.darken4,
          accent: colors.shades.black,
          secondary: colors.amber.darken3,
          info: colors.teal.lighten1,
          warning: colors.amber.base,
          error: colors.deepOrange.accent4,
          success: colors.green.accent3
        }
      }
    }
  })

(省略)......
  
}
```

# gridsome.server.jsも少しいじる

その前にwebpack-node-externalsモジュールをインストール

```
npm i webpack-node-externals
```  


```javascript:gridsome.server.js
const nodeExternals = require('webpack-node-externals')
// Server API makes it possible to hook into various parts of Gridsome
// on server-side and add custom data to the GraphQL data layer.
// Learn more: https://gridsome.org/docs/server-api

// Changes here require a server restart.
// To restart press CTRL + C in terminal and run `gridsome develop`

module.exports = function (api) {
  
  api.chainWebpack((config, { isServer }) => {
    if (isServer) {
      config.externals([
        nodeExternals({
          whitelist: [/^vuetify/]
        })
      ])
    }
  })

  (省略)......
}
```

こんだけでOKのようです!
sass-loaderとかnode-sassはいる
【Ruby】オブジェクト指向とは

今日は中々打ち合わせやらで、自分の勉強が進まなかったんだけど、
極力毎日ブログは書きたいので、簡単なものを書こうかなと。

しばらくAWSの流れだったんだけど、AWSは理解が難しいので今日はオブジェクト指向ってやつについて書くよ。

僕はプログラミング初学者なわけでRubyをずっと使ってきたんだけど、Rubyはオブジェクト指向言語と言われているらしい。

で、オブジェクト指向ってそもそもなんだよっていう話。今回はRubyを用いてまとめていこうかと思うよ。

<h2>オブジェクト指向とは</h2>

オブジェクト指向とは、複数のオブジェクトを組み合わせてプログラムを構築する考え方。

オブジェクトとはデータと処理の集まりのことですが、漠然として集合体のことではなく、**一つのテーマを持った集合体のことです。**

人であれば「名前」、「年齢」、「出身地」などの**データ**を持ちます。

オブジェクト(今回のテーマは人)であれば、こういったデータの他に「振る舞い」があります。

例えば名前を聞くという「振る舞い」と、それに対して、自分の名前を返すという「振る舞い」。
ここでいう「振る舞い」をオブジェクト指向で考えると**処理**にあたるということです。

概念的ではありますが、特別理解できないということではないと思います。

オブジェクト指向って何？という問いに対して、**「現実と一緒だ」**なんて回答もあるくらいです。


<h2>オブジェクト指向とクラス</h2>

オブジェクト指向の概念を説明しても、じゃあプログラミングに落とし込んだらどうなるか中々想像できないかと思います。

そこで必要になるのがクラスの概念です。

<h3>クラスとは</h3>

オブジェクト指向言語において、データと処理をひとまとめにしたもの。
**オブジェクトの設計図**とも呼ばれる。

実際にRubyで書いてみます。

```ruby
class Person
  def initialize(name, age , birthplace)
    @name = name
    @age = age
    @birthday = birthday
  end

  def answer_name
    puts @name
  end
end
```

人(person)クラスを定義して、名前や生年月日を持たせています。これが**オブジェクト指向におけるデータ**のことです。

人(person)クラスで定義された人は、answer_nameメソッドという「振る舞い」をします。これが**オブジェクト指向における処理**のことです。

ここで定義されたクラスもオブジェクト、@nameといったインスタンス変数もオブジェクト、answer_methodもオブジェクトということになります。

結局、オブジェクト指向で生まれたものは全てオブジェクトと呼ばれることになります。

その中でもクラスは設計図、インスタンスは実体化したデータ、メソッドは実体化した処理とでもイメージすればいいのかなと思います。
【Vue.js】Vue CLIでVue.jsを動かす〜プロジェクト作成まで

# Vue.jsとは
- JavaScriptのフレームワーク。
- どのような規模・段階のアプリケーションにも対応することができる（プログレッシブフレームワーク）
- ページの一部で部分的に使用することもできるし、大規模なSPA（シングルページアプリケーション）を構築することもできる。

プログレッシブフレームワークとは、Vue.jsの生みの親であるEvan You氏の提唱する概念です。

## 参考記事
[Vue.jsについて学習してみた ＜基礎編＞](http://tech-blog.rakus.co.jp/entry/20190621/javascript/vue-js/beginner)
[Vue.js概要？](https://qiita.com/asip2k25/items/bd4bdccd5201d542953c)

# Vue CLIとは
- 迅速なVue.js開発を支援するためのコマンドラインインターフェイス。
- Vue.jsを利用した開発には、様々なパッケージやツールについての知識・複雑な設定が必要になる。それを自動化し、開発環境の構築を補助してくれる。
- 個別に公開されているパッケージ（ビルドツール、コンパイラなど） の集合体でもある。Vue CLIを利用することにより、そこから必要な機能だけを使うことができる。

## 参考記事
[公式サイト（英語）](https://cli.vuejs.org/guide/)

# インストール
あらかじめディレクトリを作成し、初期化しておきます。（今回初期化の必要はないかもしれませんが、念の為。）

```
$ mkdir vue_cli_test
$ cd vue_cli_test
$ npm init
```

## npmによるインストール
グローバルインストールで行っています。

```
$ npm install -g @vue/cli
```

加えて、``@vue/cli-init``もインストールします。

```
$ npm install -g @vue/cli-init
```

@vue/cli-initのインストールがされていない場合、プロジェクト作成のコマンド``npm init``実行時に以下のエラーが発生します。

```
Command vue init requires a global addon to be installed.
Please run npm install -g @vue/cli-init and try again.
```

グローバルインストールの場合、パッケージは``npm list -g``で確認できるディレクトリ配下の``node_modulesディレクトリ``にインストールされます。

```
$ npm list -g
/Users/yuki/.nodebrew/node/v12.7.0/lib
```

パッケージ名を指定して確認することもできます。

```
$ npm list -g @vue/cli
/Users/yuki/.nodebrew/node/v12.7.0/lib
└── @vue/cli@3.10.0 
```

## 環境変数の設定
このままだとvueコマンドが使えないため、``.bash_profile``にパスを設定します。
まず、コマンドがどこに存在するのか確認します。

```
$ npm bin -g
/Users/yuki/.nodebrew/node/v12.7.0/bin
```

.bash_profileに追記します。

```
$ vi ~/.bash_profile
```

```bash
export PATH="$HOME/.nodebrew/node/v12.7.0/bin:$PATH"
```

反映させます。

```
$ source ~/.bash_profile
```

## Vue.jsのバージョン確認
vueコマンドが通るようになったので、Vue.jsのバージョンを表示してみます。
確認ができれば、Vue CLIのインストールは成功です。

```
$ vue -V
3.10.0
```

# プロジェクト作成
``npm init テンプレート名 プロジェクト名``でプロジェクトを作成します。

今回、テンプレートはwebpackを指定します。

テンプレートの種類については、こちらの記事が参考になります。
[Vue-cli(webpack)解剖 ーディレクトリ構成ー](https://qiita.com/h_plum/items/86b8a6a86ac0fea8a4d1)

```
$ vue init webpack my-app
```

いくつか質問をされます。
今は余分な機能を入れたくなかったので、以下の質問はNoにしました。

```
// SPA構築に必要なVue.js公式ルータ
? Install vue-router? No
// 構文チェックツール
? Use ESLint to lint your code? No
// テストツール
? Set up unit tests No
// テストツール
? Setup e2e tests with Nightwatch? No
```

プロジェクト名である``my-appディレクトリ``が作成され、必要な機能がインストールされます。
最後の方にあるメッセージの通り、my-appディレクトリに移動します。

```
To get started:

  cd my-app
  npm run dev
```

```
$ cd my-app
```

次に``npm run dev``でサーバを起動します。
``dev``というエイリアスコマンドは、``プロジェクト名のディレクトリ/package.json``の``script``で設定されています。

デフォルトでは以下の設定になっています。
``npm start``や``npm run start``でもサーバを起動することができるようです。

```myapp/package.json
"scripts": {
  "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
  "start": "npm run dev",
  "build": "node build/build.js"
},
```

```
$ npm run dev
```

表示されるメッセージの通り``http://localhost:8080``にアクセスして、Vue.jsのデモ画面が確認できれば成功です。

```
Your application is running here: http://localhost:8080
```
Laravelにサービス層を導入する

#はじめに
LaravelでWebサービスを開発していると、最初はいいのですが、Controillerが大量のロジックで埋め尽くされ見通しが悪くなっていきます。
それを改善する為にサービス層を導入します。

#1.サービスクラスの作成
今回はappの直下にServiceディレクトリを作成し、PostServiceクラスを作成します。
例としてechohogeメソッドを作成します。

```PostService.php
<?php
namespace App\Service;

use Illuminate\Support\Facades\DB;

class PostService
{
	public function echoHoge()
	{
		return 'hoge';
	} 
}
```
#2.サービスコンテナへ登録する
まずはLaravelのartisanコマンドを使用し、サービスプロバイダを作成します。

```
php artisan make:provider PostServiceProvider
```
```PostserviceProvider.php
<?php

namespace App\Providers;

use App\Service\PostService;
use Illuminate\Support\ServiceProvider;

class PostServiceProvider extends ServiceProvider
{
    /**
     * Register services.
     *
     * @return void
     */
    public function register()
    {
        $this->app->bind('Post',function($app){
            return new PostService();
        });
    }

    /**
     * Bootstrap services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }
}
```

#3.オートロード設定を行う

```app.php
'providers' => [
    /*
　　　省略
    */
        App\Providers\PostServiceProvider::class,
    ],
```

#4.依存性注入を行う
最後にコントローラーのコンストラクタで注入していきます。

```PostController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Service\PostService;
use App\Post;

class PostController extends Controller
{

    protected $postservice;

    //投稿系のサービス層をDIする
    public function __construct(PostService $postservice)
    {
        $this->postservice = $postservice;
    }

    //一覧表示
    public function index()
    {
        //サービス層のメソッドを使用する
        return $this->postservice->echoHoge（）;
    }
}

```

以上です！！
これでサービス層としてビジネスロジックを書ける場所ができました！
AWSを無料でお勉強：コンソールログインを検知したい（その３）

お約束になってきましたが、自分自身忘れないようにコンセプトを毎回書いておこうと思います。

###コンセプト
・お金かけてまでやりたくないので基本的に無料でAWSを勉強する
　→ちょっとしたサービスを起動すると結構高額になりやすい。
・高いレベルのセキュリティ確保を目指す
　→アカウントを不正に使われるととんでもない額を請求されるので防ぐ

###しゃーないのでCloudtrailを設定してみる
前回早くも無料で対応するのが難しそうなことがわかってきたので、Cloudtrailをとりあえず設定してみようと思います。
まずは項目から確認。

![201908111.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480659/2a70669a-f837-3389-0b11-522d9df6b5f9.png)


証跡名は名前なんで適当に。

全リージョンに適用は
https://dev.classmethod.jp/cloud/aws/cloudtrail-multiregiontrail/
の記事を見ると後発の機能であることがわかります。今後リージョンが追加されるかもしれませんし、リージョン個別にしたい要件もないので全リージョンを適用することにします。
ちなみに料金は
https://aws.amazon.com/jp/cloudtrail/faqs/
で確認すると、
>Q: 管理イベントを含む証跡が 1 つのみあり、それをすべてのリージョンに適用する場合、料金は発生しますか?
>いいえ。管理イベントの最初のコピーは各リージョンで無料で配信されます。

とあり、無料のようです。無料、いい響きですwwwここも設定してから確認してみよう。

続いて管理イベントです。
https://docs.aws.amazon.com/ja_jp/awscloudtrail/latest/userguide/logging-management-and-data-events-with-cloudtrail.html#logging-management-events
を読むとわかりますが、要は管理操作の証跡を取ります。データイベントのほうはデータに関する情報取得です。今回の場合、不正利用検知が目的なので、データイベントは不要です。

書き込み、読み取りの設定は以下のような内容です。
>[Read-only] 読み取り専用イベントには、リソースの読み取りのみ行い、変更を行わない API オペレーションが含まれます。たとえば、Amazon EC2 の DescribeSecurityGroups および DescribeSubnets API オペレーションは読み取り専用イベントです。これらのオペレーションは、Amazon EC2 リソースに関する情報のみを返し、設定は変更しません。
>[Write-only] 書き込み専用イベントには、リソースを変更する (または変更する可能性がある) API オペレーションが含まれます。たとえば、Amazon EC2 の RunInstances および TerminateInstances API オペレーションはインスタンスを変更します。
>すべて 証跡は両方をログに記録します。
>なし 証跡のログは、読み取り専用でも書き込み専用管理イベントのどちらでもありません。

ここはすべて、でいいでしょうね。てか、なしって何の意味があるんだ？？？




KMSの設定ですが、ここは入れておこうと思います。料金を確認すると
https://aws.amazon.com/jp/kms/pricing/
安いですし無料枠もあります。ちなみに、KMS暗号化しなくてもSSE-S3では暗号化されています。物理ディスクとしては暗号化されますが、鍵管理はできないのでAPI経由などでアクセスした場合は透過的にデータアクセスできてしまいます。ファイルを暗号化しているというよりもストレージの暗号化に近いイメージですね。

ログファイルの検証も有効化してみます。

SNSの通知についてはマニュアルに
>バケットにログが配信されるたびに通知を受け取る場合は、[Send SNS notification for every log file delivery (ログファイルの配信ごとに SNS 通知を送信する)] で [Yes (はい)] を選択します。CloudTrail は、1 つのログファイルに複数のイベントを保存します。SNS 通知は、ログファイルごとに送信されます (イベントごとではありません)。

とあります。ファイル単位だとタイムリーではないでしょうし、無くてもいいように思うので、ここはいいえでいいでしょう。




バケット作成できました。

Cloudtrail側からCloudwatchLogsの設定をします。
![201908114.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480659/2c981657-ee49-79fa-bcf6-68d1df30bffa.png)


新規ロールを作成し許可します。
![201908115.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480659/898851cd-c0bd-b7ce-096c-8490294fe4be.png)


Cloudwatch側から確認します。
![201908116.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480659/2cddf529-12e0-4335-b7e7-a7cfff3ba859.png)

設定できたようです。

今日はここまで。。。
ngrokとかserveoとか使ってWebView(LIFFとか)開発でキャッシュしないローカルサーバ構築

LIFFのサンプル動かしたりお試ししてるときにWebViewがキャッシュしちゃって、ファーめんどくさい！！ってなるときのTips

準備：NodeJSが入ってる環境で npm install -g http-server をたたく

実行したいディレクトリに移動して http-server -c 0 とたたく
ngrokとかserveoとかで8080を公開する
http-serverにはいくつかパラメータがあるんですが、-c 0 にすると０秒キャッシュになります。これでResponse Headerに cache-control: max-age=0 が入るようになってキャッシュされにくくなります。
ただ、キャッシュ制限されてない状態で初回にアクセスしたりするとずっとキャッシュしてしまったり、なぜか設定してもキャッシュするときはするんで、Androidだとアプリ設定からストレージのキャッシュを削除するとかそういう方法も覚えておいたほうがいろいろ楽でもある
laravel5.8でランダム文字列を生成するStr::random()

phpstormでlaravel5.8内でstr_random()を使ったら~~str_random()~~みたいになったので、新しいメソッドを探した。

5.8系では、str_random()は、非推奨みたい。


```php:
use Illuminate\Support\Str;

$random_str = Str::random(100);
```

ちなみに5.８でstr_random()を呼ぶと内部でStr::random()が呼ばれるみたい。


```php:vendor/laravel/framework/src/Illuminate/Support/helpers.phpより

if (! function_exists('str_random')) {
    /**
     * Generate a more truly "random" alpha-numeric string.
     *
     * @param  int  $length
     * @return string
     *
     * @throws \RuntimeException
     *
     * @deprecated Str::random() should be used directly instead. Will be removed in Laravel 6.0.
     */
    function str_random($length = 16)
    {
        return Str::random($length);
    }
}
```

[Laravel 5.8 New Features List
*) Deprecated String and Array Helpers Functions]
(https://itsolutionstuff.com/post/laravel-58-new-features-listexample.html)
Dateクラスのbefore,afterの結果を数直線で表現してみた

Dateクラスのbefore、afterの結果が、文章だと微妙にわかりにくかったので、
数直線で表現してみました。

以下、base、arg共にDate型とします。
# base.before(arg)
![before1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154305/a0e52da0-a2fe-7ab0-b924-c9bb9584f6f4.png)
![after1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154305/dbdef044-761c-5e56-8969-d6d783ab8490.png)

# base.after(arg)
![before2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154305/f9e93ba3-21f4-5c6c-d359-89eeb972acb2.png)
![after2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154305/3e5386f9-5e37-b34a-665d-89404c80291e.png)

結果：わかりやすくなった！
カスタムデータ属性とは?

HTML5からマークアップ仕様で「カスタムデータ属性」が追加されました。

何のために、どうやって使うのでしょうか?

## 1,カスタムデータ属性で何ができる?

htmlタグの属性には、classやid、hrefといった様々なものがあります。カスタムデータ属性を使用すると、**オリジナルの属性**を作ることができます。

```html

<div class="message" data-id="message.id">
```
カスタムデータ属性の名前は常に**data**から始まります。

## 2,カスタムデータ属性における記述のきまりは?

カスタムデータ属性の記述において、いくつかのきまりがあります。

まず一つ目は。**データ属性に格納するデータは文字列**である必要があります。文字列であれば、自由に記述することができます。

2つ目は、**他の要素名と被ってはいけません**

なので、class名をデータ属性として格納することは適切ではありません。

## 3,カスタムデータ属性の役割とは?

カスタムデータ属性は主にJavaScriptで値を取得するときに使われます。

class属性はスタイル情報を割り当てることが目的で、データを格納するには適切ではありません。

例えばdataの値を取得したいときは、

``` html
<div class="message" data-id="5">
```

```javascript

var message_id = $(".message").data('id');
console.log(message_id)  // "5"
```

とdata()を使えば格納されているデータを取得することができます。
R初心者のための共発現解析（相関分析） 基礎編

#前回の内容
[R初心者のための共発現解析（相関分析） イントロ編](https://qiita.com/Ykeito/items/a7554397943c2168fb17)

#目的
- irisのデータを基に列間の相関分析を全組み合わせで算出するためのスクリプトを自動化すること

#対象
- R初心者で相関分析を自動化したい方。

#実際のスクリプト
##irisの数値データをT.dataに格納
```
T.data <- iris[, 1:4]
```` 

##forでcorを回す
出力結果をtempに格納

```
temp <- c()
i <- 1
for (i in 1:c(ncol(T.data)-1)) {
  j <- i+1
  for (j in j:ncol(T.data)) {
    temp <- c(temp, cor(T.data[, i], T.data[, j]))
    j <- j+1
  }
  i <- i+1
}
```

##combn関数を使って、列名を総当たりで作成
前回rep関数を使って、列名を総当たりするように誘導しましたが、combn関数を使った方がスクリプトの量を減らせ、解析時間を短縮できる。

```
T.name <- combn(colnames(T.data), 2)
```

##PCC.tableに計算結果をまとめる
```
PCC.table <- data.frame(source = T.name[1, ],
                        value = temp,
                        target = T.name[2, ]
)
```

#次回の内容
[R初心者のための共発現解析（相関分析） 応用編](https://qiita.com/Ykeito/items/80fb013ca71fe9ba913b)
SwiftでAPIを用いる流れ(ライブラリを使わないversion)

iOSアプリにおいて、 AlamofireやSwiftyJSONなどのライブラリを用いずにAPIを利用する流れについてまとめてみました。　

##使用するもの
- Codable(https://qiita.com/UJIPOID/items/2c436a80f1167f7bcac0)
- Qiita API(https://qiita.com/api/v2/items)
- コアライブラリFondation(URL、URLRequest、URLResponse、URLSessionクラスを用いる)

##やること
TableViewにAPIから取得したデータを一覧で表示する。
サーバーにHTTPリクエストを送り、返ってきたHTTPリクエストを受け取ってTableViewに表示する。

##手順
###①Codableを使ってJSONを受け取る構造体(モデル)を作る。
```swift:QiitaStruct.swift
struct QiitaStruct: Codable {
    var title: String
    var user: User
    struct User: Codable {
        var name: String
    }
}
```


###②HTTPリクエストの生成
####URLオブジェクトの生成
```swift:QiitaViewController.swift
let url = "https://qiita.com/api/v2/items"
```

####URLRequestオブジェクトの生成
```swift:QiitaViewController.swift
let request = URLRequest(url: url)
```

###③HTTPリクエストを投げ、返ってきたレスポンスを受け取って配列に格納する。
####URLSessionクラスのインスタンスからリクエストを送り、その後のデータを受け取った後の処理について記述する。
```swift:QiitaViewController.swift
let qiitaArray:[QiitaStruct] = []
let task = URLSession.shared.dataTask(with: urlRequest) { data, response, error in
    guard let jsonData = data else { return }
  
    do {
        let articles = try JSONDecoder().decode([QiitaStruct].self, from: jsonData)
        qiitaArray.append(articles)   
    } catch {
        print(error.localizedDescription)
    }
}
task.resume()
```

###④格納した配列の値をTableViewに表示する。
```swift:QiitaViewController.swift
extension QiitaViewController: UITableViewDataSource {
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        let cell = UITableViewCell(style: .subtitle, reuseIdentifier: "Cell")
        let article = articles[indexPath.row]
        cell.textLabel?.text = article.title
        cell.detailTextLabel?.text = article.user.name
        return cell
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return articles.count
    }
    
}
```


以上の手順により、以下のようにTableViewにデータを表示することができました。

![Simulator Screen Shot - iPhone Xʀ - 2019-08-11 at 20.40.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237258/f5b96c14-7569-6254-2595-b94b4864c589.png)


作成したQiitaAPIのサンプルプロジェクトは以下のGithubページからクローンできます。
サンプルプロジェクトでは、MVVM設計でコンポーネントを作って、少しだけ実装を抽象化しています。
https://github.com/YukiNagai1016/QiitaAPI
プログラミングノート(Pythonその２)

備忘録もかねて簡単なプログラミングノートを作成していきます。

##文字列について
###◆文字列の表現
文字列を表現するには、「'(シングルクォート)」もしくは「"(ダブルクォート)」で囲めばよい
クォート自身を文字列に含みたい場合は、シングルクォートでダブルクォートを囲む、もしくはダブルクォートでシングルクォートを囲めばよい

```python
#シングルクォートで文字列を表現
print('Hello Pyton')
#ダブルクォートで文字列を表現
print("Hello Python")
#クォートを文字列に含む
print("He said I'm tired")
print('<div class="hoge">')
```
###◆エスケープシーケンス
上記で文字列にクォートを含める方法として、「\(バックスラッシュ)」をクォートの前につけることでクォートを文字として扱うことができます。この働き(エスケープ)をさせるためにつけるバックスラッシュを「エスケープシーケンス」と呼びます。
他にも、以下のような使い方があります。

| 記号 | 意味 |
|:-----------|:------------|
| \(改行)       | 改行を無視する        |
| \\    | バックスラッシュ(\)      |
| \'       | シングルクォート(')        |
| \"         | ダブルクォート(")          |
| \r\n       | 改行(CR+LF)       |
| \n    | 改行(LF)     |
| \t       | タブ文字(文字コード：0x09)        |
| \xhh        | 16進数で hh の文字(※1)          |
| \uxxx      | 16bit Unicodeで16進数 xxx の文字(※2)       |
| \Uxxxxxxxx   | 32bit Unicodeで xxxxxxxx の文字(※2)     |
※1・・・文字をコード番号で指定する際に利用します
※2・・・Unicodeの文字をコード番号や名前で埋め込みたい場合に利用します

```python
#クォートをエスケープする
print("He said I\'m tired")

#改行を無視する
print("Hello 
World")
# World")が新しいコードと解釈され、以下エラーとなる
#print("Hello 
#            ^
#SyntaxError: EOL while scanning string literal

print("Hello \
World")
# Hello Worldと表示される
```
###◆三重引用符の利用
三重引用符とは、シングルクォートもしくはダブルクォートを3回連続で表記したものである
三重引用符で囲むことでも文字列を表現できる
クォートで囲む場合との違いは、空行や改行をそのまま表せることである

```python:text.py
#三重引用符の利用
string = '''

みなさん、こんにちは
今日も良い天気ですね
暑いので熱中症などには、お気をつけください
'''
print(string)
```
```python:text.py
(空行)
みなさん、こんにちは
今日も良い天気ですね
暑いので熱中症などには、お気をつけください

```
上記の場合、最初と最後の行にも改行を含めてしまう
それを避けるには、改行が不要な場合は、「\」でエスケープすればよい

```python:text2.py
string = '''\

みなさん、こんにちは
今日も良い天気ですね
暑いので熱中症などには、お気をつけください\
'''
print(string)
```
###◆文字列の連結
文字列通しを連結させるには、「+」演算子を使えばよい
変数の値を連結させる場合も同じ
数値と文字列をそのまま連結させることはできないので、数値を文字列に連結させるには、「str(数値)」で数値を文字列に変換する必要がある。

```python
string = "今日は、" + "あいにく雨です。"
print(string)
# 今日は、あいにく雨です。

weateher = "晴れ"
print("今日の天気は、" + weateher + "です。")
#今日の天気は、晴れです。

string = '気温は、' + 30 + "°です。"
print(string)
#Traceback (most recent call last):
#  File "Main.py", line 3, in <module>
#    string = '気温は、' + 30 + "°です。"
#TypeError: must be str, not int

string = '気温は、' + str(30) + "°です。"
print(string)
#気温は、30°です。
```
###◆format()で文字列に値を埋め込む
文字列に値を埋め込みたい場合は、formatメソッドを使うと、簡潔に記載できます
<formatメソッド>
インデックスで指定する場合
"書式文字列".format(値0 , 値1 , 値2・・・)

```python:format.py
string = "気温は、{}°です。"
result = string.format(30)
print(result)
#気温は、30°です。

string = "私の名前は、{0}です。年齢は、{1}歳です。"
result = string.format("ゆうすけ" , 37)
print(result)
#私の名前は、ゆうすけです。年齢は、37歳です。
```

インデックスではなく、キーでの指定もできます
"{キー1}{キー2}{キー3}...".format(キー1=値 , キー2=値 , キー3=値・・・)

```python:format2.py
string = "私の名前は、{name}です。年齢は、{old}歳です。"
result = string.format(name = "ゆうすけ" , old = 37)
print(result)
#私の名前は、ゆうすけです。年齢は、37歳です。
```
***
本日は、ここまで
labelを使用しfile_fieldを消す方法

## 1,やりたいこと　

アイコンをクリックすると画像を選択してアップロードできるように実装したい。

<img width="1096" alt="スクリーンショット 2019-08-11 19.40.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398610/89bba574-7132-552e-83e3-6acf148c21aa.png">


## 2,画像をアップロードする機能を実装するには?

file_feildをコードに記述すると画像をアップロードすることができます。

file_filedとは、form_forで使用できるフォームです。

記述は以下の通り

```haml

= form_for [@group,@message] do |f|
        .message-box  
          %i.fa.fa-image
          = f.file_field :image
          = f.submit "Send",class: "submit-box" 

```




##3,アイコンとfile_feildを紐づけるには?

アイコンをクリックして、画像を投稿できるようにするためには、アイコンとfile_fieldを紐づける必要があります。


``` haml
= f.label :image, class: "form-image" do
   %i.fa.fa-image
   f.file_field :image
```

iタグとfile_fieldをlabelで囲むと、アイコンをクリックするとfile_filedがクリックされるように実装されます。

## 4,「ファイルを選択する」ボタンを消す

紐づけは完了しましたが、「ファイルを選択する」というボタンが画面上に表示されたままです。

<img width="1096" alt="スクリーンショット 2019-08-11 20.08.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398610/7b05c5b7-9af9-1eea-210f-dc0b4fc09765.png">

このボタンを消してあげましょう。

``` sass
.form-image{
          input{
            display: none;
          }
```

stylesheetに以上のように記述するとボタンを消すことができます。
秘匿情報を暗号化してリポジトリに格納

備忘録です

# やりたいこと

APIキーとかをリポジトリに格納したいけど、そのままGitHub(Not Private)にpushできるほど愚かではない。
でもAPIキーの変更はコミットログに残したいし、CI/CDでちゃんと動くようにしたい。

# やりかた(概要)

APIキーなどの秘匿情報は暗号化して、復号化情報をCI/CDツールの環境変数に設定し、CI/CDで復号化する

## 詳細

### 共通鍵、初期ベクトルを決める
今回は、AES-256-CBC で暗号化するので、それぞれ 256bit、128bit で準備する。
以降は、KEY, IVの変数に入っていることにする。
これは暗号化のたびに必要になるので、メモしておく
(または、変更のたびに後述のCI/CDツールの環境変数を書き換える)

### APIキーを設定したファイルを準備する
ロジックからは切り離し、環境変数となるようにする。
このファイルは、__絶対にcommit(push)してはダメ__
.gitignoreとか、登録しておくのがおすすめ

### 暗号化
次のコマンドで暗号化する。

```bash
openssl aes-256-cbc -e -in ${暗号化するファイル名} -out ${暗号化後のファイル名} -K ${KEY} -iv ${IV}
```

暗号化した方のファイルはcommit(push)してよい。
このファイルはKEY,IVがわからない限り、復号できない。
(脆弱性が見つかったり、マシンパワーがクソ上がったり(=現実的な計算時間で解決できるようになったり)したらこの限りではない、多分)

### CI/CDツールの設定
該当のCI/CDツールで上記共通鍵と初期ベクトルが参照できるように、環境変数に登録する
この際登録した情報はbuild中のログに残らないようにするなどしておくこと
(これが漏れたら復号化出来てしまう)

### 復号化
次のコマンドで復号化できる

```bash
openssl aes-256-cbc -d -in ${復号化するファイル名} -out ${復号化後のファイル名} -K ${KEY} -iv ${IV}
```

これを組み合わせて上手いこと該当ファイルをCI/CDで使えるようにする


# 参考資料
以下を参考にさせていただきました
* [CircleCIでプライベートなファイルを暗号化してレポジトリ管理する - Qiita](https://qiita.com/tomoima525/items/dbeeb6d451304333b17d)
* [コマンドラインで簡単にAES暗号化、または Java での AES 暗号化 - 理系学生日記](https://kiririmode.hatenablog.jp/entry/20160402/1459603950)
[Golang]マップやスライスをループさせるがキーやインデックスが必要でない場合、ブランク修飾子が便利な件

# とりあえずサンプルコード
## スライスの場合
```golang:スライスの場合
package main
import "fmt"

func main() {
	s := []int{2, 4, 6, 8}
	for _, v := range s {
		fmt.Println(v)
	}
}
```

```console:スライスの場合　実行結果
2
4
6
8
```

## マップの場合
```golang:マップの場合
package main
import "fmt"

func main() {
	m := map[string]int{"maeda":165, "yamada":175, "suzuki":180}
	for _, v := range m {
		fmt.Println(v)
	}
}
```

```console:マップの場合　実行結果
165
175
180
```

# ブランク修飾子の書き方
変数名のところに`_`このように、アンダースコアを書くだけです。
こうすることで、キーやインデックスに入れられる予定だった値を、処理の中で使わなくても、怒られません。
画面設計で気を付けること

最近、物忘れが激しくなってきて、具体的なことを思い出すのに時間がかかる（笑）

なので、具体的なことをメモっておく。

本内容は、私の経験に基づく、個人的な主観になります。

# 画面設計で気を付けるポイント
以下２つかな。
2つとも要件定義書に書いてあって然るべき内容です。
が、万が一書いていない場合は、確認したほうが良い内容です。

## その画面は、誰のための画面？
使う人を意識すること。
誰が使うの？

## その画面で、何をしてほしい？
その画面を使って、何をしてほしい？
何かをして欲しいために画面を用意するので、その目的を意識することが大切。

具体的には、表示項目、検索項目を決めるときに意識します。

どういう事をして欲しいから、この項目とする。

という感じです。

# 駄文
賛否両論があると思いますが、個人的な意見を述べます。

画面の項目を決める際に、今にフォーカスするのは当たり前ですが、

将来使いそうな項目は、どうする？

って議論があると思います。

要するに、今使わないけど、今後使いそうな項目を、画面項目に入れておかないと、
今後使うことになった場合に、「また改修」が必要になってしまう！！

だから、今は使わないけど、入れておいて欲しい。

これって、システム開発の構造的欠陥だと思っています。
本来、システム開発のあるべき姿は、

必要な時に、必要な分を開発する。

そうすることにより、
顧客は、無駄なお金も使わないで済む。
エンジニアは、無駄な機能を作らなくて済む。

なので、あるべき姿としては、「改修が必要になっていいじゃん！」ですが、
現実は、予算というものがあり、人を集めなければいけないし・・・。
と諸々大変です。

なので、私の落とし所としては、
　本当に必要になりそう？
というのを再確認し、今後の改修が厳しければ、追加したりします。

ポイントは、本当に必要になりそう？を再確認することです。

一時の感情で、項目追加したい！って思っている可能性もあるので、
再度、考えて貰うキッカケを作ることが大切だと思っています。
Windows EventLogをElasticSearchにimportする

# Overview

タイトル通りです.  
具体的には[EvtxtoElk](https://github.com/dgunter/evtxtoelk)を使用してimportします.

```sh
# dockerでelasticsearch, kibanaを建てる
$ docker run -p 9200:9200 -p 9300:9300 -p 5601:5601 sebp/elk

# ライブラリのインストール
$ pip install evtxtoelk
```

```python
from evtxtoelk import EvtxToElk
EvtxToElk.evtx_to_elk('example.evtx', 'http://localhost:9200')
```


##### 2019/10/06 追記: 
100倍早くしました :sushi: 
[Windows EventLogをElasticSearchにimportする(のを100倍早くする)](https://qiita.com/sumeshi/items/cb2fbafe59c2c83e3085)

# Description

DFIRの際に必須なイベントログ調査ですが, 僕はざっくりデータを眺めるときは [log2timeline/plaso](https://github.com/log2timeline/plaso) でcsvに変換して [ripgrep](https://github.com/BurntSushi/ripgrep) で検索を行っていました.
目で見るだけならこれでも十分なのですが, プログラムである程度自動化をするにあたって, pandasをデータベース的に使ったり, SQLiteで検索をするのはパフォーマンスが非常に悪いです.  
できれば最低でも1クエリ0.1秒以内で帰ってきてほしいですが, 巨大なイベントログの検索にはSQLiteでも2秒程度かかってしまいました. :cry: 

やっぱ餅は餅屋, ということでビッグデータ解析に適している[ElasticSearch](https://www.elastic.co/jp/products/elasticsearch)さんで試したところ0.02秒程度といい感じです！ ripgrep並の速度を手に入れました！ :kissing_heart: 
インデックスにやたら時間がかかるのが難点ですが, プログラム回してほっとけばそのうち終わるので検索のたびにイライラするより遥かに素晴らしいです.

---

EvtxtoElkの詳しい使い方は[作者のブログ](https://dragos.com/blog/industry-news/evtxtoelk-a-python-module-to-load-windows-event-logs-into-elasticsearch/)に書いてあったり書いてなかったりするので読んでください.
ここでは`ブログに書いてなかった(たぶん)実行オプション`についても書いておきます.

ちなみにevtx自体は, [AccessData](https://accessdata.com/) - FTK Imagerなり[log2timeline/plaso](https://github.com/log2timeline/plaso)を利用して抜き出すと良いと思います.

# Example
ぼくは解析したいファイルが複数あったのでこんな感じのスクリプトを書いて実行しました :sushi: 

## イベントログのディレクトリ構成

```tree
data/
├── server01/
│   └── Security.evtx
│
├── server02/
│   └── Security.evtx
│
└── server03/
    └── Security.evtx
```

## スクリプト(import_evtx.py)

```python
# coding: utf-8

import sys
from pathlib import Path

from evtxtoelk import EvtxToElk


def main():
    evtx_files = Path(sys.argv[1]).glob('**/*.evtx')
    for evtx in evtx_files:
        print(f"index: {evtx}")
        print(f"index-name: {evtx.parent.stem}\n")
        EvtxToElk.evtx_to_elk(evtx, 'http://localhost:9200', elk_index=evtx.parent.stem, bulk_queue_len_threshold=3000)


if __name__ == '__main__':
    main()

```

### オプション解説
#### elk_index
**インデックスの名前**
デフォルトだと`hostlogs`が使われるようになっていました.  

今回はどのサーバのログかわかるようにしたいのでevtxが入っているディレクトリの名前をindex名にするよう変更

#### bulk_queue_len_threshold
**bulkinsertのバッファサイズ**
デフォルトは`500`です
いじんなくてもそこまで速度変わらないらしいですが, 標準出力がうるさくなるので今回は3000としました.

# 実行コマンド
```sh
$ python import_evtx.py data
```
【Java】Mapの使い方

###初期化

Mapは型にプリミティブを指定できないので、IntegerやStringのようなラッパークラスを指定すること

```java
Map<Integer, String> map1 = new HashMap<Integer, String>(); 
```

###要素の追加

オブジェクト名.put(キー, "値")

```java
map1.put(1, "apple"); 
map1.put(2, "orange");
map1.put(3, "cherry"); 
```

###要素の取得
オブジェクト名.get(キー)

```java
map1.get(1); 
map1.get(2); 
map1.get(3);

System.out.println(map1.get(1));
//出力結果は"cherry"になる
  
```

**※キーが重複した場合**

```java
map1.put(1, "apple"); 
map1.put(2, "orange");
map1.put(1, "cherry"); 
					
System.out.println(map1.get(1));
//出力結果は"cherry"になる
```

Map内の要素はキーで値を管理しているため重複はできない。
putで重複したキーに値を入れた時点で以前のものと置き換えられてしまう。


###要素の削除

一つ削除する場合
オブジェクト名.remove(キー)

```java
map1.put(1, "apple"); 
map1.put(2, "orange");
map1.put(3, "cherry"); 
		
map1.remove(1);
					
System.out.println(map1);
//出力結果は{2=orange, 3=cherry}となる
```

全削除する場合
オブジェクト名.clear()

```java
map1.put(1, "apple"); 
map1.put(2, "orange");
map1.put(3, "cherry"); 
					
map1.clear();
					
System.out.println(map1);
//出力結果は｛｝になる
```

###要素の置き換え
```java
map1.put(1, "apple"); 
map1.put(2, "orange");
map1.put(3, "cherry"); 

map1.replace(2, "banana");
					
System.out.println(map1.get(2));
//出力結果はbananaになる
```

###キーの取得
mapに存在するキーを返す
オブジェクト名.keySet()

```java
map1.put(1, "apple"); 
map1.put(2, "orange");
map1.put(3, "cherry"); 
					
System.out.println(map1.size());
//出力結果は[1, 2, 3]になる
```

###キーの個数を取得
mapに存在するキーの個数を返す
オブジェクト名.keySet()

```java
map1.put(1, "apple"); 
map1.put(2, "orange");
map1.put(3, "cherry"); 
					
									
System.out.println(map1.size());
//出力結果は3になる
```
terraformの勉強記録

[Pragmatic Terraform](https://booth.pm/ja/items/1318735)の写経をしていた。
7章と8章を書いて、 `terraform apply`したら以下のエラーが出た。

```terminal
Error: Error creating LB Listener: CertificateNotFound: Certificate 'arn:aws:acm:ap-northeast-1:882275384674:certificate/8f385a88-7438-44a1-b9ac-4d95a0c1acca' not found
        status code: 400, request id: 04759268-bc20-11e9-8e88-d92bcd313ecb

  on alb.tf line 102, in resource "aws_lb_listener" "https":
 102: resource "aws_lb_listener" "https" {



Error: Invalid index

  on route53.tf line 25, in resource "aws_route53_record" "example_certificate":
  25:   name    = aws_acm_certificate.example.domain_validation_options[0].resource_record_name
    |----------------
    | aws_acm_certificate.example.domain_validation_options is empty list of object

The given key does not identify an element in this collection value.


Error: Invalid index

  on route53.tf line 26, in resource "aws_route53_record" "example_certificate":
  26:   type    = aws_acm_certificate.example.domain_validation_options[0].resource_record_type
    |----------------
    | aws_acm_certificate.example.domain_validation_options is empty list of object

The given key does not identify an element in this collection value.


Error: Invalid index

  on route53.tf line 27, in resource "aws_route53_record" "example_certificate":
  27:   records = [aws_acm_certificate.example.domain_validation_options[0].resource_record_value]
    |----------------
    | aws_acm_certificate.example.domain_validation_options is empty list of object

The given key does not identify an element in this collection value.

```

SSLのDNS検証用のレコード作成に失敗している。そのため、ALBのhttpsリスナーの作成も失敗している。（httpsリスナーの作成にはssl証明書が必要）

タイポしてるのかと思ったけど、特にタイポもしていなかった。
よくわからないので、再度 `terraform apply` したらなんか作成できた。

検証用のCNAMEレコードがちゃんと作成されていて、
<img width="813" alt="スクリーンショット_2019-08-11_19_38_03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131625/7d4472eb-8d2b-5498-e484-496b7f7cbb4d.png">

証明書も発行済みになっている。
<img width="1101" alt="スクリーンショット 2019-08-11 19.41.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131625/af9d2666-1401-aedb-691d-cec769a6e76a.png">

あと、route53のレコードセットにCNAMEレコードが表示されるのが微妙に時間がかかった（5分くらい）
ACMの方では証明書が発行済になっているのにroute53の方にはCNAMEレコードが存在しなかったから、「なんで発行済になれた？」と思ったが、時間が解決してくれた。