OmniAICreator/Qiita-1.07M huggingface dataset:
AWSにSQSメッセージ送信

// Load the SDK for JavaScript
var AWS = require('aws-sdk');


//コンフィグの読み込み
var ini = require('./config/config.json');

var REGION = ini.sqs.test.region;
var SQS_QUEUE_URL = ini.sqs.test.url;
var SQS_ACCESS_KEY_ID = ini.sqs.test.accessKeyId;
var SQS_SECRET_ACCESS_KEY = ini.sqs.test.secretAccessKey;


console.log("▼▼▼ get setting information start ▼▼▼");
console.log(SQS_QUEUE_URL);
console.log(SQS_ACCESS_KEY_ID);
console.log(SQS_SECRET_ACCESS_KEY);
console.log("▲▲▲ get setting information end ▲▲▲");

// Set the config 
AWS.config.update(
    {
        accessKeyId: SQS_ACCESS_KEY_ID, 
        secretAccessKey: SQS_SECRET_ACCESS_KEY,
        region: REGION
        
    }
);

// Create an SQS service object
var sqs = new AWS.SQS({apiVersion: '2012-11-05'});

var params = {
 MessageAttributes: {
  "Title": {
    DataType: "String",
    StringValue: "The Whistler"
   },
  "Author": {
    DataType: "String",
    StringValue: "John Grisham"
   },
  "WeeksOn": {
    DataType: "Number",
    StringValue: "6"
   }
 },
 MessageBody: "Information about current NY Times fiction bestseller for week of 12/11/2016.",
 QueueUrl: SQS_QUEUE_URL,
 MessageGroupId: '20180608'
};

sqs.sendMessage(params, function(err, data) {
  if (err) {
    console.log("Error", err);
  } else {
    console.log("Success", data.MessageId);
  }
});
Apacheのログファイルを日別にする

### 86400秒 = 1日

### エラーログ
```httpd.conf
# ErrorLog "logs/error.log"
ErrorLog "| bin/rotatelogs.exe logs/error_%Y%m%d.log 86400"
```

### アクセスログ
```httpd.conf
# CustomLog "logs/access.log" common
CustomLog "| bin/rotatelogs.exe logs/access_%Y%m%d.log 86400" common
```
カメラ幾何の式変形メモ：物体が回転する際の外部パラメータ行列

授業中にノートの隅に書いていた数式メモです。
QiitaのTex記法では太字が`\boldsymbol{E}`のように面倒なので行列が非太字なのは勘弁してください。


# 原点周りでない回転
カメラの三次元幾何に出てくる同次変換では以下のように回転Rと並進tをカメラの撮像素子を原点として定義してますよね。

```math
T_R=
\begin{bmatrix}
R & t \\
0 & 1
\end{bmatrix}
```
これはカメラ側からの回転なので例えば原点から並進$t_C$まわりにオブジェクトが回転する場合などは式が異なります。並進をずらす同次変換を

```math
T_c=\begin{bmatrix}
I & t_c \\
0 & 1
\end{bmatrix}
```
とすると，原点からずれた点$t_c$にて回転操作をする行列は次のような式になるはず。


```math
T_R'=\begin{bmatrix}
I & t_c \\
0 & 1
\end{bmatrix}
\begin{bmatrix}
R & t \\
0 & 1
\end{bmatrix}\begin{bmatrix}
I & -t_c \\
0 & 1
\end{bmatrix}
```

これをちまちま展開した結果をメモします。

```math
T_R'=\begin{bmatrix}
R & -Rt_c+t+t_c \\
0 & 1
\end{bmatrix}
```

なんかキモイ式になりましたね。これを使って今度三次元撮像幾何に関する例題でも考えておきます。
最初のオブジェクトの回転中心$t_c$がわからないと並進$t$が出せないのが微妙ですね。
ちょっと嬉しくない式です。

射影変換行列のうち外部パラメータを司る行列の形にするには4行目を削除すればいいです。


## numpy実装：平面の中心まわりにおける回転
平面を用意しててそれを回したときの像を取ろうとしたときに本記事を思い出したのでした。

```python3
import numpy as np
import math

# set plane
W = 0.3
L = 0.2
D = 0.3
points = np.array([[W/2,L/2,D],[-W/2,L/2,D],[W/2,-L/2,D],[-W/2,-L/2,D],[0,0,D]])

# set translation and rotation
theta = [0/180*math.pi, 30/180*math.pi, 0/180*math.pi] # euler angle
t = np.array([0,0,0.1]).reshape(3,1)
tc = np.array([0,0,D]).reshape(3,1)
R = eulerAnglesToRotationMatrix(theta)

# show the points
print(points.T)
points2 = R.dot(points.T) - R.dot(tc)+tc+t
print(points2)
```

Homography行列でRとtに分解してやろうと思ったのですがその後にtcが事前情報として必要なのが辛いですね。
一応以下の結果より上の計算の正しさが確認できます。

```
[[ 0.15 -0.15  0.15 -0.15  0.  ]
 [ 0.1   0.1  -0.1  -0.1   0.  ]
 [ 0.3   0.3   0.3   0.3   0.3 ]]
[[ 0.12990381 -0.12990381  0.12990381 -0.12990381  0.        ]
 [ 0.1         0.1        -0.1        -0.1         0.        ]
 [ 0.325       0.475       0.325       0.475       0.4       ]]
```
XCodeプロジェクトのLintツール xcprojectlint

## はじめに
XCodeで開発をしていると以下のような課題が出てくると思います。

- XCodeで見えているディレクトリ構造と、ファイルシステム上のディレクトリ構造が違う
- ディレクトリ、ファイルがアルファベット順になっていないので、ファイルが探しづらい
- ファイルの参照リンクが切れている

こうした課題を解決するのに便利なツールがxcprojectlintです。
https://github.com/americanexpress/xcprojectlint

## インストール
プロジェクトをクローンしてビルドします。

```bash
$ git clone https://github.com/americanexpress/xcprojectlint.git
$ cd xcprojectlint
$ swift package update
$ make build
```

ビルドが完了すると、`./.build/x86_64-apple-macosx10.10/debug/xcprojectlint`というパスにバイナリが作成されます。

## Lintを実行する
以下のコマンドで、xcprojectlintに定義されている全てのルールについてチェックをすることができます。

```bash
$ ./.build/x86_64-apple-macosx10.10/debug/xcprojectlint \
    --report error \
    --validations all \
    --project /path/to/ExampleProject/Example.xcodeproj
```

特定のルールのみ有効にしたい場合は、`--validations`にスペース区切りでルール名を指定します。


```bash
$ ./.build/x86_64-apple-macosx10.10/debug/xcprojectlint \
    --report error \
    --validations disk-layout-matches-project items-in-alpha-order \
    --project /path/to/ExampleProject/Example.xcodeproj
```

## ルール一覧
本記事執筆時点では以下の6つのルールが用意されています。

- `build-settings-externalized`: Build Settingsが`project.pbxproj`ではなく個別の`*.xcconfig`で管理されているかをチェックする
- `disk-layout-matches-project`: ディレクトリ・ファイルのレイアウト（パス）について、XCodeで見えているレイアウト（パス）とファイルシステム上のレイアウト（パス）が一致しているかをチェックする
- `files-exist-on-disk`: XCode上のファイルが参照しているパスにファイルが存在するか（リンクが切れていないかどうか）をチェックする
- `empty-groups`: ファイルがない空のディレクトリ（グループ）があるかどうかチェックする
- `items-in-alpha-order`: ディレクトリ・ファイルがアルファベット順に並んでいるかをチェックする
- `all`: 全てのルールをチェックする

## XCodeでアプリのビルド時にxcprojectlintを実行する
Swiftlintなどの他のLintツールと同様に、ビルド時にxcprojectlintを実行できると便利です。

まず、xcprojectlintバイナリファイルをXCodeプロジェクトにコピーしておきます。

```bash
$ copy ./.build/x86_64-apple-macosx10.10/debug/xcprojectlint /path/to/ExampleProject
```

メインターゲットのBuild Phasesに、xcprojectlintを実行するRun Scriptを追加します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/81715/590ac6f3-dabe-324e-b88f-fa4540d4a48e.png)

```bash
if which "${PROJECT_DIR}/xcprojectlint" >/dev/null; then
  "${PROJECT_DIR}/xcprojectlint" --report error --validations build-settings-externalized --project ${PROJECT_DIR}/Example.xcodeproj
else
  echo "warning: ${PROJECT_DIR}"
  echo "warning: xcprojectlint not installed"
fi
```
これで、アプリのビルド時にxcprojectlintによるチェックが行われます。

![error.png](https://qiita-image-store.s3.amazonaws.com/0/81715/06843f4a-d5d5-ec6d-1165-ce88be357cbc.png)
[PHP]オブジェクト配列のjsonをcsvに変換する

###バージョン

```
PHP 5.2.1 (cli) (built: May 28 2007 19:31:00)
```

###コード
```json2csv.php
<?php
ini_set("memory_limit", "512M");
$str = file_get_contents("json.txt");
$json = json_decode($str, true);
$fp = STDOUT;
$columns = array();
foreach ($json as $fields) {
    if (empty($columns)){
        $columns = array_keys($fields);
        fputcsv($fp, $columns);
    }

    $contents = array();
    foreach($columns as $column) {
        $contents[] = isset($fields[$column]) ? $fields[$column] : "";
    }
    fputcsv($fp, $contents);
}
```

###解説
json.txtに保存されたオブジェクト配列のjson形式文字列をすべてメモリに読み込んでcsvとして標準出力に出力します。

```sample.json
[
  {"key1":"value1","key2":"value2"},
  {"key1":"value1","key2":"value2"}
]
```

`ini_set("memory_limit", "512M");`
memory_limitは扱いたいjsonの量によって変わるので適宜変更します。
障害対応で書いたソースコードのため、メモリのことは特に考えていません。
なので、あまりにも巨大なjsonは扱うことができません。

`$fp = STDOUT;`
調べたら上記のコードが出てきたので、初めてSTDOUTを指定しましたが、楽で良いですね。
軽いものならそのまま出しても良いし、実行時に出力先を変えられるし楽です。
`php json2csv.php > result.csv`


```php
    if (empty($columns)){
        $columns = array_keys($fields);
        fputcsv($fp, $columns);
    }
```
上記のコードでは、1番目のobjectからヘッダー行を取得しています。
そこからマッピングして組み立てています。
pandas の環境差分に対応する

本家の変更は[これ](https://github.com/pandas-dev/pandas/pull/12882)です。

```python
pandas_version = pd.__version__.split('.')

def sort_by(df, key):
    if pandas_version[0] == '0' and int(pandas_version[1]) < 21:
        return df.sort(key, ascending=1)
    return df.sort_values(by=key, ascending=True)
```

誰かもっと良い解決方法知りませんか。
tar.gzファイルと.tarファイルの展開方法

##tar.gzファイルと.tarファイルの展開方法
自分で展開する際に、結構時間を掛けて探してしまったので、以下にまとめておきたいと思います。

###tar.gzファイルの場合

```bash:
$ tar -zxvf abc.tar.gz
```

###tarファイルの場合
```bash:
$ tar -xvf abc.tar
```
DialogflowからFirebaseにWebhook

簡単に制御するための覚え書き
<img width="512" alt="20171118172831.png" src="https://qiita-image-store.s3.amazonaws.com/0/122121/2d62e3d4-af2c-b846-8dfe-361958596122.png">
前回の「まずはDialogflowを触ってみる」の返事をFirebaseにやらせる方法です。https://qiita.com/sanoh/items/efd99ebbdee294a7beb3
■受け渡しAPIにはV1とV2がある
---
最近V2をリリースしたので、V2使ってねという事だとおもいます、今回はV1とV2両方を書きます。
![2018-06-08 (9).png](https://qiita-image-store.s3.amazonaws.com/0/122121/3df3b0d8-60db-08ef-33f6-00a462d089af.png)
■V1 APIの場合
---
・設定で「V1 API」になっている事を確認してから「SAVE」を押します。
![2018-06-08 (1).png](https://qiita-image-store.s3.amazonaws.com/0/122121/0beb5e4a-a083-0f1e-26ac-c8e28b2c48c6.png)
・Firebase設定
「Fulfilment」で他のサーバ設定ができます。
今回はFirebaseを使用するので「Inline Editor」を「ENABLED」してください
![2018-06-08 (8).png](https://qiita-image-store.s3.amazonaws.com/0/122121/406a8d15-57c0-2922-e11e-50228543bc9d.png)
「index.js」のプログラムは以下のようにし、最後「DEPLOY」を押します（デプロイされるまでしばらくかかります）

```Javascript:index.js
'use strict';

const functions = require('firebase-functions');
const {WebhookClient} = require('dialogflow-fulfillment');

exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
  const agent = new WebhookClient({ request, response });
  function foodApp (agent) {
    var params = request.body.result.parameters;
    var rFoods = params['foods'];
    var rFeel = params['feel'];

    agent.add('私も' + rFoods + 'は' + rFeel + 'です');
  }
  let actionMap = new Map();
  actionMap.set('食べ物の好み！', foodApp);
  agent.handleRequest(actionMap);
});
```
・Intentの設定
最後に「食べ物の好み！」のIntentの設定で「Fulfillment」の「Enable webhook call this intent」をOnにし「SAVE」すれば終了です。
![2018-06-08 (6).png](https://qiita-image-store.s3.amazonaws.com/0/122121/ce786b7d-9478-281e-e0d0-e5c03cd58e96.png)
■V2 APIの場合
---
・設定で「V2 API」になっている事を確認してから「SAVE」を押します。
![2018-06-08 (4).png](https://qiita-image-store.s3.amazonaws.com/0/122121/93fda51c-68ea-b41e-aa37-e2f681d8b2b9.png)
・Firebase設定
「Fulfilment」で他のサーバ設定ができます。
今回はFirebaseを使用するので「Inline Editor」を「ENABLED」してください
![2018-06-08 (7).png](https://qiita-image-store.s3.amazonaws.com/0/122121/1389f2b6-5984-c5ea-15e0-cb2296babfdf.png)
「index.js」のプログラムは以下のようにし、最後「DEPLOY」を押します（デプロイされるまでしばらくかかります）

```Javascript:index.js
'use strict';

const functions = require('firebase-functions');
const { dialogflow } = require('actions-on-google');

const app = dialogflow();

app.intent('食べ物の好み！', (conv, params, confirmationGranted)  => {
    var rFoods = params['foods'];
    var rFeel = params['feel'];

    conv.ask('私も' + rFoods + 'は' + rFeel + 'です');
});

exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app);
```
・Intentの設定
最後に「食べ物の好み！」のIntentの設定で「Fulfillment」の「Enable webhook call this intent」をOnにし「SAVE」すれば終了です。
![2018-06-08 (6).png](https://qiita-image-store.s3.amazonaws.com/0/122121/ce786b7d-9478-281e-e0d0-e5c03cd58e96.png)
■動作
---
V1,V2でも同じような動作になります、しかし、今後の事を考えるとV2のほうですかね！
![2018-06-08 (3).png](https://qiita-image-store.s3.amazonaws.com/0/122121/3a06784c-2e44-07ce-bff0-9468c5cdc744.png)

（Botの場合、V1でないと動作が怪しいので要注意ですね）
[CentOS7]特定のIPアドレスからの接続を拒否する。

サーバーをインターネットに公開していると、必ず、不正攻撃を受けます。
大抵の不正攻撃は、rootユーザーで攻撃してきますのでrootログインを許可
していなければ良いのですが、ログインが失敗したログが大量に記録されてし
まいます。

また、セキュリティの観点からも放置しておくのは、決して良いことではありません。

そこで、iptablesを使って不正攻撃を防ぎます。
CentoOS7からは、firewalldに変わりましたので、CentOS6時代とは、設定方法が異なります。

下記は、CentOS7のfirewalldでの書き方となります。
[例1]
不正攻撃元のIPセグメント、もしくは、IPアドレスをdropリストに追加する。
firewall-cmd –zone=drop –add-source=<不正攻撃元のIPセグメント、もしくは、IPアドレス>/32

firewalld再起動時など、不正攻撃元のIPセグメント、もしくは、IPアドレスを”永続的に”dropリストに追加する。
firewall-cmd –zone=drop –permanent –add-source=<不正攻撃元のIPセグメント、もしくは、IPアドレス>/32

[例2]
不正攻撃元のIPセグメント、もしくは、IPアドレスをdropリストに追加するが、再起動しないと反映されない。
firewall-cmd –zone=drop –permanent –add-source=<不正攻撃元のIPセグメント、もしくは、IPアドレス>/32

サービスを再起動してdropリストを有効にする。
systemctl restart firewalld.service

Linuxは、マメ知識の積み重ねですね。
styled-componentsで使ってるあの文法はなに？

# styled-componentsとは

React向けにCSSをいい感じに書かせてくれるライブラリです。

```tsx
const MyComponent = styled.div`
  font-size: 1.5em;
  text-align: center;
  color: palevioletred;
`;

render(<MyComponent />);
```

こんな感じで、記述できることはご存知かと思いますが、 ``styled.div`xxx` ``って何？と思いませんか？僕は思いました。

# Tagged Template Literalというらしい
知りませんでした。

# 使い方
## 文法
こんな感じで、普通に関数を定義すればよいです。

```ts
function template() {
  // do something.
}
```
こんな感じで使います。

```ts
template`This is template`;
```

## 関数の呼び出され方
こうやって呼び出すと

```ts
template`This is ${foo} temp${bar}late`;
```
こんな感じで引数がわたってきます。

```ts
function template(arg1, arg2) {
  // arg1 = ["This is ", " temp", "late"];
  // arg2 = foo
  // arg3 = bar
}
```
第一引数は、`${}`で区切った文字列が配列で得られます。また、`${}`が文字列の最後に記述されていた場合は、配列の最後に空文字が入ります。`${}`が先頭にある場合も同様の挙動です。
`${}`の中身は、第二引数以降で得ることができます。

ユーザーが`${}`をいくつ使うかわかったものではありませんので、こんな感じで書くのが賢いのでしょう。
また、arg1とargsは交互に繋げると、もとの文字列が得られるようになっていますので、ご活用ください。

```ts
function template(arg1, ...args) {
  // arg1 = ["This is ", " temp", "late"];
  // args = [foo, bar]
}
```

# 使い道(追記)
ちょっと使い道を思いついたので、メモしておきます。
普通に``console.log(`foo is ${foo}`);``とやると、`foo is [object Object]`と出てしまうので、stringifyしてくれるとかっちょいいんじゃないでしょうか。
デバッグログで、適当にオブジェクトを挟めるのは助かりますね。

```ts
function log(texts, ...objects) {
  console.log(
    texts.map((text, i) => `${text}${JSON.stringify(objects[i]) || ""}`).join(""),
  );
}

const foo = {
  foo: "foo",
};
const bar = {
  bar: "bar",
}

log`foo is ${foo} bar is ${bar}`;
// foo is {"foo":"foo"} bar is {"bar":"bar"};
```

以上です。よろしくお願いいたします。
centos7にvim8をインストール（Ansible）

いろいろ辛くてvim8を開発用のvagrantに入れた

## 環境

```sh
$ cat /etc/redhat-release 
CentOS Linux release 7.5.1804 (Core) 
```

## ansible

```yml:roles/vim/tasks/main.yml
- name: check vim.
  stat: path=/usr/local/bin/vim
  register: vim_bin

- block:
  - name: yum install.
    yum: name={{ item }} state=latest
    with_items:
      - lua-devel
      - python-devel
      - ruby-devel
      - ncurses-devel
  
  - name: clone vim8.
    git: repo=git://github.com/vim/vim.git
         dest=/tmp/vim
         version=v8.1.0037
  
  - name: make vim8.
    shell: "{{ item }}"
    args:
      chdir: /tmp/vim/src
    with_items:
      - ./configure --with-features=huge --enable-multibyte --enable-luainterp=dynamic --enable-gpm --enable-cscope --enable-fontset --enable-fail-if-missing --prefix=/usr/local --enable-pythoninterp=dynamic --enable-rubyinterp=dynamic
      - make
      - make install
    become: yes

  when: not vim_bin.stat.exists
```

これで快適
AWS LambdaでPython3でpsycopg2でRedshiftへ接続する

#やりたいこと
・S3にunloadクエリをputするとLambdaで拾ってRedshiftに流すようなサーバレスな処理を作りたい
・Python3でやりたい。


#記事で割愛していること
* VPCの設定（ネットワーク的にLambdaとRedshiftが疎通していること）
* Lambdaの基本設定（VPCや、トリガーの設定）

#手順

## Python3のインストール
Python3でやりたい。その辺にあったAmazon Linuxにて
```
sudo yum install python36
```

## psycopg2の準備
以下のコマンドで、-t で指定した場所にpsycopg2が設置される。
```
pip-3.6 install psycopg2 -t ./
```

## ソースコードの作成
```
vi lambda_function.py
```
接続⇒実行までの超最低限サンプル

``` python:lambda_function.py
import psycopg2

def lambda_handler(event, context):
    try:
        connection = psycopg2.connect(port=5439, host="(VPC内のRedshiftのホスト)", database="XXXX", user="XXXX",password="XXXX")
        with connection.cursor() as cur:
            cur.execute("※ unloadクエリ ");
        return "test"
    except Exception as e:
        print(e)
        raise e
```

## デプロイパッケージの作成
参考：https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/lambda-python-how-to-create-deployment-package.html

解凍したらディレクトリは挟まず、直接 lambda_function.pyと、pipで取得したpsycopg2/のディレクトリが出てくるように圧縮

```
lambda_function.py
psycopg2/
```

ファイル名は任意。
作成したものをコードエントリタイプ「.ZIPファイルをアップロード」よりアップ。

## すごい
デプロイパッケージでアップロードしたあとで、「コードをインラインで編集」が使える。
zipファイルと同期が取れれなくなるが開発にはとても便利。


## やって分かった事
Lambdaのタイムアウトになっても、unloadクエリの実行が開始されていればunload自体はRedshift上で処理は続くようなので、5分以上掛かるクエリであってもこの仕組みだと問題なさそう。やった！
ただし、このあたりはコンテナが破棄されなければ、みたいな話かなとも予想される。
どのみちクリティカルな処理をやるつもりは無いので深追いせず。



#エラー変遷
``` python
Unable to import module 'lambda_function': No module named 'psycopq2'
``` 
今回使うパッケージ名は psycop"g"2 である...
コピペをすれば良い、というものではないというインターネットの罠。
　

``` python
Unable to import module 'lambda_function': No module named 'psycopg2._psycopg'
```
手元のWindows10のGit Bashで作業をしていたが、WindowsのGit Bashで pip install をすると
Windows用のパッケージとなってしまい、LinuxであるLambda上で動かないというのが原因だった。
このため、psycopg2のパッケージだけLinuxで用意するという手順を踏んでいる。
　

``` python
could not connect to server: Connection timed out
```
普通にPort指定を忘れていたため。
なお、psycopg2はデフォルトだとportは5432となり
Redshiftはデフォルトだとportは5439なので、Portの指定は必須な可能性が限りなく高い。
　

``` python
FATAL: password authentication failed for user "XXXX"
```
複雑なパスワードがPython上で上手くエスケープできなかったため。
bundle install時に突然 Could not find nokogiri-1.8.2 in any of the sources と言われてしまう問題


# 問題と解決
Ubuntu16に入れたとあるRailsアプリケーション内で、
rake assets:precompileしようとしたところ、
タイトルのように言われてしまいました。（他のrakeタスクでも同じ様に言われてしまいます。）

本来ですとbundle installすれば解決するのですが、
すでにnokogiriは存在するらしく下のように言われインストールされてくれません。

```
...
using nokogiri 1.8.2
...
```

最終的に、

rm -rf [アプリ側のgem保存場所(インストール時に--path=...で指定したパス)]

をしたあとにbundle installし直すと解決しました。
結局原因は不明ですが、今思うとextensionsあたりに問題があったかもしれません。

以下、やったけど駄目だったことを記します。

# やったこと
・gemファイルの旧バージョン nokogiri 1.8.0を削除
　→ 状況変わらず

・gemファイルのnokogiri 1.8.2のみ削除、bundle install
　→ Using nokogiri 1.8.2と言われ、本体が入ってくれない

・--pathで指定していないシステム側に保存されたgemを削除
　→ 上と全く同様

・[--pathで指定したパス]/ruby/2.3.0/cache/, [--pathで指定したパス]/ruby/2.3.0/specifications/
　→ にあるキャッシュとスペックを消しても上と全く同様

・bundle updateしてみる
　→ nokogiri 1.8.2 が最新版だったので、他のgemがアップデートされただけ

・bundle info nokogiri, bundle issue, bundle env などで参照gemの場所をチェック
　→ 全く問題なし
GraphQL Ruby 1.8 Class-based APIへのアップグレード

http://graphql-ruby.org/schema/class_based_api.html

> In GraphQL 1.8+, you can use Ruby classes to build your schema. You can mix class-style and .define-style type definitions in a schema.

GraphQL-Ruby 1.8からクラス形式でのGraphQLの型定義が可能になりました

そのアップデート方法に関してドキュメントに記載のないこと、補足事項を記します

# Field
`GraphQL::Field`は`Resolver`に移行します

ベースクラスを定義し、

```rb
module Resolvers
  class Base < GraphQL::Schema::Resolver
  end
end
```

継承します

```rb
module Resolvers
  class FindUser < Resolvers::Base
    type Types::UserType null: false
    description("ユーザ情報")
    argument :user_id, ID, "並び順"
    def resolve(user_id:)
      User.find(user_id)
    end
  end
end
```

利用側で`resolver:`でセットします

```rb
field :findUser, resolver: Resolvers::FindUser
```

# Function
GraphQL::Functionはもともとクラスベースで定義することができましたが、
新しいクラスベースAPIのargumentの記法ではないため、`GraphQL::Schema::Mutation`に移行します

## resolveを書き換える
### before
```rb
def call(object, inputs_, ctx)
 ...
end
```
### after
```rb
def resolve(**inputs)
 some_context_data = context[:some_context_data]
 id = object.some_id
 ...
end
```

- 引数はセットしたargumentsがハッシュで渡ります
- context, objectは`GraphQL::Schema::Mutation`に定義されています

# GraphQLGuard
`GraphQL::Schema::Field`を継承し、field定義時にguardを受け取れるようにします

```rb
class Fields::Guardable < GraphQL::Schema::Field
  def initialize(*args, guard: nil, **kwargs, &block)
    @guard = guard
    super *args, **kwargs, &block
  end

  def to_graphql
    field_defn = super
    field_defn.tap { |d| d.metadata[:guard] = @guard }
  end
end
```

## Type側

```rb
class Types::MutationType < GraphQL::Schema::Object
  field_class Fields::Guardable
  field :createUser, mutation: Mutations::CreateUser,
                     guard: ->(_obj, _args, _ctx) do
                       ...
                     end
  ...
end
```
ホスト名を変更する方法 - Ubuntu 16.04 LTS

# ホスト名を変更する方法
### Ubuntsu 16.04 LTS の場合

```
hostnamectl set-hostname xxxx
```
これだけです。
変更後のホスト名を確認したいときは以下。

```
hostname
```
現在のホスト名はそもそもターミナルの表示がユーザー名@ホスト名なのでずっと見えていますが、ターミナルを開き直すまで反映されないので、正しく変更できたかをその場で確認したいときは素直にhostnameで。

#### ホスト名を変更した後に
そのままだとホストの名前解決ができないので、以下を編集して、変更前のホスト名が書いてあるものを、新しい値に更新します。

```
/etc/hosts
```
jsで当日0時0分からの経過分を得る

#今日の0時からの経過分をjavascriptで得る
jsのDateクラスはUNKなので力技で解決する（タイムゾーン周りはブラウザ依存で結構危ういので要検証）。
他言語でもdiffしてformatして泥臭くなりがちなのでしょうがない。

##解説

```javascript
var time1 = new Date();
console.log(time1);
var time2 = time1.getTime();//unixtimeを得る
var time3 = time2 % (1000 * 60 * 60 * 24);//時分秒msを得る
var time4 = Math.floor(time3 / (1000 * 60));//秒msを切捨て
var time5 = time4 - time1.getTimezoneOffset();//タイムゾーン分を加算(減算)
console.log(time5);

//Fri Jun 08 2018 13:20:01 GMT+0900 (東京 (標準時))
//800

```

hint
経過秒なら`time4`を`1000`だけにすると得られる。
経過時なら`time4`を`1000 * 60 * 60`すると得られる。
※そのときはタイムゾーンは分なので位合わせを忘れずに

##コンパクト

```javascript
var time = new Date();
console.log(
    Math.floor((time.getTime() % (1000 * 60 * 60 * 24)) / (1000 * 60)) - time.getTimezoneOffset()
);
```
パッケージ製作のための.Rprofile (.Rをとにかくsource)


本記事でやりたいことはCtrl+Shift+Lで賄えることを教えてもらいました。
これによりexportされない関数も読み込むことができます。
(2018/06/08 18:00)

<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">あれ、Load allはだめなの？（Ctrl+Shift+L）</p>&mdash; Hiroaki Yutani (@yutannihilation) <a href="https://twitter.com/yutannihilation/status/1004943801155182592?ref_src=twsrc%5Etfw">June 8, 2018</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


----------

ひょっとしたら便利なTip?

パッケージ製作にデバグはつきものですが、そのためのオブジェクト(関数など)の読み込みが面倒です。
多分、よくある手は

- RStudio上で、開いているソースコードを適宜source ( `Ctrl+Shift+S` )
- パッケージをビルド&ロード ( `Ctrl+Shift+B` )

のどちらかでしょう。
前者であれば、exportされていない関数も使えますが、後者であれば、exportされていない関数を使うには `package:::function` する必要があり面倒です。

そこで、以下のコードを.Rprofileに仕込んでみました。

これにより、プロジェクトを開いた時、プロジェクトがパッケージ作成を目的としていると `./R`以下にあるソースファイル(*.R)を全て `source` してくれます。

```r
rproj <- dir(pattern = '\\.Rproj$')[1]
if(!is.na(rproj) && any(grepl('BuildType: Package', readLines(rproj)))) {
  invisible(lapply(
    dir('./R', pattern = '*.R', full.names = TRUE),
    source
  ))
}
rm(rpoj)
```

関数を読み込み直したい時はRを再起動しましょう ( `Ctrl+Shift+R` )。

注意点として、オブジェクトが全てGlobal環境にassignされてしまいます。

開発中のパッケージを `library(package)` してもそれらはGlobal環境下にあるものにマスクされてしまいます。
適宜 `rm` して下さい。

Enjoy!
全角の英数字やカタカナを半角文字に変換するExcel VBA

# これは何？
全角の英数記号やカタカナが入り混じった文字列を半角文字に変換するためのExcel VBAです。
正確には、指定した要素は半角、それ以外は全角に変換するので、「英数字は半角、カタカナは全角」や「数字は全角、英字とカタカナは半角」というような変換も可能です。
ググって出てきた先人の知恵を参考にして、自分が使いやすいように書いてみました。

# プロシージャ
`agsStr`に変換したい文字列、`mode`に小文字に変換する要素を指定します。

```vb:Zen2Han
Function Zen2Han(ByVal argStr, mode) As String
    '''
    'argStrで与えた文字列に対して、modeで指定した要素を半角文字に置換するプロシージャ
    'ALL = 7, ASCII = 1, DIGIT = 2, KANA = 4, 
    '''
    Dim tmpStr As Object
    Dim RE As Object
    Set RE = CreateObject("VBScript.RegExp")
    
    '全て半角文字へ置換
    argStr = StrConv(argStr, vbNarrow)
    
    '半角カタカタを全角に置換
    If mode = 1 Or mode = 2 Or mode = 3 Then
        RE.Pattern = "[｡-ﾟ]+"
        RE.Global = True
        For Each tmpStr In RE.Execute(argStr)
            argStr = Replace(argStr, tmpStr, StrConv(tmpStr, vbWide), , 1)
        Next
    End If
    
    '半角英字記号を全角に置換
    If mode = 2 Or mode = 4 Or mode = 6 Then
        RE.Pattern = "[a-zA-Z -/:-@\[-\`\{-\~]+"
        RE.Global = True
        For Each tmpStr In RE.Execute(argStr)
            argStr = Replace(argStr, tmpStr, StrConv(tmpStr, vbWide), , 1)
        Next
    End If
    
    '半角数字を全角に置換
    If mode = 1 Or mode = 4 Or mode = 5 Then
        RE.Pattern = "[0-9]+"
        RE.Global = True
        For Each tmpStr In RE.Execute(argStr)
            argStr = Replace(argStr, tmpStr, StrConv(tmpStr, vbWide), , 1)
        Next
    End If
    
    Set RE = Nothing
    
    Zen2Han = argStr
End Function
```


# 使い方
以下のように使用します。
(追記：記事を書き終えてからmode 1～6 以外は、全て半角化になってしまうことに気づいたけど、気にしないことにします)

```vb:Test
Sub Test()
    Dim tmpStr As String
    tmpStr = "１２３５　Ａｂｃ　アイウヴ　＝～％！"
    
    Debug.Print Zen2Han(tmpStr, 1)
    '１２３５ Abc アイウヴ =~%!
    
    Debug.Print Zen2Han(tmpStr, 2)
    '1235　Ａｂｃ　アイウヴ　＝～％！
    
    Debug.Print Zen2Han(tmpStr, 3)
    '1235 Abc アイウヴ =~%!
    
    Debug.Print Zen2Han(tmpStr, 4)
    '１２３５　Ａｂｃ　ｱｲｳｳﾞ　＝～％！
    
    Debug.Print Zen2Han(tmpStr, 5)
    '１２３５ Abc ｱｲｳｳﾞ =~%!
    
    Debug.Print Zen2Han(tmpStr, 6)
    '1235　Ａｂｃ　ｱｲｳｳﾞ　＝～％！
    
    Debug.Print Zen2Han(tmpStr, 7)
    '1235 Abc ｱｲｳｳﾞ =~%!
End Sub
```

# 参考ページ
http://hichon.cocolog-nifty.com/blog/2011/09/excelvba-a251.html
Atomic Design/Component 記事置き場

- [atomic design
](http://bradfrost.com/blog/post/atomic-web-design/) - brad frost
- [Atomic Components: Managing Dynamic React Components using Atomic Design](https://medium.com/@yejodido/atomic-components-managing-dynamic-react-components-using-atomic-design-part-1-5f07451f261f) - Joey Di Nardo
- [React Component 視点でのアトミックデザインの解釈といくつかの疑問](http://mizchi.hatenablog.com/entry/2018/06/07/203739) - mizchi
- [Atomic Design を読んでの備忘録](https://qiita.com/japboy/items/9576301456b2bffb1fac) - japboy
Python + OpenCVのみで最もシンプルに画像を90度回転する

ライブラリをたくさん使いたくないので、PILを使わずに90度回転をしたい。
調べるとアフィン変換とか難しい方法ばかりだったので、numpyの知識を使ってシンプルに回転してみた。

コードだけ知りたい方は、以下のコードを実行してください。

90度回転
`img.transpose(1,0,2)[:,::-1]`

-90度回転
`img.transpose(1,0,2)[::-1]`

## 画像の読み込み
```
import cv2
img = cv2.imread('green_red_apple.png')
````

![raw.png](https://qiita-image-store.s3.amazonaws.com/0/182253/6b37ac37-2032-cd11-93f4-0ee0448ec542.png)

## 画像の転置
Opencvで読み込んだ画像はnumpy配列になっているのでnumpyのtranposeで転置することで90度回転の準備をする

```
transpose_img = img.transpose(1,0,2)
```
![transpose.png](https://qiita-image-store.s3.amazonaws.com/0/182253/cf79b18a-ec98-b02c-e3f7-3e0525306d3f.png)

## 画像の90度回転
転置した画像を横方向にひっくり返したら90度回転になる。
numpy配列の順番を逆順にする方法でできる

```
clockwise = transpose_img[:,::-1]
```
![plus90.png](https://qiita-image-store.s3.amazonaws.com/0/182253/0c8d5a6e-7026-f4eb-3d2f-40a881b07fbe.png)

## 画像の-90度回転
転置した画像を縦方向にひっくり返したら-90度回転になる

```
counter_clockwise = transpose_img[::-1]
```
![minus90.png](https://qiita-image-store.s3.amazonaws.com/0/182253/8a6dfb75-0386-b255-0a15-60cec7ccfbe3.png)
MacでWiFi通信が切れたときに通信デバイスを自動で再起動するやつ

#目的

私のMacだと、喫茶店等の公衆WiFiを使っていると通信ができなくなることが多々ある。
アクセスポイントには接続していてIPも払い出されているのに、通信だけできないのだ。
WiFiデバイスをOff→Onすれば直る。
自宅だとWiFiが切れたことはないので、おそらくアクセスポイント側の問題だと思うが調査のしようがない。
頻繁に起こり手動でOff→Onしてたらイライラしてきたので、自動でやってくれるスクリプト書いた。

# 自動スクリプト

WiFiアクセスポインント（デフォルトゲートウェイ）にpingを一定間隔でうって、返答なければWiFiデバイスを再起動するだけのもの。

```sh
#!/bin/bash

# WiFi nic
DEVICE='en0'
# ネットワーク確認の応答待ち時間（秒）
TIMEOUT=1
# ネットワーク確認の間隔（秒）
INTERVAL=10
# デフォルトゲートウェイIP
IP_ADDR=$(netstat -rn | grep UGS | awk '{ print $2 }')

while :
do 
	# alive monitoring wi-fi default getway
	ping -c 1 -t $TIMEOUT $IP_ADDR >/dev/null 2>&1

	# network interface restart
	if [ $? -ne 0 ]; then
		NOW=$(date "+[%Y/%m/%d %H:%M:%S]")
		echo $NOW "network disconnected"
		/usr/sbin/networksetup -setairportpower $DEVICE off
		/usr/sbin/networksetup -setairportpower $DEVICE on
	fi

	sleep $INTERVAL

done
```
Cost ExplorerでAWSの利用状況を把握する

AWSの請求情報にあるCost Explorerを使うことで、**どのサービスにコストがかかってる**とか、**誰がたくさん使ってるか**というのをチェックできます。

## コストエクスプローラーを開く
AWSにログインした画面の上部メニューのユーザー名の中に `請求ダッシュボード` のリンクがあります。

![スクリーンショット 2018-06-08 8.40.15.png](https://qiita-image-store.s3.amazonaws.com/0/149365/0c0df9ad-49c0-01ce-96c7-bddf9a88bf7e.png)

請求ダッシュボード画面内の左メニューに `コストエクスプローラー` があるのでそこから起動ですます。
最近はサービスメニューにも追加されましたね。
**初めて起動する場合、データ収集のためか1日ほど待たなくてはいけないようです。**

## 条件を変えて詳しく見る
無事コストエクスプローラーが見られるようになると、デフォルトで月別のEC2のランニングコストが出てきます。
その内容でもわかることがあると思いますが、グラフの表示を変えてみましょう。

### サービス毎のコストを日別で見る
1. グラフの上にあるいくつかのセレクトボックスの中身を変えていきます。

![スクリーンショット 2018-06-08 11.52.51.png](https://qiita-image-store.s3.amazonaws.com/0/149365/294084b2-0ee9-314d-4836-32dc029c60a7.png)

左から期間の指定、グラフの単位、グルーピング、グラフの種類になります。以下のような感じに変更しましょう。

* 期間の指定
    * お好みで。HistricalからMTD(Month to Date)を選ぶと当月が範囲として選ばれるので楽かもです
* グラフの表示単位
    * Daily(日別)を選択
* グルーピング
    * Serviceを選択
* グラフの種類
    * ここもお好みで。自分は日別の累計のうち、どのサービスがどれくらい使われてるか視覚的にまとめて見たいのでよくStackを使ってます。


2.画面右の方のフィルターに何か入ってたら「CLEAR ALL」で一旦全てのフィルターを解除する

![スクリーンショット 2018-06-08 11.59.13.png](https://qiita-image-store.s3.amazonaws.com/0/149365/b473dfb1-ca17-3b18-f38f-2552459b09e8.png)

3.そうするとサービス毎にグラフが表示されます。

![スクリーンショット 2018-06-08 12.01.25.png](https://qiita-image-store.s3.amazonaws.com/0/149365/5bafcba2-a419-851d-5339-3ecef97f3f80.png)

4.画像だとすでに消してますが、毎月1日に税金の金額が入ってきてグラフが見辛くなるので、画面右下の方のADVANCED OPTIONSのTaxesをオフにするといいかもしれません。

![スクリーンショット 2018-06-08 12.04.24.png](https://qiita-image-store.s3.amazonaws.com/0/149365/a1f81c3c-902e-a21c-c55e-8b769ba23409.png)

これで日別のサービス毎の料金が見れますので、AWS料金の分析に役立てましょう。

### タグ毎のコストを日別で見る
#### 準備
タグ別でコストを見る前に、請求 `ダッシュボード画面 -> コスト配分タグ -> ユーザー定義のコスト配分タグ` で、コストエクスプローラーで使えるように有効化しましょう。
自分の会社ですと、担当者毎とプロジェクト毎でコストを出したいため、そのタグでコストを見れるように設定しています。

#### グラフ表示
サービス毎で見る時とだいたい一緒なので、重複しているところは割愛します。

グラフ上のセレクトボックスのGroup byの部分を `Tag -> グラフ表示したいtag` を選択しましょう。

これでタグの値別の料金が見れるようになります。

### フィルタリングの活用
先ほどはクリアしていたフィルターを使うとサービス別、タグ別グラフの合わせ技ができたりします。

サービス別グラフを出しているときに、FILTERSの `Tag -> 担当者タグの特定の値` を選択すると、どの担当者がどのサービスを利用しているのか見れたりします。

反対に、タグ(例えば担当者)別でグラフを出しているときに、FILTERSの `Service -> EC2-Instances` で担当者毎にEC2をどれくらい使っているか確認できます。

また、FILTERSの `Usage Type` や `Usage Type Group` で各サービスのさらに細かい項目をフィルタリングできるので活用しましょう。

他にもリージョンやAZなどでもフィルタリングできるので、こちらも必要があれば活用していきましょう。

### 注意点など
#### EC2の種別について
グラフ表示するときにEC2だけEC2-Instances、EC2-ELB、EC2-Othersに別れています。
EC2-InstancesはEC2のランニングコストと通信料、EC2-ELBはELBのランニングコストと通信料、EC2-OthersはEBS、スナップショット、NATゲートウェイの料金などになっているようです。
さらに細かい内容は↑で書いたフィルターの `Usage Type` や `Usage Type Group` で確認できます。

#### 集計タイミングについて
コストの集計はUTCベースになっているようです。
日本時間で見ると結構ズレがあるので注意しましょう。
また、前日分の集計も結構タイムラグがあります。
例えば6/7のちゃんとした金額が出るのは6/8の夜とか(詳しい時間は確認していませんが・・・)なので、**「なんか前日の料金がめっちゃ安い！」**みたいなぬか喜びが無いように注意しましょう。

#### コストエクスプローラーを見る権限について
会社でAWSアカウントを持っている場合は特にそうですが、コストエクスプローラーを見る権限や、コスト配分を設定する権限がなかったりするので、そういう場合は管理者に相談しましょう。
Realmで管理してるmodelにカラムを追加したら情報が消えたお話


Realmで作ってるmodelの変えたことによって、不具合を引き起こして
Realmにちょっとだけ詳しくなったのお話。



1.そもそもRealmって?
2.現象
3.調査
4.なんとかしようと頑張る
5.解明



# 1.そもそもRealmって?
モバイルアプリ向けのデータベースです。
実際の用途としては、
・ログインしない状態でのデータの管理
・リアルタイムで管理したいデータの管理
などなどです。
LifeSports（弊社のアプリ）ではログイン前のユーザーでも見れるように、Topの情報に関わる選択（好きなスポーツ)やuser情報などを管理しています。

その他基本的なRealmの操作などは下記のサイトを見ました
https://realm.io/jp/
https://dev.classmethod.jp/smartphone/iphone/start-ios-realm-crud/

# 2.現象
今回User情報に紐づくPush通知に関わる部分の変更を行いました。
すると、なぜがユーザー情報が取得できておらず、User情報で比較する部分がぐちゃぐちゃになってしまいました。


# 3.調査
特にエラーが出ていたわけではなかったので、realmのconfig周りを見直すことに...
どうやらRealmで管理しているModelはmigrationをしなければならないらしい。
しかしわからん。。。
問題の下記のコード。どこがおかしいかわかった方いますか？

```swift
struct RealmStore {
    
    private init() {}
    
    static func setup() {
        self.migrationsForNewVersion()
    }
    
    private static func migrationsForNewVersion() {
        var config = Realm.Configuration(
            schemaVersion: 10,
            migrationBlock: { migration, oldSchemaVersion in
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~省略~~~~~~~~~~~~~~~~~~~~~~~~~~~~~               
                if oldSchemaVersion < 10 {
                    migration.enumerateObjects(ofType: Setting.className(), { (oldObject, newObject) in
                        newObject?["isRemindEvent"] = true
                    })
                }

        })
        
        config.deleteRealmIfMigrationNeeded = true
        Realm.Configuration.defaultConfiguration = config
        
        do {
            _ = try Realm()
        } catch let error {
            print(error)
            FirebaseStore.uploadError((error as NSError).debugDescription)
        }
    }
}
```

# 4.なんとかしようと頑張る
（いいタイトルが思いつかなかった）
ググってもわからないというかググりようがなかった。。。
そんな中でRealmのslackGroupを見つけたので質問してみる
![image.png](https://qiita-image-store.s3.amazonaws.com/0/55864/ebb2f8ce-3c73-d526-f3ec-79f13325cfa6.png)

一瞬で返答が。。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/55864/46a385d9-aab9-f26b-7dc7-e45111b39b40.png)
日本語で良かったのか


いくつかやりとりして。。。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/55864/7c82d215-972b-a2d9-8d8a-bd4f92471228.png)


deleteRealmIfMigrationNeeded とは？
なんとなく変数名からわかりそうですが、「Migrationするときに元のデータを消す」ってことです。
https://realm.io/docs/swift/latest/api/Classes/Realm/Configuration.html#/s:10RealmSwift0A0C13ConfigurationV06deleteA17IfMigrationNeededSbvp

ということで

```swift
        //マイグレーション時に元のデータを消さないように変更
        config.deleteRealmIfMigrationNeeded = false
```

# 5.解明
そして...

![image.png](https://qiita-image-store.s3.amazonaws.com/0/55864/03072ff1-0903-10dc-657f-bd455ac3fc3f.png)

治りました！

よくよく聞いてみると、以前も同じような問題があった模様。
その時にちゃんと調査すれば良かったんj(ry
まぁ治って良かった。

# 6.まとめ
・realmのカラム定義を変更した際には、マイグレーション設定の追加が必要
・色々なコミュニティに質問しまくればなんとかなる
・コミュニティって素晴らしい。今後は貢献しよう。
【Android】TextView + ImageView を FlexboxLayoutでLinearLayoutとRelativeLayoutのいいとこ取りをする

### こういうレイアウト
<img width="636" alt="スクリーンショット 2018-06-08 10.40.17.png" src="https://qiita-image-store.s3.amazonaws.com/0/128180/56b4a283-8362-d060-9d1d-5612c914d8ca.png">
**短い文ではその真横について、長くなったら右端に画像がついて文は折り返したい時のやり方**

- LinearLayoutの``horizontal``とRelativeLayoutの``layout_toLeftOf``と`layout_alignParentRight`を全部やりたい・・・
- ~~ConstraintLayoutでできるかなと半日考えてできなかった（できたら教えて欲しい）~~ -> できました。

### ConstraintLayoutの場合
```xml:sample.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/message"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="@string/long_text"
        app:layout_constraintEnd_toStartOf="@id/icon"
        app:layout_constraintHorizontal_bias="0"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintWidth_default="wrap" />

    <ImageView
        android:id="@+id/icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@android:drawable/ic_delete"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@id/message"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>
```

### FlexboxLayoutの場合
```xml:sample.xml
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.flexbox.FlexboxLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="@dimen/activity_margin"
        android:gravity="center_vertical"
        android:text="@string/long_text" />

    <ImageView
        android:layout_width="60dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:contentDescription="@null"
        android:src="@android:drawable/ic_delete" />

</com.google.android.flexbox.FlexboxLayout>
```

###### 短い文字列の時
<img width="263" alt="スクリーンショット 2018-06-08 12.37.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/128180/a633bcfd-39b7-7060-703a-d51632fcf05f.png">
###### 長い文字列の時
<img width="262" alt="スクリーンショット 2018-06-08 12.37.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/128180/ffb2fecf-b3e5-e892-7f2a-cae240671fc7.png">
【Python】仮想環境の作成のしかた


最近、Pythonでもくもくやりはじめたので、備忘としてまとめる。

今回は、以下のサイトを参考にしている。
[[Python] venvを用いてプロジェクトごとに独立した環境を構築する](https://www.yoheim.net/blog.php?q=20171106)

## 1.はじめに
- **venv** というツールを使用することで仮想環境を構築することができる
- プロジェクトごとにsite-pakcagesを独立して管理できる
- Python3.3から公式に組み込まれている

## 2.Pythonで使える仮想環境ツール

今回、取り扱うのは **venv** ですが、それ以外にもいくつか仮想環境ツールが存在している。

- pyenv
- venv
- virtualenv

ちょっと時間がないので、それぞれのツールの深掘りは割愛する。

## 3.使用方法

### 3.1.環境構築

```
Hoge-MBA:Python_work Hoge$ pwd
/Users/Hoge/Python_work
Hoge-MBA:Python_work Hoge$ ll
Hoge-MBA:Python_work Hoge$ 
Hoge-MBA:Python_work Hoge$ python -m venv env001
Hoge-MBA:Python_work Hoge$ 
Hoge-MBA:Python_work Hoge$ ll
total 0
drwxr-xr-x  6 Hoge  staff  192  6  8 12:05 env001
Hoge-MBA:Python_work Hoge$ 
Hoge-MBA:Python_work Hoge$ ll env001/
total 8
drwxr-xr-x  12 Hoge  staff  384  6  8 12:06 bin
drwxr-xr-x   2 Hoge  staff   64  6  8 12:05 include
drwxr-xr-x   3 Hoge  staff   96  6  8 12:05 lib
-rw-r--r--   1 Hoge  staff   75  6  8 12:05 pyvenv.cfg
Hoge-MBA:Python_work Hoge$ 

```

<font color="Red">※上記のコマンドを実行だけでは、仮想環境は有効化されていない</font>


### 3.2.仮想環境の有効化

以下のコマンドは、有効化したい仮想環境ディレクトリ配下で実施すること。

```
Hoge-MBA:Python_work Hoge$ cd env001/
Hoge-MBA:env001 Hoge$ pwd
/Users/Hoge/Python_work/env001
Hoge-MBA:env001 Hoge$ 
Hoge-MBA:env001 Hoge$ ll
total 8
drwxr-xr-x  12 Hoge  staff  384  6  8 12:06 bin
drwxr-xr-x   2 Hoge  staff   64  6  8 12:05 include
drwxr-xr-x   3 Hoge  staff   96  6  8 12:05 lib
-rw-r--r--   1 Hoge  staff   75  6  8 12:05 pyvenv.cfg
Hoge-MBA:env001 Hoge$ 
Hoge-MBA:env001 Hoge$ source ./bin/activate
(env001) Hoge-MBA:env001 Hoge$ 
(env001) Hoge-MBA:env001 Hoge$ which python
/Users/Hoge/Python_work/env001/bin/python
(env001) Hoge-MBA:env001 Hoge$ 
(env001) Hoge-MBA:env001 Hoge$ which pip
/Users/Hoge/Python_work/env001/bin/pip
(env001) Hoge-MBA:env001 Hoge$ 

```

<font color="Red">※仮想環境が有効化されると、行頭に **(env001)** などと環境名が表示される</font>

<font color="Red">※有効化後は、普通通りの使い方と同じ</font>


### 3.3.仮想環境の無効化(脱出)

```
(env001) Hoge-MBA:env001 Hoge$ deactivate
Hoge-MBA:env001 Hoge$ 
Hoge-MBA:env001 Hoge$ which python
/Users/Hoge/anaconda3/bin/python
Hoge-MBA:env001 Hoge$ 
Hoge-MBA:env001 Hoge$ which pip
/Users/Hoge/anaconda3/bin/pip
Hoge-MBA:env001 Hoge$ 

```
【Swift】Null安全なJSON変換

サーバから落としてきたデータをJSONにエンコードし、Dictionary型に変えたい時、

```swift
guard let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String : String] else {
    return
}
```

これだと`Error: Value of optional type '[String:Any]?' not unwrapped`というエラーが出てしまう。原因は、コンパイラが

```swift
try? (JSONSerialization.jsonObject(with: data, options: []) as? [String : String])
```

と解釈してしまうため。調べてみると[こんなやり方](https://stackoverflow.com/questions/43123036/guard-not-unwrapping-optional)があったのでメモ。パターンマッチを使ってオプショナルバインディングする方法。

```swift
guard case let json?? = try? JSONSerialization.jsonObject(with: data) as? [String:Any] else {
    return
}
```
Obat congek menahun paling ampuh

Bagaimana penyakit congek yang diderita oleh anak-anak atau orang dewasa ini diobati dengan obat alami yang mudah, ampuh dan mujarab ? Check it out …

Minyak bawang putih

Obat congek alamiObat Congek Menahun Herbal Paling Ampuh Dan Mujarab pertama yang dapat Anda coba ialah bawang putih. Beberapa penelitian telah menunjukkan sifat antimikroba, antiviral, dan antijamur yang kuat dari bawang putih. Ini juga terbukti memiliki efek yang sangat positif terhadap kesehatan kekebalan tubuh.

Sebagai “antibiotik alami,” minyak bawang putih dapat membantu sampai ke akar infeksi telinga dan mematikan patogen yang menjadi penyebab congek atau infeksi telinga tengah. Minyak bawang putih juga akan membantu mengurangi peradangan di dalam telinga. Ini membantu mempercepat proses penyembuhan sekaligus mencegah infeksi dan peradangan masuk lebih dalam ke telinga.

Kemangi

Obat Congek Menahun Herbal Paling Ampuh Dan MujarabSelanjutnya obat congek menahun ampuh alami yang ke-2 ialah kemangi. Kemangi diketahui efektif mengobati sakit telinga ringan, infeksi telinga, meringankan sakit telinga serta mengurangi infeksi telinga.

Bagaimana cara menggunakannya ?

Anda bisa mengambil ekstrak jus dari 5 lembar daun kemangi yang Anda siapkan dan jus daun kemangi tersebut bisa Anda aplikasikan langsung ke area telinga yang terkena infeksi. Hanya saja, dalam pengobatan Anda perlu menghindari supaya ekstrak jusnya tak sampai ke kanal telinga. Lakukan ini secara rutin, paling tidak sehari 2 kali untuk hasil yang optimal.

Sumber : http://jualqncjellygamat.net/obat-congek-menahun-herbal-paling-ampuh-dan-mujarab/
[Laravel / jQuery] 非同期（Ajax）でレコードを削除したい

#やりたいこと

[Laravel学習帳][link_1]さんのサイトを参考にLaravelで基本的なCRUDアプリを作成中。
ユーザーを非同期で削除する機能を実装したときにハマった点を備忘録としてメモ。

![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/238891/a053b57d-91d8-0a43-6118-4923b60a3709.png)

↑こんな感じでユーザーの登録や編集、削除ができるアプリです。
今回は \<a> タグで作られた削除ボタンを押すと、非同期でユーザーが削除される機能を実装します。

[link_1]:http://laraweb.net/

#環境

CentOS: 7.4
PHP: 7.2
Laravel: 5.6
jQuery: 3.3.1

#実装時に問題になった点

* Ajax を使うとき GET、POST 以外の HTTP リクエストはどうやって送信するの？
* Ajax で CSRF 対策（トークンを送信）するにはどうすればいいの？

#うまくいったコード

最終的に下記のコードでうまくいきました。
確認用ポップアップが出して、OK の場合はユーザーを削除する処理を記述しています。

```delete_user.js
$(function() {
  $('#deleteTarget').on('click', function() {
    var deleteConfirm = confirm('削除してよろしいでしょうか？');

    if(deleteConfirm == true) {
      var clickEle = $(this)
      // 削除ボタンにユーザーIDをカスタムデータとして埋め込んでます。
      var userID = clickEle.attr('data-user-id');

      $.ajax({
        url: '/user/' + userID,
        type: 'POST',
        data: {'id': userID,
               '_method': 'DELETE'} // DELETE リクエストだよ！と教えてあげる。
      })

     .done(function() {
        // 通信が成功した場合、クリックした要素の親要素の <tr> を削除
        clickEle.parents('tr').remove();
      })

     .fail(function() {
        alert('エラー');
      });

    } else {
      (function(e) {
        e.preventDefault()
      });
    };
  });
});
```

#２つのつまずきポイント

###メソッドの指定

今回はユーザーを削除したいのだが、送信できるリクエストは GET か POST のみ。
そこで、Ajax で送るデータの中に `'_method': 'DELETE'` を追記してリクエストを指定する。

###CSRF 対策

CSRF 対策ができていないと Laravel さんに怒られてしまいます。
HTTP の ヘッダーにトークンを埋め込んでおき（今回は \<meta> タグの中）、常にトークンを送るよう `$.ajaxSetup` に設定しました。

```html
<meta name="token" content="{{ csrf_token() }}">
```

```js
$.ajaxSetup({
  headers: {
    'X-CSRF-TOKEN': $('meta[name="token"]').attr('content')
  }
});
```

これを書いておけば Ajax で POST するとき、常にトークンを送ってくれます。
ここは[こちら][link_2]のサイトを参考にしました。

[link_2]:https://sota1235.hatenablog.com/entry/2015/10/11/213000

#最後にコントローラーで削除処理！

```UserController.php
public function destroy(Request $request, User $user) {
    $user = User::findOrFail($request->id);
    $user->delete();
}
```

とりあえずこれで思ったとおりに動いてくれました。
以上です。
Google アナリティクス（gtag.js）でリンクをイベントトラッキングする

# 2021年5月18日 追記

今はこんな面倒なことをしなくても Google Tag Manager で設定できるので、この記事のことは忘れて Google Tag Manager の使い方を覚えましょう。
https://tagmanager.google.com/

# ダメなパターン

```javascript
$( 'a.event_tracking' ).on( 'click', function( e ) {
    gtag( 'event', 'click', {
        'event_category': 'イベントカテゴリ',
        'event_label'   : 'イベントラベル'
    });
  });
```

これだと、次のページの読み込みが始まるとjavascriptの実行が停止してイベントトラッキングが完了しないことがある。
（よく考えれば当たり前だよね。。。）

# 成功パターン

一旦止めてコールバックで実行すればいい。
https://developers.google.com/analytics/devguides/collection/gtagjs/sending-data?hl=ja

```javascript
$( 'a.event_tracking' ).on( 'click', function( e ) {
    if ( typeof gtag === 'function' ) { // gtag.js が読まれてる時だけ実行
        e.preventDefault(); // 一旦止める
        var linkUrl = $(this).attr('href'); // そのaタグのリンク先を取得しておく
        gtag( 'event', 'click', {
            'event_category': 'イベントカテゴリ',
            'event_label'   : 'イベントラベル',
            'event_callback': function() { // イベントトラッキングが送信されたら呼び出される
                location.href = linkUrl;
            }
        });
    }
});
```

セレクタとかはよしなに変更してください。

現場からは以上です。
[小ネタ] azure cliのaccess token取得

# サクッとazureのaccess token流用したいときに

azure cliではトークンを取得するために以下のコマンドを打つと思います。

```
$ az login
To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code HOGEHOGE to authenticate.
```
表示された通りにhttps://microsoft.com/devicelogin にブラウザからアクセスし、codeを入力後ログインすると~/.azure/accesssTokens.jsonにアクセストークンやリフレッシュトークンが保存されます。
ただしこれには過去にログインしてexpireしたものだったり、今流用したいもの以外の情報も含まれています。
そこで以下のスクリプトで一発で最新のトークンをコピーします。
## Mac
jqという超便利なJSONコマンドラインパーサを使っているのでまだ入っていない人はbrewで入れてください

```
$ brew install jq
$ cat ~/.azure/accessTokens.json | jq 'map(select(.tokenType == "Bearer")) | .[-1].accessToken' | pbcopy
```
1時間でトークンは期限が切れてしまうので、切れたらaz vm listなどしてトークンを更新して上記コマンドを打つことで再取得できます。

環境変数にセット

```
$ export AZURE_ACCESS_TOKEN=`cat ~/.azure/accessTokens.json | jq 'map(select(.tokenType == "Bearer")) | .[-1].accessToken' -r`
```

以上です！
Ansible2.5 syncronizeモジュールバグ リモートコピーできない件

# 概要
- Ansibleでplaybook実行時syncronyzeモジュール(rsync的な)を使用したら謎のエラーに遭遇
- リモートホストにコピー(同期)できない
- 調査したらどうやらAnsible2.3以降のバグらしい
- もはやダウングレードするのが一番の回避策っぽいので2.5から2.2へダウングレード
- エラーは改善した
- Pythonは3を使ってvirtualenv上の環境で発生しました。

# エラー内容

```
TASK [rsync to remote] ****************************************************************************************************************************************
task path: /home/appuser/.ansible/deploy/include-tasks/app/deploy-remote-app.yml:13
Using module file /home/appuser/.pyenv/versions/3.6.5/envs/ansible-3.6.5/lib/python3.6/site-packages/ansible/modules/files/synchronize.py
<10.33.47.xxx> ESTABLISH LOCAL CONNECTION FOR USER: appuser
<10.33.47.xxx> EXEC /bin/sh -c 'echo ~None && sleep 0'
<10.33.47.xxx> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo ~None/.ansible/tmp/ansible-tmp-1528288448.485335-70755570096073 `" && echo ansible-tmp-1528288448.485335-70755570096073="` echo ~None/.ansible/tmp/ansible-tmp-1528288448.485335-70755570096073 `" ) && sleep 0'
<10.33.47.154> PUT /home/appuser/.ansible/tmp/ansible-local-7005wefvo28f/tmp7x45s940 TO ~None/.ansible/tmp/ansible-tmp-1528288448.485335-70755570096073/synchronize.py
fatal: [10.33.47.154]: FAILED! => {
    "msg": "failed to transfer file to ~None/.ansible/tmp/ansible-tmp-1528288448.485335-70755570096073/synchronize.py: [Errno 2] No such file or directory: b'~None/.ansible/tmp/ansible-tmp-1528288448.485335-70755570096073/synchronize.py'"
}
        to retry, use: --limit @/home/appuser/.ansible/deploy/include-tasks/app/deploy-remote-app.retry

```

ここでググる
https://github.com/ansible/ansible/issues/21562

結構議論されているみたい。みんな困ってるんですね。
2.2では再現しないと言っています。
釈然としないけれどその方法で対応

```
$ pyenv activate ansible-3.6.5
$ ansible --version
ansible 2.5.3
$ pip3 uninstall ansible
$ pip3 install ansible\==2.2.0
$ ansible --version
ansible 2.2.0.0
```

コピーできました(；-ω-｀) ﾌｩ…
pflogsummのログの見方

pflogsummのログの見方

# 正常なログ

receivedは受取件数
deliveredは配信件数
rejectedは受取拒否件数

```
 Postfix log summaries for
 
 Grand Totals
 ------------
 messages
 
     351   received
     583   delivered
       0   forwarded
       0   deferred
       0   bounced
     270   rejected (31%)
       0   reject warnings
       0   held
       0   discarded (0%)
 
   13805k  bytes received
   18816k  bytes delivered
     128   senders
      91   sending hosts/domains
      55   recipients
       8   recipient hosts/domains
```


# 異常なログ

アカウントの一つからスパムがばらまかれた場合。
deferredとboundedの件数が異常に多いです。
deferredは一時的に配信できなかった件数、
bouncedは送信先メールサーバーから受け取りを拒否された件数です。


```
Postfix log summaries for

Grand Totals
------------
messages

    414   received
   1073   delivered
      0   forwarded
    304   deferred  (8043  deferrals)
     92   bounced
    279   rejected (20%)
      0   reject warnings
      0   held
      0   discarded (0%)

   6523k  bytes received
   9856k  bytes delivered
    136   senders
    104   sending hosts/domains
    517   recipients
    104   recipient hosts/domains
```

----
バインドマウント auto.master メモ

### バインドマウントのメモ

既にマウントされた/dsk/test/d1を/dsk/d1として見せる。
マシン運用中にautofsをrestartしても問題ない。

```
# on redhat6.7
$ cat /etc/auto.master
/dsk/d1     -fstype=bind   :/dsk/test/d1
$ service autofs restart
```
Swift4.1 Simulatorか実機かを判別する方法

Swift4.1より前はこんな感じでした。

```swift:~4.0.swift
#if (arch(i386) || arch(x86_64)) && os(iOS)
    // iOS simulator code
#endif
```

Swift4.1からはこう書きましょうという話。

```swift:4.1~.swift
#if targetEnvironment(simulator)
    // iOS simulator code
#endif
```

詳しくは下記のTarget environment conditionへどうぞ。

[https://swift.org/blog/swift-4-1-released/](https://swift.org/blog/swift-4-1-released/)
shellでうまいこと中身だけコピーしたい

# 背景
shellスクリプトでディレクトリのコピーとかやりますよね。

```sh
$ cp -r ./src ./dst
```

こうすると、以下のようになります。

```sh
$ tree
root
├── dst
│   └── text.txt
└── src
    └── text.txt
```

では、srcが変更されたので、dstも更新しましょう。

```sh
$ cp -r ./src ./dst
$ tree
root
├── dst
│   ├── src
│   │   └── text.txt
│   └── text.txt
└── src
    └── text.txt
```
・・・
一回目のコマンドは、srcというフォルダをコピーしてdstというフォルダに変更する処理だったのですが、二回目以降はsrcというフォルダをdst下にコピーする処理になってしまっています。

# 対策
コピーコマンドの書き方をちょいと変えます。

```sh
$ cp -r ./src/. ./dst
$ tree
root
├── dst
│   └── text.txt
└── src
    └── text.txt
```

つまり、srcというフォルダの中にあるすべてのデータをdst下にコピーする、というコマンドにします。
dstが無ければつくってくれますので、こちらを活用するようにしましょう。

## 追記
`-T`オプションをつけて、以下のようなコードにしても同じ動きになるようです。

```shell
$ cp -rT ./src/. ./dst
```

以上です。よろしくお願いいたします。