OmniAICreator/Qiita-1.07M huggingface dataset:
javasript, jquery（ul,liタグ）

### ①html、 javasriptのツールの開発
　→オンラインツールを使えるため、ツールのダウンロードが不要です。
　　　https://jsfiddle.net/

![スクリーンショット 2020-12-21 10.23.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/965456/f1eea67f-b1b5-cb0e-569d-d28db2bae1f8.png)


### ②HTML分に以下のHTMLソースを追加してから、実行する
```html

<html>

  <head>
    <title>Hoge</title>
  </head>

  <body id="main-id">

    <ul>
        <li>hoge1</li>
        <li>hoge2</li>
        <li>hoge3</li>
    </ul>

  </body>

</html>
```
イメージ
![スクリーンショット 2020-12-21 13.54.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/965456/d98099f0-e5a1-a9df-5fb5-2463f4ce20af.png)


### ③HTMLのかわり、JQUERY(OOP)でページを表示する

　　①JQUERYを追加する
　　②HTMLのULが JQUERYのULに変換する
　　③HTMLのLIが JQUERYのLIに変換する　

```javascript

//マインオブジェクト
var $main  = $("#main-id");

//ulオブジェクトに変換する
var $ul = $("<ul>"); 

//liオブジェクトに変換する
var $li1 = $("<li>").html("hoge1");
var $li2 = $("<li>").html("hoge2");
var $li3 = $("<li>").html("hoge3");

//親オブジェクトに子オブジェクトを追加
$ul.append($li1).append($li2).append($li3);
$main.append($ul);
```
イメージ
![スクリーンショット 2020-12-21 14.04.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/965456/43dd1c82-b06c-b255-e2dd-b0c60ff13686.png)


### ④実行した後、HTMLの表示の結果と同じ
![スクリーンショット 2020-12-21 14.08.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/965456/116301af-aaac-a2b3-b894-bca6d8a4ee2b.png)


### ⑤JQUERY(OOP)のclickのメソッド
```javascript

//ulオブジェクトに変換する
var $ul = $("<ul>");
$ul.click(function() {
    //todo
});

//liオブジェクトに変換する
var $li1 = $("<li>").html("hoge1");
$li1.click(function() {
    //todo
});

var $li2 = $("<li>").html("hoge2");
$li2.click(function() {
    //todo
});

var $li3 = $("<li>").html("hoge3");
$li3.click(function() {
    //todo
});
```

以上
gemspecファイルたるものの存在を知った

[注意]この記事はあまり調査、精査して確認する時間をとって書いたわけではないので、話半分に読んでいただきたい。



## Gemfileとxxx.gemspecの違い


- ライブラリを管理するために使われるファイルたち
  - Gemfile
  - Gemfile.lock
  - xxx.gemspec

- これらの違いは、
  - `Gemfile`と`my_rubygem.gemspec`は自分で書き換える
     - Railsの依存ライブラリ管理は`Gemfile`を編集する
     - **gemの依存ライブラリ管理は`my_rubygem.gemspec`を編集する**
  - `Gemfile.lock`は`$bundle install`によって書き換えられる




## gemspecファイルの例

`bundle gem my_rubygem`によって作られるファイル群には、これらが含まれる。

```
my_rubygem/lib/my_rubygem.rb
my_rubygem/lib/my_rubygem/version.rb
my_rubygem/my_rubygem.gemspec
```

これらのうち、関連する以下の様に書き換える

```my_rubygem/lib/my_rubygem/version.rb
module MyRubygem
  VERSION = "0.20.0"
end
```

```my_rubygem/gemfile.gemspec
require "my_rubygem/version"

Gem::Specification.new do |spec|
  spec.name          = "MyRubygem"
  spec.version       = MyRubygem::VERSION
  spec.authors       = ["John Lennon"]
  spec.email         = ["j-lennon@beatle.com"]

  .....

end
```



## 参考

- https://qiita.com/nysalor/items/c626e893f6a0d2d3782e
    - 自分の記事はこれの劣化版です。
UiPath：カスタムアクティビティを維持するのもつらいよ

## 皆もすなるQiitaといふものを、儂もしてみむとてするなり。

と言う訳で、こん＊＊は！はなっち！です。

今回は、UiPathの機能、ライブラリで作ったカスタムアクティビティを、UiPathマーケットプレイスに登録していたら。。。ってお話です。

ちょっと手抜きで、スライド的な形式です。なお、これを登壇してＬＴに掛けることは考えていませんので、ここ限定になりますね(^^♪

では、始まり始まり！！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/54c190bb-88b9-9a65-ae83-0873a1208951.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/beafc86b-6030-5659-3a98-084246d41944.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/10592eaf-b97e-847b-224b-3abf7c6938c7.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/c0382c6e-7905-6d4b-4ae6-8b0131d14a55.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/5c4829fa-c1ed-5dae-e860-705631c51571.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/7335ea4d-c087-e880-ef64-c2ef6cc9ef25.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/9fac1ae1-149a-1a79-982d-63fa5a4aa1ff.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/ff4e9ee2-3cc6-9b51-a277-1982cb25bd2c.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/06053624-f567-c0dd-e346-5fe05e71c76e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/4be1856f-da4f-4784-3114-d8d7a474cba1.png)

##おわりに
いかがでした？

マーケットプレースも日々進化しているわけで、それ故、設計の都合で従来の資産を捨てなければならないシーンもあったんでしょうね。

たまたまダウンロードしようとした方がいて、連絡くださって、自分としても何もしていない事からＦＯＲＵＭに相談して、それに手を差し伸べてくれた方がいて、Ｇｏｏｇｌｅ翻訳を駆使して、アドバイスをもらって、資料をまとめて（この記事ね）。。。

ロボ開発は個人作業かと思うのですが、実は裏ではいろんな方がUiPathユーザを支えているんだなと思いました。

是非UiPathでのロボ開発の一助になればと思っています。

ありがとうございました！

SP TNX! Mr.Brandon And Mr.Copoiu
ネットワークを調査する

IPv6でネットワーク調査基本コマンド

```shell
$ ping6 ::1
$ traceroute6 2001:4860:4860::8888
$ dig google.co.jp AAAA @8.8.8.8 
```

パケットキャプチャ

```shell
$ tcpdump -v ip6   #小文字のvは付かない。ipv6ではない。
$ tcpdump -s 1600
````

HTTPに特化

```shell
$ curl http://127.0.0.1/ #v4
$ curl http://[::1]          #v6
$ curl -6  http://example.com   #v6
```

mDNS
基本的にユニキャストのDNSと同じパケットフォーマット
typeは、_myhome._tcp
nameは、MyDevice-33c58540でのスキャン結果
```shell
$ dns-sd -B _myhome._tcp
Browsing for _myhome._tcp
DATE: ---Mon 26 Feb 2024---
 9:52:52.861  ...STARTING...
Timestamp     A/R    Flags  if Domain               Service Type         Instance Name
 9:52:53.423  Add        2  14 local.               _myhome._tcp.        MyDevice-33c58540
$
$ dns-sd -L MyDevice-33c58540 _myhome._tcp

Lookup MyDevice-33c58540._myhome._tcp.local
DATE: ---Mon 26 Feb 2024---
 9:53:30.811  ...STARTING...
 9:53:30.812  MyDevice-33c58540._sonysmarthome._tcp.local. can be reached at Android.local.:44457 (interface 14)
 attrId=171644261 color=Default protoVer=0x10 fwVer=1.0.0 pfVer=10000
```
https://docs.oracle.com/cd/F16635_01/html/E72377/dns-sd-8.html
Microsoft Teamsの特定のチャンネルにホームページのGoogle Analyticsの昨日の結果を投稿する

slack使いたいけど契約上Microsoft Teamsがあるじゃないか！
と言われてTeamsを使っていますがなんだかんだ不便はない。

slackだとこんなことが出来ますという記事は多いけどTeamsはないに等しいので書いてみた。
参考にしたのはほぼここ。というかここまんまです。


[GoogleAnalyticsの内容をSlackへGASで通知するBotの作成 2](http://developabout0309.blogspot.com/2015/10/googleanalyticsslackgasbot-2.html)

ただし、このコードを実行すると今現在のアナリティクスが表示されるので、昨日どれくらい来ていたかどうかについては表示できない。

抜粋すると

```script.js
  var today = new Date();
  var toDate = Utilities.formatDate(today, Session.getTimeZone(), 'yyyy-MM-dd');  
  var tableId = "ga:" + profileId;
  var metric = "ga:users,ga:sessions,ga:pageviews";
  var options = {
    "max-results" : 25
```
ここの部分である。

なので、一行加える

```
  today.setDate(today.getDate() - 1);
```

```script.js
  var today = new Date();
  today.setDate(today.getDate() - 1);
  var toDate = Utilities.formatDate(today, Session.getTimeZone(), 'yyyy-MM-dd');  
  var tableId = "ga:" + profileId;
  var metric = "ga:users,ga:sessions,ga:pageviews";
  var options = {
    "max-results" : 25
  }
```

これにより、このコードが実行されるときの前の日のアナリティクスが参照されるようになる。

これで、IncomingWebhookでteamsとつないで
![スクリーンショット 2020-12-21 134303.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546003/aec8d745-90da-6713-60ee-11f00d613159.jpeg)

こんな感じで表示できる。設定をいじればもう少しデータも取り込めるはず。
マーケの人にこれで上司に報告楽ですよと進めて大変感謝されましたとさ。

slackじゃなくてもTeamsで十分いろいろできるので
会社で使っている社内コミュニケーションツールがTeamsで嘆かなくてもいろいろできますよってはなしですね。
Oracle Multitenant 4 PDBの再接続

```
SQL> create pluggable database orclpdb2 using '/opt/oracle/oradata/ORCLCDB/orclpdb3/orclpdb3.xml' nocopy;

Pluggable database created.

SQL> show pdbs
  CON_ID CON_NAME   OPEN MODE    RESTRICTED
       4 ORCLPDB1   READ WRITE   NO
```
mqtt_bridgeのrostestをcircleciで動かしてみた

## 概要

最近 ROS を触れてないのですが、[2016年に作ったmqtt_bridge](https://qiita.com/ledmonster/items/1b46fabf0415d7c0abae) のissueやPRを放置してしまっていたので、12月に入ってから改めてテコ入れしはじめました。python3 対応したいんですが、動作確認環境もままならない環境で手を入れるのもあれなんで、取り急ぎはということで rostest 対応して circleci で動かしました。実装内容は[こちら](https://github.com/groove-x/mqtt_bridge/pull/41)。

## 工夫したこと

### publisher を安定化

ROS の publisher には、[インスタンスを生成した直後に publish しても subscriber にデータが届かない問題(仕様)](https://github.com/ros/ros_comm/issues/286)があります。これだとテストを書くのに困ります。以下のように、publisher 生成後に rosmaster の subscriber 数と、publisher に紐づいた subscriber 数が一致するまで待つロジックを入れることで、解決しました。昔、社内向けに工夫していた実装ですが、bitbucketを掘り起こして見つけました。昔の自分、ありがとう！


```python
def get_publisher(self, topic_path, msg_type, **kwargs):
    pub = rospy.Publisher(topic_path, msg_type, **kwargs)
    num_subs = len(_get_subscribers(topic_path))
    for i in range(10):
        num_cons = pub.get_num_connections()
        if num_cons == num_subs:
            return pub
        time.sleep(0.1)
    raise RuntimeError("failed to get publisher")

def _get_subscribers(self, topic_path):
    ros_master = rosgraph.Master('/rostopic')
    topic_path = rosgraph.names.script_resolve_name('rostopic', topic_path)
    state = ros_master.getSystemState()
    subs = []
    for sub in state[1]:
        if sub[0] == topic_path:
            subs.extend(sub[1])
    return subs
```

### MagicMock で pubsub をテスト

[unittest.mock](https://docs.python.org/3/library/unittest.mock.html) が python2.7 向けに backport された [mock](https://pypi.org/project/mock/) を使って pubsub をテストしました。

```python
ros_callback_ping = MagicMock()
rospy.Subscriber("/ping", Bool, ros_callback_ping)
ros_callback_ping.assert_called_once_with(Bool(True))
```

みたいなコードを書くことで、 subscriber が `Bool(True)` の値で1回だけ呼び出されることをテストできます。


### CircleCI で rostest

現職では CI に CircleCI を使っているのですが、ローカル作業用のコマンド [circleci](https://circleci.com/docs/2.0/local-cli/) が便利です。
ros の docker ファイルを使ったテストを `.circleci/config.yml` を書いて、

```bash
circleci local execute --job rostest
```

のように実行すると、ローカルで簡単に rostest を実行できます。


## まとめ

久々にROS触ると楽しいですね。次は python3 + noetic 対応です。
JavascriptのES6以降で、親クラスから子クラスのクラス名をstaticメソッド内で取得.

# 「this.name」で親クラスの名前を取得

```class.js

class Parent {

 static showName() {
   console.log(this.name);
 }
}


class Child extends Parent {}

Child.showName(); //Child


````

# 親クラスに子クラスをインスタンス化するファクトリーメソッドを実装（new this)

```class.js

class Parent {

 static new() {
   return new this();
 }
}

class Child extends Parent {}

const ins = Child.new();


```
# 子クラス名を取得する際の注意点（static同士でメソッドを呼び出すと、親クラスの名前になる）

- 以下のケースだと子クラスのクラス名は取得できない。

```class.js

class Parent {

 static showName() {
   console.log(Parent._className());
 }
 
 static _className() {
   return this.name;
 }
}


class Child extends Parent {}

Child.showName(); //Parent (Childではない）

```
Laravelのchunk処理でやらかした話

とあるポイントカード系の案件でやっちゃった話。。

## 概要
事の発端は、外部のベンダーへデータ連携する為に、顧客のポイントカードテーブルのレコードを抽出してCSVファイルを作成し、AWSのS3にPUTするといったバッチ処理を実装したことから始める。

結構デカめのデータを取り扱う案件、また日次で全件出力する仕様であった為に
Laravelのchunk処理を用いてCSVファイルを作成する処理を組んだ。

具体的なソースは下記。

```php
    // チャンクサイズ
    $chunkSize = 1000;

    PointCards::query()->orderBy("loginid", "asc")->orderBy("shopid", "asc")->chunk($chunkSize, function ($pointCards) use ($file) {
        foreach ($pointCards as $pointCard) {
            $csv = [
                $pointCard->loginid,
                $pointCard->shopid,
                $pointCard->card_number,
                $pointCard->point,
            ];
            // 書き込み
            $file->fputcsv($csv);
        }
    });
```

テーブルの仕様上、 ` id ` みたいなプライマリーキーが無く、` loginid ` と ` shopid ` でユニークの構成であった為、` orderBy ` で取得データの順序を整え、出力するという実装になった。
（テーブル設計時なんでプライマリーキーを付与させなかったのは疑問であるが・・）

無事実装完了して本番リリースを行い、バッチ起動後、S3にCSVファイルが配置されていることを確認した。

よしよし、問題なしと思っていたのだが・・

## 数日後
外部ベンダーから連絡がきた。

「本日作成されたCSVファイルに重複したレコードが数件あります。確認して頂けませんでしょうか」

お・・まじか。。

まずデータがどうなっているか調査するか・・。

商用のDBに繋ぎ、該当レコードがどうなっているかを調査する。

しかし、CSVとは違いレコードの重複はない。。

テーブル的におかしなデータの持ち方はしておらず、不整合データは見当たらなかった。

小一時間データを眺めていると、ある部分が異様であることに気づく。

重複したレコードが3件ほど存在したのだが、どのレコードも行数が
` 8001、8002 ` `10001、10002` `14001、14002`と、1000件単位の区切りでおかしくなっていた。

chunkで分割して出力していた単位が1000件。この時点でchunk処理が怪しいことに気づく。

ただ、なぜこの事象が発生しているか根本的な原因が掴みきれない。。

悩み始め、攻めあぐねていると、他の同僚が一言


#### 「ん、バッチ処理中にユーザーがポイントカードを作成したんじゃね・・？」


## 原因解明

同僚の推理はビンゴだった。

レコードを追うと、どうやらバッチ処理のタイミングでポイントカードが作成、要するにポイントカードテーブルにレコードが挿入されていた。

（※ バッチ処理の仕様として、朝方4:00のタイミングで日次起動される仕様であり、
タイミング悪くその時間帯にポイントカードを作成されていた日のCSVファイルはレコード重複が確認され
そうでなかった日の他の日のCSVファイルは正常なものとなっていた。)

結局の原因としては、プライマリーキー順でなく` loginid ` と ` shopid `で` orderby `を行っているため
処理の途中でInsertが行われ、レコードの差し込みが入るとバグるということであった。

## そして対応へ
対応としては、クエリの条件に ` 日次でバッチ起動される時間前までのレコードであること ` を付与させる形で対応を行った。

今更ながらテーブルにプライマリキーを付与させるとか別案もあったが、その案でいくと一時的なシステム停止も止むを得ずといった懸念
また、クエリ条件の変更であればソース上のみで簡単に対応を行えるということで
条件付与案が採用された。

改修したソースはこちら

```php

    $now = Carbon::now();
    list($yyyy, $mm, $dd) = explode("-", $now->format("Y-m-d"));
    $time = $now->format("H:i:s");

    // バッチ起動時刻
    $executedAt = "{$yyyy}-{$mm}-{$dd} {$time}";

    // チャンクサイズ
    $chunkSize = 1000;

    // バッチ起動時刻よりも過去分を対象データとする
    PointCards::query()->where("created_at", "<", $executedAt)->orderBy("loginid", "asc")->orderBy("shopid", "asc")->chunk($chunkSize, function ($pointCards) use ($file) {
        foreach ($pointCards as $pointCard) {
            $csv = [
                $pointCard->loginid,
                $pointCard->shopid,
                $pointCard->card_number,
                $pointCard->point,
            ];
            // 書き込み
            $file->fputcsv($csv);
        }
    });
```

## 後書き
Laravelの公式から引用

https://readouble.com/laravel/5.8/ja/queries.html

```
chunkのコールバックの中で、レコードを更新／削除することにより主キーや外部キーが変化すると、
chunkクエリに影響を及ぼします。分割結果にレコードが含まれない可能性が起きます。
```

chunk 処理中に内外問わずデータ追加・更新があるとバグっちゃうのね。。

勉強になりました。
a-blog cmsでIFブロックが正しく動作しなかったりページが崩れた場合の原因

![スクリーンショット 2020-12-15 13.44.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21117/fa61ec49-b678-5daf-861f-8a50aefcf94a.png)
しばらくハマったので共有します。
以下の条件でIFブロックが正しく動作しなくなります。

- 条件分岐＝IFブロックの引数にカスタムフィールドを使用している
- カスタムフィールドの値の**改行コードを除去していない**

つまり、該当のIFブロックをレイアウトに使用していると、入力内容に改行コードが入った時点でページが崩れます。

## 経緯

### 発端

リード文を作成するテンプレートを作っていました。カスタムフィールドは仮に *{sample_text}* とします。

複数行フィールド{sample_text}には文字サイズの調整などでspan要素が入る可能性があり、敢えてエンコードしていません（校正オプション *[raw]* を付与しています）。
また、見出しを使用しない可能性があるため、IFブロックで内容が入力されたかの判定を含めています。

```html:acms_if_not_delnl.html
<!-- BEGIN_IF [{sample_text}/nem] -->
<div class="sample-text">{sample_text}[raw]</div>
<!-- END_IF -->
```

### 問題の発生

当初はこれで問題なかったのですが、コードを読みやすくするために改行を入れたら、サイト全体が崩れました。

### 解決

a-blog cmsの校正オプションには、改行コードを除去する *[delnl]* があります。これをIFブロックの引数のフィールドに付与したところ不具合が解消しました。
「空ではない」ことが判明すればいいのですから、最初からこうしておくべきでした。むしろHTMLタグも除去していいかもしれません。

```html:acms_if_delnl.html
<!-- BEGIN_IF [{sample_text}[delnl]/nem] -->
<div class="sample-text">{sample_text}[raw]</div>
<!-- END_IF -->
```

## 参考

- [IFブロック](https://developer.a-blogcms.jp/document/template/if.html)
- [校正オプション](https://developer.a-blogcms.jp/document/reference/proofreading.html)
（UE4）再スポーンしたアクターにphysicsが適用されない

##◇問題
![スクリーンショット 2020-12-21 12.02.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939279/ad7d151a-769f-4cea-9351-99158b0c5de6.png)
玉転がしゲーム制作中。
![スクリーンショット 2020-12-21 12.03.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939279/86e822e3-f414-ebc7-7b37-4f98ac7c35a3.png)
キー入力でスタート位置から新しいボールを生成させてみる。(生成時に古いボールは消える）
![スクリーンショット 2020-12-21 12.02.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939279/8b807ec1-f6ef-b90e-84bf-66c474c860c4.png)
しかし、二個目以降のボールにphysicsが適用されず、スポーン地点で浮いたまま落下してこない。
##◇原因
![スクリーンショット 2020-12-21 12.04.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939279/031b824c-dc5a-2529-39f0-4f0bac1d41d0.png)
ボールのphysicsが、レベルのDetailsで設定されていた。
この設定はあくまで「今、マップ内に見えている物体」に対してである為、アクターそのものに適用されているわけでは無い。
##◇解決法
![スクリーンショット 2020-12-21 12.05.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939279/ca26add6-ac4d-df75-57cf-11bb9e136cf2.png)
レベルの設定に加えてアクター自身のphysicsも設定したら、生成した全てのボールにしっかり適用された。
Pythonで加速度センサのアラン分散計算

#Pythonでアラン分散計算
角速度センサをはじめとするMEMSセンサのノイズ，バイアス特性を知る場合，アラン分散というものが用いられます．
1時間静置する試験から取得したセンサー出力をCSVにまとめ，そこからアラン分散を計算します．

使用言語 python
使用モジュール allantools, pylab, numpy, pandas, csv
環境 windows 10 64bit

#環境構築
以下のコマンドでアラン分散計算モジュールをインストールします．

```
python -m pip install AllanTools
```

#スクリプト例
以下の例では，LOG00.TXTというカンマ区切りのテキストファイルに書き込まれた時系列のセンサー情報を読み取り，そこからアラン分散の計算を行います．



```python
import allantools
import matplotlib.pyplot as plt
#import pylab as plt
import numpy as np
import pandas as pd
import csv

#グラフフォントの設定

col_names = ['a{0:02d}'.format(i) for i in range(15)]       #カラムの名前を指定することで，空データがある場合にもpandas読みこみできる
#txtファイル読み取り，pandas data frame形式に変換．ヘッダー無し，カラム名をcol_names(a0 ~ a15)に指定
df = pd.read_table('LOG00031.TXT',sep=',',header=None, names=col_names)
print(df) 
#該当データの特定列のみ抽出する
sim_time = df.iloc[:,0]
gyro_x_df = df.iloc[:,6]
gyro_y_df = df.iloc[:,7]
gyro_z_df = df.iloc[:,8]
#df(データフレーム形式)からリスト形式に変換
gyro_x = gyro_x_df.values.tolist()
gyro_y = gyro_y_df.values.tolist()
gyro_z = gyro_z_df.values.tolist()
#plt.plot(sim_time, gyro_x)

#-------------------------
#アラン分散計算
#-------------------------
#numpy logspaceではログスケールに均等な配列生成をする
#np.logspace(開始点，終了点，要素数，基数)
t = np.logspace(0, 4, 100)  
#y = allantools.noise.white(10000)  # Generate some frequency data
r = 30 # sample rate in Hz of the input data
(t2_x, ad_x, ade, adn) = allantools.mdev(gyro_x, rate=r, data_type="freq", taus=t)  # Compute the overlapping ADEV
(t2_y, ad_y, ade, adn) = allantools.mdev(gyro_y, rate=r, data_type="freq", taus=t)  # Compute the overlapping ADEV
(t2_z, ad_z, ade, adn) = allantools.mdev(gyro_z, rate=r, data_type="freq", taus=t)  # Compute the overlapping ADEV
#fig = plt.loglog(t2, ad) # Plot the results


#plt.rcParams['text.usetex'] = True
#フォント指定
plt.rcParams['font.family'] = 'Times New Roman' 

#figure()でグラフ表示領域を作る．figというオブジェクトを指定．
fig = plt.figure()
#plt.title('$f(x) = \sin(\pi x)$')
#プロットするグラフの位置指定(高さ2, 幅2, 象限)
ax1 = fig.add_subplot(2,2,1)
ax2 = fig.add_subplot(2,2,2)
ax3 = fig.add_subplot(2,2,3)
#ax4 = fig.add_subplot(2,2,4)

#グラフのプロット（今回はloglogグラフ）
ax1.loglog(t2_x,ad_x, color="black")
ax2.loglog(t2_y,ad_y, color="black")
ax3.loglog(t2_z,ad_z, color="black")
#ax4.loglog(t2,ad)
#グラフに目盛りを表示
ax1.grid(which='minor')
ax2.grid()
ax3.grid()
#グラフ範囲の設定
ax1.set_ylim([0.001,0.01])
ax2.set_ylim([0.0001,0.01])
ax3.set_ylim([0.0001,0.01])
#グラフタイトル
ax1.set_xlabel(r"$\tau$ [s]")
ax1.set_ylabel(r"Gyro X $\sigma(\tau)$ [deg/hr]") #LaTex形式で数式の記述
ax2.set_xlabel(r"$\tau$ [s]")
ax2.set_ylabel(r"Gyro Y $\sigma(\tau)$ [deg/hr]")
ax3.set_xlabel(r"$\tau$ [s]")
ax3.set_ylabel(r"Gyro Z $\sigma(\tau)$ [deg/hr]")

#グラフ表示
#plt.legend()#凡例表示
plt.show()
```
#グラフ
3軸方向の角速度センサー出力のアラン分散です．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/969489/3a1c06a6-bcbe-69e6-6a9a-8bbd38e13fd4.png)
プログラミング学習の過程と感想

![B905DF95-5C0F-4584-AA3F-C4B1E219D3DD.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/958041/d4412a40-31b8-7040-8475-aa6bd92366b5.jpeg)
<課題>
　プログラマーになるためには何をどう学ばなければいけないのか？ プログラマーを目指す際これが一番最初の難題だと思います。

1.スタート
　僕は最初、学習方法をネットで調べeラーニングと言うものがあり、その中でも 「Paiza」「Dotinstall」「Progate」と言うサービスが人気があると言うことを知りました。そこで、僕は物は試しと思い全部やってみて、実際に成果物が作れる「Dotinstall」が良い教材と感じました。

　「百聞は一見に如かず」と言いますが手を動かしながらものを作ることが楽しく効率的に学習できる方法だと思います

2.実践と実感
　学習してきた言語の中でもJavaScriptは覚えやすく作ってると言う感覚を得やすく学んでいて楽しかったです。そこで僕は僕のWebサイトを作り、そこにJavaScriptで作品を作っては都度公開していきました。作っている物のレベルが上るにつれ成長を実感できたのでこの時はとても楽しかったです。
※僕のWebサイト ➡︎　https://borubo.github.io/Portfolio/

　しかし、ここで問題が起こりました。プログラマー界隈の事を調べているうちにフロントエンド（見た目を作る仕事）を目指すと、沢山のデメリット（単価が安かったり、オーダーが右往左往するなど）が有ると知りこのままフロントエンドを目指して良いのか迷いが生まれました。

2.転換と挫折
　そこでフルスタックエンジニア（何でも屋）を目指そうと思いバックエンド（環境構築）の勉強も始めました。ですが環境構築は直感的に分かる物ではなく、状態や状況が理解できなかったり単語や概念の意味もなかなか飲み込めなくて何どもエラーにぶつかります。調べて解決できるものもあれば分からないので違う方法を試したりもしましたが最終的にどん詰まってしまうことがよくありました。

　大半の人はプログラマーになることを諦めるそうですが、それはぶつかる壁が多いからではないか？と思います。壁にぶつかった際の乗り越え方なんて学校では学べ無いですしね . . . .

3.苦痛と逃亡
　今までコンスタントに成果物が作れていたのに急に行き詰まることが増えてしばらく成果物作れなかったために、僕は成長を実感できなくなってしまいました。そこでフロントエンドのスキルとして有効であるBootstrapを学び僕のWebサイトを作り直してみました。やっぱり見た目を作ることは楽しい。ですがこのままでいいのか疑惑が晴れることはありませんでした。

4.認知と教材
　学習の途中でプログラミング系のインフルエンサー（情報発信をしている人）がいることを知りその方々のyoutubeを良く見るようになりました。中でも勝又健太さんと言う方はエンジニア界隈の内容を具体的かつ詳細に発信されており最短でエンジニアに成りたいのであればこの方のアドバイスを実践していけば間違いないと感じました。そこでこの方が書かれた本「Web系エンジニアになろう」を読みました。

　正直素人はIT業界のことなんて全く知らないので、学ぶべきことが分からないのだと思います。だからプログラマーを目指す方は最初にIT業界全体の事を知るべきで、そういう意味では「Web系エンジニアになろう」はとても良い教材だと思います。

5.基礎と教養
　今朝のことなんですが「基本情報技術者」と言う本を読みました。この本にはパソコンやインターネットの動く仕組みからサービスを作る過程までまさにITの根っこの部分をイラストで面白おかしく解説されています。700Pもあり専門的な技術や概念の話もあるので読むのに３日かかりました。

　正直パソコンが動く仕組みを知らなくてもエンジニアにはなれると思いますが、「知識の幅が選択肢の幅になる」と思いこの本を読みました。

　今の時代ITは電気、水と同じく生活インフラと言っても過言では無いので、一般教養として「基本情報技術者」は普及されるべきと感じました。

6.初学者に伝えたいこと
　これからプログラマーを目指す方はまず「Web系エンジニアになろう」と「基本情報技術者」を読むことをお勧めします。その上で目指す物さえ決まれば学ぶべきことが見えてくると思います。
　そして「壁に当たっても砕けるまでぶつかり続けろ！」と言う方もいるかもしれませんが僕が思う最悪なパターンは「嫌いになって諦めること」なので急がないのであれば立ち止まったり振り返ったりしても良いと思います。ただし、時間は有限であり「手遅れ」に成る前に達成しなければならないので「飛び込むタイミング」だけは決めておいた方が良いと思います。「飛び込むタイミング」までにどれだけ準備できるかが大切だと僕自身に言い聞かせながら今日も僕はプログラミング学習を続けています。
IBMCloud vSRX Speed問題

##小ネタ
vSRXの10Gデバイスをオーダしたが、よく見ると1000mbpsになっている。
現在vSRXの最新版は、**Junos: 19.4R2-S3.1**

物理インタフェースの例

```
Physical interface: ge-0/0/3, Enabled, Physical link is Up
  Link-level type: Ethernet, MTU: 1514, LAN-PHY mode, Speed: 1000mbps, Loopback: Disabled, Source filtering: Disabled, Flow control: Disabled, Auto-negotiation: Enabled,
```

rethインタフェースの例

```
Physical interface: reth2, Enabled, Physical link is Up
  Link-level type: Ethernet, MTU: 1518, Speed: 2Gbps, Loopback: Disabled, Source filtering: Disabled, Flow control: Disabled
```

###原因
Juniperに確認したところ、表示上の問題のみであり、実際は10Gbps近い数値がでるようです。
そのうち修正されるので、待つしかない。
様々なコマンドでnlコマンドを代替する

nlコマンドを用いずにテキストに行番号をつける方法をまとめます。あまり細かい挙動にはこだわりません。今回はエディタとスクリプトを除くコマンド編です。


# cat

行番号をつけるコマンドといえば、`nl`よりも`cat`を思い浮かべる人が多いかもしれません。`cat -n`で行番号をつけることができます。

```console
$ yes | head | cat -n
     1	y
     2	y
     3	y
     4	y
     5	y
     6	y
     7	y
     8	y
     9	y
    10	y
```

書式は`rn`です。大きな違いは空行にも行番号がつくことです。つまり`nl -b a`相当の振る舞いをします。



# less
`less`はページャなので対話的に実行されます。しかしながら`nl`や`cat-n`を使う場合もページャを組み合わせることは多いのではないでしょうか。-Nオプションをつけると、`less`単独で行番号を表示できます。
（`スペースキー`や`fキー`で最後まで表示するか、`qキー`で抜けられます）


```console
$ yes | head | less -N
```

一応、1画面内で収まる行数であれば、-Fと-Eオプションを組み合わせることで非対話的に出力させることができるようです。自動的に表示する`-E`だけではうまく表示できませんでした。

```console
$ yes | head | less -E -F -N
      1 y
      2 y
      3 y
      4 y
      5 y
      6 y
      7 y
      8 y
      9 y
     10 y
```

`less`も非常に多機能なコマンドなので、もしかしたら大きなファイルでもすべてを表示する方法があるかもしれません。


# grep

`grep`は-nオプションでマッチした行に行番号をつけることができます。つまりすべての行にマッチさせれば、単純に行番号を出力できます。

```console
$ yes | head | grep -n ^
1:y
2:y
3:y
4:y
5:y
6:y
7:y
8:y
9:y
10:y
```

セパレータは`:`です。桁数でガタガタになるのが嫌な場合は、-Tオプションを使うとタブを入れることができます。しかし、思ったのとはちょっと違うかもしれません。書式はほぼ`rn`になります。

```console
$ yes | head | grep -T -n ^
                   1:	y
                   2:	y
                   3:	y
                   4:	y
                   5:	y
                   6:	y
                   7:	y
                   8:	y
                   9:	y
                  10:	y
```


---

この他にも[シェル芸bot](https://twitter.com/minyoruminyon)などでおもしろい方法を見つけたら追記していこうと思います。
AWS認定 ソリューションアーキテクト-プロフェッショナルを更新してきた


AWS認定ソリューションアーキテクト-プロフェッショナルを更新をしてきたので、
勉強方法等まとめてみます。

# 受験した人
・AWS歴 約5年
・インフラエンジニアではあるが、AWS CLIも満足につかえず基本的にマネジメントコンソール でぽちぽちしている
・AWS CLIも使えないので当然、AWS Lambdaなんて書けるわけもない。
・業務においてAWSにて本番ワークロードで稼働中のサーバ運用や新規構築を担当している。

# AWS認定試験受験履歴
|資格名| 取得日 |
|---|---|
|AWS Certified Solutions Architect – Associate (SAA) | 2016/ 8/29取得|
|AWS Certified SysOps Administrator – Associate (SOA) | 2017/ 5/21取得|
|AWS Certified Developer – Associate (DVA)| 2018/11/17取得|
|AWS Certified Solutions Architect – Professional (SAP)| 2018/ 2/13取得|
|AWS Certified DevOps Engineer – Professional（DOP）| 2020/ 9/25取得| 

今回、受験したSAPの立ち位置はこちら

![スクリーンショット 2020-12-21 12.12.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282630/60d610a2-5635-64d4-2619-67ade5267a87.png)
参照：https://aws.amazon.com/jp/certification/

# 勉強方法

・AWS公式デジタルトレーニング
　https://aws.amazon.com/jp/certification/certification-prep/
・AWS WEB問題集で学習しよう
　https://aws.koiwaclub.com/
・AWS認定ソリューションアーキテクト-プロフェッショナル
<a href="//af.moshimo.com/af/c/click?a_id=1650602&amp;p_id=170&amp;pc_id=185&amp;pl_id=4062&amp;url=https%3A%2F%2Fwww.amazon.co.jp%2Fdp%2FB08F9CQ6LT" rel="nofollow"><img src="https://images-fe.ssl-images-amazon.com/images/I/51VcCPj-1OL._SL160_.jpg" alt="" style="border: none;" /><br />AWS認定ソリューションアーキテクト－プロフェッショナル～試験特性から導き出した演習問題と詳細解説～</a><img src="//i.moshimo.com/af/i/impression?a_id=1650602&amp;p_id=170&amp;pc_id=185&amp;pl_id=4062" alt="" width="1" height="1" style="border: 0px;" />

SAPはDOPとは異なり上記の参考書がでていたので、こちらベースに一通り内容をよみ、「AWS WEB問題集で学習しよう」サイトで問題量をこなしました。
当然、答えを丸暗記してもまるで意味がないので、間違えた問題は参考書の項目やAWSの公式サイトなどで確認を行い理解を深めました。

実はこれ以外にもUdemyのほうも購入したのですが、参考書や「AWS WEB問題集で学習しよう」サイトとの問題との乖離が激しかったため、私はあえて使いませんでした。
結果として、上記の勉強方法のみで合格することができました。

# 受験した感想
受験したところ、難易度が高く、時間がギリギリでした。
75問をひととおり回答した時点で、残り時間が40分しかありませんでした。
またフラグをつけた問題が20問ほどありましたが、見直しを行って試験終了となりました。

また3年前受けたときより、難しくなったように感じました。
次回の更新を考えると恐ろしいですね・・・。

# まとめ
改めて、SAPを受け直しましたが、スペシャリティを除くとやっぱり一番難しいですね。
個人的な難易度としては以下のように感じています。

SAP > DVA > DOP > SAA > SOA

私の勉強方法や難易度などはあくまで個人の感想なので、あてにならないこともあるかと思いますが
参考になればと思います。
Laravel6のAuthでパスワードリセットメールをテキストで送る


いろいろ調べても情報が見つからず、うまく行った方法をメモ。

## 1.オリジナルのNotificationを作成

```
$ php artisan make:notification PasswordResetUserNotification
```

## 2.Userモデルで1のオリジナルNotificationを呼び出すようにする。

(CanResetPasswordトレイトのsendPasswordResetNotificationメソッドをUserモデルでオーバーライドする)

```php:app/User.php
<?php

namespace App;

use App\Notifications\PasswordResetUserNotification;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Facades\Hash;

class User extends Authenticatable
{
    use Notifiable;

    protected $fillable = [
        'name', 'email', 'password',
    ];

   
    protected $hidden = [
        'password', 'remember_token',
    ];

    protected $casts = [
        'email_verified_at' => 'datetime',
    ];
	
    public function sendPasswordResetNotification($token)
    {
        $this->notify(new PasswordResetUserNotification($token));    
    }	
}

```

## 3.テキストメールを送る Mailableクラスを生成

```
$ php artisan make:mail ResetPasswordMail
```

```php:app/Mail/ResetPasswordMail.php
<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class ResetPasswordMail extends Mailable
{
    use Queueable, SerializesModels;
	
	public $subject = 'パスワード変更のご案内';	
	
	public function __construct($user,$url)
	{
		$this->user = $user;
		$this->url = $url;
	}

	public function build()
	{
		$result =  $this->view('emails.reset_password',[
			'user'=>$this->user,
			'url'=>$this->url
		]);
		return $result;
	}
}
```

## 4.テキストメールのテンプレートを作成

```php:resources/views/emails/reset_password.blade.php
{{ $user->name }} 様
<br>
パスワード変更のご案内<br>
次のURLよりパスワードの設定を行ってログインをお願いいたします。<br>
<br>
パスワード設定URL<br>
{{ $url }}
<br>
-----------------------
ホゲホゲ株式会社

```

## 5.PasswordResetUserNotificationをテキストメールを飛ばすように編集

- Illuminate\Auth\Notifications\ResetPasswordを継承してtoMailのみをオーバーライドします。
- toMailでは、toを指定済のMailableオブジェクトをReturnすればOK

```
<?php

namespace App\Notifications;

use App\Mail\ResetPasswordMail;
use Illuminate\Auth\Notifications\ResetPassword;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Illuminate\Support\Facades\Lang;
use Illuminate\Support\Facades\Mail;

class PasswordResetUserNotification extends ResetPassword
{
	public function toMail($user)
	{
		if (static::$toMailCallback) {
			return call_user_func(static::$toMailCallback, $notifiable, $this->token);
		}
		$url = url(route('password.reset',['token' => $this->token,'email' => $user->email],false));
		$mail = new ResetPasswordMail($user,$url);
		return $mail->to($user->email);
	}
}

```
la
「先生！暗号化文字列の復号化が上手くいきません！」「なに！？」

タイトルだけ見ても「なんのこっちゃ」という感じですが、「文字列を暗号化して、DBに格納→DBから取得して、復号化したいのに上手くいかないけどなんで？」という過去の自分を忘れないようにする戒めの記事になります。
# 結論
上記の原因としては、 **暗号化文字列の桁数 > DBの桁数 となっており、DB格納時に切り落とされていたから**です。
つまり、適切な暗号化文字列がDBに格納されていないので、復号化に失敗するわけです。
愚かすぎて笑っちゃいますね。ハハハ

# 関連する箇所のシステム構成
* API (Flask - python）
    * 暗号化モジュール：cryptography
* AWS Lambda（Node.js）
    * 暗号化モジュール：crypto
* Amazon Aurora（DB）

#簡単なシステム間の連携の説明
1. Flask API
    2. 文字列の暗号化
    2. DBへの格納
2. Lambda
    3. DBからデータの取得
    3. 文字列の復号化を行う

※暗号化のアルゴリズムなどの詳細は省きます。

# 事象発生までの経緯と結果
1. Flask API
    2. 成功：文字列の暗号化
    2. 成功：DBへの格納
2. Lambda
    3. 成功：DBからデータの取得
    3. **失敗**：文字列の復号化を行う

失敗した処理の箇所のログを見てみると、以下のようなエラーが。
`TypeError: error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt`

併せてDBから取得した暗号化文字列の方も見てみても、パッと見問題なさそう。（こんな感じになっていた→8e189494ffae.....）

念のため、Flask APIの方の暗号化処理のログと、DBの値も見てみることに。

**すると、暗号化処理のログで出力されている暗号化文字列の桁数と、DBの実際に格納されている暗号化文字列の桁数が一致していないことが発覚・・・**

詳細な事象としては、以下でした。

* DBの桁数（50）に対して、暗号化文字列が64文字
* DBは50桁なので、後ろ14文字が切り落とされる
* Lambdaで復号化する際に、50文字だから復号化に失敗

なので、DBの桁数を100桁まで拡張して、やり直したところ、無事成功・・・

# まとめ
暗号文字列をそのまんまDBに格納するときは、
**DBの桁数と暗号化文字列の桁数をしっかりチェックする！**

失礼しました。
mem_cache_storeでdelete_matchedをできるようにする。

mem_cache_storeはdelete_matchedをサポートしてません。なにか動的に変わるものをキーにIDなどを付与してキャッシュした時、まとめて消すことができず不便だったので、微妙ですが、モンキーパッチ書きました。

## コード

```rb
module MemCacheStoreWithDeleteMatched
  MEM_CACHE_STORE_WITH_DELETE_MATCHED_KEYS = 'MemCacheStoreWithDeleteMatchedKeys'

  def delete_matched(matcher, options = nil)
    options = merged_options(options)
    options[:support_delete_matched] = true
    instrument(:delete_matched, matcher.inspect) do
      matcher = key_matcher(matcher, options)
      key_hash = fetch(MEM_CACHE_STORE_WITH_DELETE_MATCHED_KEYS) { {} }
      key_hash.keys.each do |key|
        delete_entry(key, **options) if key.match(matcher)
      end
    end
  end

  def write_entry(key, entry, **options)
    ret = super(key, entry, **options)
    return ret unless options[:support_delete_matched]

    keys = fetch(MEM_CACHE_STORE_WITH_DELETE_MATCHED_KEYS) { {} }
    keys[key] = nil
    write(MEM_CACHE_STORE_WITH_DELETE_MATCHED_KEYS, keys, support_delete_matched: false)
    ret
  end

  def delete_entry(key, **options)
    ret = super(key, **options)
    return ret unless options[:support_delete_matched]

    keys = fetch(MEM_CACHE_STORE_WITH_DELETE_MATCHED_KEYS) { {} }
    keys.delete(key)
    write(MEM_CACHE_STORE_WITH_DELETE_MATCHED_KEYS, keys, support_delete_matched: false)
    ret
  end
end

module ActiveSupport
  module Cache
    class MemCacheStore
      prepend MemCacheStoreWithDeleteMatched
    end
  end
end
```

## 解説

結構強引ですが、キャッシュの保存時にキーのリストをmemcachedに保存しちゃってます。正確には出し入れ時に検索を早くするためhashでしまってます。

保存・削除時に`support_delete_matched: true`を渡すとキーが保存されてdelete_matchedで削除できるようになります。

```rb
Rails.cache.write(key, 'value', support_delete_matched: true)
Rails.cache.delete(key, support_delete_matched: true)
```

多分削除はdelete_matchedを使うのでdeleteは使わないと思いますが、deleteを呼ぶなら渡さないとキーにゴミが残ります。expireしたキャッシュのキーはそのままなのでリストに残ります。まあ、expireさせるなら`support_delete_matched: true`にすることもないと思いますが。

ちなみに、envで丸っとONにすることも可能です。

```rb
config.cache_store = :mem_cache_store, 'localhost:11211', { support_delete_matched: true }
```


mem_cache_storeはバックエンドで[dali](https://github.com/petergoldstein/dalli)を使用していますが、本家ではキーリストの書き込みにかかる時間でキャッシュの利点が損なわれるという[理由](https://github.com/petergoldstein/dalli/issues/397#issuecomment-51033696)で却下されてます。ただ、キャッシュって読み込み早ければそれでよくない？って気もしますが・・・まあ、使用用途にもよりますか。


確かに書き込みと削除はキャッシュの量が増えるとhashのシリアライズに時間がかかるので遅くなりますね。そこは注意してください。ベンチ載せておきます。

### Bench

```rb
Benchmark.bm 10 do |r|
  r.report "support" do
    10000.times do |num|
      key = "foobar___________________________#{num}"
      Rails.cache.write(key, 'value', support_delete_matched: true)
      Rails.cache.delete(key, support_delete_matched: true)
    end
  end

  r.report "unsupport" do
    10000.times do |num|
      key = "foobar___________________________#{num}"
      Rails.cache.write(key, 'value')
      Rails.cache.delete(key)
    end
  end
end
```

#### 結果

```
                 user     system      total        real
support      7.934330   0.920018   8.854348 (  8.901407)
unsupport    2.024292   0.253793   2.278085 (  2.287548)
```

状況によっては、削除時に、DBに接続して存在する可能性のあるキーを全部生成して削除を試みるのもアリですね。そういうこともあったので、オプションでON/OFFできるようにしてみました。
【gRPC】BloomRPCの使い方。gRPCの処理をサクッと確認する方法。

#【gRPC】BloomRPCの使い方。gRPCの処理をサクッと確認する方法。

個人メモです。

gRPCを使った処理を確認する際に、リクエストURLに対するレスポンスを確認するにはBloomRPCというツールが便利。

##BloomRPCとは？
gRPCの動作をシンプルかつ効率よく検証するために作成されたツール。

主だった処理は以下3stepのみ。

1. [ツールをインストール](#1-ツールのインストール)
2. [protobufファイルの読み込み](#2-protobufファイルの読み込み)
3. [リクエストを実行する](#3-リクエストを実行する)


<br>
##1. ツールのインストール

```:
#mac
$ brew cask install bloomrpc  

#windows
$ choco install bloomrpc
```

https://github.com/uw-labs/bloomrpc



<br>
##2. protobufファイルの読み込み
###2-1 Import Pathsでプロジェクトディレクトリの読み込み
protobufファイルを読み込むためにはまず、Imoprt Pathsでプロジェクトフォルダを読み込む。（protoファイルとサービスを記述したファイルがあるフォルダ）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/42151db4-6a46-e2d9-b7e2-455b817de503.png)
スクリーンショット 2020-12-21 11.44.15


###2-2 protoファイルの読み込み

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/a621f865-3a3d-70c0-9241-79269e9cc02c.png)

.protoファイルを選択肢、開くをクリックすると定義しているrpcが左カラムに表示される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/ad40583b-fa70-1cd0-c8c4-24aa9715b3d8.png)


###2-3 実行したいリクエストを選択
読み込んだリクエストのうち実行したいものを選択。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/55925625-9925-abc4-d5a2-581e892cd349.png)

タブが生成され、引数で渡すメッセージ型が表示される。

> リクエストを複数選択すれば、その分だけタブが作成される。


<br>
##3. リクエストを実行する
###3-1 grpcサーバーを起動しアクセスするURLを入力する。

```:dockerで起動した場合
$ docker ps
CONTAINER ID        IMAGE                       COMMAND                  CREATED             STATUS              PORTS                                            NAMES
96913c74e902        test-dev:latest           "/scripts/docker.grp…"   10 days ago         Up 46 minutes       80/tcp, 0.0.0.0:50151->50051/tcp                 test-grpc
```

ここではgrpcサーバーへのアクセスURLは`0.0.0.0:50151`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/35816ef0-58a9-fdb5-fda4-4c2a2679b9fb.png)

中央上部タブにURLを入力。

> よく使う場合は、任意の名前をつけて保存できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/6225ca6a-2930-7987-b509-11e48be10f5f.png)


<br>
###3-2 リクエストURLを指定し、実行ボタンをクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/2a53c10d-6ea8-a192-9e1b-8b9f431c4d49.png)


右側に実行結果が表示されればOK。
gRPCで意図したデータが取得できているか確認できる。
Senses x LINE WORKS

## はじめに
この度はじめてAdvent Calendarに参加させて頂きました、
株式会社マツリカです。

我々は『世界を祭り化する』をミッションに掲げ、
営業支援ツール『Senses』の開発を行っております。
https://product-senses.mazrica.com/

本日は営業支援ツールSensesとLINE WORKSの連携について書きたいと思います。



## 今回作ったもの
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/874488/6d5b5f1c-4449-5202-6fbf-230424e938ce.png)
LINE WORKSのトーク画面上から、チャット形式でSensesの活動情報を入力できるようになります。
プライベートで使い慣れたLINEのUIからSFAに情報を入力できることで、営業現場の情報入力負荷を軽減されます



## システム構成
各種APIの説明を記載します！今回弊社が開発した、SensesとLINE WORKSの連携で使用したAPIは主に2つで、Senses APIとhachidori APIを使用しています。

hachidori APIの説明
hachidori APIは、hachidori株式会社が提供している、チャットボット内製ツール『hachidori』のAPIです。hachidori APIは、LINE WORKS APIの連携周りの設定などを簡素化してくれます。
hachidoriさんはAPIのドキュメントを公開していないので、ご興味がある会社様はホームページからお問い合わせをお願いいたします！

Senses APIの利用の説明
弊社が開発するCRM SensesのAPIは、こちらに公開されているAPI ドキュメントに書かれている通り、各オブジェクト(取引先, コンタクト, 案件, アクション)を操作することが可能となっています。
今回の連携では、案件アクションを操作(取得, 更新)するAPIを利用しています。



## フロー
今回作成した連携フローは以下の通りです。

1.HOMEにあたる操作ボタンをチャット上に表示
2.「アクション結果入力」ボタンをクリック
3.Senses APIでアクションを取得
4.取得したアクションをボタン形式で表示
5.特定のアクションをクリック
6.「アクションの結果を入力してください」とチャット上に表示
7.ユーザがチャット上にメッセージを送信
8.ユーザが送信したメッセージでアクションの結果を更新
9.正常に登録が完了した場合、「アクションの結果を登録しました」とチャット上にメッセージを表示
10.HOMEに戻る
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/874488/41f9804e-35ce-7f04-c450-c682ca3ef7be.png)



## まとめ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/874488/9f7a863a-fa91-07ef-c6fb-a1378610b353.png)


営業支援ツールとLINE WORKSの連携にご興味お持ちいただけた方は、是非各社無料トライアルをご利用ください！

クラウド営業支援ツール『Senses』
https://product-senses.mazrica.com/

チャットボット内製ツール『hachidori』
https://hachidoriinc.com/

LINEと繋がる唯一のビジネスチャット『LINE WORKS』
https://line.worksmobile.com/jp/
エンジニアでも知ってると得するマーケティング知識

何を目標に開発をすればいいのか、自分の作ったものはどうだったのか、そんな疑問や悩みを解決してくれるのが、マーケティングです！（暴論）

* 自分の作ったものがどうやったらより多くの人に使ってもらえるのか、考えたことありませんか？
* 自分の作ったものがどれほど使われたか、気になりませんか？

それらを数字として可視化しているのがマーケティング郡であり、ツールがFirebaseAnalyticsやGAです。
FirebaseAnalyticsやGAでも使われているだろう、そして社内の企画やマーケターらがよく使っているだろう用語や考え方をまとめました！
これで、話を振られても怖くない！

## そもそもマーケティングとは
>企業などの組織が行うあらゆる活動のうち、「顧客が真に求める商品やサービスを作り、その情報を届け、顧客がその価値を効果的に得られるようにする」ための概念である。また顧客のニーズを解明し、顧客価値を生み出すための経営哲学、戦略、仕組み、プロセスを指す。

引用元：[Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%9E%E3%83%BC%E3%82%B1%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0)

いっぱいのユーザーに使ってもらう、自分の作ったものがどれだけの価値になったかを見るためのモノと解釈しました！


## 覚えておいて損はない用語（集客を除いた）
| 略語 | 正式名称 | 内容 |
|:------------:|:------------:|:------------|
|CV|Conversion|成果|
|CVR|Conversion Rate|問い合わせや購入などの最終成果に結びついたユーザーの割合|
|LTV|Life Time Value|顧客生涯価値<br>そのユーザーが将来までに渡ってどの程度の利益を生むかという予測|
|ARPU|Average Revenue Per User|1ユーザーあたりの平均売上を示す指標<br>売上÷ユーザー数|
|MAU・WAU・DAU|Month/Week/Day Active User|UU（特定の期間内にサイトに訪れた人数）での起動数/アクセス数|
|KPI|Key Performance Indicator|重要業績評価指標<br>目標達成のために必要な進捗やプロセスのうち重要なものを定量的に表した指標|
|KGI|Key Goal Indicator|重要目標達成指標<br>最終的な売上や利益、成約件数などを表す|

「CVが〜」や「LTVが下がって〜」などの単語が聞こえてきても怖くないですね！


## KPIツリーとは
![kpitree.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246668/025cd705-daa3-eeb7-0431-0029530f4c57.png)
KPIツリーは、KGIという目標を頂点として、目標実現のために構成されたKPIとの関係性を、ツリーの形状を使って可視化したもの

## なぜKPIツリー？
* マーケティングだけでなく、どんな問題解決にも使える！
* そもそもKPIツリー自体が、[ロジックツリー（思考フレームワーク）](https://digitalidentity.co.jp/blog/marketing/logic-tree.html#i)の派生系
* KPIツリーができるようになると自身の成長や自分が目指しているところに対して、何が足りないかを可視化できる！
    * 見えない怪物ではなくなる

上記理由から、覚えておいて損はないと思っています！
![スクリーンショット 2020-12-21 11.44.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246668/8e7c4b34-4e66-eb1b-7604-109cb3edfb4c.png)

## KPIツリー作り方
① KGIを1つ決める
　　┗ECサイトなら「売り上げ」、月額課金サイトなら「有料会員数」など
② KGIを頂点に置き、どのような要素に分解できるかを考える
分解の方法は、「ユーザーをセグメントに分解するか」と「行動を分解するか」の2パターン
#####具体的には、
* ユーザーセグメントを「新規訪者」「リピート訪問者」に分解したりする
    * この場合は「足し算」の分解。新規訪問者の売り上げとリピート訪問者の売り上げを足す
    
#####行動の場合、
* 訪問者のうち買った人の割合（購入率）と、買った場合の注文単価とに分解できる
    * この場合は「掛け算」の分解。訪問者数、購入率、注文単価をそれぞれ掛けることで全体の売り上げになる

## KPIツリー注意点
KPIツリーに正解も不正解もない
KPIツリーはあくまで最終目標の内容やそれを達成するための思考やアクションが一目瞭然にするもの
とはいえ、

* 具体的に数値化できる指標
* 計測が可能な指標
* チーム内で合意できる指標
* KGIとの関連性を持つ指標
* 明確な期間設定が可能な指標
* 要素を重複しないこと

↑これくらいは守って！

## KPIツリー具体例
〜ECで売上をKGIとした場合〜
![売上KPI.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246668/ccf00fcd-8f8b-621d-1f2b-0bbf966d0a5e.png)

すごく単純なモノを用意しました。
これ以外にも人それぞれ十人十色であると思います。
（一例くらいに思ってください！）


## 最後に
ここまで読んでくださり、ありがとうございます。
ここでの内容が何か1つでも誰かのきっかけになってくだされば、ありがたいです。
何か疑問や、より詳しく知りたいなどありましたら、コメントや[@gurensouen](https://twitter.com/gurensouen)でご連絡ください！

それでは、ありがとうございました！
node-sassがエラー吐いて困った話

・Node v6.13.1
・gulp v3.9.1
・node-sass v6.14.9

普通にgulpを実行した

```
[10:14:14] 'sass' errored after 94 ms
[10:14:14] Error: The `libsass` binding was not found in C:{hoge}\node_modules\node-sass\vendor\win32-x64-48\binding.node
This usually happens because your node version has changed.
Run `npm rebuild node-sass` to build the binding for your current node version.
    at Object.sass.getBinaryPath (C:{hoge}\src\node_modules\node-sass\lib\extensions.js:158:11)
    at Object.<anonymous> (C:{hoge}\node_modules\node-sass\lib\index.js:16:36)
    at Module._compile (module.js:577:32)
    at Object.Module._extensions..js (module.js:586:10)
    at Module.load (module.js:494:32)
    at tryModuleLoad (module.js:453:12)
    at Function.Module._load (module.js:445:3)
    at Module.require (module.js:504:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (C:{hoge}\src\node_modules\gulp-sass\index.js:186:21)
[10:14:14] Error in plugin 'run-sequence'
Message:
    An error occured in task 'sass'.
```
ダメみたいですね
エラー文にRun npm rebuild node-sassと言われているのでやってみる

```
$ npm rebuild node-sass
```

もう一回gulpしてみる
が、やっぱりダメみたいですね
同じエラーが出たのでちゃんとエラー文を読んでみた

```
The `libsass` binding was not found in C:{hoge}\node_modules\node-sass\vendor\win32-x64-48\binding.node
```

なるほど、それで…？と思いググったところ以下の2記事を発見
https://dev.classmethod.jp/articles/node-sass-could-not-find-a-binding/
https://piitre.com/blog/programming/node-sass-error/
なるほど
<br>

・sassのgitから自環境に応じたAssetsをダウンロード
[Releases · sass/node-sass · GitHub](https://github.com/sass/node-sass/releases)
今回は「C:{hoge}\node_modules\node-sass\vendor\win32-x64-48\binding.node」って書いてあるので「win32-x64-48」をDL

・DLしたbinding.nodeを配置
C:{hoge}\node_modules\node-sass\vendor\win32-x64-48\
※DL時ファイル名が「{ver}_binding.node」になっているので、verを消して「binding.node」にする

```
[10:16:02] Finished 'version' after 669 ms
[10:16:02] Starting 'browserSync'...
[10:16:02] Finished 'browserSync' after 127 μs
```
よし
RubyonRails:acts-as-taggable-onのN+1問題を解決する

# 環境

```rb
Rails.version
=> "5.2.4.1"
ActsAsTaggableOn::VERSION
=> "6.5.0"
```

```rb:model
class Model < ApplicationRecord
  acts_as_taggable
end
```

# 解決策

N+1を解消するためには`includes(:tags)`を使った上で、[tag_listではなく、tags][1]を呼ぶこと

```rb
# tagsを呼ぶこと
Model.includes(:tags).each{|m| m.tags }

# acts_as_taggable skills などとした場合
Model.includes(:tags).each{|m| m.skills }

# tag_listを呼んでしまうとN+1がどうしても発生してしまう
# Model.includes(:tags).each{|m| m.tag_list }

# tag_listと同じにするには ...
Model.includes(:tags).each{|m| m.tags.map(&:name) }
```


[1]: https://github.com/mbleigh/acts-as-taggable-on/issues/91#issuecomment-668683692
[100%] Distinct (codility lessons)

> _Painless_
> ### [Distinct](https://app.codility.com/programmers/lessons/6-sorting/distinct/)
> 配列内の個別の値の数を計算します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196344/ad17e896-b235-68cd-b85a-2caa588d4bca.png)



#### タスク説明

関数を書く

`class solution {public int solution(int [] A); }`

これは、N個の整数で構成される配列Aが与えられた場合、配列Aの個別の値の数を返します。

たとえば、次のような6つの要素で構成される配列Aがあるとします。

```js:例
  A [0] = 2 A [1] = 1 A [2] = 1
  A [3] = 2 A [4] = 3 A [5] = 1
```

配列Aには1、2、3の3つの異なる値が表示されるため、関数は3を返す必要があります。

次の仮定のための効率的なアルゴリズムを記述します。

* Nは[0..100,000]の範囲内の整数です。
* 配列Aの各要素は、[-1,000,000..1,000,000]の範囲内の整数です。
 
---

#### 解く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196344/a10a9af5-2405-f298-45b7-b607a825305e.png)

#### Program【案1：KV】
[DistinctSolution.java](https://github.com/yp2211/algorithm/blob/main/src/codility/lessons/Lesson6_Sorting/Solutions/DistinctSolution.java)

```java:KV
    public int solution(int[] A) {
        java.util.HashMap hm = new java.util.HashMap();
        for (int i = 0; i < A.length; i++) {
            hm.put(A[i], true);
        }
        return hm.size();
    }
```

Detected time complexity:

O(N*log(N)) or O(N)

#### jUnit
[DistinctSolutionTest.java](https://github.com/yp2211/algorithm/blob/main/test/codility/lessons/Lesson6_Sorting/DistinctSolutionTest.java)

#### Report1
[trainingC9WE4Y-E39](https://app.codility.com/demo/results/trainingC9WE4Y-E39/)

---
#### Program【案2：Bucket】

```java:Bucket
    public int solution(int[] A) {
        int goal = 0;
        int[] B = new int[2000001];
        for (int a : A) {
            B[1000000 + a]++;
        }

        for (int b : B) {
            if (b > 0) goal++;
        }

        return goal;
    }
```

Detected time complexity:

O(N*log(N)) or O(N)

#### Report2
[trainingKM7K8S-X97](https://app.codility.com/demo/results/trainingKM7K8S-X97/)

#### 著者注
実際の業務では、通常、アルゴリズムを決めることは具体的な業務を考えなければならないでしょう。  

* 仮に、ほとんどのシナリオで、データが少ない場合、上記の案1はメモリの節約で更に適用だと思う。
* 逆に、データの量がいつも多い場合は、案2の方が効率的だ。

> 实际业务中，通常要根据具体情况决定选用哪种算法。当业务中多数情况为少量数据时，上文案1更节约内存；相反，若大多数情况下都是大数据量，那么案2更高效。

***

### See also: [CodilityのLessonsをすべて解く（更新中）](https://qiita.com/yp2211/items/537f733060bb0f2aba8f)
番号付きリストの書き方

#はじめに
番号付きリストを使ってみたのだが、間にソースコードを入れると番号がリセットされてしまう。
今回はその解決法。
HTMLを知らないため、正式な書き方でないかもしれません。
[(参考サイト)](https://qiita.com/nutti/items/6d01b701d636b6a6b564)


#実現したいこと
　
<ol><li> いち

```
code
```

<li> に
<li> さん
</ol>


#書き方

```
(全角スペース)
<ol><li> いち

/```
code
/```

<li> に
<li> さん
</ol>
```

# ポイント
- 途中の `/` はいらない（都合上記述）
-  `<li>` で番号付きリスト
-  `<ol>` `</ol>` で番号をリセット


#まとめ
でもなんか、謎の空白が生まれるなぁ。
`1. ` を使う方法も覚えておきたい。
githubにある.ipynb ファイルをgoogle colabで実行する最速な方法

#githubにある.ipynb ファイルをgoogle colabで実行する最速な方法

自分用。なぜか検索してもgit cloneする記事しか出てこないので。

githubの.ipynbのURLの"https\://github.com"を"http\://colab.research.google.com/github"に置き換えて再度アクセス。以上。

例　
https://github.com/USC-InfoLab/rddc2020/blob/master/yolov5/tutorial.ipynb
->
http://colab.research.google.com/github/USC-InfoLab/rddc2020/blob/master/yolov5/tutorial.ipynb

参考
https://colab.research.google.com/github/googlecolab/colabtools/blob/master/notebooks/colab-github-demo.ipynb#scrollTo=WzIRIt9d2huC
ウェブサイト作成用備忘録・９号：クロスブラウザコーディングとの戦い…その２

苦労してHTMLを書き上げて、Google chromeのプレビューで正常に表示されていても、戦いはまだまだ終わらない…
今度こそedgeやIEで確認してみても、思ったように表示されない…

今回もそのような事態に遭遇した時の状況と、どのように解決したのかを記録していこうと思います。

####記事作成時の各ブラウザのバージョン<br>Google chrome：87.0.4280.88<br>Internet explorer：11.1480.14393.0<br>Microsoft EdgeHTML：14.14393<br>Firefox：83.0

---
####Ｑ・font-size をディスプレイの横幅と連動させる為に font-size: 〇〇vw と設定したら、ブラウザの拡大率を変更する際に 〇〇vw で設定した文章が拡大・縮小されず、サイトのデザインが崩れてしまった。
###Ａ・font-size を〇〇vw と設定した場合、ブラウザの拡大率に関わらず、常にディスプレイの横幅と連動した大きさで表示されてしまう。ブラウザの拡大率を変更した際にフォントサイズの拡大・縮小に対応させつつディスプレイの横幅にも連動させる為には、font-size: calc(〇rem + 〇vw) の様な設定を行う。

###※更に calc() は IE で反映されない場合がある為、font-size: 〇〇rem; の後に font-size: calc(〇rem + 〇vw); を設定する等、calc() が反映されない環境でもデザインが崩れないような工夫が必要となる。
---
####Ｑ・flexアイテムに設定した margin-bottom: 5% が edge では反映されなかった。
###Ａ・バージョンの古い edge、Firefox では flexアイテムに margin、padding のtop、bottom に%単位の値を設定すると正常に反映されないバグが存在する為、%以外の単位を設定するor flexアイテムに疑似要素(::after)を加え、疑似要素のCSSに margin-bottom: 5% を設定するor flexアイテムの子要素（Flexbox の孫要素）に margin-bottom: 5% を設定する等、状況に応じて対処する。  
---
####Ｑ・文章を縦書き＋中央寄せで表示させる為、&#60;p>タグにcss writing-mode: vertical-rl(tb-rl) ,margin: 0 auto を設定したが、Google chrome 以外では margin: 0 auto が機能せず、左寄せで表示されてしまった。
###Ａ・縦書きで表示した文章は要素がFlexアイテムでなくとも[（その１）](https://qiita.com/suzzzki/items/7dfddbccfd7cd1012324 "ウェブサイト作成用備忘録・８号：クロスブラウザコーディングとの戦い…その１")同様に margin: auto が正常に動作しない場合が多い為、縦書きで表示する&#60;p>タグの親要素に display: flex, flex-flow: wrap, justify-conntent: center と設定するか、親要素に text-align: center、&#60;p>タグに display: inline-block, text-align: left と設定することでも対処出来る。
---
####Ｑ・Flexアイテムかつ、子要素にCSSで元画像よりも小さく表示されるように設定した&#60;img>タグを持つ要素のheightの値が、IE でのみ縮小前の画像のheightの値を引き継いで表示されてしまった。
#####（元画像の高さ1000px、CSSで500pxに縮小、ブラウザ上では&#60;img>タグの高さは500px、親要素が1000pxの状態で表示され&#60;img>タグの下に500pxの余分な空白が表示される）
###Ａ・IE では flex-direction に column や column-reverse を指定した子要素に画像があると、その子要素に画像の元サイズの高さ分のスペースができてしまう。このバグは対象の子要素にCSSで min-height: 0% を設定する事で対応が出来る。

---
今回は以上になります。
誰かの参考になれば、幸いです…
kabuステーション®API - PUSH APIのティックデータからローソク足データを作成する

# 概要

　[前回](https://qiita.com/shirasublue/items/9038b187ef465019d31c)、ロガーの作成とティックデータの表示を行ったが、保存したティックデータから取引等で一般的なローソク足を作成する。なお、主なコードは[前回コード部2項](https://qiita.com/shirasublue/items/9038b187ef465019d31c#2-%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%81%BF%E8%A1%A8%E7%A4%BA)を流用する。

# 環境

- Ubuntu 20.04.1 LTS
- Python 3.8.5

# 追加パッケージ

- mplfinance

# コード

 [前回](https://qiita.com/shirasublue/items/9038b187ef465019d31c#2-%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%81%BF%E8%A1%A8%E7%A4%BA)からの追加・変更部分

## 冒頭

```python
import mplfinance as mpf

from datetime import datetime, timedelta, timezone

JST = timezone(timedelta(hours=+9), 'JST')
```

## 末尾

```python
# 1分足の生成
candle_df = tick_df['price'].resample('1Min').ohlc()

start = datetime(2020, 11, 26, 9, tzinfo=JST)
end = datetime(2020, 11, 26, 10, tzinfo=JST)

# mpf.plot用タイムゾーン処理
candle_df_slice = candle_df[start:end].tz_localize(None)

# 画像ファイルの書き出し
mpf.plot(candle_df_slice,
    type='candle', figratio=(12,4), style='yahoo', savefig='candle.png')

# CSVデータの書き出し
candle_df[start:end].to_csv('1Min-ohlc.csv')
```

# 保存されたグラフ

`201126-8306-candle.png`

![201126-8306-candle.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405755/2523ae1a-a5a5-bc82-5114-21a2b23a7f02.png)

# 参考リンク

- [pandas, Matplotlib（mplfinance）でローソク足チャートを作成](https://note.nkmk.me/python-pandas-matplotlib-candlestick-chart/)

# 関連記事

- 次回：*未定*
- 前回：[kabuステーション®API - PUSH APIから情報を取得・保存し、表示する](https://qiita.com/shirasublue/items/9038b187ef465019d31c)