OmniAICreator/Qiita-1.07M huggingface dataset:
React-Routerでサブディレクトリに配置

###サブディレクトリにビルドしたい
例えば記事サイトのドメインがあるとして、
`/article`以下に`React`のプロジェクトを置きたいと思った時

####普通にビルドして配置すると・・・
・`○○.chunk.js`などの向き先が全部ドメイン直下だったり、
・`Link`で遷移しようとしたら、おかしなページに行ってしまったり。

####解決方法は色々出てくる
・`basename='/article'`入れるらしいけど、ドコに書けばいいんだ？
・`webpack.config.js`の`output:`の中かしら？
・`cross-env`で`build`の後ろに書くのかしら？

ネットで調べるとサブディレクトリに置く方法は色々あり、どれが正解か分からないッス。
`Switch`の中に書いてみたり、`Route`のタグに書いてみたり、
`Link`の中身のURLを書き換えてみたり、と小一時間迷ってしまいます。

###結論:`<App/>`を囲んでるhistoryの書き方を変える
環境によって違うかもですが、一番上の階層にあるファイルで
`history`を読み込んでる所があると思います（ないかもですが）
そこを書き換えます。

```
yarn add history
```

```app.js
- //import history from 'utils/history';
+ import createBrowserHistory from 'history/createBrowserHistory';
```

```app.js
+ const history = createBrowserHistory({ basename: '/article' }); //←ココに追加する
const render = () => {
  ReactDOM.render(
    <Provider store={store}>
      <ConnectedRouter history={history}> //←ココに「history」がある、と思う。
        <App />
      </ConnectedRouter>
    </Provider>,
```
私の場合はこれで解決しました。
`create-react-app`の場合は、npmスクリプトに書くように書いてあったので、
そっちの場合はちょっとよくわからないです。

参考資料を見る限りだと、`Router`や`BrowserRouter`でも動きそう。
`redux`がある場合`<Provider>`と`<App/>`でサンドイッチにする感じ。

以上です。
###参考資料
https://stackoverflow.com/questions/47580538/react-router-v4-basename-and-custom-history
【Zabbix】snmptrapでの監視設定

# はじめに
Zabbix4.0でsnmptrapの監視方法を記載します。
Zabbix画面上だけでなく、設定ファイルを変更するものが多かったので、まとめました。
変更する設定ファイルは以下の4つです。

* /etc/zabbix/zabbix_server.conf
* /etc/snmp/snmptrapd.conf
* snmptt.ini
* snmptt.conf

ほとんどこのサイトをもとに設定しました。
このサイトを見て、設定したい頂いたほうがわかりやすいし、早いです。
[https://www.miraclelinux.com/product-service/zabbix/tech-lounge/zbx-tl-001] 
最低限の設定だけ記載します。


### 事前準備
* Zabbixのインストール
* snmpttのインストール

### /etc/zabbix/zabbix_server.conf
zabbixサーバの動作を設定するファイルです。
SNMPTrapperの有効化とsnmptt.logの出力先を指定します。  

```
#StartSNMPTrapperの有効化
StartSNMPTrapper=1
#snmptt.logの出力先
SNMPTrapperFile=/var/log/snmptt/snmptt.log
```
/var/log/snmptt/snmptt.logはsnmptt.iniと同じにする必要ある。

### /etc/snmp/snmptrapd.conf
snmptrapdの動作を設定するファイルです。
snmptrapをsnmpttに渡すように設定し、認証の無効化を設定します。

```
# snmptrapをsnmpttに渡すように設定
traphandle default /usr/sbin/snmptthandler
#　認証の無効化を設定
disableAuthorization yes
```
コミュニティ名で認証する場合は以下のように設定します。

```
# snmptrapをsnmpttに渡すように設定
traphandle default /usr/sbin/snmptthandler
#　コミュニティ名pubblicで認証する。
authCommunity log,execute,net public
```

### /etc/snmp/snmptt.ini
snmpttの動作を設定するファイルです。  

```
#NET-SNMP のPerlモジュールを有効化
net_snmp_perl_enable = 1
#日付と時間のフォーマットを設定。
date_time_format = %Y/%m/%d %H:%M:%S
#ログファイルの場所
log_file = /var/log/snmptt/snmptt.log
```
/var/log/snmptt/snmptt.logはzabbix_server.confと同じにする必要ある。


### /etc/snmp/snmptt.conf
snmpttのログの整形方法をしていします。 
Zabbixでsnmptrapが確認できなければ、個々の設定が間違っている可能性が高いです。

以下の設定規則で記載します。

```
EVENT <event_name> <OID> "category" severity
FORMAT format_string
```

### Zabbix上の設定
以下のサイトを参考にしてください。
[https://www.zabbix.com/documentation/4.0/manual/config/items/itemtypes/snmptrap] 
[https://www.miraclelinux.com/product-service/zabbix/tech-lounge/zbx-tl-001] 


### サービス起動
以下のサービスを起動してください。

* snmptrapd
* snmptt
* zabbix-server

### まとめ
上記に簡単に記載しましたが、設定する項目が多くなかなかうまくいきませんでした。
次回は上手くいかなかった対処方法を記載したいと思います。

上手くいかなったときの対処法を以下に記載しました。
https://qiita.com/shiojojo/items/dd7e663f2bae40b98266


### 参考文献

[https://www.zabbix.com/documentation/4.0/manual/config/items/itemtypes/snmptrap] 
[https://www.miraclelinux.com/product-service/zabbix/tech-lounge/zbx-tl-001]
【初心者に最適】なぜ我々はRPAに頼るのか。いまだに誰も教えてくれないエンジニアが使うべき自動化ベストプラクティス(2020年03月時点)


[なんでこんなクド過ぎるタイトルなのかは前回をご参照ください。](https://qiita.com/ykato/items/03306aaa55d091d61d9b)

記事としては**業務経験に漬け込んだ自動化のツール作ったので見てマサカリでも良いから感想欲しいです！という内容**です。*興味無ければそっ閉じお願いします。*

とりあえず、こんなの作ったので見て！

[opsapi](https://github.com/yasutakatou/opsapi)

![demo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189193/2f1d60da-be12-552d-043b-fef169730151.gif)


　リポジトリに書いてありますが、オジサンが中学生英語で書いたものをさらにオジサン意訳しますね！

## 前説

　定期的な申請とかeラーニングみたいなただ手を動かすメンドクサイ仕事ありますよね？
あなたは人力でどうにかしなきゃならないし、また同僚もおんなじタスクをしなきゃならない。ちょっと使いこなすのにもノウハウがいる。時間がもったいない！

　RPAとかプログラミング、OS標準スクリプトとか解決方法はあるけど、環境を構築しなきゃならないし、工数はかけたくない。やり方の共有も要るから簡単じゃないよね。

　パパっと手早くなんとかしたい。いっそのこと「ちと借りるねー」って同僚のPC遠隔から動かしたって構わないんじゃない？このツールはそんな気持ちに応えます。

## 特徴

 - Go言語で書いたのでバイナリ一個で環境整備要らんです。
 - WindowsとLinuxの両方のOSで動きます。
 - ハードウェアのキーボード操作を再現します。
 - 操作毎にエビデンス撮れますし、さらに操作をずっとアニメGIFで録画しておく事もできます。
 - 通信覗かれると困る用にHTTPSに対応しています。

　インストールはソースコンパイルか、パスが通ったとこに[バイナリ](https://github.com/yasutakatou/opsapi/releases)を置いて、アンインストールは消すだけです。

　使い方としてはCLIモードで起動して自動化したいウィンドゥをツールから操作して操作履歴(history)をためるか、liveRecordモードで操作を裏で記録するかします。

　そのhistoryをエクスポートして配布して再生(runHistory)するか、操作対象をAPIモードで起動して遠隔からAPIを叩いて操作してあげるかで自動化します。APIはトークンで守ってください。

　CLIモードはシェルとおんなじで↑で前入力を辿れますし、TABで入力補間もできます。historyはCLIモードから編集できます。

![cli_mode.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189193/a17b85b1-d31d-780c-c46b-a0ee31000405.gif)

　SIerらしくあてがわれている端末が貧弱な事を鑑みて、操作毎やキャプチャのタイミングに各種ウェイトがかけれます。[configのリファレンス](https://github.com/yasutakatou/opsapi#config)を見てください。

## こんご

　マウスも制御できなくはないけどOCRな処理を入れるとゴテゴテになってしまう。あまうりうまく動く気もしない。

　websocketでgitと連携したりしてリポジトリからhistoryをpush/pullするのもチームコラボレーションとしては面白そう！

とか追加機能もありそうだけど、今のところ、このくらいのシンプル感でどうでしょうか？

~~まあRPAなんとかしてーな人はそもそも黒い画面嫌いだろうから使えようがないツールな気もするし。(ここにきて弱気)~~

## あとがき
<details>フロントエンド記事以外がウケない理由として、Web系以外はポートフェリオって概念が無いのがあるかなー。Max Howellさん(Homebrew作者)の実績をもってもgoogleには受からないわけで。k8sの運用実績とかはアリでも、こういうツール作ったの！では転職に役に立たなそうなんだよな。ウデを見るのならバックエンド欲しがってる会社は見てくれても良いと思うけどないよなー。qiitaがそういう文化じゃないからかな。ボコられてもチラ見てしてくれるとしたらどのサイトが良いかstackoverflowなのかどこなのかわからなかった。もしご存じでしたら教えて頂きたいです。</details>
LaravelのRequestクラス(入力の取得)

Requestクラスの入力値の取得に関するメソッドのメモです。
基本的には公式リファレンスの内容を書いているだけですので、詳しくはそちらをご覧ください。
https://readouble.com/laravel/5.8/ja/requests.html

###all()
すべての入力値を連想配列で取得できる。クエリストリング、アップロードファイルも取得する。

```php

$input = $request->all();
```

###input()
添付ファイルを除く、すべての入力値を連想配列で取得。

フォーム上のフィールド名を引数にとり、限定して取得できる。

```php

$name = $request->input('name')
```

###query()
入力をクエリストリングで取得。input()と同じく引数も渡せる。

```php

$name = $request->query('name');
```

###動的プロパティによる取得

```php

$name = $request->name;
```
アップロードファイルも取得可能。

###only(),except()
入力の一部取得。基本的にはall()を使っているため、アップロードファイルの取得もできる。

```php

$input = $request->only('username', 'password');

$input = $request->except('credit_card');
```

###file()
アップロードファイルを取得。
動的プロパティによる取得も可能。

ファイルの有無を判定するにはhasFile()を使う。

```php
$file = $request->file('photo');

$file = $request->photo;

if ($request->hasFile('photo')) {
    //
}
```
C言語　リンクリスト構造を使った数字のリスト

ポインタの概念を理解するには、リンクリスト構造を使ったプログラムを書くことが良いらしい。

なので書いてみた。

###書いたコード

```c
#include <stdio.h>
#include <stdlib.h>

typedef struct List List;
struct List
{
    int number;
    List* next;
};

List* addListNotFirst(List* list, List* newList);
List* addList(List* list, int n);
List* displayList(List* list);
void deleteAll(List* list);

int main(void)
{
    List *list;
    list = NULL;
    list = addList(list, 30);
    list = addList(list, 33);
    list = addList(list, 35);
    list = addList(list, 36);
    list = addList(list, 38);
    list = displayList(list);
    deleteAll(list);
    return 0;
}

List* addListNotFirst(List* list, List* newList)
{
    List* first = list;
    while(list->next != NULL){
        list = list->next;
    }
    list->next = newList;
    return first;
}

List* addList(List* list, int n)
{
    List* newList;

    newList = malloc(sizeof(List));
    newList->number = n;
    newList->next = NULL;

    if(list == NULL){
        list = newList;
        return list;
    }
    return addListNotFirst(list, newList);
}

List* displayList(List* list)
{
    List* first = list;
    while(list != NULL){
            printf("%d\n",list->number);
            list = list->next;
        }
    return first;
}

void deleteAll(List* list)
{
    List* tmp;
    while(list != NULL){
        tmp = list->next;
        free(list);
        list = tmp;
    }
}
```

##他の人が書いたコードの一部を見て気づいたこと。
#####参考にしたコード
リスト構造をC言語プログラムの実例を用いて解説 | だえうホームページ
https://daeudaeu.com/programming/c-language/list-structure/


#####【振り返り用：最初に自分が書いたコード】リンクリスト構造を使った数字のリスト
https://qiita.com/Kchan_01/private/25ce654df5115cbfa0e1


#####最初、変なwhile文の使い方していた

```c
List* displayList(List* list)
{
    List* first = list;
    while(1){
        if(list != NULL){
            printf("%d\n",list->number);
            list = list->next;
        } else {
             break;
        }
    }
    return first;
}
```

#####変数宣言が関数の頭に来ていなかった
そもそも使わない変数を宣言していることがキモチワルイ。関数をわけて使わない変数を宣言しないようにした。

```c
List* addList(List* list, int n)
{
    if(list == NULL){
        list = addListFirst(list,n);
        return list;
    }

    List* first = list;
    List* tmp;
    while(1){
        if(list != NULL){
            tmp = list;
            list = list->next;
        } else {
            list = malloc(sizeof(List));
            list->number = n;
            tmp->next = list;
            break;
        }
    }
    return first;
}
```


#####リスト内のポインタ初期化してなかった

```c
List* addListFirst(List* list, int n)
{
    list = malloc(sizeof(List));
    list->number = n;
    // 追記したコード
    list->next = NULL;
    return list;
}
```


###参考

リスト構造の操作
http://www.cs.shinshu-u.ac.jp/Lecture/Prog2/9/list-ope.html
ディープラーニングを活用してパーティアタック的な成長戦術を考えた

# あらまし

先日、

*「色々アウトプットをしようとしていてQiitaにぼちぼち記事を書いているけど、フロントエンドじゃなくて、バックエンド、さらにいうとSIerに近い記事が好まれないのか意見をもらえないのでうまくいっていない」*

と会話したら

*「(自らの)行動が足りないからじゃないですか？」*

という返事が。

？？？？

Qiitaに記事書くのはアウトプットにはならない？？

　SIerらしくロビー活動して人海戦術で記事を見ていいね！してもらいなよ、という意味なのか？？そうじゃなくて数値化できるからスコアにはなるとしても、単純にいいね！をもらいたいのではないイケてないならマサカリでいざ神妙にカチ割られたい。再起不能になろうとも。**そうじゃないとピボットできない、ので成長もできない。**それよくない。

　えーっと、「愛の反対は憎しみではなく、無関心[^1]」ってありますよね。つまり、マサカリは愛(≒いいね！とか)の反対ではないのではないのだろうか。炎上記事を見ると内容に問題があるのもあるけど、それ以上にコメント欄がレスバだったりしてるケースが多いように思える。

　マサカリでもいい、声が欲しい。でも、僕には借りるべき人力が無い。周りにプログラムに興味がある人なぞ居ない。いっそのこと人力でなく、**コンピューターの力を借りていいね！記事を機械学習でどうにかして読んでもらえるタイトルを作ってもらえれば、見て、なんか書いてもらえるのかも？**

### どんどんブラックハット臭がしてきた。圧倒的ドンマイ感。笑

# そんで

[コードが書けない猫でもできるDeepLearningの文章自動生成(+ColaboratoryのTipsとSnippet)](https://medium.com/eureka-engineering/colaboratory-e8634e7836fa)

　これを使わせて頂く。3層LSTMだそうで。BERTを使おうかと思ったけど、手っ取り早くColaboratoryで動きそうなのを探してきた。(そこ手抜きしない方が良いような)
 遊びレベルなのでマルコム連鎖を使うべきなんですが、**「コンピューターの力を借りて」**気分を出したいのでtpu+tensorflowのを選びました。笑

Colaboratoryがこのままだと動かないので[plotly.plotlyをchart-studio.plotlyにするのと](https://github.com/plotly/plotly.py/issues/1660)、[!pip install tensorflow==1.13.1を最初のあたりで実行してあげてください。](https://teratail.com/questions/201440) (要ランタイム再起動)

学習ネタは以下から抜きました

[【2019振り返り】Qiitaのいいね数ランキング TOP100](https://qiita.com/m_kumamomi/items/0c52289d583da9099600)
[Qiitaのいろいろランキング2018](https://qiita.com/t_nakayama0714/items/865da4afde5e0600187c)

TPUさんにちろ回っていただいて。こんなんでました。10個抜粋

```
(2019年改定版)
Roassを年つしリュるぬる動くポートフォリオサ
VSCode)
[翻訳]あなたがプログラミングに
「機械学習
【2019年4月版】JavaScript解説サイ
こを作ったのでソースと解説
ディープラーニングさ
世の中のエンジニアのali
君には1時間でGitについて知
```

ゼンゼン文章にはなってないんですけど、まとめるとAI曰く、見てもらえるタイトルは

|脅し系|キュレーション系|初心者向け系|
|:-----------|:-----------|:-----------
|xxを使うな|xx選|ベストプラクティス
|誰も教えてくれない|yyyy年の|気づき
|なぜ我々は|yyyy年mm月時点|エンジニアが
|いまだに||【xxxx(肯定文)】※未経験でも挫折しないとか

　ということなんですよ！完全に文章生成してはいないのでAI使う意味あんのか！となりそうですが、まあ特徴量をAIが選んだって事にオトしておきます。

では早速いつものSIer向けの記事をこの要素を取り入れたタイトルで書いてどうなるか！？

次回に期待！！

次回↓

[【初心者に最適】なぜ我々はRPAに頼るのか。いまだに誰も教えてくれないエンジニアが使うべき自動化ベストプラクティス(2020年03月時点)](https://qiita.com/ykato/items/b9a2e47341e51be9f702)

クド過ぎる・・

[^1]: [マザー・テレサとは関係ないらしい。「“元凶”は、1981年のACジャパン広告か」。なるへそ。ミレニアル世代が知らないわけだよ。]]
ABAPを思い出す(テーブル編/PS系)

以前の現場では主にFI/CO周りをやっていましたが、少しぐらいはPS関係のテーブルも見ていたので、思い出しつつ。
なお、欠落した記憶の穴埋めに以下のサイトを参考にさせていただきました。ありがとうございます。
[SAP Fan](http://www.sapfan.jp/)
[SAP ABAP Development objects and example code](https://www.se80.co.uk/)

# テーブル

## PROJ
プロジェクト定義マスタ。

プロジェクト名や、原価センタ、利益センタ、開始日などの情報を管理している。
CJ01, CJ02, CJ03, CJ20N

## PRPS
WBS要素マスタ。

プロジェクト定義マスタにぶら下がる形で作成される。
PROJ(1)に対し、PRPS(n)の関係。(PROJ-PSPNR = PRPS-PSPHI)

ツリー構造となっている。

```:
Lv1 ─┬─ Lv2 ─┬─　Lv3 ...
     |       └─  Lv3
     ├─ Lv2 ─┬─  Lv3
...
```

CJ01, CJ02, CJ03, CJ20N

### 内部書式と外部書式
SAPシステムはそのシステム内部で保持する形式(書式)の値と、外部に見せるための形式(書式)があります。

会計伝票を例にします。
会計伝票(内部)：0012345678
会計伝票(外部)：12345678

このように、内部書式では前ゼロありですが、外部書式では前ゼロなしとなります。

PSでのプロジェクト番号/WBS要素番号も同様に内部/外部書式があります。
PSPNR(内部書式用)と、PSPID/POSID(外部書式用)です。

注意点として、アドオンテーブルにプロジェクト/WBS要素番号を持たせる場合は、内部書式を持たせるようにしましょう。
なぜなら、**外部書式は変更(更新)できてしまうためです。**

例えば、アドオンテーブルのキーをプロジェクト番号(外部書式)で持たせており、アドオンテーブルへ登録した後に、外部書式が変更された場合。
この場合、キーの紐付きがわからなくなってしまいます。

内部書式は、一意な値でかつ、変更もできません。なので、上記のような問題は発生しません。
(削除されたら別ですが...まぁそれはそれで...)

プロジェクト/WBS要素番号を外部書式で出力したい場合は、専用の変換FMを使用するか、PROJ/PRPSより内部書式+外部書式を抽出し、それに対しREAD BINARY SEARCHを行い取得させるなどの手段を検討しましょう。

以下、余談。
件数が少なければFMで十分ですが、多くなるとオーバーヘッドが問題となります。
(FMで行っている処理そのものは大したことがなくても、実行回数が多くなると...)

要件、想定件数などを加味し、どちらが良いか検討しましょーね。

## JEST
プロジェクトステータス。
そのプロジェクトのステータス(有効/無効、CRTD/REL/CMPL etc)を管理するためのテーブル。
このテーブルが持っているのはコード値なので、テキストを取得するには別のテーブルを参照する必要があります。

## JCDS
プロジェクトステータス履歴。
履歴テーブル。以上です。

### ステータス
ステータスには、システムステータスとユーザステータスの2種類あります。

システムステータスは、SAPシステムで管理しているステータス。
ユーザステータスは、ユーザ(会社)独自で定義するステータス。

TJ02(システムステータス)、TJ30(ユーザステータス)および、TJ02T(システムステータステキスト)。TJ30T(ユーザステータステキスト)です。
なお、プロジェクトプロファイルもキーに含まれていますので、直接テーブルから抜く際は考慮が必要です。

## PROJS？(思い出せない)
標準プロジェクト定義マスタ。

プロジェクト定義を登録する際に、テンプレートとして事前に用意することができる。
CJ91, CJ92, CJ93

## PRPSS？(思い出せない)
標準WBS要素マスタ。

標準プロジェクト定義マスタとセット。
CJ91, CJ92, CJ93

## CDHDR
変更履歴ヘッダ。
直接は関係ないけど、知っておいたら何かと便利なテーブル。

## CDPOS
変更履歴明細。
直接は関係ないけど、知っておいたら何かと便利なテーブル(再掲)。
【Rails】render

#render
htmlを分割します。
render というRailsのメソッドを使用して、htmlを別ファイルに分割することができます。

```
<h1>
<%= render "layouts/header" %>
</h1>
```
↓参照

```erb:app/views/layouts/_header.html.erb
<header class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
```

##render "○○○"
```app/views/messages/index.html.erb
.menu
  = render "layouts/menu"
// これはlayoutsフォルダにある_menu.html.hamlにいく

.view
  = render "view"
///これは同じmessagesフォルダにある_view.html.hamlにいく
```

##コントローラ内でrenderを使用する

```controllers.rb
def index

  render action: :new

end
```
上記の様にコードを記載するとnewアクションに対応するviewを表示することができます。

```controllers.rb
def index

  render template: "user/new"

end
```
この様に記載すると違うコントローラ内のアクションを取り出すこともできます。

##パーシャルにローカル変数を渡したいとき

```erb:index.html.erb
#中略
<%= render partial: 'index_body', locals: { index: @index } %>
　　　　　　　　　　　　パーシャル名　　ローカル変数名： インスタンス変数名
#省略形
<%= render 'index_body', index: @index %>
```
```erb:_index.body.html.erb
 <div class="media-body">
  <ul class="list-inline">
    <li>
      <%= link_to app_path do %>
      　<i class="fa fa-reply" aria-hidden="true"></i>一覧ページへ戻る
      <% end %>
    </li>
  </ul>
　　　　↓　ココに注目
  <h2><%= index.name %></h2>
  <h3><%= index.display_price %></h3>
  <p><%= index.description %></p>

（以下、省略)
 </div>
```
localsオプションを使用することで、`@index`というインスタンス変数を`index`というローカル変数にした状態で`_index_body.heml.erb`に渡すことができます。
H2databaseでコマンドラインからSQLを実行する方法

H2databaseのコンソール(H2コンソール)の使用方法に続いて、H2databaseのコマンドラインからSQLを実行する方法も良く忘れるので備忘録として残しておく

# 準備

組み込みモードでH2に接続しているアプリケーションが起動している場合は停止する

# SQL準備

任意のSQL文をファイル出力

```
$ echo select * from <テーブル名>; > select.sql
```

# SQL文実行

```h2:組み込みモードの場合
$ java -cp h2-xxx.jar org.h2.tools.RunScript -url "jdbc:h2:file:./<DBファイル名>" -user sa -password <パスワード> -script select.sql  -showResults
```
```h2:サーバーモードの場合
$ java -cp h2-xxx.jar org.h2.tools.RunScript -url "jdbc:h2:tcp://<H2DB-IP>:/./<DBファイル名>" -user sa -password <パスワード> -script select.sql -showResults
```
※「-showResults」を指定すると実行結果を標準出力に出力する

実行後、以下のようにSQLの実行結果結果が表示されば成功

```
select * from <テーブル名>;
--> colA-1 ColB-1 ColC-1
--> colA-2 ColB-2 ColC-2
--> colA-3 ColB-2 ColC-3
```

尚、接続先に指定したDBファイルが無い場合、自動的にDBファイルが作成されてしまうので注意が必要
Windows PC上のNode-REDが起動しなくなった時の対処

#概要
　原因は不明ですが、何かの拍子にNode-REDコマンドがグローバルから外れている？ような現象が起きました。

　現状がどのような状況か判断し対策する事が望ましいですが、Node.jsについて勉強不足でスマートな対策ができませんでした。

#対処
　私が行った対処は、Node-REDの実行ファイルへのショートカットをデスクトップに張り付けました。

　WindowsPCの場合、次のパスに実行コマンドがあります。（2020年3月5日現在）
Macは未確認。

```
C:\Users\ユーザ名\AppData\Roaming\npm\node-red.cmd
```

　このファイルを実行するとコマンドプロンプトが起動し、Node-REDが実行されます。

#おわりに
　Node.jsでの対処方法をご存知の方がいらっしゃいましたらコメントいただけると幸いです。
configをk8sのディレクトリ構成に組み込んでみた

# はじめに
config以外の構成に関してはkubectl側で出している[Directory Structure](https://kubectl.docs.kubernetes.io/pages/app_composition_and_deployment/structure_directories.html)に則っています

configをどのように組み込むのか簡単に調査した所
kustomization.yamlと同じまたはその配下にディレクトリを掘ってconfigを管理する方法をよくみましたが、こちらは以下の点を満たすのが難しいと判断したため、別の方法を模索しました

- 環境ごとに値が違うconfigと共通で使用したいconfigが存在する
- ローカル環境のconfigが存在する
  - k8sにlocalディレクトリは存在しない(ローカルはdocker-compose)のでどこに置くのか？
- アプリケーションエンジニアがk8sのディレクトリ構成を深く潜らなくても更新できるようにしたい

# 完成形
上記考慮点を解決する1つの案として`configs`ディレクトリを`bases`、`overlays`と同じ階層にした

```bash:ディレクトリ構成
.
├── bases
│   ├── aws-alb-ingress-controller
│   ├── aws-auth
│   ├── metrics-server
│   ├── a # microservice
│   └── b # microservice
├── configs
│   ├── a-nginx
│   │   ├── conf.d
│   │   │   ├── default.conf # 各環境共通
│   │   │   ├── dev.conf
│   │   │   ├── local.conf
│   │   │   └── prod.conf
│   │   └── nginx.conf # 各環境共通
│   ├── b-nginx
└── overlays
    ├── dev
    │   ├── ap-northeast
    │   │   ├── kustomization.yaml
    │   │   ├── patch-aws-alb-ingress-controller.yaml
    │   │   └── patch-aws-auth.yaml
    │   └── bases
    │       ├── kustomization.yaml
    │       ├── namespace.yaml
    │       ├── patch-a.yaml
    │       └── patch-b.yaml
    ├── prod
    └── staging
```

ちなみに`kustomizetion.yaml`はこんな感じ

```bash:overlays/dev/bases/kustomization.yaml
namespace: development

bases:
  - ../../../bases/a
  - ../../../bases/b

patchesStrategicMerge:
  - patch-a.yaml
  - patch-b.yaml

images:
  - name: nginx
    newTag: 1.15.2
  - name: a
    newTag: 0.0.1
  - name: b
    newTag: 0.0.1

configMapGenerator:
  - name: a-nginx-conf
    files:
      - ../../../configs/a-nginx/nginx.conf
      - ../../../configs/a-nginx/conf.d/default.conf
      - ../../../configs/a-nginx/conf.d/dev.conf
  - name: b-nginx-conf
    files:
      - ../../../configs/b-nginx/nginx.conf
      - ../../../configs/b-nginx/conf.d/default.conf
      - ../../../configs/b-nginx/conf.d/dev.conf

resources:
  - namespace.yaml
```

## 注意点
今回の構成だと`kustomization.yaml`のconfigMapGeneratorからconfig fileをそのまま参照できません

理由として以下です
> v2.0 added a security check that prevents kustomizations from reading files outside their own directory root.

> https://github.com/kubernetes-sigs/kustomize/blob/master/docs/FAQ.md#security-file-foo-is-not-in-or-below-bar


なので実行コマンドとしてはオプションとして`--load_restrictor none`を付与する必要があります

```bash:実行コマンド
$ kustomize build --load_restrictor none overlays/dev/ap-northeast | kubectl apply -f -
```
Visual Studio Codeで「参加者の～」云々が出る時に何とかする方法

# はじめに

VSCodeでファイルを編集しているときに、「参加者の保存を待っています」とかいうメッセージと共に保存がめちゃくちゃ遅くなってしまう現象が発生してしまった。

調べても症例がヒットせず、代わりにvscodeのリポジトリにたどり着いたのでよく見たら`files.participants.timeout`という設定ができるらしい。試しに

```json
{
  "files.participants.timeout": 0
}
```

としたところ、表示が一瞬でてきてすぐ消える...という感じになって保存もすぐに反映されるようになった。

# おわりに

有識者、コメント待ってます
ElasticSearch Service のディスク容量節約を実践してみる

AWS の ElasticSearch Service を使ってログをインデクスしていますが、徐々に減っていく空きディスクに震える日々を過ごしていました。
以下の記事を参考にさせていただき、インデックス容量を削減を実践してみました。
https://qiita.com/aucfan-engineer/items/706b8571440a759aec1f

## 環境
インデックスに Logstash を使用しています。以下の環境で動かしています

- Amazon Linux AMI release 2018.03
- Logstash 6.7.1
- OpenJDK 1.8.0_191
- Elasticsearch 6.7

## やったこと
基本的に文字列検索はしないため、フレーズクエリやスコアを無効にします。
Logstash 側にインデックステンプレートを用意して使用しています。

### テンプレート作成

json 形式でテンプレートを作成し、  Logstash を動かす環境に配置します。
dynamic_templates で容量を食う設定を無効にします。

```json
{
  "template" : "xxx-*",
  "mappings" : {
    "_default_" : {
      "dynamic_templates" : [
        {
          "string_fields" : {
            "match" : "*",
            "match_mapping_type" : "string",
            "mapping" : {
              "type" : "text",
              "norms" : false,
              "index_options": "freqs",
              "fields" : {
                "keyword" : { "type": "keyword", "ignore_above": 256 }
              }
            }
          }
        }
      ],
      "properties" : {
        "category": { "type": "keyword" },
        "env": { "type": "keyword" },
        "tags": { "type": "keyword" },
        ・・・
      }
    }
  }
}
```

### Logstash 設定ファイル変更
Logstash の設定ファイルはいくつか要素がありますが、今回 output が関係するのでそこのみ記述します

```
・・・

output {
  elasticsearch {
    hosts => "xxxxxxxxxx.com:443"
    ssl => true
    index => "xxxxxx-%{+YYYY.MM.dd}"
    # ここから追加
    manage_template => true
    template => "{上記テンプレートファイルのパス}"
    template_name => "template_name"
    template_overwrite => true
  }
}
```

### 結果
３種類インデックスがあるうち、２種類この設定を行いました。設定反映後のグラフは下記になります。
Y 軸がストレージの残り、 X 軸が時間です

![graph.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149365/7411a300-6c18-cb91-778a-6b25edd9935e.png)

下降気味だったストレージが設定反映後に使用する容量が減って上昇傾向になっているのが確認できました。
LINE WORKS のグループ トークルームで勤怠記録してくれる Bot

チームのグループ トークルームで、メンバーの勤務開始や終了を Excel に記録してくれる Bot を作ってみました。

チーム メンバーが、それぞれリモート ワークしている時に、メンバーからの 「勤務開始します。」とか、「休憩開始します。」とかのトークを基に勤怠記録を行う Bot です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/e52b75a3-daa0-a663-adf4-72aad1c15bea.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/19efd8fb-0b8d-edb1-cf7c-0b24ed10b38d.png)


メッセージの受信と送信には LINE WORKS の トーク Bot API を利用します。

TITLE: メッセージ送信 (text)
URL: https://developers.worksmobile.com/jp/document/100500801?lang=ja

TITLE: メッセージ受信 - Callback 形式
URL: https://developers.worksmobile.com/jp/document/1005009?lang=ja

勤怠記録は今回は Excel Online 上の Excel ワークブックに行います。

一連の処理は Microsoft PowerAutomate で、ほぼコーディングなしで行います。

## Microsoft PowerAutomate のフロー作成

トリガーに "HTTP 要求の受信時" を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/981d8c36-113a-8b75-be52-27ffcfd2b6bd.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/d26eda3c-c0a5-417a-7b57-1289546a12d3.png)

要求本文の JSON スキーマを "サンプルのペイロードを使用してスキーマを生成する" で生成します。
ペイロードのサンプルは、こちらのページの記載を用います。

TITLE: メッセージ受信 - Callback 形式
URL: https://developers.worksmobile.com/jp/document/1005009?lang=ja

TITLE: メッセージ受信 - Callback 形式 (message)
URL: https://developers.worksmobile.com/jp/document/100500901?lang=ja

-> Request Example - type "text" の箇所

```
{
  "type": "message",
  "source": {
    "accountId": "admin@example.com",
    "roomId": "12345"
  },
  "createdTime": 1470902041851,
  "content": {
    "type": "text",
    "text": "hello"
  }
}
```
次に、勤怠打刻用の条件を設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/325de611-3e84-c6b5-d5ac-905b32b0d306.png)

打刻のトリガーとなるキーワードを指定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/ea458922-0975-69f1-b5e8-fb435be2d53b.png)

条件に合致した場合は、Excel への記録とトークルームへの返信を行います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/8cbe3477-adba-afdf-8bb9-dd54797bfbb0.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/3b4bce7e-9724-273d-aff9-aa23cd35148e.png)

## 動作確認
トークルームに Bot を招待し、キーワードを入力すると Bot からトークが返り、Excel に記録されることを確認します。
Pythonでしりとりを実装

久しぶりの記事の投稿です。
記事を上げていない間にちょっとずつPythonの勉強を進めていたので、何となくPythonやプログラミングの感覚が掴めてきた気がします。

そこで、しりとりを作ってみようと思い実装してみました。
しりとりを作る上で、
・前の単語の最後の文字を引き継ぐ。＝「しりとり」
・既に使った単語は使えない。
・「ん」で終わったら負け。
この三つのルールを守ることができるように留意しました。

```Python:word_chain.py
hiragana_1 = "しりとり"
used_hiragana = []
print("しりとりスタート！\n", hiragana_1)

while True:
    hiragana_2 = str(input("ひらがなを入れてください: "))
    if hiragana_2[0] != hiragana_1[-1]:
        print("最初の文字が間違っています。")
        break
    elif hiragana_2 in used_hiragana:
        print("この単語は既に使われています。あなたの負けです。")
        break
    elif hiragana_2[-1] == "ん":
        print("これは「ん」で終わる単語です。あなたの負けです。")
        break
    else:
        used_hiragana.append(hiragana_1)
        used_hiragana.append(hiragana_2)
        hiragana_1 = hiragana_2
        print("次のターンです。")

(実行結果１)
----しりとりスタート！
     しりとり
    ひらがなを入れてください:りんご
    次のターンです。
    ひらがなを入れてください:ごりら
    次のターンです。
    ひらがなを入れてください:つばめ
    最初の文字が間違っています。
(実行結果２)
----しりとりスタート！
     しりとり
    ひらがなを入れてください:りす
    次のターンです。
    ひらがなを入れてください:すり
    次のターンです。
    ひらがなを入れてください:りす
    この単語は既に使われています。あなたの負けです。
```

実行結果を少し省きましたが、最初に触れた三つのルール通りにしりとりを作ることができました。
でも、このコードだとカタカナが含まれていないし、ひらがなの小文字を含む単語の時に困ってしまうというところが難点です。
そういうところを克服してさらに精度を上げたいですが、まだちょっと難しそうです(笑)
viewメソッドの使い方（laravel)

#viewメソッドの第一引数について

```
view('フォルダ名.ファイル名')
```

第一引数
laravel内のviewsフォルダ内にあるファイルを検索して表示させます。

#viewメソッドの第二引数について

```
view('フォルダ名.ファイル名', 使いたい配列)
```

使いたい配列ってなんやねんと思ったでしょう。
具体例を書きます。

```
こんにちは
```

まずは、上記をcontrollerでviewメソッドの第二引数を使って表示したいとする。
すると、viewの方では

```index.php

<p><?php echo $msg; ?>

```

とすると、コントローラーには・・・

```hello.controller
public function index () {
     
     $data = ['msg' => 'こんにちは'];
     return view('hello.index', $data);
}

```

こんな感じに書けばOKです！！
入れたい変数（index.phpで使いたい変数)を配列のキーに名前を入れておけば自動的に持っていってくれるということです。laravel作った人、本当に天才。
`FASTLANE_SESSION` 環境変数の生成で `Spaceship::UnauthorizedAccessError` エラー

## はじめに

`fastlane spaceauth -u {Apple ID}` を実行して `FASTLANE_SESSION` 環境変数を生成しようとしたら、6桁の確認コードの入力後に `Spaceship::UnauthorizedAccessError` エラーが発生しました。

（検索用に全文載せていますが、エラーは「Please enter the 6 digit code:」からです）

```shell-session
$ bundle exec fastlane spaceauth -u {Apple ID}
[✔] 🚀 
Logging into to App Store Connect ({Apple ID})...
Available session is not valid any more. Continuing with normal login.
Two-factor Authentication (6 digits code) is enabled for account '{Apple ID}'
More information about Two-factor Authentication: https://support.apple.com/en-us/HT204915

If you're running this in a non-interactive session (e.g. server or CI)
check out https://github.com/fastlane/fastlane/tree/master/spaceship#2-step-verification

(Input `sms` to escape this prompt and select a trusted phone number to send the code as a text message)

(You can also set the environment variable `SPACESHIP_2FA_SMS_DEFAULT_PHONE_NUMBER` to automate this)
(Read more at: https://github.com/fastlane/fastlane/blob/master/spaceship/docs/Authentication.md#auto-select-sms-via-spaceship-2fa-sms-default-phone-number)

Please enter the 6 digit code:
XXXXXX
Requesting session...
Could not login to App Store Connect
Please check your credentials and try again.
This could be an issue with App Store Connect,
Please try unsetting the FASTLANE_SESSION environment variable
(if it is set) and re-run `fastlane spaceauth`

Exception type: Spaceship::UnauthorizedAccessError

Looking for related GitHub issues on fastlane/fastlane...

➡️  fastlane cert got Unauthorized Access error
    https://github.com/fastlane/fastlane/issues/16108 [open] 31 💬
    an hour ago

➡️  The request could not be completed because: Unauthorized Access
    https://github.com/fastlane/fastlane/issues/15411 [closed] 22 💬
    08 Jan 2020

➡️  Unauthorized Access when I use Fastlane pilot upload
    https://github.com/fastlane/fastlane/issues/15125 [closed] 6 💬
    13 Nov 2019

and 16 more at: https://github.com/fastlane/fastlane/search?q=The%20request%20could%20not%20be%20completed%20because%3A%0A%09Unauthorized%20Access&type=Issues&utf8=✓

🔗  You can ⌘ + double-click on links to open them directly in your browser.

[!] The request could not be completed because:
        Unauthorized Access
```

解決に苦戦したので、備忘録として残します。

## 結論

`SPACESHIP_2FA_SMS_DEFAULT_PHONE_NUMBER` 環境変数に２FA用の携帯電話番号を設定したあと、 `fastlane spaceauth -u {Apple ID}` を実行します。

```bash
# 例：電話番号が「080-XXXX-XXXX」の場合
$ export SPACESHIP_2FA_SMS_DEFAULT_PHONE_NUMBER=+81-80-XXXX-XXXX
$ fastlane spaceauth -u {Apple ID}
```

Bundlerで管理している場合、先頭に `bundle exec` を付けるのを忘れないでください。

## 環境

- Fastlane：2.143.0

## 解決理由

わかりません…ｗ
手動で6桁の確認コードを入力する場合より、いろいろなことをやっているのかもしれません。

ちなみにですが、 `fastlane init` で同様のエラーが発生した場合も、本記事の方法で解決しました。

## 参考リンク

- [`FASTLANE_SESSION` 環境変数の生成方法 - Qiita](https://qiita.com/uhooi/items/4cdd254c7e4e70699b60)
TestFlight経由でインストールしたアプリのローカルデータは製品版インストール時に引き継がれますか？

引き継がれます!（2020年2月時点）
アプリをアップデートするようなものと考えていただければ。

バンドルIDが同じなのだからそりゃそうだと思いつつも、やはり不安になってしまうものですが、意外とネットに情報が転がってなかったので、共有しておきます。
SQLite3 はバージョンアップすると性能は向上するのか!?（測定）

# はじめに

SQLite のメイン開発者である Richard Hipp 氏が以前、「SQLite は進化していて、バージョンアップを繰り返して、性能も良くなっています。」と言っていたことを思い出したことと、CentOS7 の SQLite パッケージが古くて気になっていたので、ちょっとバージョン毎の性能を測定してみました。 

# 測定環境

測定は以下の環境で測定しました。

**CPU** : Intel Core i7-8700,  **OS** : CentOS 7.7, **メモリ** : 4GB, **ストレージ** : HDD(SATA,1TB,7200rpm, キャッシュ：64MB)

# 測定方法

SQLite 3.0 ～ 3.31 までを入手し、それぞれのSQLiteを以下の手順でそれぞれの1トランザクション、100万レコード( 108 Byte )時間を測定しています。

1. 新規データベースのオープン、テーブルの作成
2. 100万レコードのINSERT
3. 100万レコードのSELECT COUNT()
4. 100万レコードのUPDATE
5. 100万レコードのDELETE
6. VACUUM
7. データベースのクローズ、データベースファイルの削除

測定プログラムは、GitHub にアップしています。
https://github.com/kanegoon/sqlite-evaluation/blob/master/src/evalver.c

また、測定プログラムの実行結果は以下のようになります。

```bash
$ ./evalver 
Version Evaluation, SQLite3 version = 3.0.8
INSERT :          6.668143580 (sec)
SELECT :          0.318649103 (sec)
UPDATE :          6.946012056 (sec)
DELETE :          1.056959430 (sec)
VACUUM :          0.993167611 (sec)
```

# 測定結果

## 1. INSERT

100万レコードのINSERTを測定して、結果は以下のようになりました。少しづつ性能が改善していって、Version 3.16.2 で最新バージョンと同じ性能なりました。

![sqlite_eval_insert.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308856/95e5a416-7682-9280-920a-ecaef8e19bf3.jpeg)

## 2. SELECT COUNT()

INSERTされた 100万レコードの SELECT COUNT() を測定して、結果は以下のようになりました。Version 3.12.3 で性能が大きくに改善しています。

![sqlite_eval_select.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308856/55a805d5-16dd-a11c-9072-0f118ae72d55.jpeg)

## 3. UPDATE

100万レコードの UPDATE を測定して、結果は以下のようになりました。少しづつ性能が改善していって、Version 3.16.2 で最新バージョンと同じ性能なりました。

![sqlite_eval_update.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308856/8926c5f1-b682-5d3d-cbaf-6147fa36add6.jpeg)


## 4. DELETE

100万レコードの DELETE を測定して、結果は以下のようになりました。Version 3.3.17 で大きく性能が改善して、さらに Version 3.12.3 で大きく性能改善しています。

![sqlite_eval_delete.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308856/20b549bf-b370-69a0-bf55-be3462aa281e.jpeg)


## 5. VACUUM

100万レコードの DELETE の後、VACUUMを測定して、結果は以下のようになりました。Version 3.7.17 で大きく性能が改善して、さらに Version 3.12.3 で大きく性能改善しています。

![sqlite_eval_vacuum.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308856/2fe9a7a3-ea37-59cb-0f37-472124ae8104.jpeg)



# まとめ

Hipp 氏が言っている「バージョンアップでSQLiteの性能が向上する」ことを同一環境で確認しました。性能だけで考えると SQLite 3.17.0 以上、安定も考えると 3.22.0 以上を使いたいとこです。
組み込みシステムや社会インフラシステムで、SQLiteを使用している場合、長い間、バージョンアップをしていない可能性があります。また、CentOS7 の SQLite は Version 3.7.17 なので、性能を考えると、別途、最新版を入手して使用した方が良いです。

```bash
$ sudo yum list available | grep sqlite.i686
sqlite.i686                               3.7.17-8.el7_7.1               updates
```

もし、記述について誤りがあったり、気になることがあれば、編集リクエストやコメントでフィードバックしていただけると助かります。
[SQL]  UNION結合したレコードの取得元テーブルを知りたい！

下記のようなテーブルが存在するとします。

### syouyu_ramen_shop テーブル
| id | name | comment |
| :---: | :---: | :---: |
| 1 | 店A | うまかった！ |
| 2 | 店B | あんま美味しくない！ |
| 3 | 店C | おいし〜 |

### miso_ramen_shop テーブル
| id | name | comment |
| :---: | :---: | :---: |
| 1 | 店X | やっぱ味噌に限るな |
| 2 | 店Y | あと100円やすければ・・ |
| 3 | 店Z | 二郎っぽかった |

よし、じゃあ ` UNION ` でテーブル結合しよう！

### 通常パターン

#### 実行SQL
```sql
SELECT srs.id, srs.name, srs.comment FROM syouyu_ramen_shop as srs UNION SELECT mrs.id, mrs.name, mrs.comment FROM miso_ramen_shop as mrs;
```

#### 結果レコード
| id | name | comment |
| :---: | :---: | :---: |
| 1 | 店A | うまかった！ |
| 2 | 店B | あんま美味しくない！ |
| 3 | 店C | おいし〜 |
| 1 | 店X | やっぱ味噌に限るな |
| 2 | 店Y | あと100円やすければ・・ |
| 3 | 店Z | 二郎っぽかった |


あれ・・・これじゃどこの店が醤油か味噌かわかんなくない？

そういうときは、SELECT句のあとに ` 文字列 as table_name ` を入れてあげることで
結果に ` table_name ` のカラムが追加されて出力されます。

### 取得元テーブルが分かるパターン

#### 実行SQL
```sql
SELECT srs.id, srs.name, srs.comment 'syouyu' as table_name　FROM syouyu_ramen_shop as srs UNION SELECT mrs.id, mrs.name, mrs.comment 'miso' as table_name FROM miso_ramen_shop as mrs;
```

#### 結果レコード
| id | name | comment | table_name |
| :---: | :---: | :---: | :---: |
| 1 | 店A | うまかった！ | syouyu |
| 2 | 店B | あんま美味しくない！ | syouyu |
| 3 | 店C | おいし〜 | syouyu |
| 1 | 店X | やっぱ味噌に限るな | miso |
| 2 | 店Y | あと100円やすければ・・ | miso |
| 3 | 店Z | 二郎っぽかった | miso |
WinActor 配列の使い方 v6.1.0

### 背景

あるフォルダ配下のファイルを取得して変数に格納。⇒それをFor文で回して同じ処理をしたいことがあった

ふつうの開発でよく使う配列はまず配列を定義する。
↓
変数一覧に登録するかぁ　　あれっ？　変数名に配列はどう書くんだ？
↓
Answer：普通に書く　ex:test
test[]、test(5)、test(1 to 5)じゃないんだね



シナリオにはこう書く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208182/8c56ca03-10af-f6c8-4ff2-6fd5717f42bb.png)
まず配列を初期化

```vb:配列を初期化
Dim rootArray
arrayName = !配列名!

'ルート配列の存在確認
Set rootArray = WScript.CreateObject("Scripting.Dictionary")
rootArray.RemoveAll()
If rootArray.Exists(arrayName) Then
  getArray = rootArray.Item(arrayName)
  Erase getArray
  rootArray.Remove arrayName
End If
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208182/aafdae1e-d209-dadc-d5ee-d2c1bbd41a93.png)

↓
要素ごとに格納
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208182/6a5e61c1-16b4-2a31-3f0f-9fbb588bdac3.png)
以下のようにコメントアウトしないと、エラーが出る

```vb:格納
'入力チェック
'If (Len(arrayName) = 0) Then
'  errorMsg = "配列名を入力してください"
'  Err.Raise 1, "", errorMsg
'  WScript.Quit
'End If
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208182/ccc0675a-7001-7f22-bc10-56cdb28d646f.png)
↓
格納した配列からデータを取得
↓
それをメッセージで出力
データ指向なんもわからん！（①なぜデータ指向がいいのか編）

データ指向なんもわからん日記です。
なんもわからんちんなので、間違ってることいってたら、コメントください！おねがいします！

## データ指向の起源を考えてみた

なんかこう、巷で多いのってオブジェクト指向ですよね。
データ指向ってのは2009年あたりから出始めたらしいんですけど、なんで生まれたんでしょうか。

ゲームやシステムを作ってると「処理速度がーーー！」ってよく言われますよね。
そういったパフォーマンスを上げるためにハードの方もすごい成長を遂げてるわけです。

1980年のときのCPUに比べて現在のCPUは10000倍(1万倍)のスペックがあるらしいですよ。
いちまんばい！
ですが面白いことに、メモリの性能は10倍も変わってないらしいんですよ。メモリどうした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311402/555e9b15-3d3a-aeb0-5130-5a8d4532ff44.png)
[参考](https://docs.google.com/presentation/d/17Bzle0w6jz-1ndabrvC5MXUIQ5jme0M8xBF71oz-0Js/present?slide=id.i10)

僕はリテラシー低いのでメモリのことも改めて調べましたよ。
データを一時的あるいは永久的に保存することができる物理的デバイス。
そうですね。しってた！

その差を埋めるためにCPUにはキャッシュメモリというものが存在します。

僕はリテラシー低いのでキャッシュメモリのことも(ry
CPUなど処理装置がデータや命令などの情報を取得/更新する際に主記憶装置やバスなどの遅延／低帯域を隠蔽し、処理装置と記憶装置の性能差を埋めるために用いる高速小容量メモリのことである。
つまり、メモリの遅さを隠すために、CPUのキャッシュメモリが一時的に情報をもってくれてて、しかもすばやく更新とかしてくれる。ってことですかね。


###メインメモリのデータ取得の遅さ

取得する際は、この図のようにL1キャッシュ、L2キャッシュ、L3キャッシュ…でメモリに到着するわけですけど、この末端の**キャッシュ⇔メモリが**めっちゃ遅い。CPU⇔キャッシュに比べて25～100倍くらい遅いそうです。メモリがんばれ～＞＜

![めもり遅い.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311402/986155b8-cafc-0f99-bad7-ddc9cb61560f.png)


###CPUからメモリへのデータの取り方

CPUがなんらかの処理をする際、このキャッシュメモリがメモリにデータを取りに行きます。
このときキャッシュメモリがメモリから取得するデータは1個ではなく、64バイト程度のデータが同時にロードされるようです。
そのなかに目的のデータがなかった場合、再度別の場所に取りに行くのです。

![めもりとる.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311402/d6a4cecb-8f3a-dae4-4e15-f04c4ced874b.png)



取りに行きたいデータが連続した位置に配置されていたら幸せになると思いませんか？
![めもりとる２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311402/494e1ccb-c054-a7df-2b81-ad0bb6b795a8.png)


なるほど。連続で使用するデータは近い位置に配置してくれたほうが絶対いい。

###だから...

扱うデータの配置レイアウトや設計にもっと着目してパフォーマンスをあげよう！
というのがデータ指向の起源のようですね。へー。

次はUnityのデータ指向ってなに？から調べてみようと思います。
windows git bashでopenコマンド

## 指定パスのファイル・フォルダをエクスプローラで開きたい

* vscodeのターミナルをgitについてきたbashにしてる
* `code`コマンド便利
* でも主にD&Dしたいときとかにエクスプローラで開きたい
* 単純に `explorer` を使うと複数ファイルや相対パスで微妙な動作をしたため、軽いシェル芸

### 前提条件

git for windowsでgit bashを導入している

### 作った関数

```sh
open() {
    [ $# -gt 0 ] && cygpath -w "$@" | xargs -r -d "\n" -i explorer {}
}
```

#### Usage

適当に.bashrcにでも追加しておく

```sh
open FILE_PATH ...
```
あなたの個人情報大丈夫？ 

あなたは、SNSを使うときに自撮り写真をアイコンにしたりフルネームで活動していないだろうか？

どうせみるのは家族や友達のみだから平気だと思っていないだろうか？

####本当にそれは大丈夫だろうか？
この話は筆者の実体験したことである。

私は以前イタズラ電話の被害にあっていた。
ある夕方に電話が私のところにかかってきたので出たところ間違い電話だった。
相手が違うとわかり電話が切れたが。

####数日後、彼は電話をかけてきた。

それ以来彼は昼間や深夜に電話をかけてくることになった。もちろん着信拒否にしている。

数年後、ガラケーからスマートフォンに変えてSNSをインストールしたところ

####イタズラ電話の彼が友だちとして登録された。

理由は電話帳に登録して着信拒否にしていたためである。

SNS上では彼はニックネームで登録していたので名前はわからなかったが、タイムラインに自撮り写真を投稿していたので
####30代くらいのおじさんとわかった。

もし、彼が本名で登録していたり住所を公開していれば○○市にお住いの○○さんとわかる。

SNS上で自分のことを公開するの個人の自由であるが、まったく面識のない人にも公開されることがあるので気をつけけなければいけない。
目次ページ

# Amazon の研究内容発信ページ
https://www.amazon.science/

ユースケースごとに記事にいけるようにするための目次ページ

＜目的＞
SageMakerの公式ドキュメントがアレなので、機械学習エンジニア（というかSageMakerエンジニア）のための実際のMLシステム構築、運用に役立つ情報を記載していくために開設

＜SageMakerでMLパイプラインを作成する時の鬼門＞
1.カスタムコンテナ（コンテナの知識が必要、ECR、Docker）
2.学習、推論などのスクリプトの分割（SageMakerの仕様理解が必要）
この二つが、PoCでデータサイエンティストが書いた一つのノートブックから
MLシステムを構築するのに鬼門となる。。
特に1.dockerを理解し、SageMaker用の環境を作らねばならない。。

＜参考＞
https://qiita.com/odrum428/items/1788c4245fc2de4d58a8
https://qiita.com/triwave33/items/0a39e90068c57f1d2753

https://pages.awscloud.com/rs/112-TZM-766/images/Amazon_SageMaker_Overview_AWS.pdf?mkt_tok=eyJpIjoiTkdSalpHTmlaVFZtTTJNeSIsInQiOiJxcFlvXC9OZHFcLytLUDZWQkdFKzEwWVwvaDdNQzR3d0owa1hkejlJU2ZVNGErWlExb20ydVVlakV6S3Z2S0dWbW5PMzJZU0xQNllpK0NkN09ER2NtSStVdz09In0%3D

SageMakerの利点
・モデル開発が手軽にできて、データサイエンティストも嬉しい
・モデル開発が適切に管理されて、本番運用に繋げられて嬉しい
・データパイプラインや既存のAWSシステムとの連携が簡単で、データエンジニア(機械学習エンジニア）も嬉しい
・MLopsが効率的に実現できて、MLシステム運用者も嬉しい

＜開発時＞
データサイエンティストは、モデル開発をnotebookだけで完結させたい。
SageMaker用のAPIとか覚えたくない。
なので、開発はEC2上でnotobookで作ってもいいと思う。DataRobot使ってても別にいい。
業務ユーザーはExcel + QuickSightでもいい。
SageMaker notebookインスタンスだとちょっと高いし。
ローカルのmacでもよいでしょう。
そして、よいモデルを作るための設計図ができたら、
仕組み化するためにSageMakerの型に落とし込む。これはデータサイエンティストと、データエンジニアが連携して実施する。
学習も定期的に実施するなら、spot学習にした方がいいだろう。
推論はバッチ推論がよい。
SageMakerのよさの本質は、MLopsにある。
・開発したnotebookをどのようにSageMakerの型に移植すればよいか。がキモになる。
データ取得
前処理
モデル学習
- コンテナの中身を確認したい。ビルトインアルゴリズムのtrain.pyの内容をみたいなど。が発生する。
A.SageMaker にて提供している組み込みアルゴリズムのコンテナイメージは直接取得できません。

推論
後処理
評価
が含まれているので、これをどのように分解してSageMakerで運用できるようにするか。


■自身で作成したコンテナイメージをECRにpushする
以下に従い、notebookインスタンス上で実行してみた。
https://qiita.com/aokad/items/17a06c2384041bd60d16
エラーになった。IAMの権限が足らないらしい。
＜メッセージ一部＞
is not authorized to perform: ecr:InitiateLayerUpload on resource: arn:aws:ecr:us-east-2:

ここを参考にAmazonEC2ContainerRegistryFullAccessロールを付与したら解消した。
https://forums.aws.amazon.com/thread.jspa?threadID=223156



→ユースケースごとの最適なアーキテクチャがほしい。
リアルタイム推論が求められるケース
データがとてつもなく大きい場合
AIサービスを利用する場合
など

＜モデル決定後＞
開発されたモデルは、SageMaker用の学習スクリプトにして、
Spot学習などをすれば、コスト削減が可能。


■SageMakerで実現するMLシステム運用
データ収集

前処理

モデル学習

後処理

EDA

評価


モデルデプロイ

推論

モニタリング
Cloud Watch


■Studioの話
Auto Pilot


■AIサービス


■MLプロジェクトワークフローの話
企画

AWS S3にアップロードされたExcelファイルをLambdaで処理
https://qiita.com/akimai/items/d7f4c18e08347e46a18b

PoC
本番運用
MLops

■Kaggleの話
ベスト環境


■人材の話



■開発の話
SageMakerノートブックインスタンス上ではなく、
自身のMacBookProラップトップにてMLシステム開発を実施したい。どうすればよいか。
前処理、学習、後処理、推論をラップトップからSageMakerに命令したい。
【Rails】scopeを使う

DB問い合わせでよく使う条件を、モデルのscopeに登録することができる。

##scopeなし
```rb
@active_users = User.where(status: 1).order(id: :desc)
```
##scopeを使う
```rb:model
class User < ApplicationRecord
  scope :active, -> { where(status: 1).order(id: :desc) }
```
```rb:controller
@active_users = User.active
```
##scopeに引数を渡す
```rb:model
class User < ApplicationRecord
  scope :status, -> (num) { where(status: num) }
```
```rb:controller
@active_users = User.status(1)
@not_active_users = User.status(0)
```

##合わせ技
```rb:model
class User < ApplicationRecord
  scope :status, -> (num) { where(status: num) }
  scope :recent, => (int) { order(id: :desc).limit(int) }
```
```rb:controller
#@recent_active_users = User.where(status: 1).order(id: :desc).limit(10)
@recent_active_users = User.status(1).recent(10)
```

##参考
- [【Rails】scope 複数の引数](https://qiita.com/ryunishimura/items/71d4fed2300bf6ac6136)
- [Railsでよく利用する、Scopeの使い方。](https://qiita.com/ngron/items/14a39ce62c9d30bf3ac3)
SCSSとJavascriptの読み込みに関する質問

CodepenにてHTML SCSS Javascriptを用いてページを作っていたのですが、Github pagesにてページを公開する段階においてSCSSとJavascriptが読み込まれずHTMLのみの表示となってしまいます。
現在、Github内のレポジトリには、
・HTMLファイル
・SCSSファイル(stylesheet.scss)
・JSファイル(chart.js)
が入っています。
head内の記述に誤りがありますでしょうか？
よろしくお願いします。

```html
<head>
   
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <link rel="stylesheet" type="text/css" href="stylesheet.scss"><!--scss読み込み-->
    <script type="text/javascript" src="chart.js"></script><!--chart.js読み込み-->
       <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
     <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.9.0/css/all.min.css" integrity="sha256-UzFD2WYH2U1dQpKDjjZK72VtPeWP50NoJjd26rnAdUI=" crossorigin="anonymous" /><!--font awesome-->
    <link href="https://fonts.googleapis.com/css?family=Spartan&display=swap" rel="stylesheet"><!-- Google font-->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.min.js"></script><!--Chart.js CDN-->
```
GCP Compute Engineで無料のVMを建てる

# GCP Compute Engineで無料のVMを建てる

備忘録として、記録しておきます。

## 作成手順

1. プロジェクトの作成

    [Google Cloud Platform]
    (https://console.cloud.google.com)から **新しいプロジェクト** を選択。ここでプロジェクト名と場所を入力して作成を選択します。

1. VMインスタンスの作成

    左上の **ナビゲーション メニュー** から **Compute Engine** の **VM インスタンス** で **作成** を選択します。
    ここでインスタンス作成の設定画面になります。まずリージョンを **us-west1** 、ゾーンを **us-west1-b** にします。

    > これが最適かはわかりませんが、無料にはなります。

    次に、マシンタイプを **f1-micro** にします。そしてブートディスクで、 **標準の永続ディスク** のサイズを 30にします。最後にファイアウォールで **HTTP トラフィックを許可する**、 **HTTPS トラフィックを許可する** にチェックを付けます。

    > これらのネットワークトラフィックを使用する予定がない場合はチェックをいれなくても大丈夫です。

    そして下の **作成** を選択します。これでVM インスタンスを建てることができました。

1. セキュリティの設定
    
    最低限のセキュリティとして、SSHを公開鍵認証で接続するようにし、ポート番号をデフォルトの22から変更します。以下の2つの記事を参考にさせていただきました。
    [『GCE の無料枠のサーバを立るときに、初見でハマりそうなところ』](https://qiita.com/ndxbn/items/7ef0a96e409a5b5837bd)
    [『これから始めるGCP（GCE）　安全に無料枠を使い倒せ』](https://qiita.com/Brutus/items/22dfd31a681b67837a74)

    まずは、公開鍵認証での接続の設定を行います。
    まずは新しいSSH認証鍵を作成します。<>で囲まれた部分は任意な文字列で大丈夫です。
    `$ ssh-keygen -t rsa -f ~/.ssh/<keyname> -C <username>`
    次に秘密鍵を読み取り専用にします。
    `$ chmod 400 ~/.ssh/<keyname>`
    そして以下のコマンドで公開鍵をターミナルに出力します。
    `$ cat ~/.ssh/<keyname>.pub`
    出力結果をコピーし、**ナビゲーション メニュー** から **Compute Engine** の **VM インスタンス**で先程作成した、VMインスタンスの名前をクリックします。そして上の方の編集(鉛筆マーク)を選択し、SSH認証鍵のところの **表示して編集する** を選択します。そして入力欄に先程コピーした公開鍵をペーストします。そして下の保存を選択します。
    これでデフォルトのポートでインスタンスにSSH接続することができます。
    `$ ssh <username>@<外部IP> -i ~/.ssh/<keyname>`

    次にSSH接続のポート番号を変更します。
    まずは、適当なポート番号を選びます。このとき自由に使えるポート番号の範囲は1024から49151なのでここから選択してください。
    ここからは、[『GCE の無料枠のサーバを立るときに、初見でハマりそうなところ』](https://qiita.com/ndxbn/items/7ef0a96e409a5b5837bd#ssh-%E3%81%AE%E3%83%9D%E3%83%BC%E3%83%88%E7%95%AA%E5%8F%B7%E3%82%92%E3%81%8B%E3%81%88%E3%82%8B)に詳しく書かれているので、これを参考にポート番号を変更します。

    ポート番号の変更を行ったあとは、以下のようにSSH接続することができます。
    `$ ssh -p <ポート番号> <username>@<外部IP> -i ~/.ssh/<keyname>`

## まとめ

GCPを使えば、無料で簡単にVMインスタンスを立ち上げることができます。とても便利ですね。

## 参考

[『GCE の無料枠のサーバを立るときに、初見でハマりそうなところ』](https://qiita.com/ndxbn/items/7ef0a96e409a5b5837bd)
[『これから始めるGCP（GCE）　安全に無料枠を使い倒せ』](https://qiita.com/Brutus/items/22dfd31a681b67837a74)
複数のtableに対してtd要素のクリックイベントを仕込む

複数のtableに対して任意のtd要素をクリックすると
イベントが発火するということをしたかったのですが、
たどりつくまで時間がかかりました。

最初に試したコード

```js
document.querySelector('table').addEventListener('click', (e) => {
	if (e.target.nodeName === 'TD') {
		var strTarget = e.target.textContent;
		alert(strTarget);
	}
});
```

htmlの一番目に記載のtableではtd要素のテキストをアラート表示できました。
二番目以降はイベントが発火していませんでした。

querySelectorは同一要素が複数存在する場合一番目の要素に対してのみ効果があるそうです。

querySelectorAllが必要らしいです。

```js
document.querySelectorAll('table').addEventListener('click', (e) => {
	if (e.target.nodeName === 'TD') {
		var strTarget = e.target.textContent;
		alert(strTarget);
	}
});
```
しかしこう書くとエラーがでました。
forEachが必要らしいです。

さらにいろいろ調べて、ベストプラクティスかわかりませんが
以下で問題が解決しました。

```js
document.querySelectorAll('table').forEach(function(table) {
	table.addEventListener('click', (e) => {
		if (e.target.nodeName === 'TD') {
			var strTarget = e.target.textContent;
			alert(strTarget);
		}
	});
});
```

これで何番目のtableでも、
クリックされたtableのtd要素にイベントが発生します。
もちろんアラートが複数発生ということもありません。
参考になれば。
enumの複数判定を少し簡潔に書けたらいいな

※Switch文とか 可読性とか とりあえず置いといて

enumでフラグを用意すると

```c#
enum HOGE
{
  A,
  B,
  C
}

HOGE SuperUltraBigMaximGreatStrongHoge;

if (SuperUltraBigMaximGreatStrongHoge == HOGE.A ||
    SuperUltraBigMaximGreatStrongHoge == HOGE.B ||
    SuperUltraBigMaximGreatStrongHoge == HOGE.C
    )
{
  // HogeHoge-
}
```
と、SuperUltraBigMaximGreatStrongHogeを何度も書くのはチョット…
1行で簡潔に書きたいなーと。
（サジェスチョンとか補完で打つのはツラくはなさそうですが）

まず、Enum拡張を書く。

```c#
public static class HogeEnumExtensions
{
  /// <summary>論理積</summary>
  public static bool and(this HOGE m, HOGE f) => (m & f) == f;
  /// <summary>論理和</summary>
  public static bool or(this HOGE x, HOGE f) => (x & f) != 0;
  /// <summary>否定論理和</summary>
  public static bool nor(this HOGE x, HOGE f) => (x & f) == 0;
}
```
で、HOGEをpublic・Flags指定する。

```c#
[Flags]
public enum HOGE
{
  A = 0b0001,
  B = 0b0010,
  C = 0b0100,
}

HOGE SuperUltraBigMaximGreatStrongHoge;

if (SuperUltraBigMaximGreatStrongHoge.or(HOGE.A | HOGE.B | HOGE.C))
{
  // HogeHoge-
}
```
こういう書き方もあるよー的に。
…アセンブラみたいな書き方ですね
【COTOHA API】AIと会話するWebアプリ作ってみたら倦怠期

# ラバーダッキング

*ラバーダッキング* という言葉を知っていますか？

ゴム製のアヒルとひたすら会話をすることで、アイデアを整理したりできるテクニックです。

でも会社でラバーダッキングするのは **ハードルが高い** ので、Web上でやってみるアプリを作ってみました。

# できたもの

<img width="1440" alt="ps4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92027/2cf4a1bd-d293-e2cc-7999-3bd11464ae1d.png">

↑誤字発見

[LovelyRubber](https://mi-ki-ri.github.io/lovely-rubber/)

[Github](https://github.com/mi-ki-ri/lovely-rubber)

画面上部のテキストエリアに文章を入れてSubmitをクリックすると、

COTOHA APIのキーワード抽出を利用した返答が返ってきます。

内容は、送信された文章に含まれているキーワードをランダムに選んだものに、

語尾と相槌が追加されたものです。

# 開発

使い慣れているのでNuxt.jsを採用しました。

```bash
$ npx create-nuxt-app rubber-app
```

こんな感じで手軽にプロジェクトを作ることができます。

（この時点ではrubber-appという名前でした）

## COTOHA API

[https://api.ce-cotoha.com/](https://api.ce-cotoha.com/)

NTTコミュニケーションズが開発した自然言語処理APIです。

最近[プレゼント企画](https://zine.qiita.com/event/collaboration-cotoha-api/)をやっているのでよく見かけます（この記事も企画に参加する予定）。

いろんな種類があるのですが、今回はキーワード抽出を利用します。

Developer登録をするとクライアントID、クライアントSecret、トークンのURLが生成されるので、

`.env` ファイルに控えました。

envファイルの内容を読み取るのにDotenvのパッケージを使用しました。

```js:nuxt.config.js
export default {
  ...
  env: {
    clientId: process.env.CLIENT_ID  ,
    clientSecret: process.env.CLIENT_SECRET
   },
}
```

`nuxt.config.js`にこんな感じで記載することで環境変数を使用することができます。

原理はわかりませんが（すみません）、Github Pagesでも利用できるようです。

## Nuxtに戻る

あとはVueコンポーネントのmethodsの部分に、トークン生成の処理と返ってきたトークンを使ってAPIを利用する処理を書くだけです。

ajaxのために`axios`を使いました。

APIから返ってきたキーワードの配列をもとに、Vueコンポーネントのdataの中に作った `responses` 変数を書き換え、

`template`中でv-forを用いてレスポンスをレンダリングしました。

`Github Pages`にデプロイしたかったので、`nuxt.config.js`に以下を追記しました。

```js
export default {
  ...
  generate: {dir:"docs"},
  router: {
    base: '/lovely-rubber/'
  },
}
```

この時点で名前が **Lovely Rubber** に変わっています。

# できたけど倦怠期

Lovely Rubberのレスポンスは以下のような構成になっています。

```
相槌 + キーワード + 語尾
```

ただし空白のときは固定メッセージが出ます。

例：

<img width="1169" alt="スクリーンショット 2020-03-06 13.35.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92027/956cf142-16b2-d839-30ab-fa6f0baefc42.png">

<img width="1173" alt="スクリーンショット 2020-03-06 13.35.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92027/8315a3ca-fd80-f842-7e3c-bbf392855458.png">

<img width="1150" alt="スクリーンショット 2020-03-06 13.35.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92027/ddec0e57-df72-6e11-f8aa-516fccc7ec9e.png">

結果としてかなりぶっきらぼうなキャラになってしまいました。

倦怠期の夫婦的な…

キーワード抽出ではなく文章要約を利用してみることも考えたのですが、

長文を要約することが目的のAPIのようで、短文だとほとんどオウム返しになってしまいます。

キーワード抽出でもオウム返しはオウム返しなのですが、

まあラバーダッキングの相手としてはいいかなと思います。

# 会話例

<img width="1163" alt="スクリーンショット 2020-03-06 13.42.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92027/82930408-e796-7372-a63c-cc6f956625ca.png">

コツとしては、自分の持っていきたい話題に強引にハンドルを切ることです。

キーワードをランダムに選択しているので、どうでもいい部分に着目されたりします。

そこで、


```
しょうがない。他にネタもないしね。タイトルだけど
```

のように話題を転換して、話を前に進めます。

Let’ｓ　倦怠期！
Excelツールのススメ

個人的にExcelはITの仕事上最もよく使う便利なアプリケーションです。
Excelを用いて作った各種ツールは現場でもよく使われています。
そこで今回はExcelでのツールづくりに便利な関数を紹介していきたいと思います。

#TEXT関数
対象となる数値を指定した形式の文字列に変換する関数です。
形式を指定できる、という点がミソで幅広く便利に使えます。

例えば数値を特定の桁数でゼロ埋めを行いたい場合

TEXT(123,"00000")　→　00123

というような形で表示されます。

その他にも、カンマの埋め込みやパーセンテージへの変換
時刻、日付への変換や文字列の埋め込みなど
非常に便利に使える関数です。

#FIND関数
対象の文字列から指定した文字列を検索し、
先頭からの位置を返す関数です。

例えば最初のカンマの位置を取得したい場合は

FIND("123,456,789",",")　→ 4

このような形になります。

この関数単独ではそれほど役にはたちませんが
後述するLEFT、MIDなどの関数と組み合わせると
CSVファイルで,を指定して数値を切り出したり
コマンドでスペースやハイフンを指定することで
コマンドや引数などを切り出すことができます。

#LEFT,MID,RIGHT関数
対象の文字列から指定した文字数を切り出す関数です。
3つの関数の違いは切り出し方で

LEFT → 文字列の先頭から
MID → 指定した位置から
RIGHT → 文字列の末尾から

という形にそれぞれなっています。

#VLOOKUP関数
指定した範囲の先頭列から対象と同じ値を検索し
同じ行のデータを返す関数です。
検索方式には完全一致と部分一致があり
基本的には完全一致で使われることが多く
部分一致は滅多に使われません。

完全一致で検索を行う場合
動作としては主キー参照によるDB検索と
実質同じ動きをします。
そのため、この関数が有効に作用するのは
先頭列に主キーをおいているDB形式の
データを検索対象とした場合になります。
この関数を使う場合、あるいは
この関数を使うためのデータを作る場合は
その点に留意するといいでしょう。

とりあえずではありますが
便利な関数について紹介してみました。

次回は具体的なツールの作り方について
解説したいと思います。