OmniAICreator/Qiita-1.07M huggingface dataset:
Firestoreに緯度経度を保存する


記事にするほどでもないけど。
GeoPoint型を利用する。newしてやらないといけないみたい。


```js
db.collection("geos").add({
      geopoint: new firebase.firestore.GeoPoint(Number(values.latitude), Number(values.longitude)),
});
```

あと、latitudeは-90~90で、longitudeは-180~180の間。

取得は、下記のような感じで。

```js
const snapshots = await db.collection("geos").get();
const docs = snapshots.docs.map(doc => doc.data());
docs.map(doc => {
     console.log(doc.geopoint.latitude);
     console.log(doc.geopoint.longitude);
})
```
認可モデルとAWS Policyの整理

# 認可モデル
- 参考
    - https://dinolai.com/notes/others/authorization-models-acl-dac-mac-rbac-abac.html
    - https://www.imperva.com/learn/data-security/role-based-access-control-rbac/

## ACL
- Subject can Action to Object
- イメージ
    - [subject: alice] can [action: create] to [object: article]

## Role-Based Access Control
- Subject is a Role which has Permission of Action to Object
- イメージ
    - [role: manager] can [create:article, create:member]
    - [subject: bob] has [role: manager]

## Attribute-Based Access Control
- ルールベース（ユーザ属性や環境など）
- Subject who is xxx can Action to Object which is xxx in Environment

# AWS
## RBAC
- 参考：
    - https://www.slideshare.net/AmazonWebServicesJapan/20150617-aws-blackbeltiam

<img width="557" alt="スクリーンショット 2019-12-30 17.49.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124221/c688d5f3-ade0-a26c-f5cb-945c2ac77b78.png">

## ABAC

- リソースベースのPolicy
    - IAM Entity（アクセス主体）ではなく、リソースに対してPolicyをアタッチする
    - クロスアカウントのアクセス時に便利
    - https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_roles_compare-resource-policies.html
- tagによるABAC
    - https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction_attribute-based-access-control.html
Macのターミナルでログインユーザ&rootユーザのプロンプト設定の変更方法

Macのターミナルのプロンプト設定をデフォルトからLinuxのプロンプトのように変更する設定メモ

# やりたいこと
```console:変更前(デフォルト)
takahiro@ITakahiro ~ %
```
`ユーザー名@ホスト名 ~ % `

```console:変更後
[takahiro@localhost ~]$ 
```
`[ユーザー名@ホスト名 ~]$ `
※ホスト名は、「localhost」に固定

# 前提環境
macOS Catalina 10.15.1

# 1. 一般ユーザのプロンプト設定の変更

- ログインシェルの確認

```console
takahiro@ITakahiro ~ % echo $SHELL
/bin/zsh
takahiro@ITakahiro ~ % 
```
前提環境に記載のmacOSのバージョンでは、一般ユーザのデフォルトシェルはzsh
したがって、zshのプロファイル設定にてプロンプトの設定変更を行う

- zshrcプロファイル定義のコピー&編集

```
takahiro@ITakahiro ~ % cp -p /etc/zshrc ~/.zshrc 
takahiro@ITakahiro ~ % 
takahiro@ITakahiro ~ % vim ~/.zshrc 
```

- 以下の箇所を修正

```console:変更前(デフォルト)
~略~
# Default prompt
PS1="%n@%m %1~ %# "
~略~
```
```console:変更後(ホスト名：localhost固定)
~略~
# Default prompt
# PS1="%n@%m %1~ %# "
PS1="[${USER}@localhost %1~]%(!.#.$) "
~略~
```
ホスト名を表示させたくなかった為、あえて「localhost」の固定文字列にしたが、ホスト名をそのまま表示させたい場合は以下の通り定義する。

```console:変更後(ホスト名を表示)
~略~
# Default prompt
# PS1="%n@%m %1~ %# "
PS1="[${USER}@${HOST%%.*} %1~]%(!.#.$) "
~略~
```

- 設定変更後の確認

```console:
takahiro@ITakahiro ~ % source ~/.zshrc 
[takahiro@localhost ~]$
```

# 2. rootユーザのプロンプト設定の変更

- rootユーザにログイン後デフォルトログインシェルの確認

```console
ITakahiro:~ root# echo $SHELL
/bin/sh
ITakahiro:~ root# 
```

- ここではbashのプロファイルを直接修正

```
ITakahiro:~ root# vim /etc/bashrc
```

```console:変更前(デフォルト)
~略~
PS1='\h:\W \u\$ '
~略~
```
```console:変更後(ホスト名：localhost固定)
~略~
#PS1='\h:\W \u\$ '
PS1='[\u@localhost \W]\$ '
~略~
```

ホスト名を表示させたくなかった為、あえて「localhost」の固定文字列にしたが、ホスト名をそのまま表示させたい場合は以下の通り定義する。

```console:変更後(ホスト名を表示)
~略~
#PS1='\h:\W \u\$ '
PS1='[\u@\h \W]\$ '
~略~
```

- 設定変更後の確認

```console:
ITakahiro:~ root# source /etc/bashrc 
[root@localhost ~]# 
```

上記によりターミナルからログアウト、再度ログイン時にも設定が継続される。
AWS Owncloudサーバを別のＥＣ２に移転

大きすぎるＥＣ２インスタンスを縮小し適正なインスタンスのＥＣ２にしてOwncloudを立ち上げた時のメモ
## ①EC2インスタンス(nano)を立ち上げてSWAPの設定をした

下記のようにした

$ sudo dd if=/dev/zero of=/swapfile bs=1M count=1024

$ ls -la /
-rw-r--r--   1 root root 1073741824 Dec 30 08:53 swapfile

$ sudo chmod 600 /swapfile

$ sudo mkswap /swapfile
Setting up swapspace version 1, size = 1024 MiB (1073737728 bytes)
no label, UUID=c78aad23-0a53-45f7-93f1-de12c5e354fc

$ sudo swapon /swapfile

$ sudo swapon -s

Filename                                Type            Size    Used    Priority
/swapfile                               file            1048572 0       -2

下記を/etc/fstab に追記

$ sudo vi /etc/fstab
/swapfile swap swap defaults 0 0


AWSサイトだと下記だが、

$ sudo dd if=/dev/zero of=/swapfile bs=1G count=1
dd: memory exhausted by input buffer of size 1073741824 bytes (1.0 GiB)

と出てうまくいかなかった
エクセルを把握するように、ファイルリンクをバッチ挿入方法

元記事：https://jp.scrapestorm.com/tutorial/how-to-batch-insert-file-links-to-figure-out-excel/
[スクレイピング](https://jp.scrapestorm.com/)でデータを抽出します時、よくエクセルに抽出されたデータをエクスポートします。ExcelスプレッドシートはOfficeシリーズオフィスソフトの一種で、日常生活·作業中のフォームへのデータ分析を実現する上に、データ処理にもよく使えます。今回はScrapeStormで抽出された写真のファイルをエクセルに整理する方法を紹介します。
####ScrapeStormの紹介
[ScrapeStorm](https://jp.scrapestorm.com/)とは、強い機能を持つ、プログラミングが必要なく、使いやすく人工知能[Webスクレイピングツール](https://jp.scrapestorm.com/)です。違う基盤のユーザーに二つのスクレイピングモードを提供し、1-Clickで99％の[Webスクレイピング](https://jp.scrapestorm.com/)を満たします。ScrapeStormにより、大量のWebデータを素早く正確的に取得できます。手動で[データ抽出](https://jp.scrapestorm.com/)が直面するさまざまな問題を完全に解決し、[情報取得](https://jp.scrapestorm.com/)のコストを削減し、作業効率を向上させます。
![alt](https://jp.scrapestorm.com/wp-content/uploads/2019/12/%E3%83%9B%E3%83%BC%E3%83%A0%E3%83%9A%E3%83%BC%E3%82%B8.png)
####1.ScrapeStormで写真を抽出する
ScrapeStormで写真を抽出する方法は下記のチュートリアルをご参照ください。
[画像をダウンロードする方法](https://jp.scrapestorm.com/tutorial/how-to-download-images-in-smart-mode/)
[ファイルをダウンロードする方法](https://jp.scrapestorm.com/tutorial/how-to-download-files/)
ScrapeStormはダウンロードされた写真をフィールドに基づき名前を変更したフォルダに保存します。タスクを起動する画面に「別のフォルダを作成する」をチェックしてください。そして、写真は下記のように一つずつフォルダに保存します。
![alt](https://jp.scrapestorm.com/wp-content/uploads/2019/12/%E5%86%99%E7%9C%9F.png)
####2.エクセルにファイル名を入力
フォルダのリンクをコピーして、ブラウザに入力してください。出できたフォルダの索引をコピーして、エクセルに入力します。少し整理して、日付など必要ないのデータを消去します。手順は下記のようにご覧ください。
![alt](https://jp.scrapestorm.com/wp-content/uploads/2019/12/%E7%B4%A2%E5%BC%95.gif)
####3.公式HYPERLINKの運用
HYPERLINK関数は、現在のワークブックの他の場所にジャンプしたり、ウェブサーバ、intranet、Internet上に格納されたドキュメントを開くショートカットです。HYPERLINK関数を含むセルをクリックすると、Excelはリストアップされた位置にジャンプしたり、指定されたドキュメントを開きます。
公式HYPERLINKを入力してください。=HYPERLINK(“D:\写真\食べログ\”&B2)
**「D:\写真\食べログ\」**とは、フォルダのリンクです。
**「&B2」**とは、エクセルに対応するセルです。
手順は下記のようにご覧ください。
ショートカットの方法を多く知って、エクセルの達人になると、自分の仕事の効率を高めることです。
![alt](https://jp.scrapestorm.com/wp-content/uploads/2019/12/%E5%85%AC%E5%BC%8F.gif)
【ぶっちゃけAndroidアプリ開発】sqliteでデータベースを作成する

とりあえずsqliteでデータベースを作成したい人のためのTipsです。
csvからインポートしてデータベースを作成します。

<使用環境>
・Macbook Pro
・バージョン10.15.2(Catalina)

##1.csvファイル
```test.csv
1,東京都庁,東京都新宿区西新宿2-8-1,03-5321-1111,metro.tokyo.jp
2,神奈川県庁,神奈川県横浜市中区日本大通1,045-210-1111,pref.kanagawa.jp
3,埼玉県庁,埼玉県さいたま市浦和区高砂3-15-1,048-824-2111,pref.saitama.lg.jp
4,千葉県庁,千葉県千葉市中央市場町1-1,043-223-2110,pref.chiba.lg.jp
5,静岡県庁,静岡県静岡市葵区追手町9-6,054-221-2455,pref.shizuoka.jp
```
住所録ちっくなcsvファイルを作成しておく。
##2.データベースを作成してcsvをインポート
ターミナルでデータベースの器を作成しつつsqliteに入る。
既にデータベースがある場合も同じコマンドでOK。
今回、データベース名は「test.db」。

```
$ sqlite3 test.db
SQLite version 3.28.0 2019-04-15 14:49:49
Enter ".help" for usage hints.
sqlite> 
```
「create table」SQL文でテーブルを作成する。
今回、テーブル名は「addressbook」。

```
sqlite> create table addressbook(seq integer, name text, address text,phone text, mail text);
sqlite> 
```
「.tables」コマンドでテーブルが作成できているか確認する。

```
sqlite> .tables
addressbook
sqlite> 
```
「.show」コマンドでsqlite設定を確認する。

```
sqlite> .show
        echo: off
         eqp: off
     explain: auto
     headers: off
        mode: list
   nullvalue: ""
      output: stdout
colseparator: "|"
rowseparator: "\n"
       stats: off
       width: 
    filename: test.db
sqlite> 
```
colseparatorの設定が「|」であることが確認できる。
これがインポートファイルのセパレータ記号なので、「.separator」コマンドで「,」へ変更する。

```
sqlite> .separator ,
sqlite> 
```
「.show」コマンドで確認。

```
sqlite> .show
        echo: off
         eqp: off
     explain: auto
     headers: off
        mode: list
   nullvalue: ""
      output: stdout
colseparator: ","
rowseparator: "\n"
       stats: off
       width: 
    filename: test.db
sqlite> 
```

「.import」コマンドでcsvファイルをインポートする。ファイルパスは変更してください。
エラーが出なければ大丈夫。

```
sqlite> .import /Users/xxxxxxx/test.csv addressbook
sqlite> 
```
「select *」SQL文でテーブルの中身を確認する。

```
sqlite> select * from addressbook;
1,東京都庁,東京都新宿区西新宿2-8-1,03-5321-1111,metro.tokyo.jp
2,神奈川県庁,神奈川県横浜市中区日本大通1,045-210-1111,pref.kanagawa.jp
3,埼玉県庁,埼玉県さいたま市浦和区高砂3-15-1,048-824-2111,pref.saitama.lg.jp
4,千葉県庁,千葉県千葉市中央市場町1-1,043-223-2110,pref.chiba.lg.jp
5,静岡県庁,静岡県静岡市葵区追手町9-6,054-221-2455,pref.shizuoka.jp
sqlite> 
```

「.exit」コマンドでsqliteを抜ける。

```
sqlite> .exit
$ 
```
ここまででデータベースファイルの作成完了です。
Android Studioにコピペして、プログラムからアクセスできます。プログラムから使う方法は別記事[「【ぶっちゃけAndroidアプリ開発】SQLiteデータベースにアクセスして画面に表示するサンプル」](https://qiita.com/Pinehead/items/a94e75a151be811e4af1)を参照。
##3.sqliteを使う上で知っておくべきコマンド類
###(1)ターミナルコマンド
$ sqlite3 データベース名
・データベースを作成、接続する。
###(2)sqliteコマンド
sqlite> .import csvファイル名 テーブル名
・csvファイルをインポートする。
sqlite> .show
・設定を表示する。
sqlite> .exit
・sqliteから抜ける。
sqlite> .separator ,
・セパレーターを「,」に変更する。
sqlite> .header on
・テーブルのデータを表示するときにカラム名を表示する。(見やすい)
sqlite> .mode column
・テーブルのデータを表示するときにカラムが揃えられる。(見やすい)

###(3)SQL文
sqlite> create table テーブル名(カラム名1 データ型1, カラム名2 データ型2, ...);
・テーブルを作成する。
sqlite> select * from テーブル名;
・テーブルのデータを全て表示する。
sqlite> delete from テーブル名;
・テーブルのデータを全て削除する。
###(4)データ型
sqliteで使用できるデータ型は以下の5つ。
TEXT テキスト型
INTEGER 整数型
REAL 浮動小数点型
BLOB バイナリーラージオブジェクト
NULL

---
ぶっちゃけAndroidアプリ開発は、アプリ開発にあたってとりあえず知っておくべきことをズバリ書きます。例外はありますのでご了承ください。
勉強中の身でありますので、誤りなどあればご指摘いただけると有り難いです。
failed to combine variables, expected dicts but got a 'dict' and a 'AnsibleUnicode'

```
ERROR! failed to combine variables, expected dicts but got a 'dict' and a 'AnsibleUnicode':
{}
"ansible_ssh_user=web ansible_ssh_private_key_file=~/.ssh/id_rsa"
```
group_varsの設定を、=じゃなくて:で設定するとイケる
Aibo プログラミング

#必要なもの
　aibo　
#やってみる
　AIBOデベロッパーズサイトは優しく記載されていたので
　こんな記録は必要なさそうだが、今後のために念の為残しておく。
　https://developer.aibo.com/jp/docs

　まず、AIBOのAPIを操作するには下記の２つが必要の様子
　・トークン
　・デバイスID
　
###トークンの払い出し
　https://developer.aibo.com/jp/token
　よりトークンを払い出す

　トークンの種類は下記の通り
　・２４時間
　・３０日
　・９０日

　今回はお試しなので２４時間を選択した

　ここで失敗した場合は、WIFIにつながっていないか、
　AIBO本体のバージョンが古いと思われる。
　※実際、NW環境が悪く、AIBOのバージョンアップが行われてなくて苦労した。

###デバイスIDを取得する
　操作したいAIBO自体のデバイスIDを取得する。
　
 REQUEST
　`curl -X GET https://public.api.ices -H "Authorization:Bearer XXXXXXXX" `

 RESPONSE
　`{"devices":[{"deviceId":"XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX","nickname":"なまえ"}]}`

　この返却値は必ずメモしておく。

###APIを叩いてみる
　APIは下記より選択
　https://developer.aibo.com/jp/docs

　FoundObjectsStatus
　　- aibo が認識している人やものについて取得します。
　を試してみる

　**先程取得したデバイスIDとトークンを含めてAPIを実行**
REQUEST
　`curl -X POST https://public.api.aibo.com/v1/devices/デバイスID/capabilities/found_objects_status/execute -H "Authorization:Bearer トークン" -d '{}'`
RESPONSE
　`{"executionId":"XXXXXXXXXXXXX","status":"ACCEPTED","result":{}}(base) `

　ExecuteionIDが返却される。
　AIBOのAPIはすべて非同期通信のようなので、この後に結果取得のAPIを実行する必要がある。

　数秒待った後、下記を実行

　**結果取得API**
　先程実行した結果返されてきたexecutionIdをパラメータに付与し、実行結果を取得するAPIを実行する
REQUEST
　`curl -X GET https://public.api.aibo.com/v1/executions/XXXXXXXXXXX \
-H "Authorization:Bearer XXXXXXXXXXXXXXX" `
RESPONSE
　`{"executionId":"XXXXXXXXXXXXX","status":"SUCCEEDED","result":{"found_objects_status":[{"name":"person","visible":true,"distance":"middle","direction":"left_front"}]}}　`

　結果が返ってきた。
　確かに左前に私がいるので認識しているようだ。

　この他のAPIもだいたいこんな手順でいけるようなので他のAPIも試していく。
Bigqueryでワイルドカードテーブルを使用すると１テーブルのスキーマで統一される

ワイルドカードを使ってテーブル指定したい場合の注意点
[BigQueryドキュメント](https://cloud.google.com/bigquery/docs/querying-wildcard-tables?hl=ja)
> ワイルドカード テーブルは、ワイルドカード式に一致するすべてのテーブルが結合されたものを表します。

## テストクエリ

```{SQL}
CREATE OR REPLACE TABLE `your_project.your_dataset.test_tablesuffix_1` AS (
  SELECT
    1 AS a
    ,2 AS b
);
CREATE OR REPLACE TABLE `your_project.your_dataset.test_tablesuffix_2` AS (
  SELECT
    1 AS c
    ,2 AS d
);
SELECT
  *
FROM `your_project.your_dataset.test_tablesuffix_*`
```

## 結果
どうやら最後に参照したテーブルのスキーマに統一されるらしい
![image (9).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179005/e1b0193e-4b48-1475-aee6-1a70b15a0603.png)
Railsチュートリアルメモ - 第1章

[メモ目次はこちら](https://qiita.com/yokohama4580/items/dedfd5510080273dc2a0)

[Railsチュートリアル第1章はこちら](https://railstutorial.jp/chapters/beginning?version=5.1#cha-beginning)


## はじめに
ローカルワークスペースとgitレポジトリについて
Railsチュートリアルを1章から順にやっていくと、3つのアプリを作成することになります
Railsチュートリアルではherokuを使うので、1gitレポジトリに3つのアプリを突っ込んでしまうとherokuにpushするときに正常にデプロイできなくなってしまいます。
git管理する際は以下のような構成にすることをオススメします

```
. -- ここでgit initしないこと
└── environment
    ├── hello_app -- 第1章
    │   └──.git/config
    ├── toy_app -- 第2章
    │   └──.git/config
    └── sample_app -- 第3章以降
        └──.git/config

```


## 1.1 はじめに
割愛
# 1.2 さっそく動かす
ローカル(mac)で普通にチュートリアル通り実行していくと、いきなり以下のエラーが発生します。

```
printf "install: --no-document \nupdate:  --no-document\n" >> ~/.gemrc
gem install rails -v 5.1.6
```

```
Fetching: concurrent-ruby-1.1.5.gem (100%)
ERROR:  While executing gem ... (Gem::FilePermissionError)
    You don't have write permissions for the /Library/Ruby/Gems/2.3.0 directory.
```
ググると、system標準のrubyを使おうとしているため、権限エラーになっているようなので、rbenvをインストールして、別のrubyを使用（バージョンは2.5系で最新だった2.5.7を指定）

```
brew install rbenv

echo 'export PATH="~/.rbenv/shims:/usr/local/bin:$PATH"' >> ~/.bash_profile
echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
source ~/.bash_profile

rbenv install 2.5.7
rbenv global 2.5.7
rbenv versions
```

```
gem install rails -v 5.1.6
```

これでRailsをインストールできます。
もし上手くいかなかったら、ターミナルを再起動してみてください。


# 1.3 最初のアプリケーション
## 1.3.1 Bundler
Gemfileとbundlerの使い方についての章

gemはrubyにおけるライブラリのこと。bundlerを使うとgemのバージョンを管理できる。
（pythonでいうところの、requirements.txtがGemfile、pipがbundler）
なお、bundler自身もgemとのこと。
Gemfile.lockというファイルがセットで存在し、.lockの方は実際にインストールしたgemが反映される。

使い方は、
1. Gemfileに使用するgemを記載
2. bundle installでGemfileに記載されたgemをインストールしてくれる

なお、GemfileとGemfile.lockに同じライブラリが記載されているがバージョンに差異がある場合（Gemfileのバージョンを変えたときなどに発生）には、bundle updateが必要。
bundle installはあくまで、未インストールのgemのインストールしかやってくれず、gemのバージョン更新はしないらしい。

## 1.3.2 rails server
割愛

## 1.3.3 Model-View-Controller (MVC)
割愛（大事なところなので、MVCについてよく知らない人はちゃんと読んでください）

## 1.3.4 Hello, world!
コントローラーに変更を加え、ルーティング（URLと呼び出される処理のマッピング）を変える。
ルーティングはconfig/routes.rbに定義する。

```ruby:config/routes.rb
Rails.application.routes.draw do
  root 'application#hello'
end
```
↑デプロイしたURLのルートパスを開くと、application_controller.rbのhelloメソッドが呼び出される

## 1.4 Gitによるバージョン管理
割愛
## 1.5 デプロイする
herokuにデプロイしていく。
herokuのCLIが必要になるので、homebrewでインストールする（公式にcatalinaだとwarningが出ると書いてあったが、mojaveだと特に何も起きなかったので気にせず進める）

```
brew tap heroku/brew && brew install heroku
```
コマンドラインからログインし、sshキーをherokuに登録し、heroku createで新規アプリケーションを作成する

herokuにgit pushしようとすると以下のエラーが発生。

```
git push heroku master
fatal: 'heroku' does not appear to be a git repository
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
```
調べてみると、.gitがネスト（親ディレクトリにも子ディレクトリにも.gitがある）してしまっていた。
どうもheroku createすると、カレントディレクトリでgit initが実行され、.git/configのremoteにherokuが追加されるらしい。

```
environment
    ├.git/config
    └── hello_app -- 第1章
        └──.git/config

```
↑こういう状態になっていた
environment配下の.gitディレクトリを削除し、プロジェクトルートで再度heroku create実行からやり直すと解消。

無事、herokuにデプロイできた。

## 1.6 最後に
割愛

第2章に続く
AWS+NodeJSでサーバレスな環境構築①

# はじめに
サーバレスは完全に未経験ですが、勉強がてら備忘録として残しておこうと思います。
表現等が正しく無い場合はご指摘いただければ、幸いです。

# サーバレスってなぁに？
簡単に言ってしまうと、ユーザーがサーバー領域を意識せず、直接利用出来るサービスを活用した構成のことです。
「Lambda」は設定されているプログラムを起動させる実行環境となります。起動条件が整った際に、プログラムをLambda環境に呼び出し、実行されます。この為、Lambdaでは、実行した時間とその回数のみの課金となります。

**向いているサービス**
・待機時間の長いシステム
・CPUの負荷が時間帯によって差のあるシステム

**不向きなサービス**
・常にシステムの動いている必要のあるサービス
・高負荷な状態が長時間続くシステム

もう少し詳しいことを知りたい場合はこちらのサイトをご覧ください。
[サーバーレス アーキテクチャ](https://www.skyarch.net/iot/serverless.html)

# Lambda関数の作成
・AWS Lambdaページ＞関数の作成＞一から作成
・関数名を入力、ランタイムの選択（必要であれば）
・その他はデフォルト値のままで作成ボタン

# API Gatewayのトリガーを追加と設定
・「トリガーを追加」ボタンを押し、API Gatewayを選択
・APIを「新規のAPI」を選択
・その他はデフォルト値のままで追加ボタン

# ソース
```index.js
'use strict'

let fs = require('fs')
let path = require('path')

exports.handler = (event, context, callback) => {


  let filePath = path.join(__dirname, 'page.html')
  let html = fs.readFileSync(filePath).toString()

  sendHtmlResponse(context, 200, html)

}

function sendHtmlResponse(context, statusCode, html) {
  let response = {
    'statusCode': statusCode,
    'headers': {
      'Content-Type': 'text/html'
    },
    'body': html
  }
  context.succeed(response)
}
```

```page.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>サーバレス</title>
</head>

<body>
    <h1>やっちゃおう！サーバレスで</h1>
</body>
</html>
```

# ページにアクセス
API Gatewayの設置したトリガーをクリックし、表示されてるURLをクリックすれば、アクセスできるはずです。
<img width="1360" alt="スクリーンショット 2019-12-30 17.28.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43096/d21aa3aa-1019-4fad-e732-9d83db7611c7.png">
遷移先のページでこのように表示されれば、成功です。
<img width="1437" alt="スクリーンショット 2019-12-30 18.21.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43096/c0922bfc-2db9-e005-7b0d-78ae06dbbbcc.png">


# 終わりに
次はLambdaとdynamodbやS3と組み合わせて投稿しようかと思います。
Slackでリアクションのあるリンク付きの投稿を検索する

# はじめに

Slackのワークスペースでは、何かとお役立ちのリンクが共有されている。
特に大規模なワークスペースでは色々とお役立ちのリンクが共有されているが、
すべての投稿を読むことは難しいため、これらを効率良く検索したい。

# 方法

リンク付きの投稿を検索するには、```has:link```を使用する。

また、お役立ちのリンクほど、リアクションが付くと推測されるため、リアクション（絵文字）付きのリンクを検索したい。リアクション付きの投稿を検索するには、```has:reaction```を使用する。

これらを組み合わせて、Slackの検索窓で、```has:reaction```、```has:link```を入力すると、```リアクションのあるリンク付きの投稿```を検索することができる。

```
has:reaction has:link
```
上記に加えて、期間や投稿チャンネルなどで絞り込むと検索効率は高まると思われる。
また、```has:reaction```以外に、```has::絵文字コード:```を使って、特定の絵文字によるリアクションも検索することができる。

例えば、

```
has::eyes:
```

と入力すると、👀のリアクションが付いた投稿を検索できる。



# さいごに

リアクション数をもとにランキング付するとさらに良いと思うが、リアクション数をもとに検索する方法はSlackのAPIを使う以外は残念ながらないようだ。
Railsチュートリアルメモ 目次

# はじめに
- ここ1年半くらいpythonをメインに触っていたが、転職サイトを眺めていたらまだまだRailsの需要が高い（特にスタートアップ界隈）なことに気づき、ちょうど年末年始暇なので久々に[Rails チュートリアル](https://railstutorial.jp/)を復習してみようと思った
- 以前学習したときはcloud9がawsに吸収される前だったのでcloud9を使うことに抵抗がなかったが、rails tutorialをやるためにわざわざawsにログインしてcloud9使うのは手間だなと思ったので、ローカルでやってみることにした（aws経由じゃなくても使える？みたいだが、まぁ普通にローカルの方がサクサク開発できるし）
- エディタはVSCodeを使用
- 章ごとに気づいたことをまとめていきます（途中で力尽きたらごめんなさい）
- 完走したらheroku以外の環境へのデプロイ方法などもまとめていきたい（途中で力尽き。。。）

# 目次
[第1章メモ](https://qiita.com/yokohama4580/items/11216715171fd11e7931)
[第2章・第3章メモ](https://qiita.com/yokohama4580/items/754b0ac8764a03d0d83b)
[第4章・第5章メモ](https://qiita.com/yokohama4580/items/85e1566400c8c6cebc05)
[第6章メモ](https://qiita.com/yokohama4580/items/ba98a0e4a1a6652fe795)
[第7章メモ](https://qiita.com/yokohama4580/items/8785d44f5110ae09cf00)
[第8章メモ](https://qiita.com/yokohama4580/items/86c1534ce40dd42dcb68)
[第9章メモ](https://qiita.com/yokohama4580/items/3678688db59948e3ee95)
[第10章メモ](https://qiita.com/yokohama4580/items/fd67fcfbe925fa344ad9)
[第11章メモ](https://qiita.com/yokohama4580/items/e5b96e1dc5b007cbb76c)
[第12章メモ](https://qiita.com/yokohama4580/items/482f0e89d2ee8e25d318)
[第13章メモ](https://qiita.com/yokohama4580/items/dfe05ce7bd72313b7683)
[第14章メモ](https://qiita.com/yokohama4580/items/c91cf1157737ed6449e9)
navigationOptionsにコンポーネントのpropsを渡したい

アプリのヘッダーにある「保存」ボタンにコンポーネントの値を渡したいときどうするか、みたいな話です

# 処理の概要

1. コンポーネントの中で `setParams` する
2. `setParam`に渡したい値を入れる
2. `navigationOptions`の中で`getParam`する

# サンプルコード

```jsx

// 画面
const FooScreen: React.FC & NavigationStackScreenComponent = ({ navigation }) => {
  // navigationでこの値を渡したい
  const [count, setCount] = useState<number>(0)

  // countが更新されたらnavigationのparamの値も更新する
  useEffect(() => {
    navigation.setParams({ fooParam: count })
  }, [count])

  return (
    <View>
      <Button title='おしてね' onPress={() => setCount(count + 1)} />
    </View>
  )
}

// navigation options
FooScreen.navigationOptions = ({ navigation }) => ({
  title: 'ふーーー',
  headerRight: (
    <Button title='保存' onPress={() => navigation.navigate('Bar', {
      // setParamで設定した値を取得 -> Bar画面へのparamに入れ直す
      fooParam: navigation.getParam('fooParam') 
    })} />
  )
})
```
Djangoでbitflyerの収支管理アプリを作ってみる（02_03.ログイン画面を作る③。）

前の
Djangoでbitflyerの収支管理アプリを作ってみる（02_02.ログイン画面を作る②。）

https://qiita.com/redmeteor777/items/8fd573b2aee3dfa20515

前回入力フィールドを作成したのですが、表示の体裁を整えるのをすっかり失念しておりました。
というわけで、今回はtableタグを使って見栄えを整えたりしていきます。

編集するのはlogin.htmlです。

```login.html
{% load static %}
<!doctype html>
<html lang="ja">
<head>
    <meta charset="uth-8">
    <title>{{title}}</title>
    {% comment %} <link rel="stylesheet" type="text/css"
        href="{% static 'login/css/style.css' %}" /> {% endcomment %}
</head>
<body>
    <h1>{{title}}</h1>
    <p>{{message|safe}}</p>
    <table>
        <form action="{% url 'login' %}" method="post">
            {% csrf_token %}
            {{ form.as_table }}
            <tr><td></td><td><input type="submit" value="click"></td></tr>
        </form>
    </table>
</body>
</html>
```

tableタグの追加と、

{{ form }}
↓
{{ form.as_table }}

と変更しています。

ではサーバーを起動して確認してみましょう。

```
>python manage.py runserver
```

ログイン画面にアクセスして表示を確認します。

```
http://localhost:8000/login/
```

入力フィールドが縦に並んで、すこし見栄えがよくなりました。
あ、ちなみにCSS読み込みがコメントアウトしたままこっそり置いてあります。
そのうち作るかもしれませんが、殺風景だなーと思われた方は自己責任で追加どうぞ。

では、次回は今度こそユーザー登録機能を実装していきますぞー。
簡易Webアプリをプロが仕上げるとどうなるか（見積もり編）

前回ライブコーディングしたモンテカルロ法のシミュレータを
プロのフロントエンドエンジニアが仕上げると、どういう風になるかを説明します。

動画解説版：https://youtu.be/WjYFiza_LMY

# 目的

若手のエンジニアさんに
フリーランスのフロントエンドエンジニアがどういう思考回路で仕事をしているかを知ってもらいたい

# そもそもモンテカルロ法とは？

ルーレットの掛け金を決める法則で、その通りやれば必ず勝つと言われているものです。

## ルール1. 紙とペンを用意

- 用意した紙に、数列「1, 2, 3」を記入
- 両端の数字を足した値がベット額となる（1 + 3 => $4 ベット）

## ルール2-1. 負けた場合

- 数列の最後に「賭け金」を追加する（1, 2, 3 => 1, 2, 3, 4）

## ルール2-2. 勝った場合

- 両端の数字を削る（1, 2, 3 => 2）

## ルール3. 残りの数字が無くなる or 1つになれば終了

- その時点で黒字が確定する

![スクリーンショット 2019-12-30 5.47.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124296/3ba1bd9d-5372-ab88-3bcb-0283789cafcb.png)


# これをWebアプリでやりたい

カジノに紙とペンを持っていくのは面倒だから
スマホで「勝ち負け」を入力すると「次のベット額」が表示されるようにしたい

![スクリーンショット 2019-12-30 5.47.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124296/d81ec72e-226b-fc18-cc07-ddbd0c7264dd.png)

# 見積もり

私が見積もるとしたら、下記の通りです。

## フリーランスとしての見積もり

- 10〜15万円（※ソースコードのみ納品する場合）
- 20〜30万円（※ドメインの設定、サーバ設置などもろもろ含む場合）

## ※ちなみに企業だと

企業だとどんな簡易なWebアプリでも関わる人間が多くなるので、
ミニマムでも50万円〜になると思います。

ただし、50万円という数字は企業からみると大きな数字ではないので

- BGM機能
- 勝ち負け演出
- 履歴機能
- シェア機能

などの、（すごくよく言えば）付加価値を加えて 100万円 の案件になることも多いと思われます。

# 見積もり金額の意図

```
見積もり金額 = 工数 + 価値
```

見積もり金額の意図としては
自分は「工数 + 価値」を総合的に勘案して決めています。

## 工数

工数の部分は、フリーランスだと人日3〜5万円ぐらいで計算している人が多いと思われます。
企業だと人日5〜10万円ぐらい。
※人日5万 => 5万x20日 => 月100万

今回のアプリは、私の見積もり工数だと 2〜3日 なので 5 x 2 => 10万円だとします。

## 価値

多少だけど専門性があって、
このアプリがあることでカジノで快適に過ごせるようになるという価値があるので
今回はその価値を5万円とします。

## 工数 + 価値

10 + 5 で 15万円 という数字になります。

# フリーランスの実情

私が知っている世界だと、
個人に頼むことで、品質よりもコストを抑えたいと考える顧客が多いのが実情です。

したがって、10〜15万円が結構リアルな数字なんですが、
顧客の費用感としては10万円ぐらいであることが多いと思われます。
ので、じゃあ10万で収まる内容でやりましょう、というのが残念ながらリアルな実情かな、、と。

# 20分で作ったものが10万円？

仮に10万だとしても、
ライブコーディングで20分で作ったものが10万円ってどういうことだと思うかもしれません。

が、実際にプロとして仕上げる場合は
ライブコーディングにはない工程がたくさんあります

- 見積もり
- 作業の洗い出し
- 設計
- 実装
- 検証

また、顧客を幸せにするための価値をつけて提供するので、適切な金額かなと思います。

## 顧客を幸せにする価値とは？

- メンテナンスしやすい作りにする
- 不具合に強いロジックにする

などの、「脳みそを使った実装をする」ことを指します。

# まとめ

モンテカルロ法のシミュレータを題材に、簡易Webアプリを作ると想定したとき
フリーランスのフロントエンドエンジニアなら、どういう思考回路で見積もりをするかを述べました。

設計編に関しては次回まとめます。
APIを使ってスプレットシートのデータを取得する方法

自分のスプレットシートに書いてあるデータをブラウザに表示させる方法をやってみたので、整理する為に書いてみました。


#準備するもの
必要なもの

・Google Cloud Platformのアカウント作成
・APIkey もしくは OAuth tokenの取得
.スプレットシート

##Google Cloud Platformプロジェクト作成から認証情報の取得
1.Google Cloud Platformに行く
2.Google アカウントでログイン
3.Google Cloud Platformでプロジェクトを作成する
4.Google Sheet APIの有効化する
5.認証情報の作成

自分が参考にしたサイトを貼っておきます。
下のURLは4.までやれば充分です。
[Sheets API を使ってPHPでGoogle スプレッドシートにデータを保存する](http://bashalog.c-brains.jp/19/04/12-101500.php)

##APIkeyの作成
1.Google Cloud Platform
2.左側にある APIとサービス > 「認証情報」を選択する
3.認証情報を作成 > APIキー　
4.キーを制限する　> Google Sheets API を選択する(ここはしなくても利用は出来ます。)

##最後に
以下の{}内の部分に値を入力してあげると表示されます。
`GET https://sheets.googleapis.com/v4/spreadsheets/{spreadsheetId}/values/{開始Cell}:{終了Cell}?key={API キー}`


###参考
[Google Sheet APIを試す時に詰まったところ](https://qiita.com/yukyt/items/c27c344211423f2bb44d)
[Sheets API を使ってPHPでGoogle スプレッドシートにデータを保存する](http://bashalog.c-brains.jp/19/04/12-101500.php)
Visual Studio Codeをコマンドにより起動する

# 前提知識として
ターミナルで`code .`を叩くとそのディレクトリ以下のコードがVScodeで起動できる

# 問題
`code .`とコマンドを打つと`-bash: code: command not found`となってしまう。

# 解決方法

1. Visual Studio Code上でcmd+shift+p
![スクリーンショット 2019-12-30 17.18.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26860/bebd6686-a7d8-573b-c6c6-75308fa8c89c.png)
2. "Shell Command: Install 'code' command in PATH"を選択
![スクリーンショット 2019-12-30 17.18.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26860/5d15cb41-9cbe-7f08-c174-0791dfc60b6a.png)

`Shell command 'code' successfully installed in PATH.`と表示されたら設定成功
svelteでfirebaseをimportするとopenDbのエラーが出る時

```
Error: 'openDb' is not exported by node_modules/idb/build/idb.js
```

というエラーが出た。

rollup.config.jsのresolveに下記を追記する

```javascript
export default {
    plugins: [
        resolve({
            mainFields: ['main', 'module'], // ここ
```
HerokuにGitHubリポジトリの一部だけデプロイする

# つらみ
- HerokuのGitHub連携、リポジトリ内のすべてをデプロイしてしまう (ので、Procfileなどをリポジトリ直下に配置せねばならない)
- つらい (GitHubリポジトリのほうを小分けする必要があって)

たとえばこういうディレクトリ構成のとき、 **フロントエンドはデプロイしたくなくてAPIだけHerokuにデプロイしたい**、とする。
同じHerokuだけどappをフロントエンドとバックエンドで分けてる、みたいな場合も当てはまりそう。

```
.
├ v2okimochi-apps-frontend
│  └ ...
├ v2okimochi-apps-api
│  └ ... <= これだけ全部デプロイしたい
└ README.mdとか
```

既に方法は紹介されているが、本稿はそれのGUI版を書く。

Heroku CLIでやる場合の参考 https://qiita.com/amagurix/items/5fad1693752a6ad9e86c





# heroku-buildpack-monorepoを使う
https://elements.heroku.com/buildpacks/lstoll/heroku-buildpack-monorepo

Herokuデプロイ時にディレクトリ指定ができる。

1. Herokuの対象appで、settingsタブからBuildpacksにheroku-buildpack-monorepoを追加する。

![heroku1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201962/63599548-76aa-91fc-850d-ad32c592758a.png)

`Add buildpack`から、直接URLを指定する。今回は `https://github.com/lstoll/heroku-buildpack-monorepo`でいけた。

※ 言語のbuildpackより上にする必要がある。順番に読まれているのか？


2. Herokuの環境変数 (Config Vars)に、たとえば `APP_BASE` = `v2okimochi-apps-api`を追加して読み取らせる。

この指定の場合、リポジトリ直下にある `v2okimochi-apps-api`ディレクトリ内だけをデプロイし、 `v2okimochi-apps-api/Procfile`などが読み込まれる。




# おまけ
Git側で `subtree push`を使う方法が有名らしいが、そこはHerokuに勝手にやってもらうほうが嬉しい。。。

https://qrunch.net/@yumechi/entries/8d7uwLWuOFtA09sn
https://medium.com/@shalandy/deploy-git-subdirectory-to-heroku-ea05e95fce1f
🏰【Laravel6】register_shutdown_function()使うときは配列にして$thisも渡す

## 環境
PHP 7.3.10
Laravel 6.5.0

## やりたいこと
関数の実行終了前に任意の関数呼び出すregister_shutdown_function()をLaravelで使いたい
が、こいつを書くと下記の例外が発生する

```
ErrorException
register_shutdown_function(): Invalid shutdown callback 'HogeHoge' passed
```

どうやらインスタンスメソッドである「$this」を渡さないといけない様子

## やったこと
引数を配列にして$thisと対象の関数名を渡す

```HogeController.php
    /**
     * 完了前にコールバックを呼び出したい関数
     *
     * @param Request $request
     */
    public function doSomething(Request $request)
    {
        // 色々処理します
        // ...

        // ❌例外発生パターン
        register_shutdown_function('HogeHoge');
        // 🔵これで実行できます
        register_shutdown_function([$this, 'HogeHoge']);

        return back();
    }

    /**
     * 実行完了時に呼びだされるコールバック関数（public）
     *
     * @return void
     */
    public function HogeHoge(): void
    {
        // ログ作成、終了処理等の何かをする
        // ...
    }
```

※private関数だと呼び出せない

## 結果
例外発生なく呼び出せます
$thisじゃなくても指定できそうにも見えます

CakePHPでも同じ方法で解決できました
DockerHubとGitHubを連携させる2019/12版

# やりたいこと

- DockerHubとGitHubの連携

# なぜこの記事を書いたか

- ネットに転がっている手順だと、「DockerHubのページの右上の”Create”から〜〜〜」というものしかなかった。
- 自分の環境だとWebでCreate Repositoryできなかった。
- 試しながらやりたいことができたので今後の備忘のために残しておく。

![スクリーンショット 2019-12-30 16.54.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72156/348a4df1-9b4b-7c97-57f1-5ddd3263e56e.png)
こんな感じでWebからCreateできそうな雰囲気無し。

※DockerHubとGitHubの連携自体の詳細については参考URLのものを参考にしています。

# 環境

- macOS Catalina
- Chrome 79.0.3945.88

# 事前準備

- DockerHubからGitHubのアカウントを連携しておく。  
  https://hub.docker.com/settings/linked-accounts

# やったこと

- DockerHubのAccout SettingsのLinked AccountsからGitHubアカウントを連携
- Dockerfile作成
- Dockerfileからimageをbuild
- DockerHubにimageをpush
- GitHubにリポジトリ作成
- GitHubにDockerfileをpush
- DockerHubのリポジトリのページ(以下のURLの場所)の"Builds"を開く
    - `https://hub.docker.com/repository/docker/[アカウント名]/[image名]`
- GitHubを選択
- ブランチとかDockerfileの場所とかを設定  
  Source Type、Source、Docker Tag はあとから変更できない。

![スクリーンショット 2019-12-30 16.45.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72156/a7bf57bb-53ad-0752-fef0-dffa570207f3.png)

# 確認

GitHubに変更をpushしてDockerHubが自動でBuildすることを確認する。
ビルド結果がSuccessになっていれば設定完了。

![スクリーンショット 2019-12-30 16.51.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72156/1596d06b-1078-a520-bfb3-5d958a1c1c83.png)

# 今回作ったもの

- [GitHub : docker_centos7](https://github.com/yoichi-aoyama/docker_centos7)
- [DockerHub : ao41/centos7](https://hub.docker.com/repository/docker/ao41/centos7)

# 参考URL

- [Docker HubでAutomated Buildを設定する](https://qiita.com/Brutus/items/19f02df409e859406914)
- [GitHubとDockerHubを連携してDockerイメージを自動ビルドする方法(Automated Build)](https://casualdevelopers.com/tech-tips/automated-build-for-dockerhub/)
- [Docker HubとGitHubを自動連携させる「Automated Build」が楽チンすぎる件](https://nekopunch.hatenablog.com/entry/2018/10/10/214213)
小ネタ：ダブルクウォートのエスケープ｜Power Query

プログラミング界隈では当たり前なのかなと思いましたが、Power Query側での解説を見つけられなかったので、一応書き残しておきます。
要は、ダブルクウォート1個につき1個重ねればエスケープできるようです。

##例1
下記のような文字列で、`"おじいさん"`という文字列と`"おばあさん"`という文字列の間を取る。
`昔々あるところに"おじいさん"と"おばあさん"がいました。`

###失敗例

```
Text.BetweenDelimiters(テーブル,""おじいさん"",""おばあさん"")
```
###成功例
・文字列の始まり（終わり）で1個
・本文中のダブルクウォート1個に付き1個増やすので、2個
で計3個で`おじいさん`などをくくっています。

```
Text.BetweenDelimiters(テーブル,"""おじいさん""","""おばあさん""")
```

##例2
同じく、ダブルクウォートが増えた場合で実証。
`昔々あるところに""おじいさん""と""おばあさん""がいました。`

###成功例
なかなか読みづらいですが、
・文字列の始まり（終わり）で1個
・本文中のダブルクウォート1個に付き1個増やすので、2×2＝4個
で計5個で`おじいさん`などをくくっています。

```
Text.BetweenDelimiters(テーブル,"""""おじいさん""""","""""おばあさん""""")
```

##おまけ
文字列を合成するようなときも同様です。
アンパサンド後のダブルクウォート4つは、
・文字列の始まりと終わりで2個
・ダブルクウォートとそのエスケープで2個
というわけです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370992/cf573f96-a71b-76f2-0738-8add75d2bb8f.png)

##注
厄介なものもパラメータに登録しておくと、エスケープはエディタ側で自動でやってくれるので、楽です。
最初から固定値で書けばいいだけなら、パラメータを使うのがお薦めです。
Ruby/Rails でサーバ書いてたエンジニアが、転職後数ヶ月で TypeScript/React/Redux なチームで書けるようになるまでに参考にしたこと

夏に転職して、それまではrubyしか書いてこなかったのですが、
転職後はそれまで全く触ってこなかった TypeScript/React/Redux/Firebase なチームに入って開発できるようになるまでに参考になったものです。
もちろん、実際にはもっと他にも色んなものを参考にしています。
また、ここに書いたものも隅々まで読んだりしたわけではないのですが、振り返ってみて役に立ったなって思い出せるのを書いてみました。

## 本

- りあクト！
    - [りあクト！ TypeScriptで始めるつらくないReact開発 第2版](https://oukayuka.booth.pm/items/1312652)
    - [りあクト！ Firebaseで始めるサーバーレスReact開発](https://oukayuka.booth.pm/items/1572683)
    - ESLintの設定や、おすすめpackageなど書かれててたり、こういう書き方は良くないとか書かれてて最高
- [実践TypeScript](https://note.com/takepepe/n/nba34ed1ae401)
    - TypeScript に関してはとりあえずこれを読む！
- [effective react hooks](https://booth.pm/ja/items/1477000)
    - react hooks について！

## 公式サイト

- [React](https://ja.reactjs.org/)
- [Redux](https://redux.js.org/)
- [StoryBook](https://storybook.js.org/docs/basics/introduction/)
- [Jest](https://jestjs.io/docs/ja/api)
- [TypeScript](https://www.typescriptlang.org/)
- [MDN](https://developer.mozilla.org/ja/)

## その他のサイト

- [JSer.Info](https://jser.info)
    - slack にフィード流して見てる
    - twitter で見てる
- [JavaScript Primer](https://jsprimer.net/) 
    - Promise/async/await のところは何度も見てる
- [TypeScript Deep Dive 日本語版](https://typescript-jp.gitbook.io/deep-dive/)
    - 本家の英語版も合わせてみる。
- [JavaScript Weekly](https://javascriptweekly.com)
    - slack にフィード流して見てる
- [npm trends](https://www.npmtrends.com)
    - npm の比較をするときに便利。
    - ある package をいれると、関連する package が出てくるので知らない package を知るのにも便利。

## 勉強会

- JSConf
- js community(xxx.js系)
- GCP/Firebase系

## slack

- [GCPUG](https://gcpug.jp/)
- [FJUG](https://firebase.asia/)
- [ruby-jp](https://ruby-jp.github.io/)

## twitter

- 各種公式アカウント系
- 勉強会で発表してた人や情報を発信してくれてる人

# まとめ

- 公式ドキュメントは最高
    - API document はもちろんだが、guide や tutorial など、知りたいことのほとんどは公式に書いてある
- それの理解の手助けのために、他の本やサイトを活用するのが良い
    - 手っ取り早く全体像や背景などを理解するには便利。
- 最新の情報は、twitter で色んな人をフォローしていろんな記事流れてくるようにしてる
    - 定期的に勉強会にも参加する
Winrar 翻訳ファイルの作り方

# はじめに
WinRARの最新バージョン Ver5.80　を日本語化する方法です。
以前のバージョンまでのやり方では日本語にすることができなかったので備忘録代わりに書いておきます。

# ダウンロード

[lngファイル作成ツール](https://www.rarlab.com/rar_add.htm)


# やり方
## lngファイルの読み込み 


過去の日本語化ファイルを最新バージョンに対応させるにはToolフォルダ内のlngcheck.exeを使用します。
コマンドプロンプトからToolsフォルダを開き

```lngcheck.exe
lngcheck.exe　対象のファイル
```

を実行します。

これは不足している翻訳対象の言葉がないか調べるツールです。
不足がある場合は下記画像のように対象の値が表示されます。
![1.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278312/6c5946e6-de03-44f6-617d-5ed5658e4bbf.jpeg)

あとはエラーが出なくなるまで繰り返していき翻訳ファイルを完成させます。

5.80対応翻訳済みファイルは下記からダウンロードできます。

[ダウンロード(GoogleDrive)](https://drive.google.com/file/d/1UpibqBQ_iUMb8VHhcSQmJY-5Najy9sFj/view?usp=sharing)

できたファイルをWinrarのフォルダにコピーすると自動的に翻訳されています。

お疲れさまでした。
プロジェクトを始める・参加する時に決めておくこと、伝えること

今、社内でとあるプロジェクト(納期間近)に途中参加しましたが、色々関わっていると気になることが多々あります。
そのため、今後の自分への備忘録として残します。

#プログラム開発
## 命名規則は必ず決めよう
自分が関わるプロジェクトにはなぜか命名規則がありません。
決めておかないと後で見返す時or誰かに引き継ぐ時に説明しづらい。
パスカルケースかキャメルケースかスネークケースくらいは決めて欲しい。
自分は何もなければキャナルケースで書いてます。

## メソッド内にコメントをかかない
これプログラムに書かれていて愕然としたんですが。
今でもプログラムを読み取る時は苦痛。

```
#Region "Method" 
private Sub test()

    Dim testA AS String

#Region "Test Method"
    Method1(testA);
#End Region

End Sub
```

* 可読性が落ちる。
* コード行数が追えない。
* 読むことが面倒くさくなる

と何もいいことがなかった。メソッド内の説明はせめてコメントで記載してほしい。
人によっては仕様の確認でプログラムを見ることもありますし。

## プロジェクト内の独自ルールは簡単でもいいから資料にまとめよう
なお自分は勉強会に呼ばれていないのでプログラムとの会話の中で理解して行きました。一応リーダー的な役割なのでプログラマ向けの勉強会に参加する必要があるかと言われるか疑問ですが、なぜか依頼するプログラマ間で情報共有が怪しいんですよね。
プログラマに依頼する時に説明する際、最低限知っておかなければいけない情報は資料にまとめましょう。

## リーダー向け
## リーダーをするならプログラマにならない
これは今後の教訓。途中でプログラムの作成をPMから依頼されて作ることになったのですが、自分にはプログラム作りながら他の人にスケジュールを振りながら品質を維持することは無理だと悟った。
リーダーは「他の人への作業の割り振りを行い、一定の品質のものを作り上げる」が求められる役割です。
品質の維持をするためにはプログラマ

## やる気がない人、自分がリーダーとして動くにあたり負担になる人には外れてもらう
納期間近で人員の追加が何度か行われました。
自分のチームにも何人か追加されたり、別のチームの作業をやってもらうことがありましたが、やはり合わない人がいました。

いや、別にプログラムが出来る出来ないは関係ないんですよ（出来た方が当然いいです）

ただ、指示や依頼をする際に、自分に負担が来る人にはPMに連絡して外れてもらいました。
基準は色々あると思いますが、その人に仕事を振ることが仕事と思ったら外すことをお勧めします。

プログラマの方も色々思うところがありますが、仕様書を見ない段階から「プログラム作れません」と連絡することはお勧めしません。その瞬間から言われた側は見下します。

## 常識的な内容から外れたものは必ず初期で潰そう
いきなりですが郵便番号の入力を実装する場合、どのように実装しますか？

自分は動作確認を行う際、
* 半角数字7桁(もしくは「-」を含めた8桁)
* もしくはフリー入力だけど、登録時に上記内容でエラーチェック(最低限ですが)
などでチェックしようとしていました。実際はインバウンド対応も含めるともっとルールは作る必要がありますが。

しかし作ってもらったプログラムを動作確認してみると...

* コントロールによっては8桁以上入力可能
* ほぼなんでも入力可能。全角半角、ひらがななど
* エラーチェックではじいていると思ったらDB登録できた

頭抱えました。
でも他のプログラムを見てみると同じように動いているものも多く...。

相談案件となりましたが、このような実装が事前にあると仕様と言い逃れられる可能性があるため、早いうちに潰しましょう


# まとめ
 他にも色々突っ込みどころがありますがこの辺りで。

 リーダー、プログラマ問わず物事に疑問に思うために色々気にすることをお勧めします。
Git エラー「fatal: Not a valid object name: 'master'.」の対処法

#Gitでbranchを切ろうとしたら「fatal: Not a valid object name: 'master'.」とエラーが出たときの対処法

おそらく、gitでこれからプログラム管理しようとしたときに出くわすエラーだと思います。

エラーの内容としては、
「ブランチ名 'master' は有効ではありません（他のブランチ名を使ってね）」か
「masterブランチで、何もコミットされてないからmasterブランチは無効だよ」って言われてる感じです。

「え？なにそれ！？」みたいな感じでしたが、ひとまずネットで検索してみると
コミットすればいいよ的なことが書いてあったので、コミットしてみることに。

なので何でもいいのでコミットすればオッケーです。

```git:ターミナル
$ git commit -m "Initial commit"
```

そしたら、コミット処理が始まるのでそれが終わり次第、
新しく、例として "example" というブランチ名を生成します。

```git:ターミナル
$ git branch example
* master
  example
```

exampleブランチが生成されたので、`checkout`コマンドを使ってブランチを移動

```git:ターミナル
$ git checkout exapmle
  master
* example
```

以上で、マスターは残したままで、新しい編集用の無事ブランチを切ることができました！
何もない部分で不具合

マルチスレッド処理で使う、参照カウント式のオブジェクト管理の管理プログラムの例

```c++

#include <atomic>

class RefObj
{
    std::atomic<int> count;

    // ...

    void Unref_ng();
    void Unref_ok();
    void destruct();

    // ...
};

void RefObj::Unref_ok()
{
    if (0 == --count)
        destruct();
}

void RefObj::Unref_ng()
{
    --count;
    if (0 == count)
        destruct();
}

```

RefObj::Unref_ng() が駄目な理由は

```c++

// Thread A と B でほぼ同時に呼ばれる
void RefObj::Unref_ng()
{
    // Thread A では 2 から 1 に減る
    // Thread B では 1 から 0 に減る
    --count;

    // Thread A からすると「※何もない部分」で Thread B が更新した
    // 結果、Thread A も B も同時に count=0 に見える可能性がある

    if (0 == count)
    {
        // Thread A と B が同時に count=0 だと
        // 同じ処理が、別々のスレッドで実行される

        destruct();

        // メモリ内容の破壊 = 変数が意図しないところで変更される
        // 恐れあり -> 意図しない動作やクラッシュが他所で発生
    }
}

```

が発生しうるから。

---

<details><summary>アセンブラ レベルでの動作</summary><div>

g++ の "-S -O3" オプションで出力されたアセンブラ(不要な情報を排除して、シンボルを修正)を見ると

```

RefObj::Unref_ok():
        pushq   %rbp
        movq    %rsp, %rbp
        lock
        decl    (%rdi)        ;# count をデクリメント
        jne     LBB1_1        ;# デクリメント結果で分岐
        popq    %rbp
        jmp     RefObj::destruct()
LBB1_1:
        popq    %rbp
        retq

RefObj::Unref_ng():
        pushq   %rbp
        movq    %rsp, %rbp
        lock　　　　　　　　　　;# 直後の decl のみメモリアクセスを排他
        decl    (%rdi)        ;# count をデクリメントして "2" から "1" になっていても
        movl    (%rdi), %eax  ;# count を参照した時点では "0" になっているかも
        testl   %eax, %eax    ;# count 内容で判断して
        je      LBB0_2        ;# 分岐
        popq    %rbp
        retq
LBB0_2:
        popq    %rbp
        jmp     RefObj::destruct()
```

となってます。問題点は

```
        lock　　　　　　　　　　;# 直後の decl のみメモリアクセスを排他
        decl    (%rdi)        ;# count をデクリメントして "2" から "1" になっていても
                              ;# ここで、別スレッドにて count を変更することがある(※何もない部分)
                              ;# メモリアクセスの排他によって、Thread A と B は動作タイミングが変わる
        movl    (%rdi), %eax  ;# count を参照した時点では "0" になっているかも
```

で、ここでも「何もない部分」が問題になります。

8/16bit 時代のアセンブラ プログラマ間では「割り込み先で書き換わってない？」の一言で理解してもらえるのだが...

</div></detais>

---

この手の不具合が厄介なのは、不具合の発生が CPU の動作タイミングに依存することで、デバッガ上では発生しない状況になりうることです。そうなると、ソース コードと睨めっこして「バグってなさそうでバグってる(概ね正常動作、時々不具合)」部分を探すしかありません。

要は「アテが外れる可能性があるコード」を重点的に探します。

---

操作は同じなのに、動作が不安定なソフトに遭遇する度に、この手の不具合が考えられる。担当プログラマには動作環境の所為にせず、頑張ってデバッグして欲しい...
【iOS】Swiftファイルのヘッダーコメントをカスタマイズする

#概要
iOSの開発をする際にXcodeでファイルを追加すると、ファイルのヘッダーに以下のようなコメントが入るかと思います。

```swift:Sample.swift
//
//  Sample.swift
//  SampleProject
//  
//  Created by ~~~ on 2020/12/30
//  Copyright © 2020 ~~~. All rights reserved.
//
```

複数人で開発をする際に、上記コメントを合わせたかったので、コメントをカスタマイズする方法についてまとめてみました。

#環境
Xcode: 11.2.1
Swift: Swift5

#手順1
「IDETemplateMacros.plist」を生成します。
(生成したファイルの配置場所は手順3で説明します)

#手順2
手順1で生成したファイルに以下を追加します。
(サンプルでは作成者・作成元を非表示としました)

```xml:IDETemplateMacros.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>FILEHEADER</key>
  <string>
//  ___FILENAME___
//  ___TARGETNAME___
//</string>
</dict>
</plist>
```

#手順3
出来上がった「IDETemplateMacros.plist」をプロジェクトに追加します。
今回は複数人で開発することを想定し、Gitの管理下となるよう以下のディレクトリにファイルを追加しました。
`<ProjectName>.xcodeproj/xcshareddata/IDETemplateMacros.plist`
※「/xcshareddata」は「.gitignore」に入れていない前提です！

#確認
Xcodeからファイルを追加し、以下のようになっていれば設定完了です。

```swift:Sample.swift
//
//  Sample.swift
//  SampleProject
//  
```

#確認
githubに雑なメモも残してあるので、参考までにどうぞ。
https://github.com/hidetomo117/Other_SwiftFileHeaderComment

#参考
https://dev.classmethod.jp/etc/ios-xcode%E3%81%AE%E3%83%87%E3%83%95%E3%82%A9%E3%83%AB%E3%83%88%E3%81%AE%E3%83%98%E3%83%83%E3%83%80%E3%83%BC%E3%82%B3%E3%83%A1%E3%83%B3%E3%83%88%E3%81%AE%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC/
https://help.apple.com/xcode/mac/9.0/index.html?localePath=en.lproj#/dev91a7a31fc
rosdep installするパッケージの探し方

# はじめに

ROSパッケージをインストールして開発を行う時に `apt-get` で入れてしまうことがありますが、これをするとCIでプロジェクトの依存を解決する方法がありません。そこで[rosdep](http://wiki.ros.org/rosdep)を使用しpackage.xmlで管理をします。

## 前提条件

| 環境 | バージョン |
|:-:|:-:|
| 開発 | Ubuntu 16.04.6 LTS |
| ROS | Kinetic Kame |

## パッケージを探す

例として[ecl_exceptions](http://wiki.ros.org/ecl_exceptions)を使う例をみてみます。

`apt-get` でインストールする場合には、 `apt-cache` コマンドでパッケージの検索をおこないます。

```
$ sudo apt-cache search ros-kinetic | grep ecl | grep exceptions
ros-kinetic-ecl-exceptions - Template based exceptions - these are simple and practical and avoid the proliferation of exception types.
```

次にrosdepでインストールしようと思います。ecl-exceptionsなのでpackage.xmlに下記のように追記します。


```
<depend>ecl-exceptions</depend>
```

インストールを実行します。

```
$ rosdep install -i -r -y --from-paths src/test_common/ --ignore-src
ERROR: the following packages/stacks could not have their rosdep keys resolved
to system dependencies:
test_common: Cannot locate rosdep definition for [ecl-exceptions]
Continuing to install resolvable dependencies...
#All required rosdeps installed successfully
```

どうやら`apt-get`と`rosdep`でインストールするときに設定するパッケージ名が異なるようです。[wiki](http://wiki.ros.org/rosdep)には、詳しい説明がありませんが、こういう時はソースを確認するのが一番確実です。

## rosdepの仕組みを調べる

[rosdistro](https://github.com/ros/rosdistro)のリポジトリを確認すると各環境ごとにディレクトリがあることがわかります。ここで[kinetic](https://github.com/ros/rosdistro/blob/master/kinetic/distribution.yaml)を確認するとパッケージのリポジトリとパッケージ名がわかります。

今回は、`ecl_exceptions`という名称で管理されていますので、それをpackage.xmlに設定して再度`rosdep install`を実行すればインストールできます。

また、共通で使用するものについては、[base.yaml](https://github.com/ros/rosdistro/blob/master/rosdep/base.yaml)で管理されているので、こちらを確認します。

# まとめ

* ROSの開発をするときは、`apt-get`でパッケージを入れると依存関係をCIが解消できない
* `rosdep` でパッケージ名称を調べるときには、リポジトリの設定ファイルを確認すればよい
[Rails] link_toをボタン化する


ポートフォリオ作成中にlink_toをボタン化したいと思い調べて実装したので、忘れないように記録に残します。

```
<%= link_to "任意のリンク名", hoge_path, class: 'btn btn-warning' %>
```

※class名はbootstrapから引用しています!
【micro:bit 2019】micro:bit でスマホ画面のタッチ操作（28記事目）

この記事は 12/30 に執筆して、後から 「[micro:bit Advent Calendar 2019 - Qiita](https://qiita.com/advent-calendar/2019/microbit)」の 17日目 へと登録した記事です。

今年のアドベントカレンダー用に書いた記事の 28記事目で、micro:bit Advent Calendar に登録した記事としては 9記事目になります。

## はじめに

買っていたけれど眠らせてしまっていた、というものの 1つ。
マイコンボードでスマホ画面上のタッチ操作ができるものです。

●リード線付リレータッチボード（ドライバ有り） - スイッチサイエンス
　https://www.switch-science.com/catalog/3930/

この製品に関する下記のツイートを、以前、タイムラインで見かけたのを思い出し、試してみました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/microbit?src=hash&amp;ref_src=twsrc%5Etfw">#microbit</a> と <a href="https://twitter.com/hashtag/relayTouchBoard?src=hash&amp;ref_src=twsrc%5Etfw">#relayTouchBoard</a> でお手軽チートマシン。リレータッチボードの定格は5Vですが3Vでも動作しました。 <a href="https://t.co/kEMn4mk5cd">https://t.co/kEMn4mk5cd</a> <a href="https://t.co/B1WtNKLHsz">pic.twitter.com/B1WtNKLHsz</a></p>&mdash; アベ先生 (CV: 阿部和広) (@abee2) <a href="https://twitter.com/abee2/status/991584821368438785?ref_src=twsrc%5Etfw">May 2, 2018</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 試した内容

### 物理的な構成

接続は以下のとおりです。

- リレータッチボードの「5V」 --- micro:bit の「端子 3V」
- リレータッチボードの「GND」 --- micro:bit の「端子 GND」
- リレータッチボードの「EN」 --- micro:bit の「端子 P0」

![ENBLPsJUUAAaRpD.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/80ca462d-d031-efd4-42d4-fe682c1bf605.jpeg)


そして、このリレータッチボードを輪ゴムでスマホ（Pixel 3）に固定し、まずはシングルタップを試しました。
（リレータッチボードの「EN端子を HIGH/LOW」にすると、「リレーが ON/OFF ＝ 画面に触れた状態/触れていない状態」となる仕様です）

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">実家に持ち帰ったものと、実家にあるもので試しているので、輪ゴムで固定とかいう雑な構成ですが（笑）、<br>とりあえず、micro:bit からスマホのタップ操作を行えた。 <a href="https://t.co/xl6gvFT22F">https://t.co/xl6gvFT22F</a> <a href="https://t.co/RE7QMlEuob">pic.twitter.com/RE7QMlEuob</a></p>&mdash; you (@youtoy) <a href="https://twitter.com/youtoy/status/1211553784788160513?ref_src=twsrc%5Etfw">December 30, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

### プログラムの詳細

プログラムは色々とお試しをした後、最終的に以下にしました。
micro:bit のボタンを押すと、特定のタップ操作 3種が行われる形です。

- Aボタン押下 ⇒ シングルタップ
- Bボタン押下 ⇒ ダブルタップ
- A＋Bボタン押下 ⇒ ロングタップ

<img width="355" alt="Microsoft_MakeCode_for_micro_bit_touch.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/d4495f44-e0f9-cd20-6209-a3e3e4e4fb35.jpeg">

### 実際の挙動

最終的に、以下の挙動で動作確認ができました。

- ロングタップ ⇒ ホーム画面のアプリアイコンの長押しメニューの呼び出し
- シングルタップ ⇒ ホーム画面からのアプリ起動
- ダブルタップ ⇒ 地図アプリでの拡大操作

<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">micro:bit とリレータッチボードで、<br>スマホ画面上でのロングタップ、シングルタップ、ダブルタップの3つを試した時の様子。 <a href="https://t.co/p5VnEmcFlD">pic.twitter.com/p5VnEmcFlD</a></p>&mdash; you (@youtoy) <a href="https://twitter.com/youtoy/status/1211564850976944129?ref_src=twsrc%5Etfw">December 30, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## おわりに

micro:bit に限らず、電源供給をしつつデジタル出力の ON/OFF の制御ができれば利用可能なものなので、他のデバイスでの利用など使いどころがいろいろありそうです。
Railsチュートリアル　3章までのエラー（自分用メモ）

#Rails チュートリアル 3章までのエラーと対処法
ProgateでRuby, Rails, Git, HTML&CSS 終了後にスタートしました。
事前知識は大学の授業でC言語を少し扱ったくらい。

##～1章

###環境構築でのエラー

ProgateのRuby on Railsの環境構築の記事を見ながら進めていったとところ、rails new でフォルダが生成されず。

調べたところRails5.0以上ではNode.jsが必要なようで、インストールし解決しました。

###Herokuへのデブロイ

その後1.5までは順調に進められましたがHerokuへのデブロイでエラー。

$ git push heroku master　
で
$ heroku open
すると、Application errorの画面が。

heroku logsでエラーの確認をしてもよく分からず、2日ほど試行錯誤。
その後あきらめてteratailで質問を投稿したところ、Rails6でのデブロイの方法がRails5までと異なるという回答を頂きました。

そこで初めて自分がRails6を使っていることに気がつき、バージョンを指定してRails newからやり直し。Rails6でのデブロイは複雑だったのであきらめました。

[Rails6でのデブロイ](https://devcenter.heroku.com/articles/getting-started-with-rails6)

しかしそれでもデブロイできず。

エラー文をよく見るとApp crashとありました。それを元に色々調べると、postgresqlを使用することを、

config/database.yml

で明記する必要があるようでした。

修正前

```database.yml
production:
  <<: *default

  database: db/production.sqlite3
```

修正後

```database.yml
production:
  <<: *default
  adapter: postgresql
  database: db/production.postgresql
```

Gemfileを書き換えるだけではだめだったようです。ここのエラーが今までで一番時間がかかり、3日くらい取られてしまいました。

##2,3章

2章、3章ではそこまで大きくつまづくことはありませんでしたが、Gemfile変更後にbundle installや、Herokuへデブロイする前にcommitするのを忘れるミスがかなりありました。

##まとめ

Progateは1周しかしておらず、かなり答えを見てしまうくらいの理解度だったのでまだRails チュートリアルは早いかと思いましたが、2週するのはめんどうだったので始めてみました。


期間は3章までで1週間くらい。今のところ少し時間がかかっていますが、1月中に終了を目標にがんばっていきます。
ローカルネットワーク内でMariaDBレプリケーション設定

#MariaDBのレプリケーション設定

さくらのクラウドサーバーで、MariaDBのレプリケーション設定を下記記事を参考に行いました。

https://qiita.com/junsan50/items/c9e44f8d6b2599b6a2c1


ただ、スレーブ側にリストアする方法が若干異なるので、自分用メモとして残しておきます、

概要としては、さくらのクラウドのスイッチを介したローカルネットワーク内で、MariaDBをインストールしたサーバー（マスターサーバー・スレーブサーバー）2台を用意し、GTID（マスターで作成された各トランザクションの識別子）を使ってレプリケーション設定を行っています。

なお設定の流れを簡易的に記載しているため、細かい説明は省略しています。


##前提条件
・CentoOS7
・MariaDB　ver10.3
・スイッチ 1台
・MariaDBインストールサーバー(192.168.0.1)
・MariaDBインストールサーバー(192.168.0.2)
・ローカルネットワークの構築が完了している

##マスター側でfirewallの許可設定

まず準備段階として、マスタ側のデータをスレーブ側に送るので、マスタ側でfirewallの許可設定が必要となります。

そのためマスタ側で、スレーブ側のプライベートIPアドレスである192.168.0.2のみの接続をfirewallコマンドで許可します。

```
# firewall-cmd --zone=public --permanent --add-rich-rule='rule family="ipv4" source address="192.168.0.2" service name="mysql" accept'
# firewall-cmd --reload
```

##レプリケーションのみ権限を付与したユーザーを作成
マスター側でレプリケーションの権限を持ったユーザーを作成。（後にスレーブ側のマスタDB設定でユーザー情報を記述します）

```
MariaDB [(none)]> CREATE USER 'repl'@'localhost' IDENTIFIED BY 'repl';
MariaDB [(none)]> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'localhost';
MariaDB [(none)]> FLUSH PRIVILEGES;
```

##マスター側にレプリケーション用のパラメーターを設定
マスター側なのでserver-idを1とし、任意のバイナリログ（レコード変更などの履歴）ファイル名とします。

```
# systemctl stop mariadb

# vi /etc/my.cnf.d/server.cnf
[mysqld]
server-id = 1    # スレーブと異なるサーバIDにする
log-bin=master-bin   # 任意のバイナリログファイル名
binlog-format = ROW 
log-slave-updates

# systemctl start mariadb

MariaDB [(none)]> SHOW VARIABLES LIKE 'server_id'; #server_idが設定されている確認
```

##スレーブ側にレプリケーション用のパラメータを設定
スレーブ側なのでserver-idを2とし、任意のバイナリログファイル名とします。

```
# systemctl stop mariadb

# vi /etc/my.cnf.d/server.cnf

[mysqld]
server-id = 2        # マスターと異なるサーバIDにする
log-bin=slave-bin   # 任意のバイナリログファイル名
read_only # 読み込み専用 
log-slave-updates
# systemctl start mariadb

MariaDB [(none)]> SHOW VARIABLES LIKE 'server_id'; #server_idが設定されている確認
```

##マスターDBのダンプファイル作成
レプリケーションの開始時のみ、手動でマスターのDB全体を、スレーブにコピーする必要があります。
そのため、マスターのDBのデータを保存するためにダンプ（データベースに含まれるテーブルなどの構造やデータを SQL 文の形式で保存すること）をして、適当なファイル（dump.sql）にデータを入れます。

```
# mysqldump --all-databases -u root -p --master-data=2 --single-transaction --routines > dump.sql
```

##ダンプファイルのバイナリログファイル名とポジションを確認
GTIDを調べるための、バイナリログファイル名とポジションを確認

```
MariaDB [(none)]> SHOW MASTER STATUS; #File名とPosition番号を確認
```

##マスタサーバーの現時点のGTIDを調べる
GTIDはx-x-xのような記載で、ドメインID + サーバID + サーバーごとのトランザクション番号の構成となっています。

```
MariaDB [(none)]> SELECT BINLOG_GTID_POS( “File名”, Position番号);
```

##スレーブ側にGTIDを設定

このGTIDを目印として、レプリケーションを行います。

```
MariaDB [(none)]> SET GLOBAL gtid_slave_pos = ‘X-X-X’;
```

##スレーブ側にリストア

マスター側のダンプファイルを、スレーブ側にコピーします。

```
# scp dump.sql root@192.168.0.2:dump.sql
```

##スレーブ側でマスタサーバー設定とスレーブ開始設定
```
MariaDB> CHANGE MASTER TO
           → MASTER_HOST     = '192.168.0.1',
           → MASTER_USER     = 'repl',
           → MASTER_PASSWORD = 'replユーザのパスワード',
           → MASTER_USE_GTID = slave_pos;

MariaDB> START SLAVE;
MariaDB> SHOW SLAVE STATUS \G  #GTIDが合っているか、スレーブ起動がYESになっているかなど確認
```

##最終確認
適当にデータベースを作ってみて、slave側でも反映されているか確認します。

```
MariaDB [(none)]> USE test;
MariaDB [(test)]> CREATE TABLE testTable(num int, name varchar(50));
MariaDB [(test)]> SHOW TABLES;
```