OmniAICreator/Qiita-1.07M huggingface dataset:
Railsのajax送信の際にCSRF tokenでエラー

## CSRF tokenでエラー解消方法メモ
- エラー内容
  - `Can't verify CSRF token authenticity.`

### 1つ目：コントローラで制御
```ruby:controller
  # CSRF保護を無効
  protect_from_forgery :except => [:create] #対象のアクションに修正
```
でも可能。


### 2つ目：Ajaxで送信する前にtokenを取得し送信する
```javascript:jsファイル
$.ajaxPrefilter(function(options, originalOptions, jqXHR) {
    var token;
    if (!options.crossDomain) {
    token = $('meta[name="csrf-token"]').attr('content');
       if (token) {
          return jqXHR.setRequestHeader('X-CSRF-Token', token);
        }
     }
 });
```

1. $.ajaxPrefilter( [dataTypes], handler )
ajax送信する事前に処理を行う
[ajaxリファレンス](http://js.studio-kingdom.com/jquery/ajax/ajax_prefilter)
2. token取得
`token = $('meta[name="csrf-token"]').attr('content');`
3. tokenをリクエストヘッダに入れる
`jqXHR.setRequestHeader('X-CSRF-Token', token)`
【初心者向け】Google Colaboratoryの使い方

今回はGoogleさんが提供しているGoogle Colaboratoryの使い方について紹介します。
※入門者の方への情報共有のための記事です。
※疑問点やここが分かりにくいという点がありましたら、お気軽に教えていただければ幸いです。

#Google Colaboratoryとは？
公式サイトによると
>Google Colaboratoryとは、完全にクラウドで実行されるjupyterノートブック環境です。
Colaboratoryを使用すると、コードの記述と実行、解析の保存や共有、強力なコンピューティングリソースへのアクセスなどをブラウザから全て無料で行えます。

出典：[Google Colaboratory公式サイト](https://colab.research.google.com/notebooks/welcome.ipynb?hl=ja)

要するにとっても性能の良いコンピュータが使えて、さらに共有も自在にできるノートなのです。

![Google colabイメージ.png](https://qiita-image-store.s3.amazonaws.com/0/387778/2e7c13f4-439f-4c37-9c7a-48263144fbfc.png)
イメージは"高性能電卓付きノート"といったところ。

#Google Colaboratoryの始め方
まずはノートを開くまでを紹介します。

1.[Google Colaboratory公式サイト](https://colab.research.google.com/notebooks/welcome.ipynb?hl=ja)
まず公式サイトを開きます。
2.次に画面左上のファイルボタンを押します
3.最後にPython3の新しいノートブックという選択肢を選びます。

操作の様子はこちらをご覧ください→https://youtu.be/dKjfhXxKsZs

これでノートを開けることが出来ました。（重要な第一歩！）
動画を真似して、いろんな四則演算をやって見てください。(まずはGoogle Colaboratoryで何かを計算することに慣れましょう！)

#Google Colaboratory事始め

Google Colaboratoryが１番の真価を発揮するのは、大量のデータを分析する時です。
計算に飽きたら、データを取り込んでみましょう。

今回はcsvファイルを読み込む作業を行います。
（csvファイルの読み込み方は後ほど紹介します。）

コードの打ち方は下の動画を参考にしてみてください。

https://youtu.be/xKw0ZhqwToY

今後も順次加筆していきます。
Ubuntu 18.04LTSを日本語Remixイメージでインストールした後に英語キーボードを使う

設定ファイルを書き換えて対応するのが一番簡単で早い．
ターミナルを開いて，設定ファイルを編集するには，

```console
sudo vi /usr/share/ibus/component/mozc.xml
```

とする．
編集する箇所はlayoutタグの部分で，元はdefaultとなっているのをusに変更する．

```xml
<component>
  <version>2.20.2673.102+dfsg-2</version>
  <name>com.google.IBus.Mozc</name>
  <license>New BSD</license>
  <exec>/usr/lib/ibus-mozc/ibus-engine-mozc --ibus</exec>
  <textdomain>ibus-mozc</textdomain>
  <author>Google Inc.</author>
  <homepage>https://github.com/google/mozc</homepage>
  <description>Mozc Component</description>
<engines>
<engine>
  <description>Mozc (Japanese Input Method)</description>
  <language>ja</language>
  <symbol>&#x3042;</symbol>
  <rank>80</rank>
  <icon_prop_key>InputMode</icon_prop_key>
  <icon>/usr/share/ibus-mozc/product_icon.png</icon>
  <setup>/usr/lib/mozc/mozc_tool --mode=config_dialog</setup>
  <layout>us</layout>
  <name>mozc-jp</name>
  <longname>Mozc</longname>
</engine>
</engines>
</component>
```

以上．非常に簡単．
Qiitaのデフォルトの配色の件

たいそうなタイトルのわりに大したことじゃない。

白い画面に黒いコンソール画面は見えずらい。

```ruby:qiita.rb
puts 'code with syntax'
```

ためしにこのページを屋外で見てみよう。もしくは、カーテンやブラインドを開けてモニターに光があたるようにして見てみてほしい。

視認するのが厳しいと思わない？
#GCP の Google 翻訳 #API を叩く #python スクリプト例。 #JSON を標準入力に与えると 翻訳結果のテキストを付与させて同じく JSON を標準出力する。

# 前提

- gcloud コマンドが使えること
- サービスアカウントファイルを作成していること
- Google Translate API やらの設定が済んでいること

ref [google翻訳 yumanaura - Google Search](https://www.google.com/search?q=google%E7%BF%BB%E8%A8%B3+yumanaura&oq=google%E7%BF%BB%E8%A8%B3+yumanaura&aqs=chrome..69i57.3403j0j7&sourceid=chrome&ie=UTF-8)

# ./get-token.sh

フレッシュでナウでヤングな Access Token  を得る簡単なシェルスクリプト

```
GOOGLE_APPLICATION_CREDENTIALS=~/.secret/google-service-credential.json gcloud auth application-default print-access-token
```

# ./translate-json.py

- 標準入力で json を与える 
- json はオブジェクトの配列を想定
- 翻訳したいjson 的なキーを 環境変数 TRANSLATE_JSON_KEY で渡す

```py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os, sys, requests, json, fileinput, re

json_lines = sys.stdin.read()

from_language = os.environ.get('FROM') if os.environ.get('FROM') else 'ja'
to_language = os.environ.get('TO') if os.environ.get('TO') else 'en'

token = os.environ['TOKEN']
translate_json_key = os.environ['TRANSLATE_JSON_KEY']

headers = {
 'Authorization': 'Bearer {}'.format(token),
 'Content-Type': 'application/json',
}
 
api_url = 'https://translation.googleapis.com/language/translate/v2'

results = []

for line in json.loads(json_lines):
  params = {
    'q': line[translate_json_key],
    'source': from_language,
    'target': to_language,
    'format': 'text'
  }
 
  res = requests.post(api_url, headers=headers, json=params)

  translated_text = res.json()['data']['translations'][0]['translatedText']

  line["translated_text"] = translated_text

  results.append(line) 
 
print(json.dumps(results))
```


# exe

```
$ echo '[{"text":"洋梨", "owner": "Yuma"}, {"text" : "りんご", "owner" : "Inaura"}]' | TOKEN=$(./get-token.sh) TRANSLATE_JSON_KEY=text ./translate-json.py | jq .
```

```json
[
  {
    "text": "洋梨",
    "owner": "Yuma",
    "translated_text": "Pear"
  },
  {
    "text": "りんご",
    "owner": "Inaura",
    "translated_text": "Apple"
  }
]
```

# Original by Github issue

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
【Twitter】アクセストークン取得までの流れ

今更ながら、Twitter APIのトークン周りについて
特にアクセストークン取得までの流れがちょっと複雑なので、メモしました。

# Twitterトークンについて
以外にもTwitterトークンについての記事が少ないので、まずここからお話します。

## トークンの種類
トークンの種類は大きく2種類あります。APIキーとアクセストークンです。
それぞれシークレットキー（またはシークレットトークン）を持っています。
基本的に`API key`と`API key secret`または`Access Token`と`Access token secret`はペアで扱うので、まとめてAPIキー、アクセストークンといったりします。

| トークンの種類 | 説明 |
|:--|:--|
| Consumer API key        | API識別キー |
| Consumer API key secret | API識別シークレットキー |
| Access token            | Twitterアカウントに対するアクセストークン |
| Access token secret     | Twitterアカウントに対するアクセストークンシークレット |


`Consumer API key`は昔`Consumer token`と呼ばれていました。APIを識別するためのキーなので、改名して正解だと思います。

**※注意※**
Twitter4Jでは`Consumer token`の名残が**クラス名や関数名に残っています**。
混乱しないように気をつけましょう。

# アクセストークンの取得
アクセストークンはTwitterクライアントのIDとパスワードみたいなものですから、流出しては大変です。
そのためアクセストークンを入手するためには、いくつかの手順を踏む必要があります。

## 連携リクエスト
API連携をアプリケーションサーバにリクエストしてから、PINコードがTwitterサーバから帰ってくるまでの図です（簡単にするためにかなり端折っています）。
<img width="600" alt=get-accesstoken1.png src="https://qiita-image-store.s3.amazonaws.com/0/267005/fd573a67-04a2-4b51-51aa-5a91d63e1c20.png">

ほとんど書いてあるとおりですが、一応説明を
最初、クライアントはアプリケーションサーバに連携リクエストを送信します。
連携リクエストを受けたアプリケーションサーバはTwitterに連携リクエスト送信し、リクエストトークンとauthorizantion URLを取得します。autorizantion URLはこのとき限りの一時的なURLです。
クライアントはauthorization URLにアクセスし、Twitterにログインした状態で連携ボタンを押すことでPINコードが得られます。

## リクエストトークン + PINコード = アクセストークン
前の図の続きです。PINコード取得からアクセストークン取得までの流れになります。
<img width="600" alt=get-accesstoken1.png src="https://qiita-image-store.s3.amazonaws.com/0/267005/ffbc0181-3e1d-1f82-d0bc-863112fd9899.png">
クライアントは得られたPINコードをアプリケーションサーバに送ります。
アプリケーションサーバはリクエストトークンとともにPINコードをTwitterサーバに送ることで、アクセストークンを得ます。
最後にクライアントに対して連携成功のメッセージを送信すれば、連携完了です。

以降、アプリケーションサーバは`API key`と取得した`AccessToken`を用いて、Twitterアカウントへのアクセスが可能になります。

# アクセストークン取得のポイント
リクエストトークン、authorization URL、PINコードはすべて紐付いています。
（リクエストトークンからauthorization URL、authorization URLからPINコードが生成されるイメージです）
また、**リクエストトークン生成時のタイミングでは、Twitterアカウントと紐付いていません**。
Twitterアカウントを紐付けるのはアクセストークンとPINコードになるので、実装するときは十分注意してください。

当時知らなかった私は、1回の連携リクエストに対して、2回リクエストトークンを発行してしまい、連携が上手くいきませんでした。

# まとめ
本文では触れませんでたが、このような認可方式をOAuth認可方式と呼びます。
ユーザにユーザIDやパスワードを提供してもらうことなく、ユーザのアカウントにアクセスできるため、広く使われている手法です。
とはいえ、`API key`と`AccessToken`を奪われると、簡単にアカウントを乗っ取ることが可能になってしまうので、十分注意しましょう。

# 参考リンク
[【カンタローCGI】Twitterのアクセストークンとコンシューマキーを取得する](https://kantaro-cgi.com/blog/external-service/get_twitter_token.html)
ActiveSupportのsymbolize_keys!が挙動不審だった件

## はじめに

**StringとSymbolで同一名のKeyを持つHashはやめよう**

```ruby
{'id' => 10, :id => 11, 'name' => 'AAA', :name => 'BBB'}
```

## 遭遇

**ruby2.4+rails**
Hash.transform_keys!が**特定の状況でsymbolize_keys(非破壊)と互換のない**挙動をする

**ruby2.5.2+rails**
ruby2.5で同関数が実装された事で正常に動作する


## 確認

### ruby2.4+rails

symbolが先の場合

```ruby
[1] pry(main)> {:id => 10, 'id' => 11, :name => 'AAA', 'name' => 'BBB'}.symbolize_keys
=> {:id=>11, :name=>"BBB"}
[2] pry(main)> {:id => 10, 'id' => 11, :name => 'AAA', 'name' => 'BBB'}.symbolize_keys!
=> {:id=>11, :name=>"BBB"}
```

symbolが後の場合

```ruby
[1] pry(main)> {'id' => 10, :id => 11, 'name' => 'AAA', :name => 'BBB'}.symbolize_keys
=> {:id=>11, :name=>"BBB"}
[2] pry(main)> {'id' => 10, :id => 11, 'name' => 'AAA', :name => 'BBB'}.symbolize_keys!
=> {:id=>10, :name=>"AAA"}
```

### ruby2.5.2+rails

symbolが先の場合

```ruby
[1] pry(main)> {:id => 10, 'id' => 11, :name => 'AAA', 'name' => 'BBB'}.symbolize_keys
=> {:id=>11, :name=>"BBB"}
[2] pry(main)> {:id => 10, 'id' => 11, :name => 'AAA', 'name' => 'BBB'}.symbolize_keys!
=> {:id=>11, :name=>"BBB"}
```

symbolが後の場合

```ruby
[1] pry(main)> {'id' => 10, :id => 11, 'name' => 'AAA', :name => 'BBB'}.symbolize_keys
=> {:id=>11, :name=>"BBB"}
[2] pry(main)> {'id' => 10, :id => 11, 'name' => 'AAA', :name => 'BBB'}.symbolize_keys!
=> {:id=>11, :name=>"BBB"}
```


## 原因

[該当箇所はここ](https://github.com/rails/rails/blob/5-2-stable/activesupport/lib/active_support/core_ext/hash/keys.rb#L25-L30)
`self[yield(key)] = delete(key)`の部分、
`'id'`で取得した物を`:id`に対して代入し、symbolで保持していた値が失われている為。

```ruby
def transform_keys!
  return enum_for(:transform_keys!) { size } unless block_given?
  keys.each do |key|
    self[yield(key)] = delete(key)
  end
  self
end

def symbolize_keys!
  transform_keys! { |key| key.to_sym rescue key }
end
```


## おわりに

**StringとSymbolで同一名のKeyを持つHashはやめよう**
Android Studioでgradle syncできない

## エラー
```
ERROR: Unsupported method: AndroidProject.getVariantNames().
The version of Gradle you connect to does not support that method.
To resolve the problem you can change/upgrade the target version of Gradle you connect to.
Alternatively, you can ignore this exception and read other information from the model.
```

## 原因
Android Studio 3.3.2 に問題あるとのこと
> https://stackoverflow.com/a/54326157

## 解決策
以下の設定をOFF
Preferences > Experimental > Only sync active variant
【mysql】実は速度に影響する型変換

mysqlではクエリで型をそろえなかったとしても、空気を読んで変換してくれる機能があります。
それによって人為的なミスによるエラーを防ぐ効果もあるかと思いますが、
反対に暗黙で型の変換を行っているため、速度に影響していることはご存知でしょうか。

例えば


| animal(Varchar) | wingflg(Varchar) |
|:-----|----:|
| 犬  | 0 | 
| 猫    | 0 |  
| アヒル  | 1 |
| 蝶  | 1 | 
| 蛇 | 0 | 

上記のようなテーブルがあるとします。

ここから羽のある生き物のみを抽出しようとした場合

```
select * from テーブル名 where wingflg = 1
```

と書くことが多くありますが（特に焦っているときとか・・・）
上記クエリを

```
select * from テーブル名 where wingflg = '1'
```
こうするだけで、内部的に暗黙の型変換が行われなくなり
速度アップがはかれます！！

速度改善で行き詰まったりしたら、
型をもう一度確認するのもいいかもしれませんね。
TerraformのbackendでS3を使う

"terraform.tfstate"ファイルをS3に設置する手順

## バージョン情報

`Terraform v0.11.13`

## 手順

### S3バケットを作成する

[マネジメントコンソールから作成](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/user-guide/create-bucket.html)する（作り方はなんでもいい）。[Bucket Versioning](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/user-guide/enable-versioning.html)の有効化は[公式が推奨](https://www.terraform.io/docs/backends/types/s3.html)しているためやっておく。

### DynamoDB を作成する（必須ではない）

S3バケットを複数人同時に編集しないように、[DynamoDB](https://aws.amazon.com/jp/dynamodb/)を作成する。
これも、マネジメントコンソールからすぐに作れる。
この時、プライマリキーを必ず"LockID"にしなければいけないことに注意。


### Configurationファイルにbackend情報を記入する

下記の設定ファイルは、[設定ファイルと認証情報ファイル](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-files.html)がすでに完了していることを前提としている。

```
provider "aws" {
  region = "ap-northeast-1"
}

terraform {
  backend "s3" {
    bucket = "S3バケット名"               # 適宜変更
    key = "terraform.tfstate"
    encrypt = true                       # 適宜変更
    region = "ap-northeast-1"            # 適宜変更
    dynamodb_table = "DynamoDBテーブル名"  # 適宜変更
  }
}

...
```

### Backendの設定反映

```
$ terraform init
```

## ハマったところ

backendの設定に変数を使っていると、こんなエラーがでる。どうやら、backend設定の部分は変数展開の前に読み込まれるらしい。[今のところどうにもならないっぽい](https://github.com/hashicorp/terraform/issues/13022)


```
$ terraform init                                      
                                                                         
Initializing the backend...                                                                                                                         
Error loading backend config: 1 error(s) occurred:       
                                                         
* terraform.backend: configuration cannot contain interpolations                                                                                    
                                                                             
The backend configuration is loaded by Terraform extremely early, before     
the core of Terraform can be initialized. This is necessary because the backend
dictates the behavior of that core. The core is what handles interpolation
processing. Because of this, interpolations cannot be used in backend    
configuration.                                                                 
                                                               
If you'd like to parameterize backend configuration, we recommend using                             
partial configuration with the "-backend-config" flag to "terraform init".
```
変数が参照される動きを見るという視点について

#変数のデータがコードの中をどうやって動いているのかを考える
　変数を検索すると、スコープと共に語られることが多い。実際、スコープは変数の有効範囲という認識で正しいはずなのだが、スコープを作り出すのは変数では無い。ある変数は、あるスコープを所持しているというわけではなく、**ある変数は、あるスコープまででデータを参照できる**ということにすぎない。
　つまり、変数がスコープを作っているのでは無く、変数は与えられたスコープという空間を生きることしかできない、ということ。では、何がスコープを作っているのかというと、それがブロックという概念になる。

### ブロックとは
　クロージャ、レキシカルスコープとも呼ばれる概念。クロージャは、メソッドの実行環境に対して変数が存在しない時に、その親スコープへと変数を参照する能力を持つ。

> Rubyのブロックは，メソッドに与えるもの（メソッド呼び出し時に与えるもの）というところが本質です。
〈メソッドに与えるもの〉というと，引数（より詳しく言えば実引数）　
>> scivolaさんからのコメントより引用

引数を与えるために、参照先を探しに行く、と言える。

#### ブロックパラメータ
　イテレータなどで｜｜このようにパイプで括られたもの。ブロック変数とも呼ばれていることもある。語っている人によって同一概念を別単語で語られることが多いので、混乱する。

## 変数には何が内包され得るかの視点

```loop.rb
cnt = ARGV[0].to_i

def loop(n)
  (1..n).each do |n|
    p "Hello World!! #{n}"
  end
end

loop(cnt)
```

　nだらけです。一応、このプログラムは動きますが、勉強を始めた人には？となるであろうコードです。というか私はなりました。なんと、**ここに書かれたnという変数は二種類あってそれぞれが違うということです**

　このnが二種類ある理由を明確にするために、一種類の変数nを別の変数名に変えてみますn

```loop2.rb
cnt = ARGV[0].to_i

def loop(n)
  (1..n),each do |i|
    p "Hello World!! #{i}"
  end
end

loop(ctn)
```
違いが見えてくると思います。
　loopメソッドの引数nは、ARGVによってプロンプトから受け取る整数値。そして、この固定された整数値は、範囲オブジェクトにも使われています。iは、ループされた1からnまでの数値がループするたびに代入されるはずですので、pメソッドに番号を振りたい場合、nではなく、iを書かなければならないことがわかると思います。

しかし、これだと先ほど私が書いたブロックの概念がわかりにくいので、少しコードを変更します。

```loop2.rb
cnt = ARGV[0].to_i

def loop(n)
  (1..n),each do |i|
    p "Hello World!! #{n}"
  end
end
```

　これだと標準出力される数字は、変数nに代入された整数値ですが、eachで作られているブロック内で使われているnはこのブロック内でのどこにも変数として定義されていないのに、エラーを起こさないというところが重要です。
　なぜ、エラーが起こってないかというと、pメソッドで変数展開されているnは、do~endで囲まれたブロックから、def~endで囲まれたブロック、つまり、ネストしている親ブロックに変数を取りにいっています。これが、クロージャ、ブロックの作るスコープです。

　変数は様々に存在しますが、それを説明する時に、スコープを変数の有効範囲と定義してしまうと、あたかも変数がスコープを持っているような印象を受けます。が、正しくは、**ブロックによって作られたスコープを越えていく範囲が変数によって決まっている**ということなのです。

　変数の中身と、それらがどいうやって動いているのかを理解するのに非常に重要な視点だと思っています。普通の人は、これやらなくても理解できるようなのですが、私はここまで落とし込んでようやく腑に落ちました。
ちなみに、eachやtimesといったイテレータのようなブロックを作り出すメソッドを**ブロック付きメソッド**と読んだりします。

## 補足
コメントをいただきましたが、ブロックだけが変数の動きを固めるわけではないです。同一インスタンス内で参照できるインスタンス変数などが良い例かと思います。今回は、ブロックについて考察した結果をまとめたものですので、ご了承ください。

## 補足2
ブロックを作るdo endは、{}のかっこで作ることもできる。
Mac MojaveでLatexを使う

# はじめに
　個人的な事情でMac上で完璧に動くLatex環境を作る必要がありました。
その手順のメモをアップしておきます。

# 事前準備

## Xcode
　このあたりのソフトを使う場合、Xcodeもあった方がいいみたいです。
Xcodeは、App Storeから無料で導入できますので、まずは導入を行います。

## Xcode Command Line Tools
　Xcode付属のコマンドラインツールも入っていた方がいいようです。次のコマンドで導入します。

```
$ xcode-select --install
```

## MacTeX 2018 のダウンロードとインストール

[Downloading MacTeX 2018](https://tug.org/mactex/mactex-download.html)からダウンロード、インストールします。とても巨大なファイルなので注意して下さい。

## TexShopの立ち上げ
　導入が終わると、アプリケーションの中にTexというフォルダが作られ、その中にTexShopというソフトが含まれているので、まずは起動します。すぐに閉じて再起動すると、モジュールを更新するかきいてくるので、「更新する」で答えて下さい。更新後再度TexShopを起動します。

## Tex Shopの設定変更、テスト
　設定プロファイルから pTeX(ptex2pdf) を選択します。

![スクリーンショット 2019-04-09 12.47.33.png](https://qiita-image-store.s3.amazonaws.com/0/206130/1b743bda-3bea-d020-41c6-655aa50e9a95.png)

　OKを押して環境設定を終わり，TeXShopも終了します。その後、再度起動して下さい。


```
\documentclass{article}
\begin{document}
Hello, \TeX!  ヒラギノ
\end{document}
```

　上のテキストをコピペして、下の図のように「タイプセット」のところをクリックします。

![スクリーンショット 2019-04-09 12.49.08.png](https://qiita-image-store.s3.amazonaws.com/0/206130/bba80289-d725-d825-7433-e18ddba0064a.png)

　ファイル名はtestなど適当に設定すると、下の図のようにPDFファイルが生成されるはずです。

![スクリーンショット 2019-04-09 12.49.36.png](https://qiita-image-store.s3.amazonaws.com/0/206130/3b23419f-b7b3-50da-596b-dc0be6010578.png)

　今度は本格的な数式に挑戦します。次のテキストを編集エリアにコピペして同じことをやってみて下さい。

```
\documentclass[dvipdfmx,autodetect-engine]{jsarticle}
\usepackage{amsmath}

\begin{document}

\begin{align*}
&f(x, \mu, \sigma) = \frac{1}{\sqrt{2\pi}\sigma}\exp\left(-\frac{(x-\mu)^2}{2\sigma^2}\right)&
\end{align*}

\end{document}
```

　うまくいくと下の図のようなPDFができます。

![スクリーンショット 2019-04-09 12.53.17.png](https://qiita-image-store.s3.amazonaws.com/0/206130/6bef7f00-419e-11a7-47ca-248577e7c394.png)

　いったんここでTexShopを終了させて下さい。これでLatexとしては日本語を含めて十分に動くのですが、より高いクオリティを追求する道があります。それは日本語フォントを「**ヒラギノフォント**」に置き換える方法です。以下は、そのための手順になります。

## Tex Liveの更新
　まず、次のコマンドでTex Liveのモジュールをすべて最新のものに置き換えます。更新には相当時間がかかりますので注意して下さい。

```
$ sudo tlmgr update --self --all
```

## ヒラギノフォントの導入
　更新後にヒラギノフォントをLatexで使えるようにするには、相当ややこしい手順が必要です。しかし、それを全部プログラム化したツールが公開されています。Mac OSのバージョンアップにも対応できていて、2019年4月9日現在最新版であるMojaveにも対応済みです。

[bibunsho7-patch](https://github.com/munepi/bibunsho7-patch/releases)

## フォントの見分け方

　ちなみに、作ったPDFがヒラギノフォントになっているかどうか、どうみわけたらいいかです。カタカナの「**ヒ**」の時をどんどん拡大していきます。拡大した「ヒ」の横棒にヒゲのようなものがあればそれはデフォルトのフォントです。ヒラギノフォントの場合、「ヒ」の横棒は下のようになめらかになっています。

[設定前]
![スクリーンショット 2019-04-13 22.46.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/e54366d7-d2d7-eeec-0d88-b264cd7fd987.png)


[設定後]

![スクリーンショット 2019-04-09 14.49.09.png](https://qiita-image-store.s3.amazonaws.com/0/206130/23f083f7-ba9b-1d56-2bcd-3e238879b3f7.png)


## Tex2Imgの導入
　これからご紹介するツールは、数式の部分だけをクリッピングしたPDFを生成してくれるものです。
[ダウンロード先](https://tex2img.tech)から導入します。

　使い方は下の図のように簡単です。Latexのコードのうち、\begin{document}から\end{document}の内部を抜き出したコードを張り付けて、「画像生成」ボタンをクリックします。

![スクリーンショット 2019-04-09 14.54.01.png](https://qiita-image-store.s3.amazonaws.com/0/206130/c8a83153-2f4a-834b-8945-ab5e992ccc20.png)


　結果は下の図のように数式部分のみをクリップしたPDFファイルになります。このPDFはいろいろな目的で利用することができます。

![スクリーンショット 2019-04-09 14.54.18.png](https://qiita-image-store.s3.amazonaws.com/0/206130/09a31cbf-1835-2493-a46b-45f6d704ec1c.png)
MySQL と PostgreSQL の記法が地味にややこしいので整理する

#概要
MySQLに触れた経験はあるものの、仕事ではPostgreSQLを使用していたので、
久しぶりにMySQLを使うとどっちゃねんややこしいなあ〜ってなったのでまとめまーす。

よく使うものだけに絞ってまとめていくので、サーバー起動とかユーザー登録とかは避けまーす。

##データベースへのアクセス
###MySQL
```bash
$ mysql -u ユーザー名
(mysql> USE データベース名;)⇦データベースを指定した場合、以下のデータベース名.テーブル名のデータベース名は不要
```
###PostgreSQL
```bash
$ psql -U ユーザー名 -d データベース名
```

##DB一覧
###MySQL
```bash
mysql> SHOW DATABASES;
```
###PostgreSQL
```bash
$ psql -l -U ユーザー名
```

##テーブル一覧
###MySQL
```bash
mysql> SHOW TABLES FROM データベース名;
```
###PostgreSQL
```bash
データベース名> \dt
```

##テーブルカラム一覧
###MySQL
```bash
mysql> SHOW COLUMNS FROM データベース名.テーブル名;
または
mysql> DESCRIBE データベース名.テーブル名;
```
###PostgreSQL
```bash
テーブル名 > \d テーブル名
```

##テーブル作成
###MySQL
```bash
mysql> CREATE TABLE データベース名.テーブル名 (カラム名1 カラム型1, カラム名2 カラム型2, ,,, );
```
###PostgreSQL
```bash
データベース名> CREATE TABLE テーブル名 (カラム名1 カラム型1, カラム名2 カラム型2, ,,, );
```

##テーブル変更
###MySQL
```bash
mysql> ALTER TABLE データベース名.テーブル名 ADD [COLUMN] カラム名;
```
###PostgreSQL
```bash
データベース名> ALTER TABLE テーブル名 ADD [COLUMN] カラム名;
```

##テーブル削除
###MySQL
```bash
mysql> DROP TABLE データベース名.テーブル名;
```
###PostgreSQL
```bash
データベース名> DROP TABLE テーブル名;
```

##行追加
###MySQL
```bash
mysql> INSERT INTO データベース名.テーブル名 (カラム名1, カラム名2, ...) VALUES (要素1, 要素2, ...);
```
###PostgreSQL
```bash
データベース名> INSERT INTO テーブル名 (カラム名1, カラム名2, ...) VALUES (要素1, 要素2, ...);
```

##行検索
###MySQL
```bash
mysql> SELECT * FROM データベース名.テーブル名 WHERE 条件1 AND 条件2 AND ... ;
```
###PostgreSQL
```bash
データベース名> SELECT * FROM テーブル名 WHERE 条件1 AND 条件2 AND ... ;
```

##行指定変更
###MySQL
```bash
mysql> UPDATE データベース名.テーブル名 SET 変更するカラム名 = 変更後の数値等 WHERE 条件1 AND 条件2 AND ... ;
```
###PostgreSQL
```bash
データベース名> UPDATE テーブル名 SET 変更するカラム名 = 変更後の数値等 WHERE 条件1 AND 条件2 AND ... ;
```

##行削除
###MySQL
```bash
mysql> DELETE FROM データベース名.テーブル名 WHERE 条件1 AND 条件2 AND ... ; 
```
###PostgreSQL
```bash
DELETE FROM テーブル名 WHERE 条件1 AND 条件2 AND ... ; 
```

#まとめ
よく使うのはこんなもんでしょうか。
一覧表示するときと、データベースへのアクセスだけ違う感じで、それ以外はほぼ一緒なんですね〜。
ではでは。
Swift4.2から5へのマイグレーションでやったこと

最近自分のアプリでSwift4.2から5へのマイグレーションを実施したので、やったことをまとめておきます。
なお、使用しているパッケージマネージャはCocoaPodsのみです。

## XCode10.2/Swift4.2で問題なく動作するようにする
まずはじめに、XCode10.2/Swift4.2でアプリが問題なく動作すること、テストがパスすることを確認しました。

このときはXCode10.2にしたタイミングでテストライブラリの`Nimble`がコンパイルエラーを起こしていたので、`Nimble`をバージョンアップしました。

```
$ pod repo update
$ pod update Nimble
```

バージョンアップしたらコンパイルエラーは出なくなり、テストがパスしました。
`Podfile.lock`が変更されているので、ここで一旦コミットしておきます。

## アプリのコードをSwift5へマイグレーションする
次に、Swift5へのマイグレーションを行っていきます。

XCodeが提供するマイグレーションツールによるマイグレーションは、アプリ本体のコードおよびテストコードにのみ実施します。
ライブラリのコードについては、Swift5に対応しているバージョンにアップデートするか、Swift4.2でビルドするように設定することで対応します。

マイグレーション実施前に`Podfile`に以下の設定を加えておきます。
これはライブラリをSwift4.2でビルドするという設定です。

```ruby
post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['SWIFT_VERSION'] = '4.2'
    end
  end
end
```
ここで一旦コミットしておきます。

続いて、Edit > Convert > Convert to current swift syntaxをクリックします。
以下のような画面が表示されるので、アプリターゲットとテストターゲットにのみチェックを入れてNextをクリックします。

![スクリーンショット_2019_04_09_14_12.png](https://qiita-image-store.s3.amazonaws.com/0/81715/9c219cfd-7a03-52cf-1ba2-cec13513047c.png)

マイグレーション処理が開始されます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/81715/2a710b31-fe5a-818d-90c8-4e673e2ed481.png)

今回は変更箇所がなかったらしく以下のような画面が表示されました。
Updateをクリックすると、`project.pbxproj`が更新され、Swift5でビルドする設定に変更されました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/81715/5f756a6a-654f-35ac-8ab1-5b1ce4e14c71.png)

ここでアプリが問題なく動作すること、テストがパスすることを確認しました。
なお、Swift5で[Enumに一部変更があった](https://qiita.com/tamappe/items/64fbe4d0991cd222540e#handling-future-enum-cases)関係でワーニングが出ていたので、それだけ修正しました。

ここでまたコミットしておきます。

## ライブラリをバージョンアップする
アプリ本体のコードのマイグレーションが完了したので、次はライブラリをバージョンアップしてXCode10.2/Swift5に対応させます。

`Podfile`に追加していた設定をここで削除しておきます。

次に、ライブラリのバージョンアップを行います。
CocoaPodsのみでライブラリのバージョン管理を行っているので、以下のコマンドで全てのライブラリを一気にバージョンアップできます。

```
$ pod update
```

バージョンアップが完了したら、アプリが問題なく動作するか、テストがパスするかを確認します。
このときはコンパイルエラーも起こらず、アプリの動作も特に問題ありませんでした。

なお、ライブラリがまだSwift5に対応していないときは、`Podfile`に以下のような設定を加えることで、そのライブラリだけSwift4.2でビルドするということができます。
[Swiftマイグレーションガイド](https://swift.org/migration-guide-swift5/)に、Swift4.2と5でビルドしたターゲットは共存可能であると書かれています。

```ruby
post_install do |installer|
  installer.pods_project.targets.each do |target|
    if ['RxSwift', 'RxCocoa'].include? target.name
      target.build_configurations.each do |config|
        config.build_settings['SWIFT_VERSION'] = '4.2'
      end
    end
  end
end
```

## まとめ
Swift5へマイグレーションしたときの手順をご紹介しました。
自分は経験ないですが、Swift2→3、Swift3→4のマイグレーションに比べるとほとんど手間がかからなくなったようです。

今回はCocoaPodsだけを使っているプロジェクトの例でしたが、Carthageを使っていたり、Embedded Frameworkなど使ったりしていると、また違った手順になるんでしょうか。
もっとマイグレーション関連の記事がたくさん出るといいなと思います。

## リファレンス
- [Swift5マイグレーションガイド](https://swift.org/migration-guide-swift5/)
- [Swift 4 migration and cocoapods](https://medium.com/@timefrancesco/swift-4-migration-and-cocoapods-31e5ac020980)
#jq コマンドむずい。オブジェクトの配列から、任意のキーを指定してフィルタし、新しいオブジェクトの配列を組み立て直そうとして失敗した例。

- 配列の持つオブジェクト内で
- a というキーを持つ value を
-  x というキー に差し替えて
- 再び配列に収める

ということをやりたい

# json

```json
[
  {
    "a": 1,
    "b": 2,
    "c": 3
  },
  {
    "a": 3,
    "b": 4,
    "c": 5
  }
]
```

# exe

キーが一つならうまくいく

```sh
$ echo '[{"a" : 1, "b" : 2, "c" : 3},{"a" : 3, "b" : 4, "c" : 5}]' | jq '[{"x": .[].a}]'
[
  {
    "x": 1
  },
  {
    "x": 3
  }
]
```

 # exe

キーが複数だとこれだ！
なんだか組み合わせの数だけ増えているような気がするな？
べき乗っぽいぞ！

```json
$ echo '[{"a" : 1, "b" : 2, "c" : 3},{"a" : 3, "b" : 4, "c" : 5}]' | jq '[{"x": .[].a, "y" : .[].a, "z" : .[].a}]' | pbcopy

[
  {
    "x": 1,
    "y": 1,
    "z": 1
  },
  {
    "x": 1,
    "y": 1,
    "z": 3
  },
  {
    "x": 1,
    "y": 3,
    "z": 1
  },
  {
    "x": 1,
    "y": 3,
    "z": 3
  },
  {
    "x": 3,
    "y": 1,
    "z": 1
  },
  {
    "x": 3,
    "y": 1,
    "z": 3
  },
  {
    "x": 3,
    "y": 3,
    "z": 1
  },
  {
    "x": 3,
    "y": 3,
    "z": 3
  }
]

```

# exe

```json
$ echo '[{"a" : 1, "b" : 2, "c" : 3},{"a" : 3, "b" : 4, "c" : 5}]' | jq '[{"x": .[].a, "y" : .[].a, "x" : .[].a, "a" : .[].a}]'

[
  {
    "x": 1,
    "y": 1,
    "a": 1
  },
  {
    "x": 1,
    "y": 1,
    "a": 3
  },
  {
    "x": 3,
    "y": 1,
    "a": 1
  },
  {
    "x": 3,
    "y": 1,
    "a": 3
  },
  {
    "x": 1,
    "y": 3,
    "a": 1
  },
  {
    "x": 1,
    "y": 3,
    "a": 3
  },
  {
    "x": 3,
    "y": 3,
    "a": 1
  },
  {
    "x": 3,
    "y": 3,
    "a": 3
  },
  {
    "x": 1,
    "y": 1,
    "a": 1
  },
  {
    "x": 1,
    "y": 1,
    "a": 3
  },
  {
    "x": 3,
    "y": 1,
    "a": 1
  },
  {
    "x": 3,
    "y": 1,
    "a": 3
  },
  {
    "x": 1,
    "y": 3,
    "a": 1
  },
  {
    "x": 1,
    "y": 3,
    "a": 3
  },
  {
    "x": 3,
    "y": 3,
    "a": 1
  },
  {
    "x": 3,
    "y": 3,
    "a": 3
  }
]

```

# Original by Github issue

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
#jq コマンドを利用して エンコード済みのUTF-16 の文字列をデコードする例 (日本語)


```
$ echo '\u3082\u3063\u3068\u65e9\u304f\u304b'
\u3082\u3063\u3068\u65e9\u304f\u304b

$ '"\u3082\u3063\u3068\u65e9\u304f\u304b"' | jq . -r
もっと早くか
```

- 文字列をダブルクォートで囲って jq コマンドに与える
- まったく json とか関係ない利用法
- もしかしたらシステムの言語設定やらいろいろ関わってくる気もするが細かい部分は未検証
- Linux CentOS で確認


# フラットに文字列だけがある JSON とは

これでも 正常らしい。

![image](https://user-images.githubusercontent.com/13635059/55713140-00801b80-5a2b-11e9-8663-b13194b6f689.png)

![image](https://user-images.githubusercontent.com/13635059/55713162-0c6bdd80-5a2b-11e9-82d2-4c49b7d87f66.png)

# UTF-16 decoder

これとか

[UTF-16 Decode - Convert UTF-16 to Text - Online - Browserling Web Developer Tools](https://www.browserling.com/tools/utf16-decode)

# Original by Github issue

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
#python の __main__ 関数とは何なのか (いや関数じゃないよ) (初心者向け)

import時の挙動が違うらしい。 

- main 関数の中に書かないと import 時にスクリプトが実行される
- main 関数の中に書いておくと import 時に実行されない
- むしろ import 時に実行させたい処理の場合は main 判定の中に入れず、ベタで書いておくと良いのかもしれない (スマートではない気がする)

# ./a.py

処理をべた書き

```
print("this is a")
```

# ./b.py

__main__ 関数判定をする

```py
if __name__ == "__main__":
  print("This is b")
```

# ./c.py

二つのスクリプトをimportする

```py
import a
import b
```

# exe

二つのスクリプトを import すると 処理がべた書きされている a.py の内容だけが実行される

```
python3 ./c.py 
this is a
```

# ところで

- ついつい最初、ものすごくぼんやりとしたイメージで main 関数というキーワードでググってしまったが、よく見ると全く関数ではなかった件。
- __main__ という関数も作れるが __name__ という変数に収められた __main__ という値とは全く関係ない。


```py
def __main__():
  print("this is __main__ function")

if __name__ == "__main__":
  print('__name__ is ' + __name__)

  __main__()
```

```
python3 script.py

__name__ is __main__
this is __main__ function
```
# で何？


- 特殊変数 __name__ には「直接実行された場合には __main__ が」「importされた時にはスクリプトのモジュール名」が収まるらしい。(本当に？)


[__name__ (A Special variable) in Python - GeeksforGeeks](https://www.geeksforgeeks.org/__name__-special-variable-python/)


# Original by Github issue

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
#jq コマンドで文字列中のダブルクォートのエスケープを解除する例

`--raw-output` オプションを使えば ok

```sh
$ echo '"roce\"n\"roll"' | jq
"roce\"n\"roll"

$ echo '"roce\"n\"roll"' | jq --raw-output
roce"n"roll
```

# Original by Github issue

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
CircleCIのconfig.ymlの重複コードを減らす

yamlにはアンカーとエイリアスという値を再利用するための仕組みがあり、それを利用することでconfig.ymlの重複コードを減らしDRYにできます。
実際の設定値の中にアンカー定義があると読みにくいので、私は`anchors`要素としてアンカーの定義をまとめています。

全体像はこんな感じ。

``` yaml:./circleci/config.yml
version: 2
anchors:
  job_base: &job_base
    docker:
      - image: circleci/android:api-28-node
    working_directory: ~/repo
    environment:
      JVM_OPTS: -Xmx3200m
      TERM: dumb
  restore_gradle_cache:  &restore_gradle_cache
    - restore_cache:
        keys:
          - v1-dependencies-{{ checksum "build.gradle" }}
          - v1-dependencies-
  resolve_gradle: &resolve_gradle
    - run: ./gradlew dependencies
  save_gradle_cache: &save_gradle_cache
    - save_cache:
        paths:
          - ~/.gradle
        key: v1-dependencies-{{ checksum "build.gradle" }}
  resolve_gradle_dependencies_with_cache: &gradle_cache
    - restore_cache:
        keys:
          - v1-dependencies-{{ checksum "build.gradle" }}
          - v1-dependencies-
    - run: ./gradlew dependencies
    - save_cache:
        paths:
          - ~/.gradle
        key: v1-dependencies-{{ checksum "build.gradle" }}
jobs:
  fabric_debug:
    <<: *job_base
    steps:
      - checkout
      - run: bundler install
      - <<: *restore_gradle_cache
      - <<: *resolve_gradle
      - <<: *save_gradle_cache
      - run: fastlane betaDebug
  fabric_release:
    <<: *job_base
    steps:
      - checkout
      - run: bundler install
      - <<: *restore_gradle_cache
      - <<: *resolve_gradle
      - <<: *save_gradle_cache
      - run: fastlane betaRelease
  release:
    <<: *job_base
    steps:
      - checkout
      - run: bundler install
      - <<: *restore_gradle_cache
      - <<: *resolve_gradle
      - <<: *save_gradle_cache
      - run: fastlane deploy
workflows:
  version: 2
  fabric:
    jobs:
      - fabric_debug:
          filters:
            branches:
              ignore:
                - master
      - fabric_release:
          filters:
            branches:
              ignore:
                - master
  release:
    jobs:
      - release:
          filters:
            branches:
              only:
                - master
            tags:
              only:
                - /^.*$/
```

## job_base
`job_base` で各ジョブに共通する設定を定義しています。
これによって、実際のジョブ定義では主にstepsだけ設定するだけで済むようになります。

## キャッシュ関連
`restore_gradle_cache` `resolve_gradle` `save_gradle_cache` をまとめて1つの定義にしたいかもしれませんが、yamlのアンカーとエイリアスではそれは実現できないようです。
(配列を配列の要素として展開することができないっぽい？)
いつかできるといいなぁ。

## デプロイ設計
この設定ファイルでは以下のルールでジョブを実行しています
- master以外のブランチにプッシュされた時は、`fabric_debug`ジョブと`fabric_release` ジョブを並列で実行
- masterにタグがついた時は、 `release` ジョブを実行

# 注意
コマンドラインツールでのローカル実行(`circleci cli execute foo`) だと、このアンカーが正常に解析されずにエラーになってしまった。
python numpy が importエラーになる

centos:7のdockerコンテナ上で python2.7 の numpy をインストールし
importすると下記のエラーが発生

```
>>> import numpy
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "numpy/__init__.py", line 142, in <module>
    from . import core
  File "numpy/core/__init__.py", line 91, in <module>
    raise ImportError(msg.format(path))
ImportError: Something is wrong with the numpy installation. While importing we detected an older version of numpy in ['numpy']. One method of fixing this is to repeatedly uninstall numpy until none is found, then reinstall this version.
```

「古いnumpyもあるけど、どっちだ！？」的なエラー。

ちなみにdockerfileはこんな感じ

```
# OS
FROM centos:7

# install tools
RUN yum update -y \
&& yum install -y epel-release 

RUN yum install -y python-pip \
                   python-tables \
RUN pip install --upgrade pip 
RUN pip install numpy --ignore-installed \
```

numpyをインストールしないと1.7.1と古いため追加でインストール。
インストールそのものはエラーなし。
気のせいか、以前はエラーにはなっていなかった気がする。

最初に古いnumpyをアンインストールしようとすると下記のエラー。

```
Cannot uninstall 'numpy'. It is a distutils installed project and thus we cannot accurately determine which files belong to it which would lead to only a partial uninstall.
```

「このnumpyはdistutils（Pythonビルトインの配布ユーティリティ）なので消せないぜ！」
的なエラー。

`pip install --update numpy` をやっても、distutilsを理由にバージョンは変わらず。

```
Installing collected packages: numpy
  Found existing installation: numpy 1.7.1
Cannot uninstall 'numpy'. It is a distutils installed project and thus we cannot accurately determine which files belong to it which would lead to only a partial uninstall.
```


virtualenvなどの案もちらほらあるが、特定のコンテナアプリ利用なので
強制的にnumpyを削除する荒技

```
rm -rf /usr/lib64/python2.7/site-packages/numpy*
```

その後にinstallすれば正常にimportもできた
KVM　よく使うコマンド

いつまで経ってもKVMのコマンドが覚えられなくて、毎回ググるから
よく使うものを備忘としてまとめておく。

KVM初心者はこれだけ覚えてれば何とかなるかと


# 基本コマンド
```
### VMを表示
virsh list --all
(--allを付けないと停止しているVMが表示されない)

### VMを起動
virsh start <KVMドメイン名>

### VMを強制停止
virsh destroy <KVMドメイン名>

### VMを削除
virsh undefine <KVMドメイン名> --remove-all-storage
(--remove-all-storageを付けないとVMに紐づいたストレージファイルが削除されない)

# VMのコンフィグファイル(xml)を編集
virsh edit <KVMドメイン名>

```

**\<kVMドメイン名>** = **\<VM名>** or **\<VM ID>**


# クローン関連

```
# クローン作成
virt-clone --original <クローン元 KVMドメイン名> --name <作成する VM名> --file <作成する VMイメージファイルを格納するディレクトリパス　/var/lib/libvirt/images/<VM名>がおススメ>
(クローンを作成する際は、クローン元 VMは停止しておく必要がある)

```


# スナップショット関連
スナップショットにはinternalスナップショットとかexternalスナップショットとかあるけど、ややこしいのでとりあえず以下を覚えていればなんとかなるのでは?と思っております。。

```
# スナップショット一覧表示
virsh snapshot-list <KVMドメイン名>

# スナップショット取得
virsh snapshot-create-as <KVMドメイン名> <スナップショット名> "<コメント>"

# スナップショット復元
virsh snapshot-revert <KVMドメイン名> <スナップショット名>
```

都度更新します～(気が向いたら)
Symfony3系でセッションの保持にRedisを使う

# 様々なセッションのハンドラ
Symfony3ではデフォルトでファイルにセッションを保存する仕組みになっていて、`NativeFileSessionHandler`というクラスが使われます。
他にも様々なセッション用のハンドラが組み込まれており、MongoDBをセッションに使用する`MongoDbSessionHandler`や、Memcacheを使用する`MemcacheSessionHandler`などがあります。

しかし...

## Redisのハンドラがない
Redisのハンドラは組み込まれていません。MemcacheはあるのにRedisはない。なんてこったい。
ちなみにSymfony4ではRedisのハンドラは最初から組み込まれているみたいです。
開発をするパッケージの都合上、Symfony3でなければならず、それでもRedisを使いたい。そんな場合もあるかと思います。

# Redisセッションハンドラを実装する
[こちらのサイト](http://athlan.pl/symfony2-redis-session-handler/)を参考に実装しました。
サイトはSymfony2ベースでの解説ですが、ほとんど変わりません。

## 環境
php: 7.2
Symfony: 3.4

## ハンドラーの実装
```NativeSessionHandler.php
<?php

namespace App\Common;

use \Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeSessionHandler;

class NativeRedisSessionHandler extends NativeSessionHandler
{
    /**
    * Constructor.
    *
    * @param string $savePath Path of redis server.
    */
    public function __construct($savePath = "", $maxlifetime = 432000)
    {
        if (!extension_loaded('redis')) {
            throw new \RuntimeException('PHP does not have "redis" session module registered');
        }

        if ("" === $savePath) {
            $savePath = ini_get('session.save_path');
        }

        if ("" === $savePath) {
            $savePath = "tcp://localhost:6379"; // guess path
        }

        ini_set('session.save_handler', 'redis');
        ini_set('session.save_path', $savePath);
        ini_set('session.gc_maxlifetime', $maxlifetime);
    }
}
```

## yamlの実装
framesorkの記述があるyamlにセッションハンドラの指定をします。

```framework.yaml
services:
  session_handler_redis:
    class: App\Common\NativeRedisSessionHandler
    arguments: ['%session_redis_path%', '%session_redis_max_lifetime%']

framework:
  session:
    handler_id: session_handler_redis

parameters:
  session_redis_path: 'tcp://localhost:6379'
  session_redis_max_lifetime: 432000
```

## 追加パッケージ
上記のハンドラを使うにあたって、phpからRedisを扱うためにphp用のパッケージを入れる必要があります。
上記実装に伴って[phpredis](https://github.com/phpredis/phpredis)を使いました。
dockerのphpイメージだと下記のコマンドでインストールできます。

```Dockerfile
RUN git clone -b 4.3.0 https://github.com/phpredis/phpredis.git /usr/src/php/ext/redis 
RUN docker-php-ext-install redis
```

これでSymfony3からRedisを使用することができます！

# 最後に
よきSymfony Lifeを！
CLIでC#のコードを整形するツールを作ってみた

## 前回からの続き
[StyleCop.AnalyzersをCLIで動かせるツールを.NET Coreで作った](https://qiita.com/rookx/items/820c9d8f8909cf581566)
こちらでコードスタイルをチェックするツールを実装しました
その続きで、コードスタイルに引っかかったコードを整形するまで行えるようにしました

## リポジトリ
[StyleCop.Analyzers.CLI](https://github.com/rookxx/StyleCopAnalyzers.CLI)

## 使用方法
```shell
dotnet StyleCopAnalyzers.CLI.dll fix ./Sandbox 
```
このような感じで実行できます。
その他の細かいオプションなどについては、コマンドのヘルプに用意してあります

```shell
14:25:44 StyleCopAnalyzers.CLI $ dotnet ./tools/bin/style/StyleCopAnalyzers.CLI.dll fix --help
StyleCopAnalyzers.CLI 0.5.0
Copyright (C) 2019 StyleCopAnalyzers.CLI

  -r, --ruleset                                      Ruleset file path.
  -j, --json                                         stylecop.json file path
  -v, --verbose                                      verbose mode. output execution detail log.
  --help                                             Display this help screen.
  --version                                          Display version information.

  sln/csproj file path or directory path (pos. 0)
```
コード整形を行わずチェックスだけのオプションも用意してあります

```
dotnet StyleCopAnalyzers.CLI.dll check ./Sandbox 
```


## 動作gif
実行するとこのような感じでコードを整形する処理が実行されます
![cmd.gif](https://qiita-image-store.s3.amazonaws.com/0/16583/ed70deb9-1ca1-acba-e65b-a2ad666a8a4d.gif)

## 差分がどうなっているか
コード自体はあまり意味のないものですが、実行すると以下のようにルールに違反しているコードを整形してくれます
実行したのはStyleCop.Analyzersのデフォルトルールですので、コメントの追加までやってくれています
![550c21f8d4d18037fe6f5c68d30be7fa.png](https://qiita-image-store.s3.amazonaws.com/0/16583/a330fbb5-b67a-e1cf-8088-b5952f585620.png)
![a3f1535b0aa8762c2fb7db3bb36edc7c.png](https://qiita-image-store.s3.amazonaws.com/0/16583/a5639c6c-e566-91ba-8f93-f98918681b21.png)
![630bdc9942b0ee8f0650b021a5ba506e.png](https://qiita-image-store.s3.amazonaws.com/0/16583/d8ac211b-ec30-9952-53e4-03885f64f6a6.png)

## 課題
### とにかく実行速度が遅い
遅い理由は、ルール一つを整形する度に対象のコードを再読込する必要があるためです(StyleCop.Analyzersの制限でこうするしかない)
commit-hookなどで実行するには致命的な遅さなので、commitする差分だけをツールに渡せるように改良しようと思ってます

### 全てのルールの修正できるわけではない
これは、StyleCop.Analyzersにその機能がないものもありますが、全てのルール修正の挙動を追いきれていません
今後対応していきます

## 今後の追加予定
ルールを一つずつ実行できるようにしたいと思っています
一括で全て修正してしまうと、想定していない修正が入ることになるので、一つずつ確認できるようにしたら便利かなと
Unityプロジェクトの場合は、`SerializeField` の変数名なんかを変えてしまうと、Prefabなどの参照が全て外れて阿鼻叫喚となる場合も...

## 余談
ImmutableArrayが素敵なので他のプロジェクトでも活用していきたい
これも後ほどまとめます

ちなみに、Visual StudioやRiderを使えばこれと同じ処理をEditorでやってくれます
作った理由は個人的にCLIでのツールがどうしても欲しかったというのがあります
curl: (35) error:1408F10B:SSL routines:ssl3_get_record:wrong version number


***
タイトルのエラーが
.curlrcにプロキシ設定をしたら解決したため、メモとして残しておきます。
今回は、プロキシサーバ名をexample.com 、ポートを8080としています。

###.curlrcを設定

```
$ vim ~/.curlrc
```

```~/.curlerc
proxy=http://example.com:8080
```



##最後に
初投稿になるので、見にくさ分かりにくさあるかとは思いますが
書き方のアドバイス等のありましたら、よろしくお願いします。

##参考
・[curlコマンドにてProxy設定](https://qiita.com/tkj/items/c6dad4efc0dff4fecd93)
***
Firebase×Bigqueryでフルリテンションを集計する

# 動作環境
FirebaseとBigQueryを統合し、FirebaseAnalyticsのデータをBigQueryにインポートしている環境です。

# やりたいこと
初回起動(first_open)の日から2日間連続で起動しているUU割合、7日間連続で起動しているUU割合（フルリテンション）を初回起動日別に取得し、ダッシュボード化したい。
リテンションの定義は<a href = "https://tech-magazine.opt.ne.jp/entry/2018/07/19/120000">アプリのリテンションをSQLで出して可視化する</a>を参考にしました。

# 考え方
WITH句の中のstartで初回起動日とuser_pseudo_idの一覧を作成。
usedateで初回起動に限らない起動日とuser_pseudo_idの一覧を作成。
その後のSELECT文でstartに対して日付の条件を1日ずつずらしてusedateを見たい日数分LEFT OUTER JOINすることで、user_pseudo_idの件数＝連続起動しているUU数となる状態になっています。

# クエリ
``` sql
WITH start AS(
  SELECT
    user_pseudo_id AS start_id,
    EXTRACT(DATE FROM TIMESTAMP_MICROS(event_timestamp) AT TIME ZONE "Asia/Tokyo") AS start_date
  FROM
    `hogehoge.analytics_xxxxxxxx.events_*` ---BigQueryの集計対象となるテーブル名
  WHERE
    _TABLE_SUFFIX BETWEEN FORMAT_DATE("%Y%m%d", DATE_SUB(CURRENT_DATE("Asia/Tokyo"), INTERVAL 30 DAY)) AND FORMAT_DATE("%Y%m%d", DATE_SUB(CURRENT_DATE("Asia/Tokyo"), INTERVAL 1 DAY))
    AND event_name = "first_open"
  GROUP BY
    start_id,
    start_date
),
usedate AS(
  SELECT
      user_pseudo_id AS use_id,
      EXTRACT(DATE FROM TIMESTAMP_MICROS(event_timestamp) AT TIME ZONE "Asia/Tokyo") AS use_date
  FROM
    `hogehoge.analytics_xxxxxxxx.events_*` ---BigQueryの集計対象となるテーブル名
  WHERE
    _TABLE_SUFFIX BETWEEN FORMAT_DATE("%Y%m%d", DATE_SUB(CURRENT_DATE("Asia/Tokyo"), INTERVAL 30 DAY)) AND FORMAT_DATE("%Y%m%d", DATE_SUB(CURRENT_DATE("Asia/Tokyo"), INTERVAL 1 DAY))
    AND event_name IN ("session_start", "screen_view", "user_engagement")
  GROUP BY
    use_id,
    use_date
)
SELECT
   start.start_date,
   COUNT(start_id) AS startuu,
   COUNT(day2.use_id) AS secondday_uu,
   COUNT(day7.use_id) AS seventhday_uu
FROM
   start
   LEFT OUTER JOIN usedate day2 ON start.start_id = day2.use_id AND DATE_ADD(start.start_date, INTERVAL 1 DAY) = day2.use_date
   LEFT OUTER JOIN usedate day3 ON day2.use_id = day3.use_id AND DATE_ADD(day2.use_date, INTERVAL 1 DAY) = day3.use_date
   LEFT OUTER JOIN usedate day4 ON day3.use_id = day4.use_id AND DATE_ADD(day3.use_date, INTERVAL 1 DAY) = day4.use_date
   LEFT OUTER JOIN usedate day5 ON day4.use_id = day5.use_id AND DATE_ADD(day4.use_date, INTERVAL 1 DAY) = day5.use_date
   LEFT OUTER JOIN usedate day6 ON day5.use_id = day6.use_id AND DATE_ADD(day5.use_date, INTERVAL 1 DAY) = day6.use_date
   LEFT OUTER JOIN usedate day7 ON day6.use_id = day7.use_id AND DATE_ADD(day6.use_date, INTERVAL 1 DAY) = day7.use_date
GROUP BY
   start.start_date
```

# アウトプット
ダッシュボードツールのRe:dashを使うとこんな形で可視化することができます。
![スクリーンショット 2019-04-09 14.22.36.png](https://qiita-image-store.s3.amazonaws.com/0/215653/b07da058-3874-4265-cc84-f215251b609f.png)
[Laravel5.1]簡単に管理者権限機能(同じテーブル編）

今更ですが、Laravel5.1で管理者権限機能を実装したので、簡単に実装できる方法を解説します。

#手順
1.usersテーブルにis_adminカラムを追加
2.Middlewareにadmin認証を追加
3.routeに権限を追加する
4.挙動を確認


#開発環境
Laravel5.1
PHP5.5.9
macOS

#usersテーブルにis_adminカラムを追加
usersテーブルにis_adminカラムを追加します。

``` 
php artisan make:migration add_role_to_users 
```

**/database/migrations** にある新しく作成されたファイルにコードを追加します。

``` php
public function up()
    {
        Schema::table('users', function (Blueprint $table)
        {
            $table->int('is_admin');
        });
    }

    public function down()
    {
        Schema::table('users', function (Blueprint $table)
        {
            $table->dropColumn('is_admin');
        });
    }
```

マイグレーションを実行します

```
php artisan migrate
```

これで、usersテーブルにis_adminカラムを追加することができました。
<br>
is_adminカラムを追加できたら、**/app/User.php** に下記のコードを追加します。

```php
protected $casts = [
        'is_admin' => 'boolean',
    ];
```

Seeder機能を使って管理者ユーザーを追加していきます。

```
php artisan make:seeder UsersTableSeeder
```

続いて、**/database/seeds/UsersTableSeeder.php** にコードを追加します。

```php
public function run()
{
    \App\User::create([
        'name' => 'admin',
        'email' => 'admin@example.com',
        'password' => Hash::make('admin'),
        'is_admin' => 1
    ]);
}
```

次のコマンドでusersテーブルに管理者ユーザを追加します。

```
php artisan db:seed --class=UsersTableSeeder
```

#Middlewareにadmin認証を追加
ユーザーのroleがadminか判別したいので、middlewareを作成していきます。

```
php artisan make:middleware AdminAuth
```

次に、**/app/Http/Middleware/AdminAuth.php** にコードを追加します。

```php
public function handle($request, Closure $next)
    {
        if(auth()->user()->is_admin === true) {
            return $next($request);
        }

        return redirect('/');

    }
```

middlewareをRouteから呼び出したいので、**app/Http/kernel.php** にコードを追加します。

```php
use App\Http\Middleware\AdminAuth;
 /* 省略 */
protected $routeMiddleware = [
    /* 省略 */
    'admin' => \App\Http\Middleware\AdminAuth::class,
];
```

#routeに権限を追加する
routeファイルにmiddlewareを追加していきます。

```php
Route::group(['middleware' => 'admin'], function () {

    Route::get('/admin', function(){
        return 'OK';

    });
});
```

#挙動を確認
管理者ユーザーでログインしてhttp://******/adminにアクセスします。
これで、アクセスしたページに「OK」と表示されたら成功です！！！


#まとめ
Laravel5.2からはMultiAuth機能が実装されたので、できればLaravel5.2以上を使おう！
XcodeでXVim2を導入する手順

# はじめに
XcodeでXVim2を導入する手順をまとめた記事となります。

https://github.com/XVimProject/XVim2

## 動作環境
以下のXcodeバージョンにて期待する挙動を確認できています。
* Xcode 12.4
* Xcode 11.x
* Xcode 10.x

# 導入手順
## 1. Xcodeのインストール先を確認

```shell
# インストール先の確認
$ xcode-select -p
# 適切なインストール先は以下の通り
-> /Applications/Xcode.app/Contents/Developer/
```

### Xcode上からでも確認・変更可能
`Xcode -> Preferences -> Locations -> Command Line Tools`

## 2. Signing Xcode
[公式サイト](https://github.com/XVimProject/XVim2/blob/master/SIGNING_Xcode.md)を参考にSingingを行う

### 証明書の作成
`キーチェーンアクセス > 証明書の作成`

![スクリーンショット 2021-02-22 18.46.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198898/8284be96-1812-2294-6aac-4acf6121cc8c.png)

### Xcodeの再署名
```shell
# AppStoreからダウンロードした場合
$ sudo codesign -f -s XcodeSigner /Applications/Xcode.app
```

## 3. XVim2の初期設定を行う
```shell
# インストールディレクトリに移動 - 任意の場所で問題ありません
cd ~/Library/Application\ Support/Developer/Shared/Xcode/Plug-ins/
# XVim2をclone - 任意の場所で問題ありません
git clone https://github.com/XVimProject/XVim2.git
# XVim2直下のディレクトリに移動
cd XVim2
# makeコマンド実行
make

# インストール後 XVim2.xcplugin が存在するか確認する方法
ls -l ~/Library/Application\ Support/Developer/Shared/Xcode/Plug-ins/
```
### 追記
`/Xcode/Plug-ins`配下に`XVim2.xcplugin`が存在しないことで期待する挙動を確認できない恐れがあります。
私の場合、make時に生成される`/XVim2/build/Reaease`のディレクトリに存在していたため、`/Xcode/Plug-ins`配下に`XVim2.xcplugin`をコピーすることで解消しました。

```shell
$ ls ~/Library/Application\ Support/Developer/Shared/Xcode/Plug-ins/XVim2/build/Release
-> XVim2.xcplugin
$ cp -r build/Release/XVim2.xcplugin ~/Library/Application\ Support/Developer/Shared/Xcode/Plug-ins  
# /Xcode/Plug-ins 配下に XVim2.xcplugin が存在するか再度確認
$ ls -l ~/Library/Application\ Support/Developer/Shared/Xcode/Plug-ins/ 
```

## 4. Xcodeを再起動
- Xcodeを開いている場合は終了(`command`+`q`)してから起動
- 選択画面が表示されるので**Load bundle** を選択

# 最後に
お疲れ様でした🎉
少しでも誰かの役に立つことを願って:pray:

## 関連資料
[XVim2 - GitHub](https://github.com/XVimProject/XVim2)

## 追記：選択画面が表示されない場合
### Case 1. **Skip bundle**を押してしまった、もしくは表示されなかった場合は下記を行う
 
```shell
# Xcode-X.X: 自身が使用されているXcodeのバージョン
$ defaults delete com.apple.dt.Xcode DVTPlugInManagerNonApplePlugIns-Xcode-X.X
```

### Case 2. case1を適用してもが表示されなかった場合
https://github.com/XVimProject/XVim2/blob/master/SIGNING_Xcode.md


```shell
# Xcode8以降でプラグインを使用するには、Xcodeの署名を解除
$ update_xcode_plugins --unsign
```
### Case 3. Xcodeをアップデートした場合
再度署名書発行のステップ（2. Signing Xcode）からやり直す必要があります。
OpenJDK 12「Support for Compact Number Formatting (JDK-8177552)」を試す

# 概要
OpenJDK 12 Release Note「Support for Compact Number Formatting (JDK-8177552)」を試す。

#実行
## コード
```java
package com.mycompany.examplejdk12;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.text.NumberFormat;
import java.util.Locale;

public class ExampleMain {
    public static void main(String[] args) {
        Class<Locale> classLocale = Locale.class;
        for(Field field : classLocale.getDeclaredFields()) {
            // public static final Locale ～を探す
            if((field.getModifiers() == (Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL)) &&
               (field.getType() == classLocale)) {
                try {
                    var numberFormat = NumberFormat.getCompactNumberInstance((Locale)field.get(classLocale), NumberFormat.Style.SHORT);
                    System.out.println(field.getName() +  "[" + numberFormat.format(1000) + "]");
                }
                catch(IllegalAccessException e) {
                    System.out.println(e);
                }
            }
        }
    }
    
}
```
## 結果
```tex
ENGLISH[1K]
FRENCH[1?k]
GERMAN[1.000]
ITALIAN[1.000]
JAPANESE[1,000]
KOREAN[1?]
CHINESE[1,000]
SIMPLIFIED_CHINESE[1,000]
TRADITIONAL_CHINESE[1,000]
FRANCE[1?k]
GERMANY[1.000]
ITALY[1.000]
JAPAN[1,000]
KOREA[1?]
CHINA[1,000]
PRC[1,000]
TAIWAN[1,000]
UK[1K]
US[1K]
CANADA[1K]
CANADA_FRENCH[1?000]
ROOT[1K]
```
# memo
<ul>
	<li>リフレクション使用</li>
	<li>Fieldクラス、修飾子はgetModifiers()で取得
取得値はint値、Modifierクラスの各値のOR値</li>
</ul>