OmniAICreator/Qiita-1.07M huggingface dataset:
TSQLの解析4 MERGE文からの参照元テーブル名の取得

# TSQLScriptDomParser
## MERGE文からの参照元テーブル名の取得
### using にテーブル名が指定されている場合
- SQL

```sql:sql\merge01.sql
merge into db.sch.tab1 AS target
using db2.sch2.tab2 as  source
on  target.id = source.id
when matched then update set targat.name = source.name
when not matched by target then insert (id,name) values (source.id,source.name)
;
```

- 実行例

```batchfile
sqlparser -o xml -i -f sql\merge01.sql > out.xml
query -s:out.xml -qs://node[@class='MergeSpecification']/children[@type='TableReference']/node[@class='NamedTableReference']/children[@type='SchemaObject']/node[@class='SchemaObjectName'] !indent=true
```

- 出力例

```xml
<?xml version="1.0" encoding="UTF-8"?>
<node token="db2.sch2.tab2" class="SchemaObjectName" value="">
   <children type="DatabaseIdentifier">
      <node token="db2"
            class="Identifier"
            value="db2"
            QuoteType="NotQuoted"/>
   </children>
   <children type="SchemaIdentifier">
      <node token="sch2"
            class="Identifier"
            value="sch2"
            QuoteType="NotQuoted"/>
   </children>
   <children type="BaseIdentifier">
      <node token="tab2"
            class="Identifier"
            value="tab2"
            QuoteType="NotQuoted"/>
   </children>
   <children type="Identifiers">
      <node token="db2"
            class="Identifier"
            value="db2"
            QuoteType="NotQuoted"/>
      <node token="sch2"
            class="Identifier"
            value="sch2"
            QuoteType="NotQuoted"/>
      <node token="tab2"
            class="Identifier"
            value="tab2"
            QuoteType="NotQuoted"/>
   </children>
</node>
```

- 解釈

|項目|値|
|:--|:--|
|データベース名|/node/children[@type='DatabaseIdentifier']/node のvalue属性|
|スキーマ名|/node/children[@type='SchemaIdentifier']/node のvalue属性|
|テーブル名|/node/children[@type='BaseIdentifier']/node のvalue属性|

### using に副問合せが指定されている場合
- SQL

```sql:sql\merge02.sql
merge into db1.sch1.tab1 AS target
using  (
	select id,name from db2.sch2.tab2 ) as  source
on  target.id = source.id
when matched then update set targat.name = source.name
when not matched by target then insert (id,name) values (source.id,source.name)
;
```

- 実行例/出力例
[SELECT文からのテーブル名の取得](https://qiita.com/Hidenori/items/a72b53bb036994e86166)と同じ。

# ANTSQLParser 
[SELECT文からのテーブル名の取得](https://qiita.com/Hidenori/items/a72b53bb036994e86166)と同じ方法で取得できる。
AWS Data Analytics資格に合格しました

# はじめに
今日（11/8）にAWS Certified Data Analytics - Specialty資格（以降DAS）に受かったので、いつものようにその時の所感や実践した勉強など。
ネットワークの時と同様、データ分析系のサービスは実務未経験だったので、なかなか難しい試験でした。（一発合格でしたが、合格点は751/750の超ぎりぎりでした）
誰かの役に立てば幸いです。

※過去の記事
[AWS SAAに受かった話](https://qiita.com/kkino1985/items/85bcfa50686fcfe69c56)
[AWS SOAに受かった話](https://qiita.com/kkino1985/items/295509d3d94c726ae56a)
[AWS DVA(とCLP)に受かった話](https://qiita.com/kkino1985/items/8f3db5e102876cca47b1)
[AWS SAPに受かった話](https://qiita.com/kkino1985/items/7ad6bcdde44a2b4e4916)
[AWS SCSに受かった話](https://qiita.com/kkino1985/items/7182ada488b60d196ec5)
[AWS ANSに受かった話](https://qiita.com/kkino1985/items/1976c5a55f4047dc5385)
[AWS DBSに受かった話](https://qiita.com/kkino1985/items/25e9e19e6a83b6f0161f)

# 獲得スコア
|受験日|スコア/合格点/満点|結果|
|:--|:--|:--|:--|
|2020/11/8|751/750/1000|合格|

# 勉強に使った教材
※親の顔よりも見たWhizlabsとBlackbelt、あと公式模擬試験は省略

## AWS Summit 2020/2019資料
Blackbelt以外だと、Summitでデータ分析系やRedshiftのセッションを観ました。
「データ分析とは何ぞやか」を知る上では良い教材だったと思います。
https://aws.amazon.com/jp/summits/tokyo-osaka-2019-report/
https://resources.awscloud.com/aws-summit-online-japan-2020-on-demand

## QuickSightセミナー
直近（10/14）に開催されたQuickSightのオンラインセミナー資料が公開されていました。
QuickSightのアーキテクチャーやアクセス制御の考え方など、詳しく説明されています。
https://aws.amazon.com/jp/blogs/news/quicksight-matome-20201014/

## チュートリアル/ハンズオン
Kinesisは直近の案件で触る機会がありましたが、GlueやEMRなど実務で触っていないサービスは公式のチュートリアルやハンズオンで補いました。
（言いつつ、Kinesis以外のハンズオンは横着してあまりやらなかったのですが）
Kinesisだと例えば下記のようなハンズオンをやりました（他にもいくつかやりましたが）
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/with-kinesis-example.html

## Exam Readiness
公式のデジタルトレーニング。
勉強始めであれば最初から通してやった方が良いと思いますが、終盤だったので最後の練習問題だけ何度か解きました。
Exam Readiness: AWS Certified Data Analytics - Specialty
https://www.aws.training/Details/eLearning?id=46612

# 試験の所感
- 全体的に「データ分析とは何か」が問われている試験だった
    - DASに限らず、専門資格はAWSサービスだけではなくその分野自体の一般的な知識が問われている（気がする）
    - Glueなどを使ったデータ分析やETLのハンズオンをやっていればイメージ付きやすいかも
- DAS試験は（ネットワークやSAPに比べて）簡単、という話はたまに聞いていたが、今回受けた感じだと「当たらずも遠からず」といった印象
- Glue/EMR/Kinesisはそこそこ詳しく出る
- サービスの使い分け問題は非常に多かった
    - KinesisとMSKとSQS(FIFO)や、GlueとEMRとRedshiftなど
- どのサービスにもメリデメはあるので、問題文の要件に応じた回答をする
    - コストを最小限にするとか
- アクセス権限の制御問題は多数出た
- 分析クエリ遅い問題は鉄板
    - 読み込むデータセットのサイズを減らすか、処理効率の良い形式（Parquetなど）に変換するか、性能が良いサービス（EMRやRedshiftなど）に変えるかが基本的な対応
- リアルタイムのデータ分析＆可視化ではElasticSearchが強い
- 難しい問題は多かったが、一方で簡単な問題（というより他に選びようがない問題）も多かったので、諦めずに最後まで解く
- データ同期用途で意外と出てくるDatasyncとDMS
IBM Cloud で AWX を構築する

Red Hat Dojo #02 [Ansible Tower/AWX を体験してみよう](https://connpass.com/event/192916/)
 でデモする環境をIBM Cloud上で AWX の環境構築しました。
その際、てくなべ(tekunabe)さんの[「[Ansible]AWX を RHEL 8 にインストールする（HTTPS化もあり）」](https://tekunabe.hatenablog.jp/entry/2019/10/06/rhel8_awx7)を参照しました。

## インストール・起動

1. 準備編

- Git インストール

```
dnf install git -y
```
- python3 インストール 

```
dnf install python3 -y
```

- ansible インストールに必要な python ライブラリ・インストール

```
pip3 install docker-compose selinux
```

- ansible インストール

```
pip3 install ansible
```

- Docker インストール
 
```
dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo
dnf install --nobest docker-ce -y
systemctl start docker
systemctl enable docker
```

- AWX インストール準備

```
git clone https://github.com/ansible/awx
```

Ansible Tower/AWX を構成するコンテナの１つに「awx_task」があります。
この中にGit等のSCMリポジトリからダウンロードしてきたファイルが格納されます。
しかし、以下の設定を行わないとリソースをダウンロードすることができません。

```
cd awx/installer/
vi inventory
```

151行目 「project_data_dir」で始まる行のコメントアウトを外してください。

- インストール Playbook 実行

```  
ansible-playbook -i inventory install.yml
```

Playbook を実行したマシンに Web ブラウザからアクセスします。
http://localhost
5分くらい待ってもAWXが起動しないときには、一旦Ansibler Tower/AWXコンテナを停止し、再度インストール Playbook を実行してください。
    sudo docker stop $(sudo docker ps -aq)
    sudo /usr/local/bin/ansible-playbook -i inventory install.yml
【営業向け】スプレッドシートに記録した行動管理シートをSFの取り込み用フォーマットに整形する

#やりたいこと＆その理由
外部の営業のアウトソースを利用する際に、CRMとは別でスプレッドシートを用意して、委託先に共有したスプレッドシートに活動履歴を入力いただき、行動履歴を管理することがあるかと思います。ただ、その場合、以下のようなスプレッドシートで管理するのではないでしょうか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271600/6b77ef40-61d1-4456-8b83-61c685fa2285.png)

縦に会社名が並んでおり、横に1回目、2回目っという感じで活動履歴が並んでいるイメージです。

なお、SFに活動履歴を取り込むときには、以下のような形でCSVをアプロードする必要があり、手で作業をしようとすると、地獄のような作業量になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271600/10b3b6c8-4946-1664-fa53-fb12604da271.png)

これを何とか自動化できないかと思い、GASでスクリプトを作成。


#実装方法
１：　対象のスプレッドシートを取得
２：　取得したいシートの名前を指定して取得
３：　2で取得したシートで必要な情報を取得
４：　転記したい情報を別のスプレッドシートの一番最後の行に挿入


#完成系
ということで、完成形は以下。

```gas.js
function SalesforceImportMacro(){
  const SpreadSheet    = SpreadsheetApp.openById("スプレッドシートのID");
  var caldListSheet    = SpreadSheet.getSheetByName("営業管理シート");
  var caldListForMacro = SpreadSheet.getSheetByName("SF取り込み用シート");
  var ownerId          = "SFの所有者ID";
  var lastRow          = caldListSheet.getLastRow();
  
//活動履歴が記録されているシートのデータを配列で取得
  var data = caldListSheet.getDataRange().getValues(); 
  
  for(i = 1; i <= lastRow; i++){//行数の数に応じて繰り返し処理
    var columnNum  = 0; //下のFor分の処理が終わったら、columnNumを0にし、初期化
    for(num = 1; num <= 7; num++){
      var sfId        = data[i][0];
      var eventTitle  = data[i][9 + columnNum];//活動の件名を取得
      if(eventTitle == ""){//仮にeventTitleが空だったら処理を止めて次の処理へ
        break;
      }
      var startTime   = data[i][12 + columnNum];//開始時刻を取得
      var endTime     = data[i][13 + columnNum];//終了時刻を取得
      var description = data[i][15 + columnNum];//活動の詳細を取得

     //appendRowメソッドを使って、最終行に値を挿入する      
     caldListForMacro.appendRow([sfId,startTime,endTime,eventTitle,description,ownerId]);
      columnNum += 8; //8列毎に1回目、2回目、と並んでいるので、+8してあげる
    }
  }
```

#var data = caldListSheet.getDataRange().getValues(); の中身
console.log(data);で表示をしてみると、dataの中身は配列が入っています。後は、繰り返し処理で必要な情報を取得し、appendRowしているということです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271600/2592a7fa-3ee1-7a8c-a63e-cbfdb0fe10a5.png)




#アウトプット
無事に出したい形でアウトプットがされているが、とにかく処理が遅い。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271600/10b3b6c8-4946-1664-fa53-fb12604da271.png)

実はもともと、以下のようなコードを書いていたのだが、処理が遅すぎて終わるまでネットフリックスを見ていたぐらいｗ　getValueの量を減らして、かなり早くなったのだが、それでも遅い。

```コード.gas
  for(i = 2; i <= lastRow; i++){
    var columnNum  = 0;
    for(num = 1; num <= 7; num++){
      var sfId        = caldListSheet.getRange(i,1).getValue();
      var eventTitle  = caldListSheet.getRange(i,10 + columnNum).getValue();
      if(eventTitle == ""){
        break;
      }
      var startTime   = caldListSheet.getRange(i,13 + columnNum).getValue();
      var endTime     = caldListSheet.getRange(i,14 + columnNum).getValue();
      var description = caldListSheet.getRange(i,16 + columnNum).getValue(); 
      caldListForMacro.appendRow([sfId,startTime,endTime,eventTitle,description,ownerId]);
      columnNum += 8;
    }
  }
```

appendRowは非常に便利なメソッドなのだが、流石にこれを1,000回以上コールしてしまうと、時間がかかる。もう少し、良いアルゴリズムがあるはずなので、探ってみる。
TSQLの解析3 TRUNCATE文からの更新対象テーブル名の取得

# TSQLScriptDomParser
- 実行例

```batchfile
sqlparser -o xml -i -s "truncate table db1.sch1.tab1" > out.xml
query -s:out.xml -qs://node[@class='TruncateTableStatement']/children[@type='TableName']/node[@class='SchemaObjectName']/children[@type='BaseIdentifier']/node
```


- 出力例

```xml
<?xml version="1.0" encoding="UTF-8"?>
<node token="tab1"
      class="Identifier"
      Value="tab1"
      QuoteType="NotQuoted"/>
```

- 解釈

|項目|値|
|:--|:--|
|データベース名|/node/children[@type='DatabaseIdentifier']/node のvalue属性|
|スキーマ名|/node/children[@type='SchemaIdentifier']/node のvalue属性|
|テーブル名|/node/children[@type='BaseIdentifier']/node のvalue属性|

# ANTSQLParser 
- 実行例

```batchfile
sqlparser -o xml -i -s "truncate table db1.sch1.tab1" > out.xml
query -s:out.xml -qs://node[@rule='truncate_table']/node[@rule='schema_object_name'] !indent=true
```

- 出力例

```xml
<?xml version="1.0" encoding="UTF-8"?>
<node token="" rule="schema_object_name" value="db1.sch1.tab1">
   <node token="" rule="database_name" value="db1">
      <node token="" rule="id" value="db1">
         <node token="" rule="simple_id" value="db1">
            <node token="ID" rule="" value="db1"/>
         </node>
      </node>
   </node>
   <node token="'.'" rule="" value="."/>
   <node token="" rule="schema_name" value="sch1">
      <node token="" rule="id" value="sch1">
         <node token="" rule="simple_id" value="sch1">
            <node token="ID" rule="" value="sch1"/>
         </node>
      </node>
   </node>
   <node token="'.'" rule="" value="."/>
   <node token="" rule="table_name" value="tab1">
      <node token="" rule="id" value="tab1">
         <node token="" rule="simple_id" value="tab1">
            <node token="ID" rule="" value="tab1"/>
         </node>
      </node>
   </node>
</node>
```

- 解釈
 
|項目|値|
|:--|:--|
|データベース名|/node/node[@rule='database_name']//node[@token='ID']のvalue属性|
|スキーマ名|/node/node[@rule='schema_name']//node[@token='ID']のvalue属性|
|テーブル名|/node/node[@rule='table_name']//node[@token='ID']のvalue属性|
TSQLの解析2 INSERT/UPDATE/DELETE/MERGE文からの更新対象テーブル名の取得

# TSQLScriptDomParser
## INSERT/UPDATE/DELETE/MERGEでの更新テーブル名の取得
- 実行例

```batchfile
sqlparser -o xml -i -s "update db.sch.tab set a=1" > out.xml
query -s:out.xml "-qs://node[@class='DeleteSpecification' or @class='InsertSpecification' or @class='UpdateSpecification' or @class='MergeSpecification']/children[@type='Target']/node[@class='NamedTableReference']/children[@type='SchemaObject']/node[@class='SchemaObjectName']/children[@type='BaseIdentifier']/node" !indent=true
```

- 出力例

```xml
<?xml version="1.0" encoding="UTF-8"?>
<node token="db.sch.tab" class="SchemaObjectName" value="">
   <children type="DatabaseIdentifier">
      <node token="db" class="Identifier" value="db" QuoteType="NotQuoted"/>
   </children>
   <children type="SchemaIdentifier">
      <node token="sch"
            class="Identifier"
            value="sch"
            QuoteType="NotQuoted"/>
   </children>
   <children type="BaseIdentifier">
      <node token="tab"
            class="Identifier"
            value="tab"
            QuoteType="NotQuoted"/>
   </children>
   <children type="Identifiers">
      <node token="db" class="Identifier" value="db" QuoteType="NotQuoted"/>
      <node token="sch"
            class="Identifier"
            value="sch"
            QuoteType="NotQuoted"/>
      <node token="tab"
            class="Identifier"
            value="tab"
            QuoteType="NotQuoted"/>
   </children>
</node>
```

- 解釈

|項目|値|
|:--|:--|
|データベース名|/node/children[@type='DatabaseIdentifier']/node のvalue属性|
|スキーマ名|/node/children[@type='SchemaIdentifier']/node のvalue属性|
|テーブル名|/node/children[@type='BaseIdentifier']/node のvalue属性|

# ANTSQLParser 
## INSERT/UPDATE/DELETE/MERGEでの更新テーブル名の取得
- 実行例

```batchfile
sqlparser -o xml -i -s "update db.sch.tab set a=1" > out.xml
query -s:out.xml -qs://node[@rule='ddl_object']/node[@rule='schema_object_name'] !indent=true
```

- 出力例

```xml
<?xml version="1.0" encoding="UTF-8"?>
<node token="" rule="schema_object_name" value="db1.sch1.tab1">
   <node token="" rule="database_name" value="db1">
      <node token="" rule="id" value="db1">
         <node token="" rule="simple_id" value="db1">
            <node token="ID" rule="" value="db1"/>
         </node>
      </node>
   </node>
   <node token="'.'" rule="" value="."/>
   <node token="" rule="schema_name" value="sch1">
      <node token="" rule="id" value="sch1">
         <node token="" rule="simple_id" value="sch1">
            <node token="ID" rule="" value="sch1"/>
         </node>
      </node>
   </node>
   <node token="'.'" rule="" value="."/>
   <node token="" rule="table_name" value="tab1">
      <node token="" rule="id" value="tab1">
         <node token="" rule="simple_id" value="tab1">
            <node token="ID" rule="" value="tab1"/>
         </node>
      </node>
   </node>
</node>
```

- 解釈 
 
|項目|値|
|:--|:--|
|データベース名|/node/node[@rule='database_name']//node[@token='ID']のvalue属性|
|スキーマ名|/node/node[@rule='schema_name']//node[@token='ID']のvalue属性|
|テーブル名|/node/node[@rule='table_name']//node[@token='ID']のvalue属性|
C++で湯婆婆を実装してみる

# はじめに
@Nemesis さんの [Javaで湯婆婆を実装してみる](https://qiita.com/Nemesis/items/c7192a7c510788d2cba2) が話題になっていたので便乗しました。

# コード
``` yubaba.cpp
#include <algorithm>
#include <codecvt>
#include <iostream>
#include <locale>
#include <random>
#include <string>

using std::cout;
using std::endl;

int main()
{
  setlocale(LC_ALL, "ja_JP.UTF-8");

  std::string name_u8;
  std::u32string name;
  std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> utf32conv;
  std::random_device rnd;

  cout << "契約書だよ。そこに名前を書きな。" << endl;
  getline(std::cin, name_u8);
  cout << "フン。" << name_u8 << "というのかい。贅沢な名だねぇ。" << endl;

  name = utf32conv.from_bytes(name_u8); //名前を奪いやすくするためにUTF-32に変換
  name = name.substr(rnd() % name.size(), 1); // 適当な一字を拾って名前を奪う
  name_u8 = utf32conv.to_bytes(name); // UTF-8に戻す

  cout << "今からお前の名前は" << name_u8 << "だ。"
    "いいかい、" << name_u8 << "だよ。分かったら返事をするんだ、" << name_u8 << "!!" << endl;

  return 0;
}
```
[Wandbox で湯婆婆を実行してみる](https://wandbox.org/permlink/Fchxg6HEBNlLU0jf)

# 実行結果
### 千尋
```
契約書だよ。そこに名前を書きな。
千尋
フン。千尋というのかい。贅沢な名だねぇ。
今からお前の名前は尋だ。いいかい、尋だよ。分かったら返事をするんだ、尋!!
```

### Chihiro
```
契約書だよ。そこに名前を書きな。
Chihiro
フン。Chihiroというのかい。贅沢な名だねぇ。
今からお前の名前はrだ。いいかい、rだよ。分かったら返事をするんだ、r!!
```

# 解説
## 名前を入力してもらう
```
getline(std::cin, name_u8);
```
`std::cin >> name_u8;` としてそのまま入力を受けてもいいのですが、それだと何か入力しないと受け付けてもらえないので、`getline()` を使用しました。

## 名前を奪う
```
name = utf32conv.from_bytes(name_u8); //名前を奪いやすくするためにUTF-32に変換
name = name.substr(rnd() % name.size(), 1); // 適当な一字を拾って名前を奪う
name_u8 = utf32conv.to_bytes(name); // UTF-8に戻す
```
入力されたマルチバイトな文字列から文字を抜き取るのには工夫が必要なため、一旦 1 文字あたりのバイト数が固定の UTF-32 に変換し、扱いやすくしてから一字奪っています。
一字奪うときの乱数生成機には `random_device` クラスを使い、剰余演算で入力された文字列の中から奪えるように調整しています。

※剰余演算で調整すると偏りができるので、等確率な乱数を求めるなら `uniform_int_distribution` クラスを使って値を絞ったほうが良いです。

# おまけ
未入力時は `rnd() % name.size()` の箇所で浮動小数点例外が発生し、ちゃんとクラッシュします。

```
契約書だよ。そこに名前を書きな。

フン。というのかい。贅沢な名だねぇ。
浮動小数点例外
```
2020年しあわせ大賞：emacs + org-capture on macOS

# 背景

今年はコロナでいろいろあった（まだ終わってないけど）。いちばん良かったのは「macOSでかんたんにemacsが使える」のを発見できたこと。2020年でいちばんハッピーなことだったかも（まだ終わってないけど）。

macOSはunixであると再確認できたし、Homebrewなどのパッケージ管理がすげー便利であることも知ることができた。MacBookさいこー。

macbook/emacsさいこー、と言いつつも、めっちゃコーディングをするわけでもなく。なにより便利で使い続けているのはorg-capture。まじでべんりです。

何をどうしたか、忘れそうなので記録しておく。


# emacsのインストール

1. Homebrewを使えるようにする
1. emacsをインストールする


## Homebrewを使えるようにする

```bash
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
```

Xcodeの「command line tools」が入っていない場合は、インストールするか聞かれるのでYesを選択。ダウンロード＆インストールしてくれる。


## emacsをインストールする

```bash
$ brew tap railwaycat/emacsmacport
$ brew cask install emacs-mac
```

①emacs on terminal　②emacs with cocoa　③cask emacs ④emacs-mac　があって、まあ、④emacs-macが良いみたい。理由がいまいち思い出せないんだよな。たぶん、日本語入力のときにチラつかないんだったと思う。


## 設定する

- 月ごとぐらいに1ファイル作って、ここに何でも書き込む
- このファイルから、メモもブログも生み出されてほしい
- できれば先頭に新しいエントリが入ってほしいが、これは尚可要件　→　設定の仕方がわからないので求めない

```emacs-lisp:init.el
  ;; キーバインドの設定
  (global-set-key (kbd "C-c c") 'org-capture)

  ;;ファイルパスの設定
  (setq work-directory "~/xxx/xxx/")
  (setq journalfile (concat work-directory "yymmdd_xxxx_journal.org"))

  (setq org-capture-templates
        '(
          ("j" "Journal" entry (file+datetree journalfile)
           "* %U\n%?\n%i\n"
           :empty-lines 1)
          )
        )
  (setq org-refile-targets '((journalfile :maxlevel . 3)))
```


# 使用感

## メモをとる（キャプチャ）

![output.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184128/4be7a8eb-d293-10e0-bb77-f4847b127304.gif)

## 操作

- （org-modeにいると、だろうか？）`<C-c> c`で`*org-select*`画面になる
- `j`を押すと`[j] Journal`テンプレートを選ぶ（テンプレは`init.el`で設定してある） 
- キャプチャ画面になるので、適当に書いて`<C-c><C-c>`するとjournal.orgファイルに書き込まれる（書き込み先は`init.el`で設定してある） 
- キャプチャ画面で`<C-c><C-k>`すると、書いたものを破棄


# 参考サイト

## 主にemacsのインストール

[homebrewからインストールできるemacsの違い](https://qiita.com/kokorinosoba/items/ecceaabe07d91c6f2c66)

[Mac で emacs を使ってみる 2020年度版](https://mac-ra.com/mac-emacs-2020/)

[Emacs Mac PortをHomebrewからインストールする](https://qiita.com/hnw/items/d7d71dfcfecff80ad8f1)


## 主にorg-mode, org-capture

[モーレツ! ORG MODE 教室 その1: 素早くメモを取る](https://www.mhatta.org/wp/2018/08/16/org-mode-101-1/)

[org-captureをカスタマイズして、すばやくメモを取る方法](https://www.5ing-myway.com/org-capture/)

[Org-modeで、ライフログを録ろう](https://qiita.com/takushi1969/items/1653235191c0d1538a84)

[モーレツ! ORG MODE 教室 その2: まとまった文章を書く](http://www.mhatta.org/wp/2018/08/18/org-mode-101-2/)

[org-mode 私の使い方](https://blog.mallfun.info/archives/439)


## 自分の作業ログより

[虎（牛）龍未酉2.1](https://masatler.hatenablog.com/search?q=org)


# 環境

GNU Emacs 27.1 (build 1, x86_64-apple-darwin19.6.0, Carbon Version 162 AppKit 1894.6) of 2020-11-05
macOS Catalina バージョン 10.15.7（19H2）
MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports)
Win10のIntelliJ IDEAにてDartでHello Worldを書く

### 前提
IntelliJ IDEA
Dart SDK
をインストールされました。

IntelliJ IDEAのインストール手順は少々お待ちくださいね。
Flutter SDKをインストールすると、Dart SDKは自動的にインストールされました。
Flutter SDKのインストールは下記の記事に記載しています。
[Win10にてFlutterの開発環境構築ーーFlutter SDK Install（2020年保存版）](https://qiita.com/blue_skytree/items/6063aedef38d6c663214)

本文は三つの部分を分けています。
● Dart Pluginインストール
● 新規プロジェクト
● Hello Worldを書く

### Dart Pluginインストール
IntelliJ IDEAを開いて、下のConfigureボタンをクリックして
![tempsnip.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/858237/4989f732-e40d-b0db-067a-3a8ca7fefdcb.png)
プルダウンのPluginsをクリックして、プラグイン画面がポップアップします。
![tempsnip2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/858237/51c59742-0981-9cbf-dee4-b81765443d55.png)
Dartを検索して、右のインストールボタンを押して、
![tempsni4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/858237/8b62424c-3128-c6a5-0781-ee1b57049c42.png)
インストールした後でOKボタンを押します。
![tempsnip4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/858237/d1bd7743-2cc8-4568-e7e0-597c75ee36ab.png)

### 新規プロジェクト
IntelliJ IDEAを開いて、New Projectをクリックして
![tempsnip7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/858237/81c04beb-dd7a-399c-568f-ed322aaa4042.png)

Dartを選択して、インストールされたDart SDK Pathを選択して、Nextボタンを押下して
![tempsnip5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/858237/dc301436-56d3-70fb-c5cc-effb208e9a7a.png)
プロジェクト名前と場所を書いて、Finishボタンを押下します。
![tempsnip6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/858237/824b297d-ee23-1105-7594-7ec69cb31804.png)

### Hello Worldを書く
Dart-Basicプロジェクトを選択して、右クリックして、New→Directory
![tempsnip8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/858237/04e91be3-2d44-fe62-808c-e8e64e536c5e.png)
Directory名を入力して、Enterを押して
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/858237/c8b5895f-147c-ac54-14ae-9cd0d831b890.png)
先ほど作成したchapter1というDirectoryを選択して、右クリックして、New→Dart File
![tempsnip9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/858237/99ed4505-48ee-6564-9774-4145ed47da59.png)
Dart File名を入力して、Enterを押します。
![キャプチャ3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/858237/1532a2ce-3681-8d66-db51-c677bab28112.png)
hello_world.dartにて下記のコードを書きましょう。

```
void main(){
  print("Hello World!");
}
```
hello_world.dartというファイルを選択して、右クリックして、「Run 'hello_world.dart'」をクリックします。
![tempsnip1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/858237/77a7e782-3362-efeb-3759-d2774d08d257.png)
コントロールにて下記の結果が出ますと、正確に実行されました。
![キャプチャ4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/858237/b6dff144-314b-cffb-bd18-402b762fb6cd.png)

以上です。ここまで読んでいただきまして、ありがとうございました。
もし何か質問があれば、遠慮なくコメントしてくださいね。

またね。:smiley:
高さが動的な要素を含むFlatListで特定位置までのスクロールを実装する 【React Native】

## 概要

高さが動的な要素を含むFlatListで特定位置までのスクロールを実装する際に 、詰まった点が少しあったので備忘録を残しておきます。

## ScrollToIndex ではなく ScrollToOffset を使用する

高さが静的な要素のみの場合は scrollToIndex を使用しても問題ないです。
要素の数が多く一画面に収まらない場合には getItemLayout を一緒に用いるのも忘れないようにしましょう。
上記を用いることで、数百個のアイテムを持つリストのパフォーマンスを大幅に向上させることができます。

```tsx

getItemLayout={(data, index) => (
    {length: ITEM_HEIGHT, offset: ITEM_HEIGHT * index, index}
  )}
```
今回は高さが動的な要素を含むので、getItemLayoutでの特定の位置までの計算が上手くいかず、結果的に ScrollToIndex を使用するべきではないと判断しました。
その代替案として ScrollToOffsetを使用することにしました。
ScrollToOffsetは、特定位置までのオフセット(基準点からの位置)を指定するだけで、その位置までのスクロールを実装することができます。

実装例

```tsx 
import { useEffect, useRef } from 'react';
import { FlatList } from 'react-native';

const Smaple: React.FC = () => {
  const ref = useRef<FlatList>(null);
  useEffect(() => {
    ref.current?.scrollToOffset({
      offset: 
      // NOTE: offsetの高さ(内部で計算可能 ex index * LIST_HEIGHT)
      animated: false,
    });
  });

  return (
    <FlatList
      ref={ref}
      data={data}
      renderItem={({ item }) => item}
      keyExtractor={(item): string => item}
    />
  );
};
```

上から順にコード内容を解説していきます。
まず、useRef を用いることで FlatList にアクセスして ScrollToOffset 関数を使用できるようにしています。

次に関数の内容に関してです。
FlatListの型定義を見てみましょう。(他の関数も定義されているが長くなるので、 scrollToOffset の箇所のみ抜粋)

```ts
export class FlatList<ItemT = any> extends React.Component<FlatListProps<ItemT>> {
    /**
     * Scroll to a specific content pixel offset, like a normal `ScrollView`.
     */
    scrollToOffset: (params: { animated?: boolean | null; offset: number }) => void;
```

上記の型定義からわかるように、ScrollToOffset は2つの引数を取ります。
offset は必ず指定する必要があります。
スクロールしたい箇所までのオフセットを指定します。(内部で計算可能 ex index * LIST_HEIGHT)
animated に関してはオプショナルで必ず指定する必要はないです。(デフォルトの設定は true)

useEffect を使用しているのは、関数の実行タイミングを調整するためです。
前提として useEffect に渡された関数はレイアウトと描画の後で遅延されたイベントとして実行されます。
今回は動的な高さを持つ要素を含むリストでのスクロールなので、レンダリング前に上記関数を実行すると、特定位置までのオフセットの値を正確に取得できなかったです。(オフセットの値を LIST_HEIGHT (固定値) * Index ( Redux から取得した値)で指定していたため。)

今回の実装例では、本関数を使用するファイル内で定義することを想定していますが、カスタムフックとして別ファイルに抜き出すことをおすすめします。
その際には引数として`ref:RefObject<FlatList>`を受け取るようにすれば良いでしょう。

## まとめ

今回はFlatListで特定位置までのスクロールに関してまとめました。

- 高さが**静的**な要素のみの場合は scrollToIndex を使用しても問題なし。
- 高さが**動的**な要素を含む場合は scrollToOffset を使用する。

場合によっては ScrollToOffset でも上手くいかない場合はあると思います。
その際には公式ドキュメントをしっかり読んで、それぞれの関数の役割を理解することから始めましょう。

## 参考

ReactNative 公式ドキュメント
https://reactnative.dev/docs/flatlist
画面遷移の方法

# はじめに
学習でのアプリ開発で、`1 Storyboard — 1 ViewController`で設計しているのですが、画面遷移についての方法をいつもネットで検索していると気づきましたので、備忘録として投稿します。

上記の方法で設計している理由としまして、1つの`ViewController`につき1つの`StoryBoard`を用意する作り方は共同開発におけるコンフリクトが少なくなるとのことです。


# 動作環境
【Xcode】Version 12.0.1
【Swift】Version 5.3


# 実装方法 （ navigationController を使う）

```Swift:
// 遷移先のView（NextViewController）を取得
let storyboard = UIStoryboard(name: "Next", bundle: nil)
let nextVC = storyboard.instantiateViewController(withIdentifier: "NextVC") as! NextViewController
// NextViewControllerへ画面遷移
self.navigationController?.pushViewController(nextVC, animated: true)
```


# 実装方法 （ navigationController を使わない）

```Swift:
// 遷移先のView（NextViewController）を取得
let storyboard = UIStoryboard(name: "Next", bundle: nil)
let nextVC = storyboard.instantiateViewController(withIdentifier: "NextVC") as! NextViewController
// NextViewControllerへ画面遷移
self.present(nextVC, animated: true, completion: nil)
```


# 実装方法 （ storyboard の設定）
* `Storyboard`の画面をインスタンス化するので、`Storyboard ID`をつけておく必要があります。`Use Storyboard ID`にチェックをつけるのを忘れないように注意してください。

![スクリーンショット 2020-11-08 20.16.46（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692635/38a99300-a383-cc8e-f5e2-ef294fb2b45f.png)


# まとめ
画面遷移の方法はまだまだありますので、随時更新できればなと思います。
Google Colabで今使っているNotebook名を取得する方法

Stackoverflowに回答がありました。

```
from requests import get
filename = get('http://172.28.0.2:9000/api/sessions').json()[0]['name']
```

https://stackoverflow.com/questions/61901628/it-is-possible-to-assign-the-google-colab-notebook-name-to-a-python-variable-in
Herokuのアップデート対処

Herokuのアップデートに失敗したときの対処を備忘録として残しておきます。

# アップデートコマンド実行時（失敗）
Herokuの実行ログを見ていると、下記の表示が出てきたため、バージョン更新コマンド`heroku update`を実行した。

```
root@raspberry:/home/pi# heroku logs --app sample-project
 ?   Warning: heroku update available from 7.42.1 to 7.47.0.
（省略）
```


```
root@raspberry:/home/pi# heroku update
 ?   Warning: update with: "npm update -g heroku"
heroku: Updating CLI... not updatable
Updating completions... done
```
しかし、herokuアップデートに失敗した。

# 対処
上記のログ通り、`npm update -g heroku`を実行して解決した。

```
root@raspberry:/home/pi# npm update -g heroku
npm WARN npm npm does not support Node.js v10.19.0
npm WARN npm You should probably upgrade to a newer version of node as we
npm WARN npm can't make any promises that npm will work with this version.
（省略）
/usr/local/bin/heroku -> /usr/local/lib/node_modules/heroku/bin/run
+ heroku@7.47.0
added 250 packages from 38 contributors, removed 4 packages, updated 98 packages and moved 2 packages in 238.005s
```

# 確認
バージョンアップを下記のコマンドでも確認した。

```
root@raspberry:/home/pi# heroku version
 ?   Warning: Our terms of service have changed:
 ?   https://dashboard.heroku.com/terms-of-service
heroku/7.47.0 linux-arm node-v10.19.0
```
音声合成でインストールされているパーソナリティを表示し、しゃべらせる

いまさら？というスクリプトだけど、一応とりあげとく。

ファイルをダブルクリックで実行。
(実行環境： Windows10, Window7 等)

PS: Microsoft David はどのファイルでインストールされたのか？


persons.vbs


```vb

Dim aa
Set Speaker = CreateObject("SAPI.SpVoice")
Speaker.Rate = 1
aa = ""
For i = 0 To Speaker.GetVoices.Count -1
  aa = aa & i & ": " & Speaker.GetVoices.Item(i).GetDescription & vbCrLf
Next
WScript.echo aa
For i = 0 To Speaker.GetVoices.Count -1
  Set Speaker.Voice = Speaker.GetVoices.Item(i)
  Speaker.Speak Speaker.GetVoices.Item(i).GetDescription
Next
Set Speaker = Nothing

```


しゃべらない？　なら、
マイクロソフトスピーチプラットフォームをインストールしてる？

マイクロソフトスピーチプラットフォーム

http://www.microsoft.com/en-us/download/details.aspx?id=27225

* x86_SpeechPlatformRuntime￥SpeechPlatformRuntime.msi <br>
　　または
* x64_SpeechPlatformRuntime￥SpeechPlatformRuntime.msi

日本語を追加

http://www.microsoft.com/en-us/download/details.aspx?id=27224

* MSSpeech_TTS_ja-JP_Haruka.msi
* MSSpeech_TTS_en-US_Helen.msi
* MSSpeech_TTS_en-US_ZiraPro.msi
* MSSpeech_SR_ja-JP_TELE.msi 　　　　これは音声認識だけれど ついでに



#### 無料 フリーウェア スクリプト アプリ プログラム
【エラー解決】springをdockerで環境構築しようとした際に発生

##目的

<font color="OrangeRed">**エラー**</font>発生。
Dockerで開発環境を構築した際に遭遇した。
エラー文と解決策を忘れないように載せておく

##結論
以前作ったコンテナはプロジェクトではなくコマンドで削除しないと消えないことがわかった
ポート番号でエラーがおきた原因は分からなかった。


##状況
javaのspringをdockerで環境構築をしようとした際に発生した。
Flywayをマイグレーションツールとして入れていた。


##<font color="OrangeRed">**【環境構築】**</font>

```iterm
$ docker-compose up -d
Starting vi_bank_db_1 ... error
ERROR: for vi_bank_db_1  Cannot start service db: Ports are not available: listen tcp 0.0.0.0:3306: bind: address already in use
$ lsof -i :3306 →何も表示されない
```

##<font color="OrangeRed">**エラー**</font>

```
ERROR: for db  Cannot start service db: Ports are not available: listen tcp 0.0.0.0:3306: bind: address already in use
ERROR: Encountered errors while bringing up the project.
$ docker-compose down
WARNING: Found orphan containers (vi_bank_flyway-repair_1, vi_bank_flyway-info_1, vi_bank_flyway-migrate_1, vi_bank_flyway-clean_1) for this project. If you removed or renamed this service in your compose file, you can run this command with the --remove-orphans flag to clean it up.
Removing vi_bank_db_1 ... done
Removing network vi_bank_default
$ docker-compose up -d --remove-orphans
Creating network "vi_bank_default" with the default driver
Removing orphan container "vi_bank_flyway-migrate_1"
Removing orphan container "vi_bank_flyway-repair_1"
Removing orphan container "vi_bank_flyway-info_1"
Removing orphan container "vi_bank_flyway-clean_1"
Creating vi_bank_db_1 ... error

ERROR: for vi_bank_db_1  Cannot start service db: Ports are not available: listen tcp 0.0.0.0:3306: bind: address already in use

ERROR: for db  Cannot start service db: Ports are not available: listen tcp 0.0.0.0:3306: bind: address already in use
```

##<font color="OrangeRed">解説</font>

Found orphan containers
同じプロジェクトにすでにコンテナがあるよ、注意されました。
以前個人で作ったコンテナが残ったままだったようです。
Dockerでの開発初めてなので勉強になります。
これの`docker-compose up -d`が実行されない原因のようです。
エラーにしたがってコマンドを実行します

```
$ docker-compose up -d --remove-orphans
```

<font color="OrangeRed">**【解決策】**</font>

- ポート番号を3306→3307に変更した

```yaml:docker-compose.yml

version: '3.7'
services:
  db:
    image: mysql:8.0.20
    ports:
      - "3307:3306"
```

その後

```
$ docker-compose up -d
Recreating vi_bank_db_1 ... done
$ docker-compose exec db mysql -u docker -p
パスワード入力→成功
mysql>
```

<font color="OrangeRed">**発生したエラー**</font>
ERROR: for vi_bank_db_1  Cannot start service db: Ports are not available: listen tcp 0.0.0.0:3306: bind: address already in use

対処法

```
$ lsof -i :3306
#何も表示されない
$ docker-compose up -d
Recreating vi_bank_db_1 ... done
```

更新201108
####<font color="OrangeRed">エラー解決</font>

Gradleのjavaのバージョンが設定できていなかった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313771/73050c82-0d7d-da14-0290-6edbfbf2614e.png)


参考にした記事（いつもありがとうございます）
---

[DockerでMySQLを利用する[docker container run オプション]
](https://noumenon-th.net/programming/2018/12/26/docker-mysql/)

[Error starting userland proxy: listen tcp0.0.0.0:3306: bind: address already in use](https://stackoverflow.com/questions/37896369/error-starting-userland-proxy-listen-tcp0-0-0-03306-bind-address-already-in)
path_providerをAndroidで利用するとエラーが発生してしまう

Flutterにおけるストレージのパス取得のためのプラグイン`path_provider`がAndroidで動作しない問題でハマったので解決策をメモしておきます。

# 事象

[path_providerプラグイン](https://pub.dev/packages/path_provider)の`getTemporaryDirectory()`などのメソッドをAndroidで実行すると、以下の例外が発生していました。

```shell
MissingPluginException(No implementation found for method getTemporaryDirectory on channel plugins.flutter.io/path_provider)
```

# 解決策

該当プロジェクトでは、ネイティブのUIをそのまま組み込むことができる**PlatformViewを利用**していますが、AndroidのネイティブコードにおけるPlatformViewを登録する場所で、**overrideしたメソッドの親メソッドを呼び出していない**ことが原因でした。

```kotlin:MainActivity.kt
class MainActivity: FlutterActivity() {
    override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
        // 以下1行を記述していなかった
        super.configureFlutterEngine(flutterEngine)

        flutterEngine
                .platformViewsController
                .registry
                .registerViewFactory("<platform-view-type>", NativeViewFactory())
    }
}
```

# 補足

[公式のPlatformViewのサンプル](https://flutter.dev/docs/development/platform-integration/platform-views#android)には、`super`メソッドの呼び出しが記述されていないので、そのままコピペすると発生してしまいます。

詳しい原因は調べられていないですが、親メソッドの呼び出しがスキップされることで、プラグインで利用するネイティブ側のメソッド登録が実行されないために、事象が発生してしまうと考えられます。
composer のバージョンをアップデートする

## アップデートコマンド

最新バージョンにアップデート (今だとバージョン 2.x へ)

```
composer self-update
```

バージョンを指定してアップデート (1.10.17 を指定する場合)

```
composer self-update 1.10.17
```

バージョン 1 の最新 stable にアップデート

```
composer self-update --1
```

[Command-line interface / Commands - Composer](https://getcomposer.org/doc/03-cli.md#self-update-selfupdate-)

## エラーが発生する場合

下記のようなエラーが発生する場合

```
SHA384 is not supported by your openssl extension, could not verify the phar file integrity 
```

composer のバージョンが古すぎるため、コマンドで更新できません。再インストールが必要です。

[公式ドキュメント](https://getcomposer.org/doc/00-intro.md#installation-linux-unix-macos)通りにインストールしていれば、同じように。

```
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('sha384', 'composer-setup.php') === 'c31c1e292ad7be5f49291169c0ac8f683499edddcfd4e42232982d0fd193004208a58ff6f353fde0012d35fdd72bc394') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"
```

Mac/Linux であれば下記のように `composer.phar` をグローバルで使えるように。

```
mv composer.phar /usr/local/bin/composer
```

インストールできたか確認する。

```
$ composer -v
   ______
  / ____/___  ____ ___  ____  ____  ________  _____
 / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
                    /_/
Composer version 2.x.x
```
【Rails】Travis CIを導入してdb:createで詰まったこと

# はじめに
自動テストツール`Travis CI`を導入するときにつまづいたことを書きます。

# 環境
・Ruby 2.6.5
・Rails 6.0.3.2
・Mysql Ver 14.14 Distrib 5.6.47

# 問題点
以下のような`.travis.yml`に記述している`db:create`がどうしても通らないという問題が発生しました。

```yaml

script:
  - bundle exec rake db:create RAILS_ENV=test
  - bundle exec rake db:migrate RAILS_ENV=test
  - bundle exec rspec
```

`Travis CI`の画面ではこのようなエラーメッセージがでました。

![DBcreate.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667396/43835429-0815-b85e-2299-ea2fc58ab7f5.png)

```
Mysql2::Error::ConnectionError: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
```

いろいろ調べてみるとソケットファイルが無いということがわかりました。
`database.yml`の記述のソケットファイルへのパスが誤っているということです。
今回使用したDBは　`MySQL`です。

```yaml

test:
  <<: *default
  database: (myapp)_test
  adapter: mysql2
  encoding: utf8
  username: root
  password:
  socket: (ここの記述)

```

# 解決策

でもローカルではない`Travis CI`のなかのファイル構成はどうしてもわからなかったので自力で確認することにしました。

まずはソケットファイルの場所を調べるコマンドは以下です。

```
$ mysql_config --socket
```

ローカル環境ではこれでわかるので、もしかしたら`.travis.yml`の`script:`に記述すれば「Travis CI上の`mysqld.sock`の場所がわかるかもと思い、この記述をプラスしました。(正しいやり方かはわかりませんけど・・・)

```yml

script:
  - mysql_config --socket　　（←ソケットファイルを確認する）
  - bundle exec rake db:create RAILS_ENV=test
  - bundle exec rake db:migrate RAILS_ENV=test
  - bundle exec rspec
```
すると、

![MySQL.soke.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667396/f01df185-572b-09e4-43a2-b21875f69597.png)

なんと値が返ってきました！５１５行目の記述です！

```
/var/run/mysql/mysqld.sock
```

これをdatabase.ymlに記述すれば、無事に`db:create`が通りました！

# ローカルの時とTravisCIの時の使い分け

このままだと逆にローカルでのテストがうまくいかないので`TravisCI`でのテストの時には上記でしらべたソケットを参照するようにします。

`TravisCI`専用として`database_travis.yml`を作成し以下のような記述。

```yml

test:
  <<: *default
  database: (myapp)_test
  adapter: mysql2
  encoding: utf8
  username: root
  password:
  socket: /var/run/mysqld/mysqld.sock
```

そして`.travis.yml`に以下を追記

```yml

before_script:
  - "cp config/database_travis.yml config/database.yml"
```

この時だけ書き換えるようにしたらローカルでも`TravisCI`でもテストが動きました。
データベースのエラーはなかなか原因にたどり着けなく苦労しました。

![buildpass.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667396/7470993f-4411-4878-c2b1-0fde9191d5ec.png)

無事にこのバッジをReadmeにつけることができました！！
Nuxt.jsで無限スクロール（Infinite Scroll）を実現する方法

nuxt.jsで無限スクロールを実現する方法を紹介します。

# vue-infinite-loadingのインストール

[vue-infinite-loading](https://github.com/PeachScript/vue-infinite-loading)をインストールします。

```
npm install vue-infinite-loading --save
```

# 無限スクロールの実装

### プラグイン導入

pluginsディレクトリ配下にinfiniteloading.jsファイルを作成し、以下を追加します。

```javascript:infiniteloading.js
import Vue from 'vue'
import InfiniteLoading from 'vue-infinite-loading'
 
Vue.use(InfiniteLoading)
```

`nuxt.config.js` にプラグインを追加します。

```javascript:nuxt.config.js
plugins: [
    { src: '~/plugins/infiniteloading', ssr: false }
]
```

### ページに実装

無限スクロールを実現したいページに以下を入れます。（dataを３件ずつ表示するという単純な例です。実際の表示部分は例では実装していないので、適宜追加してください）

```vue:index.vue
<template>
~~
~~
  <infinite-loading
    ref="infiniteLoading"
    spinner="waveDots"
    @infinite="infinite"
  >
    <span slot="no-more">これ以上ない</span>
    <span slot="no-results">データはない</span>
  </infinite-loading>
~~
~~
</template>
~~
~~
<script>
import InfiniteLoading from 'vue-infinite-loading'

export default {
  components: {
    InfiniteLoading
  },
  data() {
    return {
      data: [1,2,3,4,5,6,7,8,9,10],
      displayData: [],
      pageIndex: 0,
      perPage: 3
    }
  },
  methods: {
    infinite($state) {
      this.pageIndex++
      this.displayData = this.data
        .slice(0, (this.pageIndex + 1) * this.perPage)
      if (this.displayData.length !== this.data.length) {
        $state.loaded()
      } else {
        $state.complete()
      }
    }
  }
</script>
```

`spinner="waveDots"` は読み込み中の表現を指定します。上記の例では以外にも`spiral` `circles` `bubbles` などがあります。
詳細は[こちら](https://peachscript.github.io/vue-infinite-loading/guide/configure-load-msg.html)。

`<span slot="no-more">` はこれ以上表示内容がない場合（`$state.complete()` が呼ばれた場合）、`<span slot="no-results">` はデータがない場合に表示されます。


# 静的ページの場合

`nuxt generate` を実行する場合は上記のままだと `ReferenceError: document is not defined` というエラーになります。
そのため、以下のように修正が必要です。

### less と less-loader のインストール
```
npm install less less-loader --save-dev
```

### import の修正
```修正前のindex.vue
import InfiniteLoading from 'vue-infinite-loading'
```

```修正後のindex.vue
import InfiniteLoading from 'vue-infinite-loading/src/components/InfiniteLoading.vue'
```

以上により、nuxt generateも可能になります。
Rails6でのjQuery導入方法

# はじめに
## やりたいこと
- いいね機能のAjax対応を実装したい
- そのためにjQueryを導入したい

## 動作環境
ruby 2.6.5 / Rails 6.0.3.4

## やってみて
Rails６から標準装備されているWebpackerを利用することで簡単に実装できました。
多くの記事がRails5までの情報でとっっっても遠回りしたので、6以降の方は僕のように無駄な時間を使わないでいただけたら…

##参考URL
[Railsガイド > Rails で JavaScript を使用する](https://railsguides.jp/working_with_javascript_in_rails.html)

#手順
- jQueryのインストール
- Webpackの設定
- application.jsの設定
- 動作確認

##　jQueryのインストール
そもそもjQueryとは
>JavaScriptをより簡単に記述するためのライブラリのひとつ。

したがって、jQuery（ライブラリ）を使うのであればJavaScript（元のプログラミング言語）にコンパイル（翻訳）する必要があります。
コンパイルする方法はいろいろありますが、初学者故、とりあえず簡単なWebpackerを使用していこう！というのが本記事の主旨であります。

ではまず、jQueryのインストールを行います。

```:ターミナル
% yarn add jquery
```
Rails5以前の導入方法ではjquery-railsというGemをインストールするのが基本線のようですが、Webpackerで管理する際はyarnコマンドを使用してインストールします。

***GemをGemfileからインストールしていたのでこちらの記事を参考に削除しました***
[> GemfileでインストールしたGemを削除する](https://qiita.com/sys_cat/items/16d55e7cd8a3f177863a)


yarnとは
>JavaScriptのパッケージマネージャー。Node.jsで動作するパッケージを管理する。

Node.jsとは
>本来フロントサイド開発用の言語であるJavaScriptをサーバーサイドで使うための「環境」のこと
Node.jsのおかげで簡単にAjax対応ができたりする。

つまり、Webpackerという翻訳機にjQueryという言語をyarnというサーバー用の説明書で登録した、という感じでしょうか（違ってたらごめんなさい）

## Webpackの設定
Webpackの設定ファイルでjQueryを管理下として認定します。

```javascript:config/webpack/environment.js
const { environment } = require('@rails/webpacker')
// 以下追記
const webpack = require('webpack')
environment.plugins.prepend('Provide',
    new webpack.ProvidePlugin({
        $: 'jquery/src/jquery',
        jQuery: 'jquery/src/jquery'
    })
)
// ここまで
module.exports = environment
```

## application.jsの設定
application.jsでjQueryを呼び出せるようにします。

```javascript:javascript/packs/application.js
//中略

require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
// 追記
require('jquery')

//中略
```
以上で導入は完了です。

## 動作確認
jQueryが問題なく動作しているか確認します。
好きなページに次のコードを転記します。

```:好きなページ.html.erb
<p>テスト</p>
<script type="text/javascript">
  $(document).ready(function() {
    $("p").text("成功！！");
  });
</script>
```
p要素のテキストに”成功！！”を代入するようになっています。

(成功例）
![スクリーンショット 2020-11-08 18.55.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/771826/ba50f174-66ee-28b3-96ea-636b728f8505.png)
このように「テスト」ではなく「成功！！」と表示されていれば動作確認は完了です。


#おわりに
いろいろな記事を調べてgemを導入したりしていたのですが、Webpackerを使えば簡単に実装できました。

特に今回、JavaScriptとjQueryを調べていく中で、Node.jsのことを表面的にでも理解できたのはよかったかなと思います。

参考にさせていただいた記事
[エンジニアの入り口 > 初心者向け！3分で理解するNode.jsとは何か?](https://eng-entrance.com/what-is-nodejs)


***

***Ruby / Rails 初学者向けの記事を書いています。***
***今後も週3〜4記事ペースで更新していきたいと思いますので、初学者のみなさん、ぜひフォローお願いします！！***

最後までお読みいただきありがとうございました！

✔︎
Mysqlで、テーブル内のデータを消したいとき

##本記事の内容
特定のテーブルないのデータを消すだけです。
カラムやテーブル、DBを削除する方法ではありません。

##方法
以下は全てターミナルで行う動作です。
###1 ```mysql -u root```　でmysqlにログイン。
###2 ``` use DB名```　で、扱いたいデーターベースを指定する。
###3 ```delete from テーブル名;``` で、データを削除。テーブル名は削除したいデータがあるテーブル名を指定。
###(4) ```ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`DB名`)　```
もしも、上記のようなエラーが出たら、これはそのテーブルと他のテーブルで外部キーを使用しているので、削除ができないという表示です。
その時は、``` set FOREIGN_KEY_CHECKS=0;```と入力し、一旦外部キー制約を無効にします。
その上で、もう一度3の動作を行ってください。
```Query OK, 8 rows affected (0.00 sec)```　が表示され、削除に成功しています。
その後、以下のコマンドで、再び外部キー制約を有効にします。
```set FOREIGN_KEY_CHECKS=1;```

以上で、データの削除は完了です。
【Android】SpinnerをXmlのみで初期選択値を決める【Databinding＆BindingAdapter】

Android 開発において、Spinnerというものがあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520701/3f5316cb-3a5f-3a19-b6f4-e972d5349a71.png)

Webでは`select`が挙げられると思われます。

selectでは、option要素にて、

```
<select name="example">
<option value="サンプル1">サンプル1</option>
<option value="サンプル2">サンプル2</option>
<option value="サンプル3" selected> サンプル3</option>
</select>

```
`selected`を指定すれば、自動でサンプル3に選択されますが、

Androidの場合、初期値をXmlで指定することができなさそうでした。（もしあったら教えてほしい(´;ω;｀)）


ゆえに何を使うかと調べたところ、

```kotlin:Activity.kt
val spinner: Spinner = findViewById(R.id.spinner)
spinner.setSelection(positon)
```

こんな感じでActivityやFragmentにて、Spinnerを呼び出し`setSelection()`メソッドを呼び出し、インデックスを指定するそうです。


しかし、自分はDataBindingやViewModelを勉強しだしており、ちょっと、ここにベタベタ書きたくない。。と思ってしまった。


ということでDataBindingを使った方法で切り抜けます。


## やり方

https://developer.android.com/topic/libraries/data-binding/binding-adapters?hl=ja

### 1. Moduleを使えるようにする

まず、DataBindingとViewModelを実装できるようにします。

https://developer.android.com/topic/libraries/data-binding/start?hl=ja
↑DataBindingのスタートガイド
https://developer.android.com/jetpack/androidx/releases/lifecycle?hl=ja
↑LifecycleのModuleの依存関係

こちらを参照して、`build.gradle(app)`を変更して使える状態にします。
### 2. Xmlを変更

```xml
<Spinner
            android:id="@+id/spinner_one"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="30dp"
            android:OnItemSelected="@{ここに数値}"
```

ここのOnItemSelectedの中に、リスト何番目を選択してほしいか書いていきます。

現状でBuildしてもXmlのエラーが出ます。


### 3.メソッドを実装
https://developer.android.com/topic/libraries/data-binding/binding-adapters?hl=ja
こちらはBindingAdapterのメソッドの話があります。これを見れば、正直僕より参考になります。
僕は、カスタムロジックでやったので、Kotlin-kaptをapplyしなきゃでした。

``` build.gradle(app)
apply plugin: 'kotlin-kapt'
```

その後、適当にファイルでも作って、メソッドを実装していきます。

```kotlin:BindingAdapters.kt
BindingAdapter("android:OnItemSelected")
fun onItemSelected(view: Spinner, position: Int) {
    view.setSelection(position)
}
```

こうすれば、FragmentやActivityに直接書き込むことはないので、ちょっとキレイかもしれません。

んで実際にBuildしてみると、指定した数値が最初に選択済になっていると思います！


DataBindingでやることで、ViewModel内で色々計算させて、ViewModelのメンバから参照するやり方もできるので、本来Fragmentで書いちゃうことを更に減らせちゃいます。

とっくに既知の技術ですが、自分的によく使いそうな手法だったので書いておきました。
メモ

\![Mac OS X-10.15.7](<https://img.shields.io/badge/MacOSX-10.15.7-brightgreen>) \![ruby-2.7.1p83](<https://img.shields.io/badge/ruby-2.7.1p83-brightgreen>) 


# qiitaの投稿コマンド

qiita post fileName private

\*privateは限定共有

リンクの付け方&#x2026;[URL][リンク名]を[]でくくる


# githubのアップロードの仕方

    git pull origin main      #gitから自分のPCへファイルをダウンロード
    git add -A
    git commit -m 'commit'
    git push origin main      #自分のPCからgitにアップロード

rakeを使うと，

    rake push



------
 - **source** ~/grad_members_20f/members/Kenny0704/memo.org
テーブル設計での制約について

<h1>テーブル作成の制約について</h1>
機能開発をすることになり、テーブル追加するということで、制約について調べたので、
アウトプットとして残しておきます。

<h2>NOTNULL制約</h2>
データベースの値を空にしてはいけない制約

<h3>NOTNULLをかけないケース</h3>
メモや備考などは中身があってもなくてもよいので、NOTNULL制約をつけなくても良い


<h2>ユニークキー制約</h2>
重複した値が格納できなくなる
お店の商品名などは重複してはいけないので制約をかける

<h3>ユニークキー制約をかけないケース</h3>
人の名前などは重複することはあるので制約はかけない

<h2>外部キー制約</h2>
リレーション先にレコードがあることを保証する。
営業職からMOOCsを利用して機械学習エンジニアを目指す

##はじめに
-年齢: 35歳 (2020年現在)
-キャリア: 新卒から１１年ほどソフトウェアの営業職、直近７年は外資のセールスに従事(業務でプログラミングを行う機会は無し)
-きっかけ: 転職とコロナ禍での新しい働き方を真剣に実現するためにプログラミングの学習を開始。 
主にデータサイエンス、AI/ML領域のエンジニアを目指し日々勉強の記録を残していきます。


##これまでの学習経緯
2018 
- Progate (HTML, CSS, Python)
- Tech Academy Python/AIコース 終了
- Coursera Machine Learning Course →挫折
しかし、その後何かプロダクトを作るわけでもなく、仕事で使うわけでもなく、お勉強で終了。

2020
- PyQ （Python)
- Udemy (Python, HTML, CSS)
- ドットインストール (HTML, CSS)

上記を経て2020年9月以降からMOOCs(Massive Open Online Courses)を利用した学習を開始

MOOCsとは
https://education-career.jp/magazine/data-report/2016/moocs/

2020.09~
- edX: Python for Everybody 終了
- Udacity: Programming for Data Science with Python ★取組中
https://www.udacity.com/course/programming-for-data-science-nanodegree--nd104

##なぜMOOCsを利用？

自分がプログラミングで何をやりたいのかが定まっていなかったこともありますが、プログラミング学校や各プログラミング学習サイトでは
「ある言語を習得する」為にプログラムが組まれており、ポイントポイントでの学習となってしまっていました。
結果、なんとなくわかった気にはなるが、自分で何か成果物を作れるレベルには全く至らないということを繰り返していました。

また、改めてプログラミングスクールを受けるには費用面もあり今回の選択肢には入っていないので、ある程度手頃な値段で無数にある学習コンテンツから学んでいこうと考えました。

##なぜ今Udacityで学習している？
####■企業運営でより実務にフォーカスしている
Udacityは本格的にMOOCｓを調べ始めてから知りましたが、Udacityでは各言語を習得する為ではなく、各業務、キャリアで必要となるスキルをセットにして一つのコースが組まれています。
例えば今学んでいるProgramming for Data Science with Pythonのプログラムは以下のようなものです。

- Introduction to SQL
- Command Line Essentials
- Introduction to Python
- Introduction to Version Control
- Career Services
- Congratulations and Next Steps

シラバス
https://d20vrrgs8k4bvw.cloudfront.net/documents/en-US/Programming+for+Data+Science+with+Python+Nanodegree+Program+Syllabus.pdf

Udacityは大学が中心となって運営されているCourseraやedXと違い、テクノロジー企業を中心に運営されている組織なので、企業での業務によりそった形でコースが組まれている点も魅力を感じました。CourseraやedXはいかにも大学の講義、という感じで、理論や各言語について学ぶというイメージです。

####■nanodegree
また、nanodegreeという形でCertificationが発行され、Linkedinなどで訴求できるスキルとして残せる点も良いと思いました。
(日本のプログラミングスクールなどでの実績はLinkedinなどでは理解されないため、実績としては弱いと感じています)

####■費用面
日本のプログラミングスクールは30万~場所によっていは80万程度とそれなりの費用感となりますが、Udacityのコースは3ヶ月10万程度。
最初はキャンペーンを利用して50%offの5万程度で受講することができました。
CourseraやedXの1コース5,000程度(Certification発行代)と比べたら高いですが、UIやシラバスも非常にわかりやすく設計されており、費用以上の効果を感じています。

####■デメリット
デメリットは言うまでもなく、すべてのコースが英語で提供されている点です。
英語に抵抗がない方であれば問題ないですが、英語が苦手な方には難しいかもしれません。

##まとめ
オンライン学習であるMOOCsを利用して、どこまで独学で行けるかどうかを試してみようと思います。
まずはUdacityのProgramming for Data Science（Beginner)を終わらせた上で、AI Programming with Python(Beginner)、
Data Engineer or Data Analyst(Intermediate)、Machine Learning Engineer or Data Scientist(Advanced)といった順にレッスンを進めつつ、これまでおろそかになっていたポートフォリオづくりをしっかり進めたいと思います。
v-forでオブジェクトの名前を自由に設定する方法

# この記事の対象者

三度の飯よりvueが好きな方

## 実現したかったこと

v-forのオブジェクトのプロパティ名をコンポ側で決め打ちしたくなかった ><

## 具体的にどういうことか

コンポ内で `item.name` とすると取得するプロパティ名を制約しているので使い所が限られますね。

```vue

<div v-for="(item, index) in list" :key="index">
  {{ item.name }}
</div>
```

## コンポ側ではプロパティ名を保持しない

propsでプロパティ名を取得すればOK！
これだけで汎用的なコンポに早変わり！！

```vue

<div v-for="(item, index) in list" :key="index">
  {{ item[itemText] }}
</div>

props: {
  list: {
    type: Array,
    default: () => []
  },
  itemText: {
    type: String,
    default: ""
  }
}
```
応用数学 第三章 情報理論【ラビットチャレンジ】

# 概要
本記事は「JDLA E資格」の取得に必要なJDLA認定プログラムのひとつであるラビットチャレンジの受講レポートとして投稿したものです。

E資格について
https://www.jdla.org/certificate/engineer/

# 目次
[導入](#導入)
[自己情報量](#自己情報量)
[シャノンエントロピー](#シャノンエントロピー)
[カルバックライブラー ダイバージェンス](#カルバックライブラー ダイバージェンス)
[交差エントロピー](#交差エントロピー)

# 導入
10から11に増えた時も、1から2に増えた時も、増加量$Δw = 1$は同じだが
直観的な違いのわかり易さは違う。
そこで増加量$Δw$ではなく増加率$Δw/w$を考える。

# 自己情報量
$1/w$を積分した$\log w$を考える。

```math
I(x) = - \log \bigl( P(x) \bigr) = \log \bigl( W(x) \bigr)
```

・対数の底が2のとき、単位はビット(bit)
・対数の底がネイピア数eのとき、単位はナット(nat)
・$P(x)$と$W(x)$は逆数の関係
・情報の珍しさのようなもの（確率の低いことががわかった方が情報量が多い）

# シャノンエントロピー
・自己情報量の期待値
・微分エントロピーともいうが、微分しているわけではない(differential)

```math
\begin{align}
H(x) &= E \bigl( I(x) \bigr) \\
&= - E \Bigl( \log \bigl( P(x) \bigr) \Bigr) \\
&= - \sum \Bigl( P(x) \log \bigl( P(x) \bigr) \Bigr)
\end{align}
```

# カルバック・ライブラー ダイバージェンス
・同じ事象・確率変数における異なる確率分布$P,Q$の違いを表す
・異なる確率分布の性質が近いか遠いかという距離のようなもの

```math
\begin{align}
D_{KL} &= \mathbb{E}_{x～P} \Biggl[ \log \frac{P(x)}{Q(x)} \Biggr] \\
&= \mathbb{E}_{x～P} \bigl[ \log P(x) - \log Q(x) \bigr] \\
&= \sum_{x} P(x) \biggl( - \log \bigl( Q(x) \bigr) - \Bigl( - \log \bigl( P(x) \bigr) \Bigr) \biggr) \\
&= \sum_{x} P(x) \log \frac{P(x)}{Q(x)}
\end{align}
```

# 交差エントロピー

```math
\begin{align}
H(P, Q) &= - \mathbb{E}_{x～P} \log Q(x) \\
&= - \sum_{x} P(x) \log Q(x)
\end{align}
```