OmniAICreator/Qiita-1.07M huggingface dataset:
gcloudコマンドからIAM Permission付与、取り消し

Cloud Build 経由の AppEngineデプロイなど、サービスが関連して処理するものにはあらかじめPermissionが必要。
（この場合、CloudBuildのサービスアカウントに appengine/appAdmin のロールが必要）

=> こちらも参考に：[Permissionに対する適切なRoleを調べる方法](https://qiita.com/ideodora/items/d3e99e838638bbdaf426)

毎度GCPのConsoleから付与してたけど、付与したいものもだいたい決まってきたから、コマンドで実行したい。

と思い立って調べたけど、タイプ数考えたら画面からポチポチするのと大差ない気もした。

---

サービスアカウントを特定する必要もあるので、多分手順の流れとしては、

* 現在のpermission確認
* 付与したいサービスアカウント名コピペ
* （必要であればロール一覧確認）
* permission付与（メンバーのとこでサービスアカウント名貼り付け）

な感じになるんじゃなかろうか。

---

以下、プロジェクトID = ideodora-sandbox001 とする。

## Permission 確認

```
gcloud projects get-iam-policy ideodora-sandbox001

=>
bindings:
- members:
  - serviceAccount:xxxx@cloudbuild.gserviceaccount.com
  role: roles/cloudbuild.builds.builder
- members:
  - user:ideodora@gmail.com
  role: roles/owner

...中略...

etag: BwWIYRKoU44=
version: 1
```

## Permission 付与

```
gcloud projects add-iam-policy-binding ideodora-sandbox001 \
> --member serviceAccount:xxxx@cloudbuild.gserviceaccount.com \
> --role roles/appengine.appAdmin

=>
Updated IAM policy for project [ideodora-sandbox001].
bindings:
- members:
  - serviceAccount:xxxx@cloudbuild.gserviceaccount.com
  role: roles/cloudbuild.builds.builder
- members:
  - user:ideodora@gmail.com
  role: roles/owner
- members:
  - serviceAccount:xxxx@cloudbuild.gserviceaccount.com
  role: roles/appengine.appAdmin

...中略...

etag: BwWIav2yCRA=
version: 1
```

## Permission 取り消し

```
gcloud projects remove-iam-policy-binding ideodora-sandbox001 \
> --member serviceAccount:xxxx@cloudbuild.gserviceaccount.com \
> --role roles/appengine.appAdmin

=>
Updated IAM policy for project [ideodora-sandbox001].
bindings:
- members:
  - serviceAccount:xxxx@cloudbuild.gserviceaccount.com
  role: roles/cloudbuild.builds.builder
- members:
  - user:ideodora@gmail.com
  role: roles/owner

...中略...

etag: BwWIavlbwJU=
version: 1
```

## そもそもロールって何がある？

以下のコマンドで確認できる。リソースの指定がプロジェクトIDだけではできず、フルパスを指定しろと言われる。。。長いし覚えれん。。。

configで対象プロジェクトセットしてんだから、そっから判定して欲しい。。。

**--filter** つけないと、全ロール出力するので、適当に欲しい

```
gcloud iam list-grantable-roles //cloudresourcemanager.googleapis.com/projects/ideodora-sandbox001 --filter=appengine

=>
---
description: Full management of App Engine apps (but not storage).
name: roles/appengine.appAdmin
title: App Engine Admin
---
description: Ability to view App Engine app status.
name: roles/appengine.appViewer
title: App Engine Viewer
---
description: Ability to view App Engine app status and deployed source code.
name: roles/appengine.codeViewer
title: App Engine Code Viewer
---
description: Necessary permissions to deploy new code to App Engine, and remove old
  versions.
name: roles/appengine.deployer
title: App Engine Deployer
---
description: Can view and change traffic splits, scaling settings, and delete old
  versions; can't create new versions.
name: roles/appengine.serviceAdmin
title: App Engine Service Admin

```
ひげボタンで遊んでみた

# ひげボタンって？

SORACOM LTE-M Button Plusの愛称です。製品については詳しくは[こちら](https://www.soracom.jp/products/gadgets/button_plus/)。

要は接点情報の取れる[あのボタン](https://www.soracom.jp/products/gadgets/aws_button/)ですね。そして中身は[Enterprise(しろボタン)](https://www.soracom.jp/products/gadgets/enterprise_button/)なので、beam使って色々なサービスにつなげることができます。これは夢が広がりますね！

# 作業記録を取りたい

[ポモドーロ・テクニック](https://next.rikunabi.com/journal/20161026_m1/)などにも見られるように、業務の効率化のためには自分の作業の見える化は重要です。
とはいえ、現状世の中にあるものは作業のたびに

- アナログにメモする
- アプリを開いてポチポチ
- ブラウザで特定の画面を開いてポチポチ

など。とにかく思考が中断するしめんどくさいです(慣れるとそうでもないのかもしれませんが・・)。

# ボタンならどうよ？

では、記録をあのボタンでやってはどうか？と考えると、やはり手に取ってボタン押して・・というのは手間としては似たようなものですよね。

# 解決案

サイズ大きくしてみました(発想が雑)。

![IMG_20190508_181421.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59415/7c27cf4b-f454-944d-51c9-840686d08fab.jpeg)

![IMG_20190507_162209.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59415/349bd3af-41de-193a-dee7-13a3d383ce01.jpeg)

100均で買ってきたライトを分解して繋ぐだけのお手軽工作。接続先はbeamからAPI Gateway経由でLambda叩いてgoogle spreadsheetに記録してみましたが、[TimeCrowd](https://timecrowd.net/)とかのサービスに繋ぐと更に面白そうです。

google spreadsheetへの記録は[LTE-M Buttonで子育て支援するシステムを作ったお話](https://qiita.com/kkimura/items/c13fc9ad14896c6c1430)をご参照ください。

これなら手を伸ばしてバチコーン！とするだけです。持ち替えるとか画面切り替えるとかロックを外すとか一切無しなので思考も停止しません。

# 今後の課題

- LEDが見えないのでどうにかしたい(穴を空けるというお手軽工作でいいか？)
- 電池ボックスを、ケースの電池ボックスに繋ぎたい

# まとめ

接点は正義。そしてボタン大きくしただけでこんなに便利(^o^)
【Android】Androidアプリの評価計算方式が変更される

昨日、Google Play Consoleを開いた際、気になる記述を見つけましたので共有を兼ねて。

現在、Androidアプリの評価は全期間での平均値となっていますが、どうやらそれが変わるようです。
![注意.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106030/d85938ca-8eab-d1c7-7483-7f690566ef6a.png)

 **■Google Play の新しい評価**
>**原文**
Developers have asked us for their Google Play rating to better reflect recent feedback from users. Based on this, we’ve updated the way your rating is calculated to place greater significance on your most recent ratings. You can see how this change will affect your rating below. This will be visible to users on Google Play from August 2019.

>**翻訳後**
開発者は、ユーザーからの最近のフィードバックをよりよく反映するために、Google Playの評価をお願いしています。これに基づいて、最新の評価により大きな影響を与えるように、評価の計算方法を更新しました。あなたはこの変更があなたの評価にどのように影響するかを以下で見ることができます。これは2019年8月からGoogle Playのユーザーに表示されます。

書いてある通り2019年8月から、直近の評価を重視して計算されるようになります。
Google Play Console上では、上記計算方法にて算出された評価が、仮ですでに表示されていました。
これによって、評価点数が変わるアプリがかなりありそうです。

Apple Storeの計算方法に寄せてきたな、というのが感想です。
定期購読然り、最近Appleの方式を真似してますね。
Androidアプリ全体の品質を向上させたいからでしょうけど……
正直、もう少し早めに周知しておいてほしかった……
Android開発者の皆様、お気をつけください。

##おまけ
昨日、Android Developers BlogにAndroid Jetpackの新機能についての記事が上がっていますが、記事下部にこの件についての記載がありましたので貼っておきます。
https://android-developers.googleblog.com/2019/05/whats-new-with-android-jetpack.html
Capacitorの情報まとめとnative-pluginの作り方

## はじめに

CapacitorとはクロスプラットフォームWebアプリケーションのネイティブブリッジ。
1つのコードベースでiOS、Android、Electron、Web上でNative SDKを起動出来る。Ionic Frameworkアプリ用に最適化されていて、あらゆるWebアプリフレームワークで使用できる。
[公式ドキュメント](https://capacitor.ionicframework.com/docs/getting-started/)
## Cordovaとの相違点

CordovaのようにWebView上にWebページを表示するが、ページの一部、たとえばトーストだけはネイティブUIを利用するといった、ネイティブとWebViewの共存を行える点が特徴。
Web アプリケーション用のPWA。



## オリジナルnative-plugin作成手順(Web版)

### プロジェクト作成

ionicを使いプロジェクトの生成。

```shell
$ ionic start hoge blank
```

ここでionicのSDKを使うか聞かれるのでnを選択。

### プロジェクトに移動

```shell
$ cd [project-name]

$ npm install
```



### Capacitorのインストール

下記のコマンドでインストール。

```shell
$ npm install --save @capacitor/core @capacitor/cli
```



### Capacitorの下記コマンドで初期設定

アプリ名とバンドル名を聞かれるので入力

```shell
$ npx cap init
```



### お好みのプラットフォームの追加

```shell
$ npx cap add android

$ npx cap add ios

$ npx cap add electron
```



### オリジナルnative pluginの作成

下記のコマンドを入力してplugin を作成する。

```shell
$ npx @capacitor/cli plugin:generate
```



これにより、新しいプラグインに関する情報の入力を求めるウィザードが起動するので入力する。

例:

```shell
✏️  Creating new Capacitor plugin

//npmで使用する名前の設定

? Plugin NPM name (snake-case): LogDasu

//ドメインの識別子。用途はJavaのパッケージ名

? Plugin id (domain-style syntax. ex: com.example.plugin)com.example.plugin

//JavaとSwiftで使用されるクラスの初期名。

? Plugin class name (ex: AwesomePlugin) LogDasuNen

//pluginの説明

? description: log dasuyo

//PluginのソースコードがホストされるgitリポジトリのURL

? git repository:

//作者

? author: Shinjiro Suzuki

//デフォでOKそのままEnter

? license: MIT

//Yで作成される。

? package.json will be created, do you want to continue? Y/n
```



### pluginをいじる

ここでいじるファイルは下記のファイルです。

LogDasu/src/web.ts

自分はログ出すだけでいいので下記だけ追記しました。

```typescript
console.log('ログだしたよ！');
```



### pluginをnpm publishするorローカルでインストールして使う

自身で作ったpluginはそのままimportして使用しようとするとpluginがroot配下にないからダメとエラーがでます。



### pluginをnpm publishする

このパターンは特にpublishしても良いよーという奴専用です

npm publishしてnpm install [plugin name]してnode_modulesの中に入れてimportして使用する必要があります。

初めてnpm publishしたが、npmでめっちゃ詰まりました。

この件は今度また別でブログあげます…



### ローカルでインストールして使う

これは簡単で下記の様にインストールするとnode_modulesに入ってくれます。

例：

```shell
$npm install /Users/s-suzuki/Desktop/hoge/LogDasu
```



### home.tsにインポートしてちゃんと動くか確認する

エラーが出ずログを出してれば成功！！



## 不具合

5月9日現在Beta版になっておりGW中にテコ入れがあった為、公式のドキュメントとnpmでインストールした物とでは相違点がありドキュメント通りにiosとandroidのプラグインを作成しようとすると失敗する。

(確認出来ている物でyour-plugin/ios/Plugin/Plugin.xcworkspaceが無くなっておりX-codeで開く事が出来ない。

Androidに関してもyour-plugin/android/your-pluginが無いのでAndroid Studioが開けない。)



## おわりに

CapacitorはBeta版なんだなと。

実用化するにはちょっと早い気がします。

いつの日かまたCapacitorを使いnative-pluginを作ってみたいと思います。
パッケージとクラスの関係

#クラスとは
クラスとは、簡単に言えば「フィールドとメソッドの集合」です。
（数学に置き換えると「フィールド」は変数or定数、「メソッド」は関数に近いです）

```
class Sample01{
//フィールド
  int a = 0;
  int b;
  
//メソッド
  int sum(int c, int d){
    return c+d;
  }  
  int add_a(int c){
    return a+c;
  }
}
```
上のサンプルを見るとわかりやすいかと思います。
メソッドの２つ目のように、同じクラス内のフィールドはメソッドの内部に登場させることができます。
ここで引数を int a にしていた場合、引数として入力した方は「a」、フィールドの方は「this.a」と区別されることに注意しましょう。

#パッケージとは
パッケージはクラスまたはパッケージの集合です。
クラスとパッケージの関係は、ファイルとフォルダの関係に似ています。
同一パッケージ内のクラスにあるフィールドやメソッドには、アクセス修飾子（.）を用いてアクセスすることができます。

```
class Sample02{
  int a = Sample01.a;
  int b = 2;
  
  public void main(String[] args){
    int c = Sample01.sum(a,b);
    System.out.println("c = " + c);
  }
}
```
上のコードを実行すると「c = 3」が得られるはずです。
それでは、別のパッケージのクラスにあるフィールド等にアクセスするにはどうすればいいのでしょうか。
そんなときは「import」を使います。

```
import パッケージ名.クラス名;
```
を宣言すれば、先程と同様の手順でそのクラスのフィールドやメソッドにアクセスすることができるようになります。
GLSLでSSBOのメモリアライメントに引っかかったこと

GLSLで定義した構造体を含めたSSBO（ShaderStorageBufferObject）についてです。
例えば、以下のようなコードで想定外の動作に遭いました。

```
struct TPoint
{
    int Status;
    vec3 Position;
    vec3 Velocity;
};

layout (std430, binding = 0) buffer Point
{
    TPoint Points[];
};
```

問題は2つです。
1. vec3はvec4としてアライメントされる
2. 最大のデータサイズに応じてメモリパディングが行われる（構造体は構造体としてサイズ定義）
これを踏まえると、GLSLではTPoint構造体の変数1つについて図のようなメモリ配置と認識します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251232/3b8341ce-af6a-7186-e6ae-174b6b1e39b5.jpeg" width=15%>

アライメントさえ分かっていれば、SSBOのメモリ確保をこれに合わせれば解決です。
あるいは、vec3の変数をXYZの3要素に分解してもいいです。パディングが無駄に感じる場合は（筆者はそうですが）この方がいいでしょう。
次が修正したコードです。

```
struct TPoint
{
    int Status;
    float PositionX;
    float PositionY;
    float PositionZ;
    float VelocityX;
    float VelocityY;
    float VelocityZ;
};

layout (std430, binding = 0) buffer Point
{
    TPoint Points[];
};
```

<b>参考：</b>
https://stackoverflow.com/questions/29531237/memory-allocation-with-std430-qualifier
if文を抜けた後の$?

#問題
下のようなシェルスクリプトがあったとします。

```shell:iftest.sh
#!/bin/sh

if [[ $1 == "test" ]]; then
  echo "argument passed"
  #以下引数に"test"を渡した時に実行したい処理
  hogehoge
fi

exit $?
```

このスクリプトを引数を渡さずに実行したとします。

```shell-session
$ ./iftest.sh
```

さて、この時にこのスクリプトが返すexit codeは何でしょう？

1. 最後に評価した`[[ $1 == "test" ]]`の結果を返す。引数を渡さずにスクリプトを実行したので、1を返す。
2. 評価の結果に関わらず0を返す。

# 答え
正解は2番です。[ここ](https://unix.stackexchange.com/questions/400868/if-statement-based-on-a-command)でこのシェルの振る舞いについて語られています。また、[こちら](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_04_07)にシェルの仕様が明記されています。

> The exit status of the if command shall be the exit status of the then or else compound-list that was executed, or zero, if none was executed.

if文の条件がfalseとなりthenやelseに続くコマンドが実行されなかった場合、その直後のexit codeは0になるそうです。条件がtrueとなってthenやelseに続くコマンドが実行された場合は、そのコマンドのexit codeが返ります。

# おわりに
このシェルの振る舞いを知らない人もいるかもしれないので、もしif文の条件がfalseの場合には必ず0を返したい場合、下のスクリプトの方がわかりやすいかもしれないですね。

```shell:iftest.sh
#!/bin/sh

typeset rc=0

if [[ $1 == "test" ]]; then
  echo "argument passed"
  #以下引数に"test"を渡した時に実行したい処理
  hogehoge
  rc=$?
fi

exit $rc
```
Facebookからデータを収集する前に知っておくべき5つのこと

#1.実際、robots.txtファイルによると、Facebookはスクレイピングを禁止している

Webサイトをスクレイピングするする前に、必ずrobots.txtを確認してください。[Robots.txt](http://www.robotstxt.org/robotstxt.html) は、Googleなどのロボット型検索エンジンのクローラーの巡回を指示するファイルです。ターゲットWebサイトのURLの最後に「/robots.txt」を加えることによってファイルにアクセスすることができます。 

ブラウザに[https://www.facebook.com/robots.txt](https://www.facebook.com/robots.txt)を入力して、Facebookのrobotsファイルを確認しましょう。この2行はファイルの末尾にあります。
![Facebook1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262932/4eb08419-9323-ddcd-ccb5-7d0248043a74.png)

それは、Facebookがすべてのデータスクレイピングを禁止すると表示しています。つまり、Webサイトのどの部分にも自動クローラーがアクセスすることはできません。

**なぜrobots.txtの規則に従うべきですか？**

robots.txtを利用すると、「指定したWebページやファイルに対するアクセス可否」をクローラーの種類別に指定することが可能です。robots.txtファイルに従うことは、非公開の情報を盗むため使ったり、スクレイピング禁止するWebサイトを無断でスクレイピングしたり、著作権者の同意なく著作物をコピーするなどの非倫理的なデータ収集や法的な問題を回避することができます。


#2.Facebookからデータを収集する唯一の合法的な方法は、事前に書面の許可を得ることだ

Facebookは、robots.txtファイルの冒頭で次のように警告しています。「明示的な書面による許可がない限り、Facebookのスクレイピングは禁止されています。」
![Facebook2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262932/af098640-e207-ed5a-2329-6ad20f8f671e.png) 

2行目のリンクを確認すると、Facebookの[Automated Data Collection Terms](https://www.facebook.com/apps/site_scraping_tos_terms.php)（自動データ収集規約）が見つかります。これは2010年4月15日に改訂されました。
![Facebook3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262932/a2e8e252-7add-0c61-1144-c6c1cf103197.png)

ソーシャルメディアの巨人として、Facebookには資金、時間、そして専任の法務チームを持っています。自動データ収集規約を無視してFacebookのスクレイピングを進めても大丈夫ですが、少なくとも「書面による許可」を得るように警告されます。時には彼らは違法なスクレイピングに対してかなり攻撃的である可能性もあります。

 
#3.GDPRが施行された後は、個人データをスクレイピングしようとしている場合に訴訟を起こす可能性が高くなる

GDPR（EU一般データ保護規則）が2018年5月25日から施行されます。これはこの20年以来データプライバシー規制の最も重要な変更であると言われています。テクノロジーから広告、そして医療から銀行業務に至るまで、あらゆる面で大きな変化を強いることになります。

Facebookのようなテクノロジー企業のように、大量の消費者データを保管し処理する企業や組織は、GDPRの下で最も影響を受けます。以前は、ユーザーデータを保護するために、会社は規則を強制していました。今GDPRの下で、彼らは法律を完全に遵守していることを確認する必要があります。

ただし、良いことはGDPRは個人データにのみ適用されるのです。

ここで「個人データ」とは、特定の個人を直接的または間接的に識別するために使用される可能性があるデータを指します。このような情報は、個人の識別情報（PII）と呼ばれ、個人の名前、住所、メールアドレス、電話番号、IPアドレス、生年月日、雇用情報、さらにはビデオ/オーディオの記録も含まれます。

もし個人データをスクレイピングしていない場合、GDPRは適用されません。

簡単に言えば、本人の明示的な同意を得ていない限り、GDPRの下でEU居住者の個人データをこすることは現在違法です。

 


#4.必要に応じてFacebookからデータを収集することができる

robots.txtを無視してクローリングを行ったことがあれば、ルール違反のために法的な問題が起こるわけではありません。

ソーシャルメディアから収集されたデータは、間違いなく人間の行動や現実の出来事に関する最大かつ最も活躍ななデータセットです。10年以上にわたり、世界中の研究者やビジネス専門家がスクレイピング技術を利用してFacebookから収集した情報で、個人、グループ、社会を理解できる代表的なサンプルを作成し、データに隠されたまったく新しい機会を探っています。

ユーザーにとっては、ソーシャルデータの使用は必ずしも悪いことではないことに同意するでしょう。たとえば、マーケティングをパーソナライズするためのソーシャルデータを使って、パーソナライズマーケティングを実施するのは、インターネットを自由に保ち、広告やコンテンツをより関連性の高いものにすることができます。

Facebookは昨年4月からAPIのアクセス制限を実施しました。APIがなければ、ユーザーインターフェース、つまりWebページを介してのみFacebookのデータを取得できます。この時は[スクレイピングツール](https://www.octoparse.jp/blog/make-web-scraping-easy/)の出番です。「[2018年ソーシャルメディアスクレイピングツールトップ5](https://www.octoparse.jp/blog/top-5-social-media-scraping-tools-for-2018/)」という記事をご参考ください。

 


#5.Facebookの代替ソースを探しよう

前述のように、Facebookではすべての自動クローラーを禁止していますが、技術的にサイトからデータを収集することは依然として可能です。もちろんこれは危険です。

法的な影響以外にも、Facebookが不審なIPをブロックするため、定期的に目標データを取得することが難しくなります。そして厳しいブロッキングメカニズムを実装する可能性さえあり、それはサイトからのデータスクレイピングを全く不可能にするかもしれません。

ですから、TwitterやInstagramなど信頼性の高いソースからソーシャルメディアデータをスクレイピングすることをお勧めします。
Windows10でRealSenseD435iの動作確認をする。

# はじめに
RealSenseD435iを買いました。今回はgithubで公開されている`Intel.RealSense.Viewer.exe`を利用して動作確認をしようと思います。

# 環境
Windows10

# 準備
### ダウンロード
[こちらのページ](https://github.com/IntelRealSense/librealsense/releases/tag/v2.21.0)から`Intel.RealSense.Viewer.exe`をダウンロード。
![download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318451/d8858b57-adaf-9c2e-5c50-084633fedd36.png)

### RealSenseD435iを接続
PCにRealSenseD435iを接続します。するとデバイスのセットアップを勝手にやってくれるので完了するまで待ちましょう。

# 動作確認
それでは早速動作確認を行います。先ほどダウンロードしたファイルを実行しましょう。下の画像のようなものが出たら正常に動作をしています。
![download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318451/83e42d65-0d68-cd68-135a-5450e47f9209.png)

# 最後に
動作確認は簡単な手順で行えますね。
次は自分でいろいろいじれるように開発環境を整えたいと思います。
【エクセル資料からの】データクレンジング 後編(結合編)【備忘】

#はじめに
[前回][link-1]、こんな感じのエクセルデータから
![スクリーンショット 2019-04-18 12.27.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131499/1c7c311d-f98c-a9f7-6478-a5972998941f.png)

こんな感じの、DataFrameまで落としました。
![スクリーンショット 2019-05-09 10.01.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131499/9cfc3e5f-c1d9-36d5-6ec0-f8e4d304abc8.png)

今回は、月ごとに生成された複数のDataFrameを一つのDataFrameまで結合します。

#使用データ
[前回][link-2]参照

#1行に整形する
まずは、df.stack()をpandas.DataFrameにかけます。
df.stack()にかけるとマルチインデックスのpandas.Seriesになります。
ここにreset_indexをかけることで、DataFrameを1行にのばすことが出来ます。

[参考にさせていただいたサイト様][link-3]

```python
df_201710 = df.stack().reset_index(name="201710")
```

出力：
![スクリーンショット 2019-05-09 10.51.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131499/046b92bb-ec50-640c-949b-fb469dbf4702.png)
次に1行になるよう加工します。

```python
# インデックス名にlevel_1,level_2を結合して使用
ind = se["level_0"] + "_" + se["level_1"]

df_201710.drop(["level_0","level_1"],axis=1,inplace=True)
df_201710.index = ind
```
出力：
![スクリーンショット 2019-05-09 10.58.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131499/b702e71f-eb9b-be4e-6241-36d0761c5443.png)
#結合
最後に結合してデータの整形は完了です。

```python
trip = pd.concat([df_201810,df_201807,df_201804,df_201801,df_201710,df_201707,df_201704,df_201701],axis=1).T
```

出力：
![スクリーンショット 2019-05-09 11.03.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131499/bb8e982b-d526-b686-2773-18edd1df5d25.png)

gitに[ソース][link-4]上がってます。

[link-1]:https://qiita.com/sakabe/items/6924fb1363a03b6643a8
[link-2]:https://qiita.com/sakabe/items/6924fb1363a03b6643a8#%E4%BD%BF%E7%94%A8%E3%83%87%E3%83%BC%E3%82%BF
[link-3]:https://note.nkmk.me/python-pandas-stack-unstack-pivot/
[link-4]:https://github.com/Gsakabe/data_clean_for_excel/blob/master/data_clean.ipynb
protocolでstaticなプロパティ

ただのメモです。
Swift 4.2

# 定義

```swift
protocol Hoge {
    static var date: Date { get }
}

class StoredHoge: Hoge {
    static var date = Date()
}

class ComputedHoge: Hoge {
    static var date: Date {
        return Date()
    }
}
```

# 実行

```swift
let hoges: [Hoge.Type] = [StoredHoge.self, ComputedHoge.self]

print(Date())
//2019-05-09 02:07:28 +0000

hoges.forEach {
    print($0, $0.date)
    sleep(1)
}
//StoredHoge 2019-05-09 02:07:28 +0000
//ComputedHoge 2019-05-09 02:07:29 +0000

hoges.forEach {
    print($0, $0.date)
    sleep(1)
}
//StoredHoge 2019-05-09 02:07:28 +0000   //変わらない
//ComputedHoge 2019-05-09 02:07:31 +0000 //変わる
```
Yahoo APIのアクセストークンとリフレッシュトークンの有効期限

## 本稿で学べること

* Yahoo! APIのアクセストークンとリフレッシュトークンが期限切れになるまでの時間。
* 申請により、リフレッシュトークンの有効期限は延長できること。

## アクセストークンの有効期限

* 通常は3600秒(1時間)[^1]。
    * アクセストークン自体の有効期限は短いが、リフレッシュトークンでアクセストークンを更新し続ければ、リフレッシュトークンの有効期限が来るまでは、再認可が必要になることはない。

## リフレッシュトークンの有効期限

* 通常は4週間[^1]。
* ただし、セキュリティの観点[^2]から、下記API[^3]は12時間に短縮されている。
    * [ショッピング:注文検索API - Yahoo!デベロッパーネットワーク](https://developer.yahoo.co.jp/webapi/shopping/orderList.html)
    * [ショッピング:注文詳細API - Yahoo!デベロッパーネットワーク](https://developer.yahoo.co.jp/webapi/shopping/orderInfo.html)
    * [ショッピング:注文内容変更API - Yahoo!デベロッパーネットワーク](https://developer.yahoo.co.jp/webapi/shopping/orderChange.html)
    * [ショッピング:メッセージ投稿API - Yahoo!デベロッパーネットワーク](https://developer.yahoo.co.jp/webapi/shopping/question/send.html)
    * [ショッピング:質問詳細API - Yahoo!デベロッパーネットワーク](https://developer.yahoo.co.jp/webapi/shopping/question/detail.html)
    * [ショッピング:質問一覧API - Yahoo!デベロッパーネットワーク](https://developer.yahoo.co.jp/webapi/shopping/question/list.html)
    * 延長申請し、クライアント証明書認証を使うことで4週間に拡大できる[^3]。
* リフレッシュトークンが期限切れになった場合は、再認可が必要になる。(つまり、Yahoo!のログイン画面で認証し、認可しなおす手動対応が必要になる)

## リフレッシュトークンの有効期限の更新

* リフレッシュトークンは、再認可すると有効期限が更新される[^4]。
    * その際、リフレッシュトークンの文字列は変わらない[^4]。
    * つまり、4週間(12週間)たたずに再度認可しなおすオペレーションを繰り返せば、リフレッシュトークンの有効期限だけが更新されるため、同じリフレッシュトークンを4週間(12時間)以上使い回すことが可能。
    * 文字列が更新されるのは有効期限切れ、もしくは同意撤回をした後に再度同意した場合[^4]。

[^1]: [Yahoo! ID連携:Tokenエンドポイント - Yahoo!デベロッパーネットワーク](https://developer.yahoo.co.jp/yconnect/v1/client_app/explicit/token.html)
[^2]: [一部の注文APIで証明書認証に対応しました - Yahoo!デベロッパーネットワーク](https://developer.yahoo.co.jp/changelog/2014-09-17-shopping145.html)
[^3]: [ショッピング:ヘルプ - Yahoo!デベロッパーネットワーク](https://developer.yahoo.co.jp/webapi/shopping/help.html#orderapicertificate)
[^4]: [Yahoo WEB APIをバッチ処理から実行したい - Qiita](https://qiita.com/ynn/items/ae260ef5316d9d864026#comment-8a03108d26b58d9bb235)のコメント

## リフレッシュトークンのrevoke(無効化)

* Yahoo APIは、OAuth規格のrevokeには対応していないため、リフレッシュトークンをrevokeすることができない。そもそもエンドポイントが生えていない。

## 関連

* [Yahoo APIでアクセストークン有効期限切れのレスポンスサンプル - Qiita](https://qiita.com/suin/items/5241f461d8ced89f1091)
* [yahoo-id.sh: Yahoo APIのアクセストークンを取得する開発ツール - Qiita](https://qiita.com/suin/items/a40bb903604e9f3215f9)
* [Yahoo! ID連携(v1)でアクセストークンを取得する手順をHTTPだけで説明する - Qiita](https://qiita.com/suin/items/a47ab0412c46e32537bf)
Salesforce-レコードのロック解除

【備忘録】
SalesforceでApexからレコードをロック解除する方法です。

まず、カスタムオブジェクトの中で承認プロセスが起動した際、
レコードがロックされ編集できなくなる事が問題でした。
いちいち管理者側でレコードロックを手動で解除するのは面倒だったので自動化。
##事前準備

まずは設定画面からクイック検索で「**プロセスの自動化設定**」より
「**Apexでのレコードのロックおよびロック解除を有効化**」にチェックを入れ、保存。

これをしないと上手く処理が回りません。

##Apexクラス
```java:OpportunityApprovalUnlock
public class OpportunityApprovalUnlock{

    @InvocableMethod(label='レコードロック解除')
    public static void doUnlockByFuture(List<ID> appIds){
      //Unlock操作
      List<Opportunity__c> apps = [SELECT ID FROM Opportunity__c WHERE ManagerApproval__c!='承認済み' AND ApplyingForManager__c=true];
      List<Approval.UnlockResult> unLockResults = Approval.unlock(apps, false); 
   }
}
```



プロセスビルダーからある一定条件を満たした場合に
承認プロセスが走り出す仕組みになっていますが
それと同時にこのApexも起動させることでロックが解除されます。

##テストクラス作成時注意点
現状Salesforceではレコードがロックされているかどうかを判断するメソッドが存在しないそうなので、テストではupdateを実行して例外が発生するかを見る方法が有効だそうです。


##リリース時注意点
上記コードをリリースする際、テスト環境でのコードカバー率は100％なのにリリースの検証時にコードカバー率エラーが発生し、リリースが出来ませんでした。
原因としては実質テストコードでコードカバー率を上げていたのではなく、プロセスビルダーで上記クラスのメソッドを呼んでいたからというもの。
プロセスビルダーから呼んだ場合でもコードカバー率が上昇してしまうとのことでした。

そもそもトリガーの中などに組み込めれば上記の事象は発生しないのですが
ミジンコスキルではこの方法での実装が限界だったという…(´-`) .｡oO
ubuntuでマウスホイールのスクロール量を設定する[imwheel]

## 0. この記事を作成するにあたっての動作環境

- UbuntuMATE 18.04.2
- Ubuntu ユーザーならこれを見れば大体はできるだろう、くらいのつもりで書いています。

## 1. imwheel をインストールする

普通のLinuxユーザーはここでコマンド叩くんだけども、自分は「GUIでやれることはGUIでやれ派」なので、GUIパッケージマネージャー "**Synaptic**" を使います。

Synaptic から imwheel を適当に検索して適当にインストールしてください。

Synaptic をインストールしていなかったらさっさとインストールしましょう。デフォルトで入っている "ソフトウェア" や "Software Boutique" からインストールできます（これらから imwheel インストールは無理）。

## 2. ~/.imwheelrc を編集する（not管理者権限）

**ホームディレクトリに設定ファイル ".imwheelrc" を作って編集する**、ということでテキストエディタを使って以下のように書きます。

```:~/.imwheelrc
".*"
None, Up,   Button4, 3
None, Down, Button5, 3
```

- 設定ファイルのユーザーは一般ユーザーで。管理者で編集してはいけない。
- そんなわけなので、使用するエディタはなんでも良い。vim でも gedit でも Pluma でも好きなものを使うこと。
- 書式は以下のような感じの模様（※ちゃんとしたことを知りたいなら各自調べてください）
    - 最初の行はアプリの指定。この例の場合は「全てのアプリで」。
    - アプリ指定行以下に挙動の設定を書いていく。
        - 行の1番最初の要素（`None`の部分）はキーボードの操作。「このキーを押しながら」みたいな。
        - 2番目はマウスホイールの操作。`Up`は上回転、`Down`は下回転。他にもあるかも。
        - 3番目は「どのキーを押した時の動きをするか」。`Button4`は上キー、`Button5`は下キーを押した時相当の挙動と思われる。
        - 最後の数値は倍率。`3`としたら3倍の量で動く。画面スクロール速度で言えば3倍早くスクロールする。
    - 複数のアプリで別々の設定をしたい場合は、1行開けてアプリ指定から同様に書いていく。
- **ファイル名を"`~/.imwheel`"としている記事もあるけど、それは誤り。ここで書いた通り"`~/.imwheelrc`"とすること。**

## 3. imwheel の起動と停止

これらは流石にコマンドで。

起動は単純に "`imwheel`"。

```
$ imwheel
```

imwheel を起動すると、`~/.imwheelrc` で書いた設定の通りにマウスホイールによるスクロール速度が速くなる。

停止するときは無理やりプロセスを kill する。

```
$ killall imwheel
```

## 4. 自動起動設定

1. **「メニュー」から「コントロールセンター」を起動して、「ユーザー向け」グループにある「自動起動するアプリ」をクリックして、設定画面を立ち上げる。**
    - 「これじゃわからん！！」という方はターミナルから"`gnome-session-properties`" と打ってコマンドを実行し画面を立ち上げてください。このへん、環境によって全然違うと思うので。
2. 「自動起動するアプリの設定」が立ち上がったら、「追加」ボタンをクリックする。<br>
![自動起動.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319287/39302633-e5c2-d4c5-a58e-f0810d7b8112.png)
3. プログラム追加の画面で以下のように設定して「追加」ボタンをクリックする。
    - 名前 ... 任意（ここでは"imwheel"）
    - コマンド ... "`imwheel`"
    - 説明 ... 任意（ここでは空欄）<br>
![自動起動追加.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319287/d22652a2-b2e6-c704-3475-dcb784691fe1.png)
4. 以上で自動起動設定は完了。再起動してマウスロールによる画面スクロールが速くなっていたら成功。

## 参考

- [Ubuntu16.04/18.04でマウスのホイールの回転量を調整する](https://qiita.com/yumetodo/items/de3ae4155ff83544879b) ←imwheelの導入と基本設定の参考に。
- [Ubuntu 18.04でマウスホイールのスクロール量を調節する](https://qiita.com/ys22_/items/f87c05a1141092c1d548)←自動起動設定の参考に。
openrestyコンテナを動かす

# 環境

# あらすじ
- [Docker Hubのopenresty/openrestyコンテナ](https://hub.docker.com/r/openresty/openresty/)をrunするも落ちる
- [GitHub](https://github.com/openresty/docker-openresty)からDockerfileをcloneしてbuildしたイメージをrunしたら動作

# Docker Hubのopenresty/openrestyコンテナをrunするも落ちる
## 試したimageたち
- openresty/openresty      latest                  feebb0109819
- openresty/openresty      1.13.6.2-2-alpine-fat   bbd570a716e8
- openresty/openresty      1.13.6.2-2-alpine       a339c66710f6
- openresty/openresty      alpine-fat              cd2775f53e7b
- openresty/openresty      alpine                  00e4e0b735c3

## 動作
- docker run するも数秒後に終了する。
- run自体には成功しいそう(docker.log上はerrorにはなっておらず、startしてstopしている)

``` docker.log
time="2018-12-12T11:21:16Z" level=info msg="shim docker-containerd-shim started" address="/containerd-shim/moby/f75d65a916aaea1d08ef9dd045c2c525c5ca5191c2e0fee888dda014237dcbd4/shim.sock" debug=false pid=25735
time="2018-12-12T11:21:19Z" level=info msg="shim reaped" id=f75d65a916aaea1d08ef9dd045c2c525c5ca5191c2e0fee888dda014237dcbd4
time="2018-12-12T11:21:19.422010008Z" level=info msg="ignoring event" module=libcontainerd namespace=moby topic=/tasks/delete type="*events.TaskDelete"
```

- コンテナ内でshからopenrestyを起動してみると`Illegal instruction`のエラー

```
# /usr/local/openresty/bin/openresty
Illegal instruction
```

解決できず断念。

# GitHubからDockerfileをcloneしてbuildしたイメージをrunしたら動作
- [ソース](https://github.com/openresty/docker-openresty)をclone
- buildしてrunしてアクセスしてみる

``` docker操作ターミナル
# docker build -t openresty-test -f alpine/Dockerfile .
# docker run -p 80:80 openresty-test
# docker run -p 80:80 openresty-test192.168.11.1 - - [12/Dec/2018:11:29:08 +0000] " " 400 179 "-" "-"
192.168.11.10 - - [12/Dec/2018:11:29:32 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36"
192.168.11.12 - - [12/Dec/2018:11:29:57 +0000] "GET / HTTP/1.1" 200 649 "-" "curl/7.62.0"
```

``` 他のターミナル
# curl http://192.168.11.12
<!DOCTYPE html>
<html>
<head>
<title>Welcome to OpenResty!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to OpenResty!</h1>
<p>If you see this page, the OpenResty web platform is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="https://openresty.org/">openresty.org</a>.<br/>
Commercial support is available at
<a href="https://openresty.com/">openresty.com</a>.</p>

<p><em>Thank you for flying OpenResty.</em></p>
</body>
</html>
```
ArchLinuxで日本語入力環境を整える

最近、自作PCを組んで、MacからArchLinuxへ環境を移行しました。その時少々日本語入力の設定に手こずったのでメモしておこうと思います。

iBusやFcitxなど様々なインプットメソッドがありますが、調べてみるとiBusよりもFcitxに乗り換える傾向が多いようなので今回はFcitxでやります。

# 環境
* Arch Linux x86_64
* 5.0.12-arch2-1-ARCH
* WMはi3
* ターミナルは、urxvt

# Fcitx関係のインストール

```
pacman -S fcitx fcitx-mozc fcitx-configtool
```

インストール完了後、ユーザーのホームの下に、「.xprofile」の名前でファイルを作成し以下の内容を書き込みます。エディタなんでも構いません。僕は、Neovimが好みです。

```
export GTK_IM_MODULE=fcitx
export QT_IM_MODULE=fcitx
export XMODIFIERS=@im=fcitx
```

ファイル作成後は、一旦ログアウトしログインします。

# 入力ソースの設定
rofiを使っているのでその場合は、「fcitx」で検索するとfcitxの設定画面が開きます。
コマンドで実行する場合は、「fcitx-configtool」です。

「➕」のボタンを押して、「Japanese」とか入力すると、「Mozc」が選択できるので追加します。

この段階で、ChromeやSlack等での日本語入力はできました。

# urxvtで日本語入力するための設定
ユーザーのホームの下に、「.Xdefaults」または「.Xresources」の名前でファイルを作成し以下の内容を書き込みます。

```
URxvt.perl-ext-common:      xim-onthespot
URxvt.inputMethod:          fcitx
URxvt*preeditType:          OnTheSpot
```

.Xresourcesで設定を行った場合は、毎回忘れずに、`xrdb -merge ~/.Xresources`を行う必要があります。

コマンドが見つからない場合は、インストールされていないのかもしれません。以下のコマンドでインストールできます。

```
pacman -S xorg-xrdb
```

ここで、またFctixの設定を行います。
「Addon」 -> 「Advanced」にチェックを入れ -> 「Fcitx XIM Frontend」にチェックを入れ -> 「Configure」-> 「Use On The Spot Style for XIM」にチェックを入れます。

設定後、再度ログインを行います。

僕の場合は、これでurxvtでも日本語入力が行えました。これで、ncmpcppで日本語の曲が検索できます。

# 最後に
Qiita初投稿なのでなにかおかしいところや、直したほうがいいところなどあれば気軽に教えてくれると助かります。記事でわかりにくいところや、やっても動かない等あれば教えてください。できる限り協力します。あと、ArchLinux良いですよね。
自作のinputコンポーネントの受け取りデータ型をnumberとnullだけにしたい

propsで受け取りデータ型を指定してinputもtype="number"してやれば堅牢なコンポーネントが作れるんじゃないかということでやってみたら、タイトルの通りの部分で詰まったのでまとめる。

## ダメな例

基本的なpropsの受け取りデータ型の指定方法を使ってnullを追加してみる。

```javascript=
Vue.component('num-input', {
  props: {
    val: {
      required: true,
      type: [Number, null]
    }
  },
  template: `
    <input
      type="number"
      v-bind:value="value"
      v-on:input="$emit('input', $event.target.value)"
    >
  `
})
```

すると、`Right-hand side of 'instanceof' is not an object`と怒られる。

## 解決法

`type`プロパティで指定するのではなく、独自のバリデーションを作ることで解決できる。

```javascript=
Vue.component('num-input'. {
  props: {
    val: {
      required: true,
      validator: prop => typeof prop === 'number' || prop === null
    }
  },
  template: `
    <input
      type="number"
      v-bind:value="value"
      v-on:input="$emit('input', $event.target.value)"
    >
  `
})
```

とはいえ、HTMLで`type="number"`と指定しても`string`で渡される。(完全に忘れてて、[vue warm]でめっちゃ警告された…ありがとうvalidator)
親コンポーネントで使うときには、

```htmlmixed=
<num-input v-model.number="val" />
```

という感じにv-modelに[number修飾子](https://jp.vuejs.org/v2/guide/forms.html#%E4%BF%AE%E9%A3%BE%E5%AD%90)を使えば`number型`に変換された値が渡される。

## 参考文献

- [How to allow null prop](https://forum.vuejs.org/t/how-to-allow-null-prop/39259)
- [[Vue.js] input要素の入力値を数値変換したいときは number修飾子を使う](https://qiita.com/yu-smc/items/7c17c3eb8f1b4fd1527a)
Apacheで特定ローカルフォルダ内のファイルのMIMEを強制的に変更する

#Apacheで特定ローカルフォルダ内のファイルのMIMEを強制的に変更する

今までMIME変更はアプリケーションでしかやったことがなかったのだが、apacheでホストされる静的ファイルにおいて実現する要件が最近があったのでメモする。

```apache:/etc/httpd/conf/httpd.conf
<Directory "/var/www/html/json-text">
  ForceType application/json
</Directory>
```

上記設定で、/var/www/html/json-textのコンテンツにアクセスしたら、全てがapplication/jsonとしてレスポンスされる。
GoでのGETとPOST


GET

```main.go

package main

import (
  "net/http"
  "io/ioutil"
  "fmt"
  "net/http/httputil"
)


func main() {
  url1 := "http://xx.xxx.xx.xxx/hoge"

  url := url1 + url2 + url3

  req, _ := http.NewRequest("GET", url, nil)

  dump, _ := httputil.DumpRequestOut(req, true)
  fmt.Printf("%s", dump)

  client := new(http.Client)
  resp, _ := client.Do(req)

  dumpResp, _ := httputil.DumpResponse(resp, true)
  fmt.Printf("%s", dumpResp)

  defer resp.Body.Close()


  byteArray, _ := ioutil.ReadAll(resp.Body)
  fmt.Println(string(byteArray))
}

```
linux command >多数のファイルから一つだけ（最後のファイルだけ）を開く手順 > $_使用 > ls log.* してから vi $_ (またはless $_)

```txt:動作環境
CentOS 6.9
```

### 関連

- [mkdir と同時に cd でディレクトリ移動させるには（空白入りディレクトリ名の場合）](https://qiita.com/KEINOS/items/1da5ca6443bd7f254119) by @KEINOS さん
    - `$_`に関する説明が詳しいです

情報感謝です。

### 多数のファイルから一つだけ（最後のファイルだけ）を開く手順

- 1. `ls log.*`
    - log.*のファイルが表示されます
- 2. `vi $_`
    - log.*の最後のファイルをviで開きます
    - vi以外のsublでもsublimeでもidleでもgeanyでもお好きなエディタでどうぞ

### 用途

- 用途1
    - 多数のファイルがある
    - その一つだけでも確認したい
    - マウスで選んでコピー・ペーストが面倒なとき
- 用途2
    - 最終処理ファイルを瞬時に見たい
        - `$ls log.*`
        - `$less $_`
国連ベクトルタイルツールキットの技術要点

結局のところ、私という人間はデータフロー設計技師としての性格が強いなと思っているところ、その性格から素直に描写した「国連ベクトルタイルツールキットの技術要点」を書き出してみました。

![Annotation 2019-05-08 210936.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102082/4ec11903-a04a-3439-f9d7-a8c4595d549b.jpeg)

https://hackmd.io/p/HyB-Kg-hN#/
Rails routing（member/collection）

# member
collectionの各メンバーに対してリソースを追加することができる。
例えば以下があったとする。

```routes.rb
resources :author
```

これに対して、お気に入り機能をつけたい。
以下のようなパスになるはず。
`/author/1/favorite`

これは以下のように `routes.rb`に再現できる。

```routes.rb
resources :author do
  post :favorite
end
```

こうすると、railsは以下のパスを認識する。
`author/{author_id}/favorite`
該当する `author.id`を `params[:author_id]`で取得できる

## ちょっと一工夫

```routes.rb
resources :author do
  post :favorite, on: :member
end
```

とすると、railsは以下のパスを認識する。
`author/{id}/favorite`
該当する `author.id`を `params[:id]`で取得できる

# collection
collectionの全体に対してroutingを設定したい時につかう。
つまり、collectionの各要素を認識するような `id`が必要ないということ。

## 間違い
```routes.rb
resources :author do
  get :search
end
```

こうすると以下のようなroutingができてしまう。

```
            author_search GET    /author/:author_id/search(.:format)                                                      author#search
```
authorの各instanceに対して何かを検索してる感

## 正解

```routes.rb
resources :author do
  get :search, on: :collection
end
```
とすると、以下のようになる。
```
      search_author_index GET    /author/search(.:format)                                                                 author#search
```

# memberのちょっと使えた話
共通処理のメソッドを作成することができるようになりました！

## Before
これを知る前は、以下のようにしてました。

```routes.rb
resources :author do
  post :favorite
end
```

```AuthorsController.rb
...

def show
  @author = Author.find_by(id: params[:id])
end

def favorite
  @author = Author.find_by(id: params[:author_id])
  current_user.likes.create(author: @author)
end
```

## After
以下のように変更できて見通しが良くなりました。

```routes.rb
resources :author do
  post :favorite, on: :member
end
```

```AuthorsController.rb
...
before_action :set_author

def show
end

def favorite
  current_user.likes.create(author: @author)
end

private
def set_author
  @author = Author.find_by(id: params[:id])
end
```
monorepoでReact Hooksを使うライブラリを使うとInvariant Violationエラーになった

## 環境

- react-native 0.59.5
- react 16.8.3
- apollo-client 2.4.6
- react-apollo 2.5.4
- react-apollo-hooks 0.4.5

yarn workspaceを使ってmonorepoとして運用している。

```text
sampleProject
  ├── packages
  │   ├── core
  |   |   └── ...
  │   ├── app (React Native)
  |   |   ├── ...
  |   |   ├── package.json
  |   |   └── node_modules
  |   |       └── ...
  |   └── ...
  ├── package.json
  ├── yarn.lock
  └── node_modules
      └── ...
```

yarn workspace内でReact Nativeを動かすとき、プロジェクトレベルのnode_modulesにreact-nativeがインストールされてしまうと `react-native` コマンドが正常に動かない。yarn workspaceのnohoistの設定でreact-nativeを指定することでプロジェクトレベルではなくパッケージレベルのnode_modulesにインストールすることでこの問題を解決している。

参考: [nohoist in Workspaces | Yarn Blog](https://yarnpkg.com/blog/2018/02/15/nohoist/)

```json:package.json
{
  "name": "sampleProject",
  "private": true,
  "workspaces": {
    "packages": [
      "packages/*"
    ],
    "nohoist": [
      "**/react-native",
      "**/react-native/**"
    ]
  }
}
```

## 発生した問題

[react-apollo-hooks](https://github.com/trojanowski/react-apollo-hooks) を使おうとすると、Function Component内で使用したにも関わらず以下のようなエラーになる。

````
Invariant Violation: Hooks can only be called inside the body of a function component. (https://fb.me/react-invalid-hook-call)
```

```tsx:App.tsx
import React, { useState } from 'react';
import { useQuery } from 'react-apollo-hooks';

...

interface Props {}

const App: React.FC<Props> = props => {
  // Invariant Violationが発生する
  const { data, error, loading } = useQuery(SOME_QUERY);

  // こちらはエラーにならない
  const [count, setCount] = useState(0);

  ...
}

export default App;
```

## 原因と解決法

`react` モジュールが複数存在してしまっていたのが原因だった。
[https://github.com/facebook/react/issues/13991](https://github.com/facebook/react/issues/13991)
[https://reactjs.org/warnings/invalid-hook-call-warning.html#duplicate-react](https://reactjs.org/warnings/invalid-hook-call-warning.html#duplicate-react)

nohoistにreact-nativeを指定したことで、react-nativeが使用する `react` がパッケージレベルに、react-apollo-hooksが使用する `react` はプロジェクトレベルに存在する状態になっていた。

```
sampleProject
  ├── packages
  │   ├── app
  |   |   ├── ...
  |   |   └── node_modules
  |   |       ├── react <- パッケージレベル
  |   |       ├── react-native
  |   |       └── ...
  |   └── ...
  ├── node_modules
  |   ├── react <- プロジェクトレベル
  |   ├── react-apollo-hooks
  |   └── ...
  └── ...
```

これを解決するために、[issueのコメント](https://github.com/facebook/react/issues/13991#issuecomment-488085464)のようにreact-nativeが依存するreactをnohoistから除外することで、プロジェクトレベルに巻き上げた。

```diff:package.json
     "nohoist": [
       "**/react-native",
-      "**/react-native/**"
+      "**/react-native/!(react)/**"
     ]
```

## まとめ

1. yarn workspaceを使っている
2. reactがnohoistの対象になっている（主にReact Nativeで起こる）
3. ライブラリ内でReact Hooksを使っている

というかなり限定的な条件でしかこの問題は発生しませんが、[ReduxもHooksを提供するっぽい](https://react-redux.js.org/next/api/hooks)ので今後は似たようなハマり方が多くなるんじゃないかなと思いました。
【Flutter】BLoC と BLoC　Library について

# 概要

Flutterにおける、BLoCについて少々自分が躓いてしまったことを記述します。

# BLoCとは

BLoC とは、一般的に

Business Logic Component

のことであり、

State Management を

- 効率的に
- 整合性を保持し
- 一貫性を持って

行うために提唱されている

一種のパターン化された方法論(パターン)

です。

# 誤解しがちなこと

BLoCとしての概念・方法論とは別に、

pub に実際にこのパターンを規定した

BLoC のライブラリが存在します。

従って、初心者の僕などは当初混同しがちであったのですが、

1. 一種の方法論(パターン)としての概念
2. 概念を落とし込んだ実際のライブラリ

の2種類は全くの別物であることに

注意しなければいけません。

## 実際の例

[公式ページ](https://flutter.dev/docs/development/data-and-backend/state-mgmt/options#bloc--rx)
には、

<img width="815" alt="1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252691/bd0d008b-d634-d1f7-cf9c-7e0f875b7e14.png">


とありますが、

ここでいう

[Architect your Flutter project using BLoC pattern, by Sagar Suri](https://medium.com/flutterpub/architecting-your-flutter-project-bd04e144a8f1) は

- 一種の方法論(パターン)としての概念


[Bloc Library](https://felangel.github.io/bloc), by Felix Angelov は

BLoC ライブラリを用いて

- 概念を落とし込んだ実際のライブラリ


をそれぞれ指しています。

## 最後に

最後に  
間違いやご指摘などが御座いましたらご教示願います！
Xamarinで作る iOS, Android で動作するクローラー

スマートフォン上で動くクローラーを iOS, Android 両対応でお手軽に作れないか調べたところ、XamarinでC#を使って書くのが一番よさそうなのでやってみました。

Webページをとってくるのみなら HttpClient でも良いのですが、スクレイピングには [AngleSharp](https://anglesharp.github.io/) を使うのが簡単なようです。

AngleSharpはとても便利で、form の submit 周りも簡単に処理できます。C# なので iOS、Android の他、たぶん Winows などでも動くはずです。

## 実装例

Qiitaにログインして通知数を取得する処理を書いてみました。
ユーザー名とパスワードの部分を書き換えて、Xamarin Workbooks に貼り付ければ簡単に動作確認ができます。

```c#
using AngleSharp;
using AngleSharp.Dom;
using AngleSharp.Html.Dom;

//Cookieを有効化
var config = Configuration.Default.WithCookies().WithDefaultLoader();
var context = BrowsingContext.New(config);
//URLを取得
await context.OpenAsync("https://qiita.com/login");

//ログイン前のURL表示
Console.WriteLine(context.Active.Location);

//submit
var document = await context.Active.Forms[0].SubmitAsync(new
{
    identity = "Qiitaのユーザー名またはメールアドレス",
    password = "Qiitaのパスワード"
});

//ログイン後のURL表示
Console.WriteLine(context.Active.Location);

//通知件数取得
var notifications = document.QuerySelector(".st-Header_notifications");

Console.WriteLine(notifications.InnerHtml);
```

Visual Studio for Mac で作成したテストプロジェクトを Github にあげておきました。

https://github.com/kenji0302/testAngleSharpForQiita
documentとdocumentationどう違う 英語(10)

documentは文書
documentationは、documantateの名詞。

documentとdocumentateの違いを知ることが大事。

# doc

語源doc, docu, docere (教える)の英単語の意味まとめ
https://eng-etymo.com/archives/405
>ラテン語のdocumentum(証拠)

# document
TOEIC英単語 語源調査ノート
http://unetymology.blogspot.com/
>doc- 教える ＋ -ment 名詞化接尾辞
「語源中心英単語辞典」（南雲堂）

# documentation
mentも名詞化
tationが名詞化
名詞化が二つもある。

documentationは、不要な文書と一緒に捨てよう。

あるいは、既存の文書を圧縮して保存するようにdocumentationは圧縮して使おうか。
## 自己参考(self reference)
英語(0) 一覧
https://qiita.com/kaizen_nagoya/items/680e3f5cbf9430486c7d

言語・文学記事　１００
https://qiita.com/kaizen_nagoya/items/42d58d5ef7fb53c407d6

日本語（０）一欄
https://qiita.com/kaizen_nagoya/items/7498dcfa3a9ba7fd1e68

一覧の一覧( The directory of directories of mine.) Qiita(100)
https://qiita.com/kaizen_nagoya/items/7eb0e006543886138f39

プログラマが知っていると良い「公序良俗」
https://qiita.com/kaizen_nagoya/items/9fe7c0dfac2fbd77a945

Error一覧 error(0)
https://qiita.com/kaizen_nagoya/items/48b6cbc8d68eae2c42b8

＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞
This article is an individual impression based on the individual's experience. It has nothing to do with the organization or business to which I currently belong.

# 文書履歴(document history)
ver. 0.01 初稿 　 20190519
ver. 0.02 ありがとう追記 　 20230529
### 最後までおよみいただきありがとうございました。
いいね　💚、フォローをお願いします。
####  Thank you very much for reading to the last sentence.
Please press the like icon 💚　and follow me for your happy life.
api リクエストレスポンス



```:全体の流れ

require 'net/http'
require 'uri'
require 'json'


uri = URI.parse('http://localhost:3000/products/1')


ここでリクエストを出してる
ここは違和感だった。getメソッド使ってるのに、responseの変数を使ってる

response = Net::HTTP.get(uri)

result = JSON.parse(response)

p result

```

```:resultの結果

{"id"=>1, "name"=>"aa", "price"=>"1000", "integer"=>"1", "detail"=>"dsa", "image"=>"a", "created_at"=>"2019-05-08T15:29:33.411Z", "updated_at"=>"2019-05-08T15:29:33.411Z"}

```


```:responseの結果
json型になっていないみたい

JSON.parseで成形される

"{\"id\":1,\"name\":\"aa\",\"price\":\"1000\",\"integer\":\"1\",\"detail\":\"dsa\",\"image\":\"a\",\"created_at\":\"2019-05-08T15:29:33.411Z\",\"updated_at\":\"2019-05-08T15:29:33.411Z\"}"

```

```:値の撮り方

result["price"]
→ 1000
```



### メモ

- URI

https://docs.ruby-lang.org/ja/latest/class/URI.html
noVNCで画面のEscキーを押すと任意のキーが送信されるようにする

## 目的

* `:`を押しても`;`が送信されて困った。

## noVNC起動

```
git clone git://github.com/kanaka/noVNC
cd noVNC/
./utils/launch.sh --vnc サーバーのIP:5900
```

* http://localhost:6080/vnc.html?host=localhost&port=6080

にアクセスしnoVNCが表示されることを確認。


## 書き換え

noVNCのキー定義は `core/input/keysym.js`

![colon.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/56837023-1d45-48b7-7019-c370feca2ffd.png)

noVNCの画面のキーを押すとどのキーが送信されるかは `app/ui.js`

![colon2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/4e653937-58b6-b53c-facc-29434788c0f0.png)

```diff
    sendEsc() {
-       UI.rfb.sendKey(KeyTable.XK_Escape, "Escape");
+       UI.rfb.sendKey(KeyTable.XK_colon, "colon");
    },
```

## 動作確認

Escを押すとキーが送信された。
しかし`colon`にしても`;`が送信され、当初の目的が解消しない。
念の為`semicolon`にしてみたが当然`;`が送信された。

![スクリーンショット_2019-05-09_08-33-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/afdeab5b-9672-9a5c-2679-c960046bad70.png)

## 結果

* kvm起動時の`-k ja`指定で解決しました。
blueqatで量子ゲート

#概要

blueqatで量子ゲートやってみた。

#サンプルコード


https://colab.research.google.com/github/Blueqat/Blueqat/blob/master/tutorial/001_basic_circuit.ipynb

https://colab.research.google.com/github/Blueqat/Blueqat/blob/master/tutorial/002_basic_two_qubits.ipynb

https://colab.research.google.com/github/Blueqat/Blueqat/blob/master/tutorial/003_basic_superposition.ipynb

https://colab.research.google.com/github/Blueqat/Blueqat/blob/master/tutorial/004_basic_entanglement.ipynb

https://colab.research.google.com/github/Blueqat/Blueqat/blob/master/tutorial/005_basic_toffoli.ipynb

https://colab.research.google.com/github/Blueqat/Blueqat/blob/master/tutorial/006_basic_swap.ipynb

https://colab.research.google.com/github/Blueqat/Blueqat/blob/master/tutorial/007_basic_control.ipynb

https://colab.research.google.com/github/Blueqat/Blueqat/blob/master/tutorial/008_basic_general.ipynb

https://colab.research.google.com/github/Blueqat/Blueqat/blob/master/tutorial/009_basic_adder_hadamard.ipynb

https://colab.research.google.com/github/Blueqat/Blueqat/blob/master/tutorial/010_basic_multi.ipynb

https://colab.research.google.com/github/Blueqat/Blueqat/blob/master/tutorial/011_basic_ghz.ipynb

https://colab.research.google.com/github/Blueqat/Blueqat/blob/master/tutorial/012_algo_teleportation.ipynb

https://colab.research.google.com/github/Blueqat/Blueqat/blob/master/tutorial/013_algo_qft.ipynb

https://colab.research.google.com/github/Blueqat/Blueqat/blob/master/tutorial/014_algo_grover.ipynb

https://colab.research.google.com/github/Blueqat/Blueqat/blob/master/tutorial/015_algo_pea_simple.ipynb

https://colab.research.google.com/github/Blueqat/Blueqat/blob/master/tutorial/021_algo_vqe.ipynb

https://colab.research.google.com/github/Blueqat/Blueqat/blob/master/tutorial/022_algo_qaoa.ipynb

https://colab.research.google.com/github/Blueqat/Blueqat/blob/master/tutorial/023_h2_on_vqe.ipynb

https://colab.research.google.com/github/Blueqat/Blueqat/blob/master/tutorial/024_jij.ipynb

https://colab.research.google.com/github/Blueqat/Blueqat/blob/master/tutorial/025_qubo.ipynb

https://colab.research.google.com/github/Blueqat/Blueqat/blob/master/tutorial/026_maxcut.ipynb

https://colab.research.google.com/github/Blueqat/Blueqat/blob/master/tutorial/027_one_plus_one.ipynb



以上。
書籍を２軸マトリクスで整理するためのプログラムを作る。（作成中）


# やりたいこと
読んだ本を２軸でマトリクス表示できるようにして、ブログなどで公開できるようにしたい。
思考整理のために簡単にマトリクス（分布図？）が作成できるようにしたい。

# 進捗
最新版はAppScriptでWebアプリケーションとして公開中。
https://script.google.com/macros/s/AKfycbzbjBsAR6lIbhqV3Bj_l0gc4SzF6IecovL6gyTrUxk/dev

# 実装した機能と参考リンク

## マトリクスの線を引く

```javascript:drawline.js

// The .drawLine() object
var hobj = {
  strokeStyle: 'gray',
  strokeWidth: 2,
  rounded: true
};

// Your array of points
var hpts = [
  [w/100, h/2],
  [w-w/100, h/2],
];

// Add the points from the array to the object
for (var p = 0; p < hpts.length; p += 1) {
  hobj['x'+(p+1)] = hpts[p][0];
  hobj['y'+(p+1)] = hpts[p][1];
}

// Draw the line
$('canvas').drawLine(hobj);

// The .drawLine() object
var vobj = {
  strokeStyle: 'gray',
  strokeWidth: 2,
  rounded: true
};

// Your array of points
var vpts = [
  [w/2, h/100],
  [w/2, h-h/100],
];

// Add the points from the array to the object
for (var p = 0; p < vpts.length; p += 1) {
  vobj['x'+(p+1)] = vpts[p][0];
  vobj['y'+(p+1)] = vpts[p][1];
}

// Draw the line
$('canvas').drawLine(vobj);
```

## canvasをフルスクリーン表示にする

```canvas.js
$( '#canvas' ).get( 0 ).width = $( window ).width();
$( '#canvas' ).get( 0 ).height = $( window ).height();
```

[HTML canvasを画面いっぱいに表示したい - Qiita](https://qiita.com/gonshi_com/items/e26d57b255319e728a1a)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268023/96c12bfe-095f-23e3-e776-87c6cbca82de.png)

## jcanvasを使って描画してみる

## ウェブアプリケーションとして公開する

Google App Scriptを使って簡易的に公開してみた。
<img width="886" alt="6F432110-6ADB-4EBF-B2FD-8DC8E2ADD08C.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268023/65e4f1cf-fb30-cad1-d38c-6fefcbe1f2da.png">
[Google Apps Script でHTMLファイルを作って表示。 - Qiita](https://qiita.com/taromorimotohf/items/5e52cb9062600e8ccac3)

# やりたいこと

これから実装したい機能と参考になりそうなリンクのまとめ

1. 書籍検索機能を追加する
[検索ボックスの値をリアルタイムに取得して、部分一致の絞込み検索を実装する ｜ Tips Note by TAM](https://www.tam-tam.co.jp/tipsnote/javascript/post11315.html)

* スマートフォンでも操作できるようにする
* レスポンシブデザインにする
* ~~キャンバスの縦サイズが画面いっぱいにならない問題の解決~~
* 評価軸を設定できるようにする
* 保存できるようにする
* デザインを整える
* 入力ボックスの表示場所をクリックした場所にする
* 文字を編集できるようにする
* テキストにHTMLリンクを追加できるようにする
Jupyter-notebook(Anaconda3) on Docker for Mac

# 【Overview】
- Establishing an execution environments on Jupyter-notebook via Anaconda3 using Docker.

## 【Environments】
- macOS Mojave 10.14.4
- MacBook Pro

## 【Prerequisites】
- Docker has been installed.

## 【Workflow】
### ▼Pulling the image of Anaconda3
```
$ docker pull continuumio/anaconda3
```
### ▼Provisioning Anaconda3 Container
- 【-v】ホスト側のディレクトリをコンテナ側にマウントすることでデータを永続化
- 【Format】{Any directory on host-side}:/opt/notebooks

```
$ docker run -it -p 8888:8888 --name jupyter-notebook -v /Users/{UserName}/data/jupyter-notebook/notebooks:/opt/notebooks  continuumio/anaconda3 /bin/bash
```
### ▼Installing pandas_datareader(Optional)
- 任意
- 必要だったためインストール

```
$ pip install pandas-datareader
```
### ▼Displaying available Python versions
```
$ conda search python
```
### ▼Installing Python3.6
```
$ conda create -n py366 python=3.6.6 anaconda
```
### ▼Pythonのバージョン切り替え
```
$ source activate py366
```
### ▼切り替え完了を確認
```
$ conda env list
```
### ▼Launching Jupyter-notebook
```
$ jupyter notebook --notebook-dir=/opt/notebooks --ip 0.0.0.0 --no-browser --allow-root
```

### ▼Access the following URL
```
http://127.0.0.1:8888/?token={token}
```
完全学務爆破マニュアル Light版 ① : 機上座標系と地上座標系の変換

前のページ [目次] (https://qiita.com/lier80/items/8d4ababd14e4db4222e3)
次のページ 来週中には進みます

## 地上座標系と機上座標系の変換

### なぜ座標系を変換するか

当然の疑問だと思います。我々の住む世界と飛んでいるものの世界が違うということはありませんし、実際のところ飛翔体の運動を地上から見た座標系で記述することも
十分に可能です。

ところが、実際にこれを行ってみると非常に面倒なことに気がつくと思います。

簡単のため - それでも頭にくるほど面倒ですが - 2Dの世界で考えてみます。
平面上にX,Y軸を貼り付けて、Y軸負方向に重力がかかるとします。

空力を考慮した放物運動を考慮すると、

(中略を読むには優しい言葉をかけてください)

[このようなコード](https://github.com/yasu80/dqn_missile/blob/master/script/missile.py)が出来上がります。ここで注目したいのが、座標系が一定の姿勢であるにもかかわらず、飛翔体の進行方向と飛翔体にかかる力の象限(方向同士の関係)
が変化しているため、これらの処理を正しく行うためには迎角(A.O.A)による場合分けが多数必要に鳴るということです。一応動くようにしましたが、めっちゃめんどくさいです。発展性もないですし。

これ端的に言ってクソなんで、別の方法を考えます。

そもそもの原因は、機体に対しての力の働き方がAOAに対して全部変わってくるところにあります。
だから、機体に座標軸を貼り付けてします。そうすれば、軸の変換(回転)をパラメータとしてすべての力を一定の関係性で表すことができます。

思いつく方法はいくつかあります。

1.回転行列によってxyz-にたいしてロール角、ピッチ角、ヨー角(r,p,y)を用いて、機体の座標系がどのような向きをしているのかを直接表してしまう
2.そもそも角度を用いず、四元数で座標を表してしまう。

いろいろな理由から、ここではrpyを用いた表し方を先ず選択します。
(あとで四元数もやります)

さて、よく見かける回転行列は、以下のように表されています。

```math
\begin{matrix}
cos \theta & sin \theta & 0\\
-sin \theta & cos \theta & 0\\
0 & 0 & 1
\end{matrix}
```

これは x 方向の回転を表す行列であり、ここでの θ はx軸周りの回転を表すロール角となっています。面倒なので このページのみすべての回転角を全部 θ で表します。

全く同様に、 y, z 方向の回転も表していきます。

y方向(ピッチ)

```math
\begin{matrix}
cos \theta & 0 & sin \theta \\
0 & 1 & 0 \\
-sin \theta & 0 & cos \theta
\end{matrix}
```
z方向(ヨー)

```math
\begin{matrix}
1 & 0 & 0\\
0 & cos \theta & sin \theta\\
0 & -sin \theta & cos \theta
\end{matrix}
```
ここで注意して欲しいのが、r-p-yという書き順にはすでに意味があり、入れ替えは不可能となることです。
参考までに、

一般にベクトル積は

AB != BA

であります。具体的には、クリップのついたボールペンをロール30度、ピッチ45度、ヨー30度で動かしてみてください。順番によって向いている方向が違うはずです。
感覚的には、”回転の回転”が発生することが原因です。そのため、機上の座標系-機内の計器-が表しているr,p,yの数値で表される姿勢を、地上からの変換行列という形にすると、複数形式：複数数値で表すことができます。

極端な話、ひとつの姿勢系を表す際、r-p-r系なんていうもので三次元座標系を表すことも可能です。

そのため、なにか参考書を読む際はどの系で書いてあるか、rpy系なのかyrp系なのかを常に気をつけてください。
いま手元にある本はXYZ系に対してz-x-yの順番で回転しています。なので、yrp系ということになります。

さて、これによって系同士、機上座標系と地上座標系の間の角度の違い…具体的には飛翔体の姿勢…との関係性を表すことができましたから、
この関係性を使って、元の座標系もベクトルに直して行列として、2つの座標系の間の位置関係をベクトル同士の掛け算で表してみます。

以下、地上座標系を $ R_1, = (x_1,y_1,z_1) $ 機上座標系を $ R_2 = (x_2,y_2,z_2)$とします。ここでは簡単のため変換はx-y-zの順番で行うものとし、変換行列Aを使って

```math
A = r \cdot p \cdot y \\

R_2 = A \cdot R_1
```
とします。
これらの計算を行うことによって、座標の変化を表すことができます。
これは、理系向けに言うと、端的に言って一次変換(ベクトルの写像)です。

ですから、飛翔体の座標系を絶対座標からの相対関係において記述することについて、飛翔体の姿勢の記述が記述できるということがお分かりいただけると思います。

※ 当方の都合上一旦ここで中断します。次回までに機上座標系を具体的に記述し、最低でも四元数記述まで、余裕があれば機体の位置推定の途中まででも行ければ良いなぁと思っていますが、何分時間が取れないので一旦失礼。@出社前

前のページ [目次] (https://qiita.com/lier80/items/8d4ababd14e4db4222e3)
次のページ 来週中には進みます