OmniAICreator/Qiita-1.07M huggingface dataset:
Linuxファイルサーバー構築(Ubuntu & Samba)

Windowsにvirtualboxを使ってLinux(Ubuntu20.04.1)を入れたので、
試しにファイルサーバー構築をやってみました。のメモです。

###共有するディレクトリの作成
```
$sudo mkdir /home/share
$sudo chmod 0777 /home/share
```
homeの下にshareディレクトリを作り、そのディレクトリのアクセス権限を許可しました。
このディレクトリの中身を共有します。（名前は任意、shareの部分は好きに決めてください）

mkdir→ディレクトリ作成
chmod→アクセス権限の変更

###Sambaのインストール
```
$ sudo apt-get -y install samba
```

###ファイルサーバーの設定
```
$ sudo vim /etc/samba/smb.conf
```
上記のコマンドで開き、smb.confを編集していきます。
22行目くらいに以下のような記述があると思います。

```smb.conf
#======================= Global Settings =======================

[global]

## Browsing/Identification ###
```

以下の記述を追加します。

```
unix charset = UTF-8
dos charset = CP932
```

こんな感じにします。

```smb.conf
#======================= Global Settings =======================

[global]
unix charset = UTF-8
dos charset = CP932

## Browsing/Identification ###
```

必要であれば以下を編集します。僕のでは編集の必要ありませんでした。


```smb.conf
#Change this to the workgroup/NT-domain name your Samba server will part of
  workgroup = WORKGROUP
```
Winodwsのワークグループの値をWORKGROUPのところに記述します
　workgroup = <ここ>
確認は以下でできます
`コントロールパネル->システムとセキュリティ->システム
->コンピュータ名、ドメインおよびワークグループの設定`

38行目付近に以下の記述があります。

```smb.conf
#### Networking ###
```
このの項目は接続元IPアドレスの制限などに使用するみたいです。
今回は編集しませんでした。


ファイルの最後に以下を追加します。

```smb.conf
[Share]
   path = /home/share
   writable = yes
   guest ok = yes
   guest only = yes
   create mode = 0777
   directory mode = 0777
```
[Share]　には、共有する際のフォルダ名を任意の名でつけます。
path　には最初に作った共有したいディレクトリのパスを入れます。

###ファイルサーバーを再起動します
```
$ sudo systemctl restart smbd
$ sudo systemctl enable smbd
```
###サーバー名の確認
linuxでサーバー名の確認をします。

```
$ hostname
サーバー名
```

###Windowsでファイルにアクセス

Windowsでエクスプローラーを開き、ネットワークドライブの割り当てから
ネットワークドライブの割り当てをクリックします。

フォルダーの欄に「¥¥サーバー名¥共有フォルダ名」と指定します。

サーバー名は先程、Linuxで確認したものです。
フォルダ名は、先程指定した[Share]の部分です。(この場合、share)

ユーザー認証の画面が出てきて入力します。
これでファイルにアクセスできるはずです。

##おまけ

グループでユーザーのアクセス制限をする方法です。
###グループの作成

```
$ sudo groupadd share
```

shareグループが作成されました。

###ファイルサーバーの設定
smb.confの最後に追加したものを編集します。

```smb.conf
[Share]
   path = /home/share
   writable = yes
   guest ok = no
   create mode = 0777
   directory mode = 0777
   valid users = @share
```

valid users で認証できるグループ名を指定します。
今回はshareのグループに所属しているユーザーがアクセスできます。

###ユーザーを追加
新しくユーザを作りたい場合のみです。
元から作ってあるユーザでも大丈夫です。

```
$sudo useradd -m ユーザ名
$sudo passwd ユーザ名
```
この後、パスワードを2回入れたらユーザーが作成されます。
ユーザは同じ名前にしてください。
useradd のオプションの -m をつけることで、ホームディレクトリが作成されます。
(-m は無くてもいいです)

###ユーザーをグループに追加
```
$ sudo usermod -aG share ユーザ名
```
これでグループにユーザが登録できます。

###sambaにユーザ追加
```
$ sudo pdbedit -a ユーザ名
```
パスワードを2回入力したら、追加完了です。
（pdbeditではなく、smbpasswdでも同様にアクセスできました。）

これでWindowsからアクセスするときの認証でアクセス制限できるようになりました。

##参考記事
https://qiita.com/k-Mata/items/8bee9e02e74565b6c147
https://qiita.com/msrks/items/1385cf13258dd1a0da08
https://www.server-world.info/query?os=Ubuntu_16.04&p=samba
https://linuxfan.info/ip-address
https://www.server-world.info/query?os=Ubuntu_18.04&p=samba&f=2
https://renoji.com/IT.php?Contents=OS_CentOS/Server_File/Samba_UserRegistration.html
https://qiita.com/orangain/items/056db6ffc16d765a8187
https://eng-entrance.com/linux-user-add
tmuxinator with fish

# はじめに

自分はfishを好んで使っている。tmuxinatorを入れる際、参考の記事がなかったので残すことにした。

### 注意

tmuxinatorのgithubを読めばこの記事は要りません。

GitHub : [tmuxinator/tmuxinator](https://github.com/tmuxinator/tmuxinator)

# 環境

動いた環境を載せています。

| OS | Version |
| --- | --- |
| macOS Mojave | 10.14.6 |
| macOS Catalina | 10.15.5 |

# インストール

brewでインストールした。gemでのインストールも可能です。

```
$ brew install tmuxinator
```

gemでのインストール

```
$ gem install tmuxinator
```

利用するエディターの設定をします。自分はvimを登録しました。

```
$ export EDITOR='vim'
```

登録できているかは、環境変数から確認できます。

```
$ echo $EDITOR
vim
```

設定は以上で終了です。
SQLServerから取得したレコードデータをPowerShell一発でCSVファイルに出力する方法

## SQLServerから取得

業務上でSQLServerから情報を取得してCSVにするという案件が多いので、PowerShellでテンプレ化してみました。

![PowerShell-7.0.3](https://img.shields.io/badge/Powerhell-7.0.3-brightgreen) ![SQL Server-Microsoft SQL Server 2017 (RTM-CU13-OD) (KB4483666) - 14.0.3049.1 (X64)](https://img.shields.io/badge/SQLServer-Microsoft SQL Server 2017 (RTM CU13 OD) (KB4483666) 14.0.3049.1 (X64)-brightgreen)

メインの実行ファイルです。

```PowerShell:exec.ps1
. ".\config.ps1";
. ".\sql.ps1";
. ".\util-db.ps1";

# DBから取得
SQLServerSelect $dataSource $database $userId $password $sql;
```

Config系をまとめました。

```PowerShell:config.ps1
[string]$dataSource = "localhost";
[string]$database = "Database";
[string]$userId = "sa";
[string]$password = "xxxx";
```

SQLだけ別ファイルで外だししました。

```PowerShell:sql.ps1
[string]$sql = "
SELECT @@version;
";
```

SQLServer認証でSQLServerにアクセスしてSelect分を発行しています。CSV形式で標準出力しております。

```PowerShell:util-db.ps1
function SQLServerSelect([string]$dataSource, [string]$database, [string]$userId, [string]$password, [string]$sql){

    # SqlConnectionStringBuilder を使用してSQL接続の設定を保存
    [System.Data.SqlClient.SqlConnectionStringBuilder]$connectionString = New-Object -TypeName System.Data.SqlClient.SqlConnectionStringBuilder;
    [object]$connectionString['Data Source'] = $dataSource;
    [object]$connectionString['Initial Catalog'] = $database;
    [object]$connectionString['User ID'] = $userId;
    [object]$connectionString['Password'] = $password;

    # DataTableを利用してSQL実行結果を一時格納
    [System.Data.DataTable]$resultsDataTable = New-Object System.Data.DataTable;

    # SQLConnection、SQLCommandを設定
    [System.Data.SQLClient.SQLConnection]$sqlConnection = New-Object System.Data.SQLClient.SQLConnection($connectionString);
    [System.Data.SQLClient.SQLCommand]$sqlCommand = New-Object System.Data.SQLClient.SQLCommand($sql, $sqlConnection);

    # データベースへ接続
    [object]$sqlConnection.Open();

    # ExecuteReaderを実行してDataTableにデータを格納
    [object]$resultsDataTable.Load($sqlCommand.ExecuteReader());

    # CSV形式で標準出力
    $resultsDataTable | ConvertTo-Csv -NoTypeInformation;

    # データベース接続解除
    [object]$sqlConnection.Close();
}
```

## 使用例

１．ps1配置場所に移動します
２．実行ポリシーを変更します
`Set-ExecutionPolicy RemoteSigned -Scope Process -Force`
３．実行します
`.\exec.ps1 > out.csv`
４．実行ポリシーを戻します
`Set-ExecutionPolicy Restricted -Scope Process -Force`

悪意のあるスクリプトを実行させないために実行ポリシーがデフォルトでは制限されている場合があります。
下記エラーが出力される場合は、上記使用例の２．を実行してください。戻す場合は４．となります。

```
.\exec.ps1 : このシステムではスクリプトの実行が無効になっているため、
ファイル ・・・.ps1 を読み込むことができません。
```
備忘録（openpyxlで①別ブックからのコピペ②対照表の参照）

#概要
前回記事で第2ステップとした「表1の対照表を使って各行に設定1/設定2を付ける」がとりあえず実装できたので纏めておく。
https://qiita.com/wellwell3176/items/7dba981b479c5933bf5f

#成果
図1に示す生データと対照表から、図2の成果の自動生成に成功
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/721074/cf843845-54cb-04e5-a290-816f34d90d81.png)
　　　　　　　　　　　　　　　　　　　　図1　左：生データ　右：対照表
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/721074/793440e7-3405-6bcd-bd02-8f147581d83c.png)
　　　　　　　　　　　　　　　　　　　　　　　　　図2 成果

```python:program
import openpyxl
wb1=openpyxl.load_workbook('/content/drive/My Drive/Colab Notebooks/data3.xlsx')
ws1=wb1.active

#対照表をマスターとして別に用意しておく。マスター側からは数式では無く数値を引っ張りたいので、data_only=trueで開く
wb2=openpyxl.load_workbook('/content/drive/My Drive/Colab Notebooks/table.xlsx',data_only=True)
ws2=wb2.active

for i in range(12):
  for j in range(3):
    copy = ws2.cell(row = i+1, column = j+3).value
    ws1.cell(row = i+1, column =j+10,value=copy)

#別ブックからの参照が上手く行かなかったので対照表を一度コピペ
#rangeはi=0から始まるが、行と列は1から始まるので調整

min_row=2
max_row=ws1.max_row #2行目から最終行まで処理を掛けるので行数取得

ws1["H1"].value="設定1"
ws1["I1"].value="設定2" #見出しは入力した方が早かった

for i in range(min_row, max_row):
  ws1.cell(row=i, column=7).value ="=D{}&E{}".format(i,i)
  #7列目に区分＋業務を入力
  ws1.cell(row=i, column=8).value ="=INDEX($J$1:$L$12,match(G{},$J$1:$J$12,0),2)".format(i) 
  ws1.cell(row=i, column=9).value ="=INDEX($J$1:$L$12,match(G{},$J$1:$J$12,0),3)".format(i) 
  #INDEXを使い、参照表と7列目を照会。結果を入力

wb1.save('/content/drive/My Drive/Colab Notebooks/data4.xlsx')
```

#問題点
・図2のG列J列K列L列は後工程で不要なので消したいが、参照を使ってるので消せない。

　⇨強引な解決策としてdata4をdata_only=trueで開き、不要列以外を新ファイルにコピペする手はあるが、無駄な処理な気がする。

・別ブックの参照方法が分からない

　今回はtable.xlsxの中身をdata4.xlsxにコピペし、それからINDEX関数を使ったが、
　どう考えても最初からtable.xlsxを参照した方が良い・・・が、記述方法を見つけられず。
　次回の課題とする。
【Python】長テーブルのうなぎ屋


##1.問題

円状になったテーブル(テーブル数n)に何人が座る事ができるかを求める問題。
グループの内、一人でも座れない場合そのグループは帰ってしまう。

入力はm+1行から成る。
1行目にはn(座席数)とm(グループ数)が半角スペース区切りで入力される。 
i+1行目(1≦i≦m)には2個の整数a_i(グループの人数)とb_i(着席開始座席番号)が半角スペース区切りで入力される。

条件
全てのテストケースにおいて、入力される値は以下の条件を満たす。
1≦n≦100
1≦m≦100
1≦a_i≦n
1≦b_i≦n

![951A057A-C7C6-4595-ADBF-2CBC7D6FC8E0.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689780/8b9fbb4d-7db9-bfb8-f168-8a4e93fe5333.jpeg)


##2.考えた方法


__`(1)テーブル番号`__

あるグループiがk人おり、b_i番テーブルから座る時
このグループは

b_i,...,b_(i+k-1)

までのテーブルに座る事を想定している。

例えば、上記でテーブル数が6、(a_i,b_i)=(4,5)だった場合
座る予定のテーブル番号は(5,6,7,8)ではなく(5,6,1,2)となる事に注意する。
ここで全てのテーブル番号は__b_j%n(b_jをnで割った余り)__と考える事にした。

__`(2)あるグループが座るか座らないか:check_arr関数で判定`__

着席しているテーブル配列:ar_table
あるグループが座る想定をしているテーブル番号の配列
(make_tblarr関数で作成):ar_chk
ar_tableにar_chkの要素が一つでも含まれる場合座れないと判定する。

__`(3)座っている人数の表示`__

上記で座れる判定をされたグループは、それらのテーブル番号を着席テーブル配列に追加していく。
最終的に、着席テーブル配列のサイズを表示する。


##3.コード例

動作は確認済。


```python

# coding: utf-8
# Your code here!
in1=input()
arr1=in1.split()
n1=int(arr1[0])
n2=int(arr1[1])

in2=[]
for i in range(n2):
    tmp=input()
    in2.append(tmp)
#print(in2)


def make_tblarr(in2,nmax):
    arr3=[]
    arr2=in2.split()
    nn=int(arr2[0])
    st=int(arr2[1])

    for i in range(nn):
        arr3.append((st+i)%nmax)

    return arr3


#ar_table:座っているテーブル番号の配列
#ar_chk:チェック対象の配列
#ar_tableにar_chkの全ての要素が含まれない時0、含まれる要素が見つかった場合1
def check_arr(ar_table,ar_chk):
    flg=0
    for i in range(len(ar_chk)):
        #チェック対象の配列要素が既にar_tableに含まれる場合
        if ar_table.count(ar_chk[i])>0:
            #flgを1にする
            flg=1
            break
    return flg


retar=[]
for i in range(n2):
    ar3=make_tblarr(in2[i],n1)
#print(ar3)
    if check_arr(retar,ar3)== 0:
        for j in range(len(ar3)):
            retar.append(ar3[j])

print(len(retar))

```
zlib を使って gzip 圧縮する

# zlib を使って gzip 圧縮する


## ソースコード

`test test test\n` を 3回分含むデータを gzip 圧縮して `out.gz` に保存する。

```
/*
        gcc test.c -lz -o test
*/
#include <string.h>
#include <zlib.h>

int main()
{
        char * data = "test test test\n";
        gzFile fi = gzopen("out.gz","wb");
        gzwrite(fi,data,strlen(data));
        gzwrite(fi,data,strlen(data));
        gzwrite(fi,data,strlen(data));
        gzclose(fi);
        return 0;
}

```

## コンパイル

```
gcc test.c -lz -o test
```


## 実行

```
./test
```


## 解凍

```
gunzip out.gz
```
【CNN】1x1 convolutionって何してんの？

1x1convolutionってたまに見かけるけど何の為にしてんの？

<h1>概要</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/0e89978d-3e0a-de42-71e9-be4645027bb4.png)
入力画像のサイズを変えずにチャネル方向のみに畳み込みをする


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/d01d1635-4435-d29b-6ac7-b319ca750915.png)
28x28x192のinputに28x28x192のfilter32個を掛け合わせると、28x28x32の出が得られる！

出力チャネル数が減った事により計算量を削減できる!

<h1>例</h1>
入力28x28x192 出力28x28x192とする

<h3>3x3 convの場合</h3>
(28x28x192) x (3x3x192) = 260,112,384

<h3>1x1 conv(half channel) => 3x3 convの場合</h3>
(28x28x192) x (1x1x96) + (28x28x96) x (3x3x192) = 14,450,688 + 130,056,192 = 144,506,880




<h1>参考文献</h1>
Network In Network
https://arxiv.org/pdf/1312.4400.pdf
1×1 Convolution
https://axa.biopapyrus.jp/deep-learning/cnn/1x1_convolution.html
A Comprehensive Tutorial to learn Convolutional Neural Networks from Scratch (deeplearning.ai Course #4)
https://www.analyticsvidhya.com/blog/2018/12/guide-convolutional-neural-network-cnn/
Laravelとは＋導入方法

今回はphpのフレームワークの中で最もポピュラーであるLaravelという物を紹介していきたいと思います。

#フレームワークとは
そもそもフレームワークとはなんだろうと思われる方もいらっしゃると思いますので、まずフレームワークの説明をしていきたいと思います。

フレームワークとは概念的な意味で言うと「枠組み」と言う意味合いをもっています。あるいは、システム開発を楽に行えるようになるプログラムや雛形のことを意味します。このフレームワークを使う事により、開発時間の短縮化、複数人で開発を行う際にコードの統一化を図ることができ、効率的に開発を進めていく事ができます。
下記はphpのフレームワークと簡単な特徴を紹介します。

###1.<a href="http://laravel.jp/">Laravel</a>
世界で人気のフレームワーク
2020年現在、国内において主流のPHPフレームワークであり日本語のドキュメントも充実しています。
###2.<a href="https://cakephp.org/jp/">Cakephp</a>　
日本では最も利用されてきたPHPフレームワーク
Ruby on Railsの概念を取り入れて開発されたPHPのフレームワークで、セキュリティ対策が充実しているので商用アプリケーションに最適です。
###3.<a href="https://codeigniter.com/">CodeIgniter</a>
2006年にリリースされたPHPのフレームワークで、動的なWebサイトの開発に最適です。
必要に応じて随時機能追加していくような設計となっているので、軽量で高速動作するのが特徴です。
###4.<a href="https://symfony.com/">Symfony</a>
2007年にリリースされたRuby on Railsの概念とMojaviの思想を取り入れたPHPのフレームワークで、大規模なWebサービスを開発するのに最適です。
###5.<a href="https://fuelphp.com/">FuelPHP</a>
FuelPHPは2011年にリリースされた比較的新しいPHPのフレームワークで、「規約より設定」を重視して設計されているので高度なWebアプリケーションの開発に適しています。


他にもフレームワークの種類はいくつかありますので興味のある方は是非調べてみてください。
この中で今回は最もポピュラーなLaravelを紹介していきます。

#Laravel
Laravelは<a href="https://snome.jp/framework/mvc-model/">MVCモデル</a>に基づいてます。
MVCモデルとは**M(Model),V(View),C(Contoroller),**の頭文字をとったものです。
下記の流れで処理が実行されていきます。以下のような流れで処理が実行されていきます。①のリクエストの後にRoutingという物も存在します。それを介してContollerに処理を繋げていきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592457/eaa5bba7-9f47-284e-f2b3-1e763f99c0f3.png)

#導入方法
まずMAMPのhtdocsに移動していきます。

```
$ cd /Applications/MAMP/htdocs/
```
ここでは<a href="https://qiita.com/hirotototototo/items/d7acc3da445a39ff366b">composer</a>を使うと簡単にインストールできますので、composerを使ってインストールしていきます。composerの導入は省略します。

 ```
$ composer global require laravel/installer
```
こちらのコマンドでインストールできます。そして、次のコマンドでLavavelでblogという新しいプロジェクトを作成できます。

```
$ laravel new blog
```
また、ターミナルでComposerのcreate-projectコマンドを実行し、Laravelをインストールする方法もあります。

```
$ composer create-project --prefer-dist laravel/laravel blog
```


#終わりに
今回はLaravelを導入するまでの流れを紹介しました。次回は実際にLaravelを使って、一連の流れを紹介していきたいと思います。

#参考サイト
https://kredo.jp/media/php-framework/
https://futurizm.jp/articles/191
https://readouble.com/laravel/7.x/ja/installation.html
https://www.ritolab.com/entry/49
SQLの個人的備忘録2

##DISTINCT
検索結果から重複するデータを除くことができる。

```haml
-# purchasesテーブルからnameが重複するデータを除いたデータの表示。
SELECT DISTINCT(name)
FROM purchases;
```

##四則演算
SQLでは四則演算が可能。

```haml
-# purchasesテーブルから「name」、「price」、「price * 1.08」のデータの取得。
SELECT name, price, price * 1.08
FROM purchases;
```

##SUM関数
数値の合計を計算する場合に使用。

```haml
-# purchasesテーブルのpriceの合計値のデータを取得する。
SELECT SUM(price)
FROM purchases;
```

##AVG関数
数値の平均を計算する場合に使用。

```haml
-# purchasesテーブルのpriceの平均値のデータを取得する。
SELECT AVG(price)
FROM purchases;
```
##COUNT関数
指定したカラムのデータの合計数を計算する。NULLは計算されない。COUNT(*)ではNULLも含めて計算する。

```haml
-# purchasesテーブルのNULLを含めないnameデータの数の取得。
SELECT COUNT(name)
FROM purchases

-# purchasesテーブルのNULLを含めたnameデータの数の取得。
SELECT COUNT(*)
FROM purchases;
```

##MAX・MIN関数
MAXを使うと最大のデータを、MINを使うと最小のデータを取得する。

```haml
-# purchasesテーブルのpriceの最大値のデータを取得。
SELECT MAX(price)
FROM purchases;

-# purchasesテーブルのpriceの最小値のデータを取得。
SELECT MIN(price)
FROM purchases;
```

##GROUP BY
データのグループ化をすることができる。

```haml
-# purchasesテーブルのpurchased_atごとのpriceの合計のデータを取得する。
SELECT SUM(price), purchased_at
FROM purchases
GROUP BY purchased_at
;
```

##WHEREとGROUP BY
併用する場合はWHEREを先に記入する。

```haml
-# purchasesテーブルのcharacter_nameが犬であるデータをpurchased_atでグループ化し、priceの合計、purchased_atのデータを取得。
SELECT SUM(price), purchased_at
FROM purchases
WHERE character_name = “犬”
GROUP BY purchased_at
;
```
##HAVING
GROUP BYでグループ化したデータを更に絞り込むときに使用。WHEREはグループ化される前のテーブル全体を検索対象にし、HAVINGはGROUP BYによってグループ化されたデータを検索対象とする。

```haml
-# purchasesテーブルをpurchased_atでグループ化し、priceの合計が2000以上のデータを取得。
SELECT SUM(price), purchased_at
FROM purchases
GROUP BY purchased_at
HAVING SUM(price) > 2000
;
```
GitHub使い方



今日からはじめるGitHub 〜 初心者がGitをインストールして、プルリクできるようになるまでを解説
https://employment.en-japan.com/engineerhub/entry/2017/01/31/110000#%E7%92%B0%E5%A2%83%E3%81%AE%E6%A7%8B%E7%AF%892-SSH%E3%81%AE%E9%8D%B5%E3%82%92%E5%8F%96%E5%BE%97%E3%81%99%E3%82%8B
macOS で Ruby 3.0.0-preview1 をインストール（Homebrew の ruby-build を使わない方法も）

# はじめに

Ruby 3.0.0 Preview 1 がリリースされました。
https://www.ruby-lang.org/en/news/2020/09/25/ruby-3-0-0-preview1-released/

型システム（という呼び方でいいのかしらん？）とか，並行プログラミングをサポートする Ractor だとか，超目玉機能が試せます。

macOS だと Homebrew で rbenv と ruby-build の二つのパッケージを入れて Ruby をインストールしている人が多いと思います。
本記事の読者はそういう方を念頭に置いています。
# インストール　その(1)

今回，3.0.0 Preview 1 がリリースされて速攻[^sok]で ruby-build が更新されたので，

[^sok]: タイムラグ 1 日くらい？

```shell
brew update
brew upgrade ruby-build
rbenv install 3.0.0-preview1
```

とすれば OK。

# インストール　その(2)

ところが，Homebrew の ruby-build は，対応する Ruby がリリースされてすぐに更新されるとは限りません。
今回はたいへんありがたいタイミングでしたが，3.0.0-dev の場合はリリースされてもなっかなか入らず，結局 3.0.0-preview1 と同時に入ったのでした。

こういう場合，Homebrew の ruby-build パッケージを使わない方法があると Slack の ruby-jp で教えていただきました。

試してみたので，その方法を書きます。

まず，現状では Homebrew で rbenv と ruby-build が入っているので，ruby-build のほうをアンインストールします。
しかし，単純に

```shell
brew uninstall ruby-build
```

とやると，

```
Error: Refusing to uninstall /usr/local/Cellar/ruby-build/20200926
because it is required by rbenv, which is currently installed.
You can override this and force removal with:
  brew uninstall --ignore-dependencies ruby-build
```

とエラーが出て実行できませんでした。
（なお，消そうとしたヤツが「20200926」と最新になっているのは，`brew upgrade` したあとでこれを行ったからです）

そこで，上記のメッセージに書かれているとおり，

```shell
brew uninstall --ignore-dependencies ruby-build
```

とやってアンインストールしました。

次に，ruby-build を GitHub のリポジトリーからクローンします。
ruby-build は（単体でも使えるそうですが）rbenv と組み合わせる場合は，rbenv のプラグインとして働くよう，プラグイン置き場に置く必要があります。

典型的には，それはホームディレクトリーの `.rbenv/plugins` という場所です（Homebrew で ruby-build を入れた場合はこの場所にはありません）。
つまり，`~/.rbenv/plugins` ですね。

しかし，典型的でないケースもありうるので，確実に場所を把握したいところ。

```shell
rbenv root
```

で `plugins` ディレクトリーの親ディレクトリーが表示されるので，以下の手順ではこれを利用します。

まず，`plugins` ディレクトリーは存在するとは限らないので，

```shell
mkdir -p "$(rbenv root)"/plugins
```

とやってディレクトリーを作ります。既に存在していたとしても問題は生じません。

そして，

```shell
git clone https://github.com/rbenv/ruby-build.git "$(rbenv root)"/plugins/ruby-build
```

とやると，しかるべき場所に最新の ruby-build がクローンされます。

この状態で

```shell
rbenv install 3.0.0-preview1
```

とすると，3.0.0 Preview1 がインストールされます！
説明が長かったけど，やるべきことは単純ですね。四箇所コピペするだけでした。

将来，新しい Ruby がリリースされたら

```shell
git -C "$(rbenv root)"/plugins/ruby-build pull
```

で ruby-build を最新版にすればそれがインストールできます。

このへんのことは ruby-build の [README](https://github.com/rbenv/ruby-build/blob/master/README.md) にちゃんと書いてあります。

## コピペ用まとめ

Homebrew で rbenv と ruby-build がインストールされている環境で，Homebrew 版の ruby-build をアンインストールしてから Ruby 3.0.0-preview1 をインストールするまでの全手順を，コピペしやすいよう，ここにまとめました。

Homebrew 版の ruby-build をアンインストール：

```shell
brew uninstall --ignore-dependencies ruby-build
```

GitHub から ruby-build をクローン：

```shell
mkdir -p "$(rbenv root)"/plugins
git clone https://github.com/rbenv/ruby-build.git "$(rbenv root)"/plugins/ruby-build
```

Ruby 3.0.0-preview をインストール：

```shell
rbenv install 3.0.0-preview1
```

クローンした ruby-build を更新：

```shell
git -C "$(rbenv root)"/plugins/ruby-build pull
```

# さいごに

Ruby の新しい時代が始まる。さあ，扉を開こう！

え？　「うちは Windows」だって？
Pandas100本ノックをTidyverseで (42まで)

# head --> head

```R
library(tidyverse)
df <- read_csv('input//titanic3.csv')
df %>% head()
```

# tail --> tail

```R
df %>% tail()
```

# shape --> dim
```R
df %>% dim()
```

# read_csv --> read_csv
```R
df2 <- read_csv('input//data1.csv')
df2 %>% head()
```

# sort_values --> arrange
```R
df %>% arrange(fare)
df %>% arrange(desc(fare))
```

# copy --> Rには参照はない。
```R
df_copy <- df
df_copy <- tibble() #df_copy can be deleted.
df #original df is still kept.
```
# dtypes, dtype 知らない。

# astype --> as.character, as.numeric, as.integerなど
```R
df %>% mutate(pclass = as.character(pclass))
```

# len --> nrow
```R
df %>% nrow()
```

# info --> 知らない。

# unique --> unique
```R
df %>% pull(sex) %>% unique()
df %>% pull(cabin) %>% unique()
```

# columns --> colnames
```R
df %>% colnames()
```

# index --> indexによるアクセスは良くない。

# [] --> Rでも使えるけれど、selectとpullを使い分けたほうがいい。
```R
df[,'name'] # tibble
df$name # array
df %>% select(name) # tibble
df %>% pull(name) # array
```

```R
df[ , c('name', 'sex')] # tibble
df %>% select(name, sex) # tibble
```

# [] --> []
```R
df[1:4, ]
df[4:10, ]
df %>% slice(4:10)
```

# loc --> 必要ではない。print(n = )で表示行数を調整。
```R
df[ , ] %>% print(n = 20)
```

nに対して nrow(.)を入れれば一応全行表示できるけれど。（説明省略）

```R
df[ , c('name', 'ticket')] %>% print(n = nrow(.))
df %>% select(name, ticket) %>% print(n = nrow(.))
```
# : --> :
```R
df %>% select(name:ticket)
```

# iloc --> 必要ではない。

# write_csv --> write_csv
```R
df_copy <- df %>% select(name, age, sex)
df_copy %>% write_csv('output//sample.csv')
```
# [] --> []
不等号の時はNAが入ってしまうのでお勧めできない。filter関数を使おう。

```R
df[df$age >= 30, ] # not good, NA is not removed
df[(df$age >= 30) & (F == is.na(df$age)), ] # complicated
df %>% filter(age >= 30) # easier
```

 等号の時はNAは入らない。

```R
df[df$sex == 'female', ]
df %>% filter(sex == 'female')
```

# query --> filter
Rのfilter関数の場合、&で接続しなくてもいい。,でつなげて書ける。

```R
df %>% filter(sex == "female" & age >= 40)
df %>% filter(sex == "female", age >= 40)
```

# str.contains --> str_detect
```R
df %>% filter(T == str_detect(name, "Mrs"))
```

# select_dtypes --> 知らない

# nunique --> 一つでこなす関数は思いつかない。

# value_counts() --> group_byからのcount
```R
df %>% group_by(embarked) %>% count()
```

# [] --> []
indexを使ってアクセスするのは良くない。

```R
df[3,'age'] <- 40
```

以下でも一応できるけれども、

```R
df[df$sex == 'male', 'sex'] <- "0"
df[df$sex == 'female', 'sex'] <- "1"
```

case_when関数を使って高速化を狙いたい。

```R
df %>% mutate(sex = case_when(
    sex == 'male' ~ '0',
    sex == 'female' ~ '1'
))
```

mutate関数で直感的に書きたい。

```R
df[,'fare'] <- df$fare + 100
df %>% mutate(fare = fare + 100)
```

# round --> round
```R
df[, 'fare'] <- df$fare %>% round()
df %>% mutate(fare = fare %>% round())
```

# 新規列
```R
df[,'test'] <- 1
df %>% mutate(test = 1)
```

# str.cat --> str_c

```R
df[ ,'test'] <- df$cabin %>% str_c(df$embarked, sep='_')
df %>% mutate(test = cabin %>% str_c(embarked, sep='_'))
```

# 列のdrop --> selectでマイナスを使う
行のdropの関数は知らない。dropを使うよりはfilterをかけて部分行を取り出すほうがよい。

```R
df %>% select(-body)
```
【超入門者向け】GitHub初心者がaddからpush、pullまで実行する方法

#概要
この記事を読めば、リモート、ローカルリポジトリの作成からリモートリポジトリへのファイルの登録、およびリモートリポジトリからローカルリポジトリへのファイルを取得させる方法がわかります。ただし、GitHubへのユーザー登録の仕方はこの記事には記載しません。また、よくわからないままGitHubを使ったときに、リモートリポジトリとローカルリポジトリの間でバージョンがずれて苦痛を味わったので、バージョンを合わせる方法も記載しておきます。

#環境
OS:Windows10

#リモートリポジトリとローカルリポジトリ
<img src="https://share.getcloudapp.com/jkuZx5zb/リモートリポジトリとローカルリポジトリ.png" width=50%>
　GitHubは2種類のリポジトリを使ってファイルを管理しています。一つは、リモートリポジトリで、もう一つはローカルリポジトリです。
<UL>　
<L1>リモートリポジトリ
GitHubが管理しているサーバ上に作成するリポジトリ。これがマスター。
<L1>ローカルリポジトリ
クライアントPC上に作成するリポジトリ。作業するたびにリモートリポジトリと同期させて使う。
</UL>

#最初にする作業
##リモートリポジトリ作成
GutHubへのユーザー登録が完了したら新しいリモートリポジトリを作成します。
下図の赤枠をクリックします。
<img src="https://share.getcloudapp.com/4gu968Jx/GitHub.png
" width=50%>

すると次の画面が出てきます。
<UL>　
<L1>①リモートリポジトリの名前。好きな名前をつけてください。
<L1>②リモートリポジトリの説明。空欄も可です。
<L1>③公開するか公開しないか選択します。私は無料版GitHubなので公開しか選択できないです。
<L1>④リポジトリにオプションをつけるときはここから選択します。
<L1>⑤①～④を埋めたら⑤をクリックすれば新しいリポジトリの完成です！
</UL>
<img src="https://share.getcloudapp.com/5zuG0KrQ/New.png" width=75%>

ここまでできたらリモートリポジトリは完成です！
この後はローカルリポジトリを作成していきます。

##ローカルリポジトリの作成
まず最初に手元のクライアントPCにフォルダを好きなところに作ります。
このフォルダの中に、GitHubで管理したいファイルを入れていきます。
その後、下記のコマンドをコマンドプロンプトなどで打ち込んで、フォルダをローカルリポジトリにします。

```
rem ローカルリポジトリにしたいフォルダに移動する
cd (上で作成したクライアントPCのフォルダ)

rem フォルダをローカルリポジトリにする
git init
```
ここまで打ち込んだら、クライアントPCのフォルダがGitHubで用いられるローカルリポジトリになります。
見た目は変わりませんけどね。

次に、GitHubで管理したいファイルを先ほど作成したフォルダにボンボン入れていきましょう。
普段やっているファイルのフォルダ間移動と同じです。

GitHubで管理したいファイルをフォルダに入れましたか?
入れたら、ファイルをローカルリポジトリに登録します。
次のコマンドを打ってください。

```
rem ファイルをローカルリポジトリに登録する
git add .
```
ちなみに、git add . はフォルダ内のファイル全てをローカルリポジトリに登録するコマンドです。
git add (ファイル名)で特定のファイルだけ登録することもできます。
また、(ファイル名)の中は正規表現を使うこともできます。

ファイルをローカルリポジトリに登録できたら、commitします。
commitとは、ファイルを新しく追加したり、編集したりしたときに履歴をGitHub上に追加することです。

```
rem commitする
git commit -m "1st commit"
```
上のコマンドの"1st commit"はcommitのコメントです。コメントをつけたくない場合は、下のコマンドでOKです。

```
git commit
```

ちなみに、commitしたときのコメントは下の図のように表示されます。
<img src="https://share.getcloudapp.com/8LuPveZR/remote.png" width=75%>

commitができたら、ローカルリポジトリとリモートリポジトリをつなげましょう。
ローカルリポジトリとリモートリポジトリの間に「トンネル」を作るイメージです。
まずはリモートリポジトリのURLをコピーしましょう。
下の図を参照してください。
<img src="https://share.getcloudapp.com/OAuJ0x4o/URL.png" width=75%>

URLをコピーしたら次のコマンドを打ちます。ちなみにURLの前後にダブルコーテーションなどはいりません。

```
git remote add origin (さっきコピーしたURL) 
```

最後に、ローカルリポジトリの情報をリモートリポジトリへ反映させます。
下記コマンドを打ってください。

```
git push origin master
```

これで、最初に必要な作業は終わりました！


#ソースコードの編集などを行うときにする作業
<b>まず最初にpullしましょう!</b>
pullをすると、リモートリポジトリの情報がローカルリポジトリへ反映されます。
これを忘れてコードの編集等をしだすと、リモートリポジトリとローカルリポジトリの情報が
ずれて面倒なことになります。
pullは次のコマンドで実行します。

```
git pull
```

これでローカルリポジトリ内の編集ができるようになりました。

あとはローカルリポジトリ内のコードを編集して、add, commit, pushを実行するだけです。
最初の作業で行ったremoteは2回目以降は実行しなくてOKです。

#リモートとローカルのバージョンに差が出てしまったときの対処法
私がGitHubを使い始めた次の日、pullをせずにローカルリポジトリを編集してしまいました。
その際commitができなくなって非常に困ったので復旧方法が記載されたHPを紹介します。
まず、確実にうまくいくのは[git pull でエラーが出た時、強制的にpullする方法](https://brainlog.jp/post-1078/)です。ただし、ローカルリポジトリの情報がリモートリポジトリの内容に上書きされるなどのデメリットがあるので注意してください。
ちなみに、リンク先で紹介されているfetchは[【入門者向け】Gitのfetchコマンドについて図を用いて解説](https://eng-entrance.com/git-fetch)に解説があります。
ルータの機能

応用情報技術者平成28年秋期 午前31

ルータの機能に関する記述のうち，適切なものはどれか。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/029a276a-7e0a-f333-cc37-c4f87d39eb1b.png)


１、ルータは、
OSI基本参照モデルのネットワーク層でネットワーク同士を接続し、
通過するパケットのIPアドレスを見てパケットを最適な経路に転送する通信装置です。

ネットワーク層は、OSI基本参照モデル第3層に位置するため下層の伝送媒体(物理層)やアクセス制御方式(データリンク層)の方式に影響されることなく接続することが可能です。


２、
・MACアドレステーブルの登録情報によって，データフレームをあるポートだけに中継するか，全てのポートに中継するかを判断する。
⇒×。ブリッジやスイッチングハブの説明です。

・OSI基本参照モデルのデータリンク層において，ネットワーク同士を接続する。
⇒×。ブリッジやスイッチングハブの説明です。

・OSI基本参照モデルのトランスポート層からアプリケーション層までの階層で，プロトコル変換を行う。
⇒×。ゲートウェイの説明です。

・伝送媒体やアクセス制御方式の異なるネットワークの接続が可能であり，送信データのIPアドレスを識別し，データの転送経路を決定する。
⇒○。ルータの説明です。


OSI基本参照モデル
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/90dc90f5-88b2-b8af-f78c-eabcd24e1379.png)


参照：
https://www.ap-siken.com/kakomon/28_aki/q31.html

https://qiita.com/lymansouka2017/items/b7555fc283543f86a072
歌詞サイトから手軽にクリップボードにコピーするためのブックマークレット

# 歌詞サイトから歌詞をゲットしたい

転載対応なのか歌詞サイトの多くはコピペ禁止というか、古のテクニックで右クリック禁止をしている場合が多い。 
ソースを開発者ツールでみると、要素自体は取りやすい模様。
ファイルとして保存してもいいが、とりあえずコピペできれば十分だとおもったので、ブックマークレットにすることにした。

今回は検索でよくヒットするJ-Lyric.netをターゲットにする。


## ブックマークレットの作成

ブラウザのブックマーク編集で、以下のjavascriptをURLとして入力する。

```:javascript
javascript:function getLyric(){var a=document.createElement("textarea");var t = document.getElementById("Lyric").innerHTML.replace(/<br>/g, "\n").replace(/&amp;/g, "&");a.textContent=t;var d=document.getElementsByTagName("body")[0];d.appendChild(a);a.select();var b=document.execCommand("copy");d.removeChild(a);return b};getLyric();
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23242/98a8e2e6-a763-0869-6898-8654b4995b00.png)


## 使い方

1. ブラウザのブックマーク編集で、ブックマークレットを作成。
2. [J-Lyric.net](https://j-lyric.net/artist/a005098/l05129e.html)でなんらかの曲を表示。
3. ブックマークレットを選択（クリップボードにコピーされる）
4. メモ帳などにペースト


## 概説

元のソースは、[こちら](https://qiita.com/xshoji/items/93d5345d4bf282f60817)を参考にした。 
単純にgetElementByID("Lyric")した内容をそのままクリップボードにもっていけなかったので、内部的にテキストエリアをつくってコピーさせているのがミソ。
ロールフォワード、ロールバック


応用情報技術者平成28年秋期 午前30

DBMSをシステム障害発生後に再立上げするとき，ロールフォワードすべきトランザクションとロールバックすべきトランザクションの組合せとして，適切なものはどれか。ここで，トランザクションの中で実行される処理内容は次のとおりとする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/66e92455-d1e4-4d2b-56af-32984919db20.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/c1696862-2edf-70c0-58da-85196210343f.png)


１、システム障害の回復流れ：
①直近のチェックポイントに回復、
②直近のチェックポイント以降、コミットされていたのトランザクションを回復（＝ロールフォワード）
③直近のチェックポイント以降、コミットされていないのトランザクションを捨てる（＝ロールバック）


直近のチェックポイント以降は、
　T2、T5はコミット・トランザクションありますので、ロールフォワードが可能。
　T3、T6、T4はトランザクション途中ので、ロールバックが必要。

ただ、T3、T4がRead100ので、Writeがないので、ロールバックが必要なりませんね。


参照：
https://www.ap-siken.com/kakomon/28_aki/q30.html
Mac OSでDockerを使ってCentOS上でnginxを起動するまで

[nginx実践入門](https://gihyo.jp/book/2016/978-4-7741-7866-0) をMac OSで進めたいです。

### DockerでCentOSを起動
[Runtime privilege and Linux capabilities] (https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities)
[F.2.4. /SBIN/INIT プログラム](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/6/html/installation_guide/s2-boot-init-shutdown-init)

```zsh
$ docker run --detach --name mycentos --privileged centos /sbin/init
```

### コンテナ内でBashシェルを起動
[インタラクティブなコンテナを実行](http://docs.docker.jp/v1.11/engine/userguide/containers/dockerizing.html#run-an-interactive-container)

```zsh
$ docker exec -it mycentos bin/bash
```

### YUMレポジトリーの設定

[9.5. YUM と YUM リポジトリーの設定](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/system_administrators_guide/sec-configuring_yum_and_yum_repositories)
[nginx: Linux packages](http://nginx.org/en/linux_packages.html)

```bash
[root@b626534eeb51 yum.repos.d]# vi nginx.repo
```

```nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/mainline/centos/8/$basearch/
gpgcheck=0
enabled=1
```

### nginxのインストールと起動

```bash
[root@b626534eeb51]# yum install nginx
[root@b626534eeb51]# nginx

[root@b626534eeb51]# systemctl enable nginx.service
[root@b626534eeb51]# systemctl start nginx.service
[root@b626534eeb51]# curl localhost
```
fatal: remote origin already existsのエラーで怒られたとき


リモートリポジトリをローカルリポジトリに紐付けしようとしたら
以下のエラーが！！

```
$ git remote add origin git@github.com:coｍ/ユーザー名/リポジトリ名.git
fatal: remote origin already exists.
```

要は、既に紐付き先があるから浮気しないでくれって感じなのでそれに消えてもらって、再度登録をし直せばいいとのこと。

そこで念のためにどのリポジトリに紐付いてるかを確認するために

```
git remote -v
```
を入力。

```
origin  git@github.com:～(fetch)
origin  git@github.com:～(push)
```
↑
すると今の紐付け先が出てくるので、削除するために

```
git remote rm origin
```
を入力。
そしてもう一度

```
git remote -v
```
を入力して削除されたかの確認。
削除されてたら何も出てきません。

そして、

```
git remote add origin git@github.com:ユーザ名/リポジトリ名.git
```
を入力して、新しいリポジトリの紐付け完了。
Unity から Xcode経由でiOSへビルドするときのエラー「library not found for -liPhone-lib」



##バージョン
Xcode  Version 12.0.1 
Mac OS　Catalina
iOS 13.7


##エラー
Unity から Xcode経由でiOSへビルド
Xcodeのビルドの最後の方で、こんなエラー

```
ld: library not found for -liPhone-lib
clang: error: linker command failed with exit code 1 (use -v to see invocation)
```

##原因
Unityのプロジェクト名が<B>全角の文字</B>を含んでいたため。

（誤） TEST１

（正） TEST1
　

以上

<br>
これだけで、半日悩んだ・・・・・
Python(Colab)でウェブ上の画像をドライブに保存する

下記の写真をドライブに保存するコードです。

https://www.pakutaso.com/shared/img/thumb/nyannko458A3685_TP_V.jpg
![nyannko458A3685_TP_V.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428239/657275c2-d4d6-e376-0ea7-938173a68573.jpeg)


前提としてColabで実行するコードで、
Pythonでやる場合はGCPでOAuthの設定が必要です。

# ドライブの認証を通す

```python:Colabでの認証
from google.colab import auth
auth.authenticate_user()

from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive
from oauth2client.client import GoogleCredentials

gauth = GoogleAuth()
gauth.credentials = GoogleCredentials.get_application_default()
drive = GoogleDrive(gauth)
```

# 画像を保存する

```python:画像をjpegで保存
import requests
from io import BytesIO
from PIL import Image

url = 'https://www.pakutaso.com/shared/img/thumb/nyannko458A3685_TP_V.jpg'
file_name = 'ネコ.jpg'
FOLDER_ID = '' #保存したいフォルダIDを指定

r = requests.get(url)
i = Image.open(BytesIO(r.content))
i = i.resize(size=(200, 100)) #リサイズしたい場合に使用
i.save(file_name)

#IDを指定してUPLOADする
f = drive.CreateFile({'title' : file_name, 'parents':[{'id' : FOLDER_ID }]})
f.SetContentFile(file_name)
f.Upload()
```

別のセルでiを実行すると画像の確認が可能です。

jpeg以外で保存したい場合はファイル名の拡張子を変更したら変わります。
サポートされているフォーマット一覧は下記に載っています。
https://pillow.readthedocs.io/en/latest/handbook/image-file-formats.html


# エラーが出た場合

ファイル名に拡張子を付け忘れると下記のエラーがでるので注意。

![2020-09-26_11h03_41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428239/790d67ed-a3be-205c-78df-3989a5b1a033.png)


# PILでできること

https://pillow.readthedocs.io/en/latest/handbook/tutorial.html#using-the-image-class
MySQLのログイン時にエラーが発生しました。 -- error 2003 (hy000) can't connect to mysql server on 'localhost' (10061)

MySQLの起動（コマンドプロンプト）の際にエラーが出たのでその内容と解決方法を備忘録として投稿します。

自分のパソコンに先日MySQLをインストールしてDB環境を用意しました。
MySQLの起動をせずにいきなりログインしようとしてしまい（下記 コマンド実行）

```
mysql --user=root --password
```

<br>
以下のエラーが発生しました。

```
error 2003 (hy000) can't connect to mysql server on 'localhost' (10061)
```

<br>
解決方法を調べたところ、先にMySQLの起動が必要との事で下記コマンドを実行

```
brew services start mysql@5.7
```

<br>
するとまた、下記エラー発生

```
'brew'は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。
```

<br>
原因を調べると「brew・・・」はmac用のコマンドでした
なのでwin用の下記コマンドを実行

```
net start mysql57
```

<br>
続いて再度ログインを試みますと・・・（下記実行）

```
mysql --user=root --password
```

<br>
無事、ログインできました！！！
まだまだ学ぶことがいっぱいですがコツコツ行きたいと思います。

Qiita活用の練習もかねて、投稿しました。
【技術書まとめ】『React.js&Next.js超入門』を読んだまとめ

## 読み終えて

Reactを本当に一から丁寧に教えてくれる本だった。1枚のペラページを改良しながら進んでいくやり方もいい。Reactの概念部分がコードとして具体的に見えて理解しやすかった。Amazonで低評価をつけている人もいるが、自分としてはReact入門者にとってすごくいい本だと思った。

> 「こんな本を読んだだけで、Reactをマスターできる人間なんて絶対にいない！」......わかりませんよ、一度読んだくらいでは。......この本は、......「入り口まで誘導する、導入書」です。ここから、Reactの本格的な学習が始まるのです。

最後にある言葉だが、これはとても真摯な言葉だ。


## 第1章 Reactを準備しよう！

いきなりReactの機能紹介に入らずに、htmlの1枚ファイルで仮想DOMなどの説明をしてくれる。とてもわかりやすい。

通常の技術書と違って話しことばに近く、かなりフレンドリーな印象を受ける。「覚えなくていいことですよ」といろんなところで強調して、覚えないと！　と焦って途中で詰まってしまうのを防いでくれている。

> 表示を更新したければ、またエレメントを作ってレンダリングし直せばいい

なるほど。

```terminal
$ npx create-react-app react_app # reactアプリを作る

$ yarn start # 起動
$ yarn build # ビルドする。これをプロダクションにあげるとそのまま動く

```


## 第2章 JSXをマスターしよう！

ここも１枚のhtmlで丁寧にReactの挙動を確認した。覚えることもまとめられていてとても親切。

- エレメント
    - HTMLの各タグ
        - `div`や`p`など
- ノード
    - HTMLのあらゆる要素を扱うオブジェクト
        - 「開始タグ」、「終了タグ」、「中のコンテンツ」など

> 「Reactでは、仮想DOMのエレメントを作って組み込むのだ」ということだけ頭に入れておきましょう。

なるほど。

> 「JSXは、あらゆるところで使うことができる」ということを頭によく入れておきましょう。そして、エレメントを利用する必要がある場合は、「ここでJSXが使えないか」を常に考えるようにしましょう。

ふむふむ。

- リスト表示には`map`を使う

> JSXは変数代入時にコンパイルされる

変数のみ更新して`render`しても表示は更新されない。

- 覚えること
    - JSXはキャメルケース
        - `onClick`など
    - タグは単発でも閉じる
        - `<input />`
    - 変数は`{}`に入れられる
    - `ReactDOM.render(el, dom)`でレンダリングする
        - 変数だけ変えても更新されない


## 第3章　コンポーネントをマスターしよう！

コンポーネントを作り、stateを管理したりつなげたり、Contextで共通の値を保持したりをしっかり確認できる。

- コンポーネント名は大文字で始める
    - `Welcome`

> setStateは、値を追加するだけで、削除はしません。この点は忘れないようにしましょう。

なるほど。

- オブジェクトや配列を使うとき
    - プロパティとして値を用意（`data = []`）
    - `setState`で設定する
- Context
    - 「すべてのコンポーネントで同じ値を設定し、一斉に変更できる」
    - テーマ切り替え


## 第4章 Reduxで値を管理しよう！

- Reduxは状態管理ユーティリティ
    - 値の保管場所は1つだけ
        - 「ストア」
- Reducer
    - 「どういうtypeの時にどんな値をreturnするか」
        - Reducer作成のポイント
    - Reducerで呼び出す処理は常に新しいステートをreturnする
- `connect`で渡されれるステートは`this.props`に組み込まれる
    - 属性の値もいろいろ保管されている
        - 名前が被らないようにステートのマッピングで必要なものだけ取得するようにする

```js
// ステートのマッピング
function mappingState(state) {
  return state;
}
```

- `dispatch`
    - Reduxにアクションを送る
        - Reducerが呼び出される
            - 必ず`type`という値を用意する

```js
this.props.dispatch({ type: 'DECREMENT' });
```

> 「ステートを用意する」→「レデューサーを用意する」→「ストアを用意する」という手順。「ディスパッチを呼び出す」→「レデューサーが呼び出される」→「アクションのtypeで処理を分岐」というアクションの流れ。これらをしっかりと頭に入れておきましょう。

なるほど。

> アプリケーションは、極論するなら「用意されたデータ本体と、それを処理するための付け足し部分でできています。

データこそが本体。

- export
    - 最後にエクスポートして使えるようにしておく
- Redux Persist
    - オブジェクトは正しく保管できない時がある

1. Reducerの書き方を覚える
2. Storeの使い方を覚える
3. ReduxPersistの組み込み方を覚える


## 第5章 Next.jsでReactをパワーアップしよう！

- Reactは使っている間、常にどこかが書き換わっている
    - クライアントサイド・レンダリング
- Next.js
    - 「HTMLファイルを使わずにWebアプリを開発する」
    - `pages`フォルダが一番重要
        - ページ内容を用意する
- レイアウトの基本構成
    - Layout
    - Header
    - Footer
    - Style
- ReduxをNext.jsで使う
    - `redux-store.js`
    - `app.js`
    - を用意する


## 第6章 Firebaseでデータベースを使おう！

- `firebase`の`on`は非同期
    - 「終わったらこれを実行しておくように」という処理
- firebaseの項目はパスで指定できる

```terminal:Next.jsアプリ作成
npm install --save react react-dom
npm install --save next
npm install --save redux react-redux redux-thunk
```

- コンポーネントの属性をメソッドとして実行
    - コンポーネントを組み込んでいる側の処理を呼び出せる

```jsx

<Account onLogined={this.logined}onLogouted={this.logouted} />
```
Pythonによる画像処理100本ノック#7 平均プーリング

## はじめに
どうも、らむです。
今回は画像をグリッド分割する手法であるプーリング処理の中でも、領域中の平均値を代表値とする平均プーリングについき実装します。

## 7本目：平均プーリング
プーリングとは画像を固定長の領域にグリッド分割し、その領域内の値を全てある値にする処理です。この処理を施すことで画像はモザイク状になります。
平均プーリングでは領域内の画素値の平均値で領域内を埋めます。

平均プーリングは以下の式によって定義されます。
Rは領域のことで、例えば8×8ピクセルの領域であれば$|R|=8×8=64$になります。

```math
v = \frac{1}{|R|}\sum_{i \in R}v_i
```

## ソースコード

```avePooling.py
import numpy as np
import cv2
import matplotlib.pyplot as plt


def avePooling(img,k):
  dst = img.copy()

  w,h,c = img.shape
  # 中心画素から両端画素までの長さ
  size = k // 2

  for x in range(size, w, k):
    for y in range(size, h, k):
      dst[x-size:x+size,y-size:y+size,0] = np.mean(img[x-size:x+size,y-size:y+size,0])
      dst[x-size:x+size,y-size:y+size,1] = np.mean(img[x-size:x+size,y-size:y+size,1])
      dst[x-size:x+size,y-size:y+size,2] = np.mean(img[x-size:x+size,y-size:y+size,2])

  return dst


# 画像読込
img = cv2.imread('image.jpg')

# 平均プーリング
# kは領域サイズ
img = avePooling(img,40)

# 画像保存
cv2.imwrite('result.jpg', img)
# 画像表示
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.show()
```

<img width="300" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519081/5f7ccd93-cb2d-f14b-9004-0fd116035c34.jpeg">　<img width="300" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519081/9b66587a-3f2c-5a21-0146-192b3be445c9.jpeg">


画像左は入力画像、画像右は出力画像です。
上手くモザイク状の画像になっていることが分かりますね。グロそうなものに見えてしまいますが、ちゃんとお刺身です。

<img width="300" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519081/a676887f-929e-ccd1-c012-e6e90299301d.jpeg">

画像処理でよく使われるLenaさんの画像のフルバージョンも平均プーリング処理をかければQiitaにも載せることができますね。

## おわりに
もし、質問がある方がいらっしゃれば気軽にどうぞ。
imori_imoriさんの[Github](https://github.com/yoyoyo-yo/Gasyori100knock/blob/master/Question_01_10/answers_py/answer_6.py)に公式の解答が載っているので是非そちらも確認してみてください。
それから、pythonは初心者なので間違っているところがあっても優しく指摘してあげてください。
Ubuntu 使用時におけるRstanのcompile error

##1.はじめに
UbuntuとWindowsと同時にRstanを走らせていると、Ubuntu側のRstanで次のようなerrorがでました:anguished:

```{r}
 prep_call_sampler(object) でエラー: 
  the compiled object from C++ code for this model is invalid, possible reasons:
  - compiled with save_dso=FALSE;
  - compiled on a different platform;
  - does not exist (created from reading csv files).
```
ググってみたのですが、このようなエラーには、stanのHPに下記のサイトがありましたが、解決にはいたりませんでした:sob:
[Problems compiling in ubuntu machine](https://discourse.mc-stan.org/t/problems-compiling-in-ubuntu-machine/1944)

でもWindows側では同じコードのRstanは問題ありません。

##2.解決法

モデルを記述しているstanfileの名前を別名に変更すると治りました。
実に簡単でしたが、同じような症状が出ている人がいたら、試してください:grin:
【用語メモ】バリデーション

#バリデーションとは
入力された内容の**妥当性を確認すること**。

もっと砕けた言い方をすると、変な内容やありえない内容を入力していないか確認すること。

##例
**お酒を販売するECサイトの場合：**

年齢が20歳以上かの確認。
アレルギーを持っている持っていないかの確認。
生年月日を入力したときの数字が小文字になっているかの確認。など
SourceTreeのインストール


#要点
- 無料利用可能
- Mac、Windows に対応
- インストールはexe形式のインストーラーを使う（Scoopは使わない）
- 詳細オプションは、有効化しない

#SourceTreeとは
バージョン管理システム（GitとMercurial）をGUI操作できる無料ツール。
MacとWindowsに対応している。

#インストール手順（通常版）
##1. インストーラーをダウンロードする
https://www.sourcetreeapp.com/
公式サイトからインストーラーをダウンロードする

##2. インストーラーを起動する

###2.1. Install
ダウンロードしたインストーラーを起動します。

###2.2. Registration
Bitcuketのアカウント登録を行えますが、Bitcuketを使わないのであれば「スキップ」で問題ありません。
![rapture_20200926010925.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39680/0a2b7d59-2d35-5280-6b6a-145ec7ee862b.png)

###2.3. ツールをインストール
SourceTreeと同時にインストールしたいバージョン管理システム（GitやMercurial）を選択します。
すでにバージョン管理システムがインストールされている場合は、自動選択された状態で表示されます。
![rapture_20200926010953.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39680/4f4278e2-0380-e2f9-f660-03ee0ff82e8e.png)

####詳細オプション
「詳細オプション」の選択は行わない方が無難です。
#####改行の自動処理を設定する
取得したテキストの改行コードが全て LF から CRLF 自動変換されます。Windows上のDockerでLinuxを動作させる時など、CRLF が問題を起こす原因となります。
#####Configure Global Ignore
グローバル無視リストを作って exe、dll、obj のような通常はリポジトリにプッシュしないような拡張子のファイルを無視する設定。この設定はチャックしないで、意図的に拡張子を個別設定した方が無用な混乱を避けられます。

###2.4. Preferences
アカウント名とメールアドレスを登録します。
![rapture_20200926011140.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39680/0f6c8c3d-fa18-aeeb-3b91-43fbe85be6ee.png)



#インストール手順（Scoop版）
Scoopを使わずにexe形式のインストーラーでインストールする方が無難です。
SourceTree を Scoop でインストールすること自体は可能ですが、SourceTree から参照しているパスが固定なのでトラブルが発生するようです。

- 参考：[Scoop で Git と SourceTree をインストール - ありふれた備忘録](https://blog.isonishi.com/posts/scoop-git-sourcetree)

##Scoopを使用したインストール手順
##1. パッケージを検索する
SourceTreeのパッケージが extras バケットに存在することが確認できる。

```powershell:PowerShell
PS C:\> scoop search sourcetree
Results from other known buckets...
(add them using 'scoop bucket add <name>')

'extras' bucket:
    bucket/sourcetree
```

##2. パッケージを含むバケットを追加する
extras バケットをパッケージのダウンロード元として追加する。

```powershell:PowerShell
PS D:\> scoop bucket add extras
Checking repo... ok
The extras bucket was added successfully.
```

##3. パッケージをインストールする
SourceTreeパッケージをインストールする。

```powershell:PowerShell
PS D:\> scoop install sourcetree
Updating Scoop...
Updating 'extras' bucket...
Installing 'sourcetree' (3.3.9) [64bit]
SourceTree-3.3.9-full.nupkg (23.3 MB) [========================================] 100%
Checking hash of SourceTree-3.3.9-full.nupkg ... ok.
Extracting SourceTree-3.3.9-full.nupkg ... done.
Linking ~\scoop\apps\sourcetree\current => ~\scoop\apps\sourcetree\3.3.9
Creating shim for 'sourcetree'.
Creating shortcut for Atlassian SourceTree (sourcetree.exe)
'sourcetree' (3.3.9) was installed successfully!
```
Shopify 環境別deploy方法について

# はじめに
- インストール等は割愛しております。
- 使用ツール```Shopify Theme Kit```
- テーマIDの一覧を取得しておきます。
- [live]とついているIDがShopify管理画面上での本番の事を意味しています。

```terminal
$ theme get --list -p=パスワード -s=ストア名
  [11111111111] Debut
  [22222222222] Masonry
  [33333333333][live] Pacific
```


- 目的のテーマIDをダウンロードしたい場合

```terminal
$ theme get --list -p=パスワード -s=ストア名 -t=テーマID
```


# 設定ファイルの準備
- テーマIDを設定ファイルに記載して準備します。
 - 余談ですが、初期設定時の```config.yml```の環境名は```development```となっていて、ファイルの監視と自動更新を行うコマンド```theme watch```は```development```に向いているようです。そのため下記のようにそれぞれの環境に自動更新するのではなく```development```だけなので安心です。

- 公式ドキュメント https://shopify.github.io/themekit/configuration/#config-file

```config.yml
# 本番環境
production:
  password: パスワード
  theme_id: テーマID
  store: ストア名

# ステージング環境
staging:
  password: パスワード
  theme_id: テーマID
  store: ストア名

# 開発環境
development:
  password: パスワード
  theme_id: テーマID
  store: ストア名
```

# 環境別にdeploy
- 続いて環境別にdeployする方法の説明です。
- 基本的にdeployは```theme deploy```コマンドで実施します。
- optionをつけないと```development```の環境を更新します。

```terminal
$ theme deploy
```

- optionで```–env=[環境名]``` を追加することで環境別にdeployしてくれます。

```terminal
$ theme deploy --env=development
```
```terminal
$ theme deploy --env=staging
```
```terminal
$ theme deploy --env=production
```

- また、個別ファイルを更新する方法の説明です。
- 個別ファイルを更新したいこともあると思いますので```assets/ファイル```を例にします。

```terminal
$ theme deploy assets/ファイル --env=development
```
```terminal
$ theme deploy assets/ファイル --env=staging
```
```terminal
$ theme deploy assets/ファイル --env=production
```

- すべての環境にまとめてdeployする方法です。

```terminal
$ theme deploy -a
```

警告が出る場合

```terminal
[production] 
This is the live theme on ライブテーマの名前.
If you wish to make changes to it, then you will have to pass the --allow-live flag
cannot make changes to a live theme without an override
```

解決
当然ながらテーマID[live]が含まれています

ライブテーマごとすべて変更したい場合は --allow-live フラグを渡す必要があります。

```terminal
$ theme deploy -a --allow-live
```
AWS Systems Manager、Lambdaを使ってS3のファイルをEC2(Windows)内にダウンロード(同期)してみた。

#概要図
Lambda ⇒ Systems Manager ⇒ EC2 ⇒（同期コマンド）⇒ S3 

▼参考（にさせていただきました！）
https://dev.classmethod.jp/articles/lambda-s3-ec2-windows-sync/

#作業ステップ
▼前提
・S3にバケットを作成し、ファイルをアップロード済み
###①IAMロールを作成（EC2用）
AmazonEC2RoleforSSM
※上記権限は範囲が広いため、別のポリシーへの移行が推奨されていますので、
　仕事で使用する場合は下記ページをご確認いただければと思います。
　https://dev.classmethod.jp/articles/check-amazonec2roleforssm-policy/
###②EC2インスタンス作成（windowsサーバ　※ami-038c59e921e8b9c7d 使いました）
ロールに”①”をアタッチ
⇒SystemsManagerでEC2のオペレーションができるようになる
※SSMエージェントはデフォルトでインストールされていました。
###③IAMユーザを作成（EC2用）
AmazonS3FullAccess（S3フルアクセス）
###④EC2にRDP（リモートデスクトップ）し、AWS CLIをインストール
私はMSIインストーラでインストールしました。
https://dev.classmethod.jp/articles/first-login-to-ec2-windows/
https://docs.aws.amazon.com/cli/latest/userguide/install-windows.html
###⑤EC2にRDP（リモートデスクトップ）し、AWS CLIにアクセスキー・シークレットアクセスキーを設定
”③”で振り出した、アクセスキーシークレットアクセスキーを設定
⇒これにより、AWS CLIで、S3にアクセスできるようになる。
###⑥IAMロールを作成（lambda用）
AmazonEC2FullAccess
AmazonSSMFullAccess
※lambdaデフォルトポリシーに上記を追加
###⑦lambdaを作成
EC2にS3のファイルを同期するようなコマンドを実行させる。

#結果
S3のファイルがEC2に同期されました！
![キャプチャ.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350277/7692424d-f73d-6ebc-9ddb-a3e173dc1aed.jpeg)


#はまったポイント
##①lambdaからaws cliのコマンドを実行すると、下記のエラーが表示される。
>aws : The term 'aws' is not recognized as the name of a cmdlet, function,
>script file, or operable program. Check the spelling of the name, or if a path
>was included, verify that the path is correct and try again.

まぁ、はまりました(笑)
▼試したこと
①コマンドを管理権限で実行する方法を探す
　⇒sudo的なのはない、ただファイルを置けばできそうな感じ、、いったん放置
②EC2にadmin権限なしのユーザを作ってログインし、Power Shellでaws cliコマンド実行
　⇒普通に実行できる。（admin権限周りは関係なさそう）
③EC2にデフォルトでインストールされているSSMエージェントのverを最新にしてみた
　AWSコンソール＞AWS System Manager＞マネージドインスタンス＞Agent auto updateを押下
　⇒ダメもとでためしただけなんですが、、解決！！！

まさか、これなん、という感じでした。
いやー、無事解決、気持ちよかったです(*'▽')

#なるほどポイント
元々、パブリックサブネットでEC2/VPC外lambdaで実行していました。
EC2をプライベートサブネット（NATつき）に移動させても問題ないのか、確認してみました。
⇒Lamdbaからのコマンドが実行されなくなりました。

試していないですが、下記の作業で可能となるようです。
VPCエンドポイントは双方向なんですね。
https://dev.classmethod.jp/articles/tsnote-private-ec2-ssm-vpc-endpoint/

以上です。勉強になりました。
X-Forwarded-Forヘッダーから接続元クライアントのIPアドレスを特定し、アクセス制御する方法


## X-Forwarded-For(XFF)ヘッダーとは

*  HTTP プロキシ又はロードバランサーを通過してウェブサーバーへ接続したクライアントの、送信元 IP アドレスを特定するための(事実上の)標準ヘッダー。

### 形式

```http
X-Forwarded-For: <client>, <proxy1>, <proxy2>
```

* `<client>`
  クライアントの IP アドレス

* `<proxy1>, <proxy2>`
  * リクエストが複数のプロキシを経由して行われる場合、それぞれのプロキシの IP アドレスが追加される。
  * 右端の IP アドレスが最も後段のプロキシであり、左端の IP アドレスが元のクライアントの IP アドレスを指す。



## 接続元クライアントのIPアドレス特定方法

### 通常の場合

![XFF_Architecture.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586535/da68ac7a-fe46-af38-e194-e0ae3842dd33.png)

* 上図のような構成で、EC2インスタンス(Apacheなど)で接続元クライアントのIPアドレスを特定したい場合は、`X-Forwarded-For`ヘッダーの右から２つ目の値を確認する。
  ※ELBへの直接アクセスなどを許容しないことが前提

### XFFヘッダーを偽装された場合

![XFF_Architecture_cheat.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586535/59b1b3d6-f3a5-c4e1-1a17-826843c511f6.png)

* クライアントが意図的にヘッダーに値を設定(偽装)した場合も、`X-Forwarded-For`ヘッダーの右から２つ目の値を確認する。

## Apacheでの接続元IPアドレスに基づくアクセス制御

* 接続元クライアント(上記の例で右から2番目)のIPアドレスが`XXX.XXX.XXX.XXX`の場合に`/test`へのアクセスを許可したい場合、httpd.confに以下を記述する。

```
SetEnvIf X-Forwarded-For "(:?^| )XXX\.XXX\.XXX\.XXX, [\d.]+$" allowed

<Location /test>
Order deny,allow 		# 拒否してから許可
Deny from all			# 全アクセスを拒否
Allow from env=allowed	# envからのアクセスを許可
</Location>
```



## 参考情報

* [X-Forwarded-For](https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/X-Forwarded-For)

* [CloudFront→ELB→EC2構成におけるIPアドレスのアクセス制御](https://int128.hatenablog.com/entry/2017/09/13/143702)
* [ELB配下のApacheでのアクセス制御](https://dev.classmethod.jp/articles/access-limit-behind-elb/)
【Firebase】FireStoreに一括でcsvまたはjson形式のデータをアップロードする

## 概要
[FireStore](https://firebase.google.com/docs/firestore)は、モバイル開発においてとても便利なDatabaseの一つですが、データの一括importが少々手間取ったので方法を記載しておきます。

## Step1: Jsonデータの用意
私の場合はMacのNumbersを使用して、CSVを作成し、[CSV→Json変換サイト](https://csvjson.com/csv2json)を用いてjsonデータに変換しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/f8749bcc-f8ca-75ae-1bdc-83703642ed09.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/fe45d726-0f5b-8711-3d89-e280a30d5fb0.png)


## Step2: Service Key をFirebaseコンソールよりダウンロード
Service Key をFirebaseコンソールよりダウンロードします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/22083068-40a8-d73c-4524-f397a008ad44.png)
![Screen Shot 2020-09-26 at 8.30.16 AM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/cbd4d42a-77c6-770a-4a32-b40a7b9eb53d.png)

## Step3: node.js プロジェクトの設定

![Screen Shot 2020-09-25 at 11.22.42 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/366addc2-a27f-822d-ffa2-07936d3c4c58.png)

上記のコマンド実行後、実行したディレクトリにPackage.jsonが生成されます。
Step1で生成したjsonファイル(data.json)Step2で生成したServiceKeyのファイル(serviceAccountKey.json)も同ディレクトリ内に格納します。

## Step4: index.jsの作成

terminalで以下を実行。
```
npm install firebase-admin
```

すると、node_moduleというディレクトリが生成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/c2408a58-62d3-6c88-e8d3-80429e08a8ff.png)


Firestoreにimport用のプログラムを作成します。

```js:index.js
const admin = require('./node_modules/firebase-admin');
const serviceAccount = require("./serviceAccountKey.json");

const data = require("./data.json");
const collectionKey = "words"; //Change!! name of the collection

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: "https://your-database.firebaseio.com" //Change!! your database URL
});

const firestore = admin.firestore();
const settings = {timestampsInSnapshots: true};
firestore.settings(settings);

if (data && (typeof data === "object")) {
    Object.keys(data).forEach(docKey => {
        firestore
        .collection(collectionKey)
        .doc(docKey)
        .set(data[docKey])
        .then((res) => {
            console.log("Document " + docKey + " successfully written!");
        }).catch((error) => {
            console.error("Error writing document: ", error);
        });
    });
}

```

## Step4: 実行

```
node <Your_Project_Folder_Name>
```

すると
以下のように一括でインポートされました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/24884cf3-9011-faf7-ae63-8eacc3ce4cd5.png)

## その他
nodeのバージョンが低いとスプレッド構文が対応していなかったり等あるので、バージョンが最新かどうか確認してください。

## 参考文献
[How to upload data to Firebase Firestore Cloud Database](https://medium.com/@devesu/how-to-upload-data-to-firebase-firestore-cloud-database-63543d7b34c5)