OmniAICreator/Qiita-1.07M huggingface dataset:
RubyでDFS(深さ優先探索)の再帰呼び出しを実装

###入力：
今回は隣接行列表現で入力を与えます

例）

```init.txt
0 0 0 0 0 1 1 0 0 0
0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 1 1 0 0 1
0 0 0 0 0 0 0 1 1 0
0 1 0 0 0 0 1 0 0 1
1 0 1 0 0 0 0 0 0 0
1 0 1 0 1 0 0 0 0 0
0 0 0 1 0 0 0 0 1 0
0 0 0 1 0 0 0 1 0 0
0 0 1 0 1 0 0 0 0 0
```

###コード
```dfs.rb
@V # 頂点数
@v = []
@matrix = []
@pre_cnt = 0 # pre配列のカウンタ
@pre_array = [] # pre配列
@st_array = [] # st配列

# 行列をファイルから入力
def init
    File.open(ARGV[0]) do |f|
        puts "入力 : "
        f.each_line do |line|
            list = []
            list = line.split(' ')

            row = []
            list.each do |val|
                row << val.to_i
            end
            p row
            @matrix << row
        end
    end

    @V = @matrix.size
end

def output
    # 調整
    graph_num = 0
    @st_array.each_with_index do |st, i|
        if st == nil
            @st_array[i] = i
            graph_num += 1
        end
    end

    print "\nindex   :  "
    @matrix.size.times do |i|
        print "#{i}  "
    end
    puts "\npre配列 : #{@pre_array}"
    puts "st配列  : #{@st_array}"
    puts "グラフ数 : #{graph_num}"
end


def DFS(i)
    @v[i] = 1;

    @V.times do |j|
        if (@matrix[i][j] == 1 && @v[j] == 0)
            puts "#{i} -> #{j}"

            #　pre配列を作る
            if @pre_array[i] == nil
                @pre_array[i] = @pre_cnt
                @pre_cnt += 1
            end

            if @pre_array[j] == nil
                @pre_array[j] = @pre_cnt
                @pre_cnt += 1
            end

            # st配列を作る
            @st_array[j] = i

            # 再帰呼び出し
            DFS(j)
        end
    end

end

def main
    init # 入力
    puts "\n頂点数 : #{@V}"

    @V.times do |i|
        @v[i] = 0
    end

    #/* -- 探索開始 -- */
    @V.times do |i|
        if @v[i] != 1
            DFS(i)
        end
    end

    output # 出力
end

if __FILE__ == $0
    main
end
```

###出力:
```
入力 :
[0, 0, 0, 0, 0, 1, 1, 0, 0, 0]
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 1, 1, 0, 0, 1]
[0, 0, 0, 0, 0, 0, 0, 1, 1, 0]
[0, 1, 0, 0, 0, 0, 1, 0, 0, 1]
[1, 0, 1, 0, 0, 0, 0, 0, 0, 0]
[1, 0, 1, 0, 1, 0, 0, 0, 0, 0]
[0, 0, 0, 1, 0, 0, 0, 0, 1, 0]
[0, 0, 0, 1, 0, 0, 0, 1, 0, 0]
[0, 0, 1, 0, 1, 0, 0, 0, 0, 0]

頂点数 : 10
0 -> 5
5 -> 2
2 -> 6
6 -> 4
4 -> 1
4 -> 9
3 -> 7
7 -> 8

index  :  0  1  2  3  4  5  6  7  8  9
pre配列 : [0, 5, 2, 7, 4, 1, 3, 8, 9, 6]
st配列  : [0, 4, 5, 3, 6, 0, 2, 3, 7, 4]
グラフ数 : 2
```
docker-compose とは

#docker-composeとは
忘備録です。
むずかしいことや詳しいことは苦手なので、シンプルにかきます。

思いついた時に、色々書き加えます。

事前知識：[Dockerとは/Qiita](https://qiita.com/yuta-ushijima/items/d3d98177e1b28f736f04)

参考サイト1：[Docker入門（第六回）〜Docker Compose〜](https://knowledge.sakura.ad.jp/16862/)
参考サイト2：[【Docker】初心者はdocker-composeから始めた方がいいかもしれない説【チャーハン例えをお借りして】
](https://coinbaby8.com/docker-beginner.html)参考サイト3：[docker-compose.ymlの書き方について解説してみた](https://qiita.com/yuta-ushijima/items/d3d98177e1b28f736f04)

##0.Dockerの環境構築方法
方法1 - Dockerレジストリ(DockerHub)から1つずつダウンロードする
　　　-> webサーバーならnginxかapache
　　　-> データベースならmysqlなど
　　　-> プログラミング言語(laravelならPHPなど)
　　　を、一つずつダウンロードして、コンテナとして立ち上げる。
　　　※手順が多く、初心者の私はよくつまづき苦しみました。

方法2 - docker-compose.ymlファイルに書いてまとめてインストールする
　　　※手順が少なくシンプルなので、初心者にはこちらがいいかもしれません。

##1.docker-composeとは
・複数のコンテナからなるサービスを構築・実行する手順を自動的にし、管理を容易にする機能。
・composeファイルを用意してコマンドを1回実行する(0.方法2)ことで、
　そのファイルから設定を読み込んで、すべてのコンテナサービスを起動させることができる。

##2.docker-composeを使うまでの主な3ステップ
1.それぞれのコンテナのDockerfileを作成（既にあるイメージを使う場合は不要)
2.docker-compose.ymlを作成し、それぞれ独立したコンテナの起動定義を行う
3.`docker-compose up -d`コマンドを実行し、docker-compsoe.ymlで定義したコンテナを開始する
PHP For Beginnersチュートリアル　その1　PHPMailerの基本的な設定について。

##この記事の目的

体系的なwebコーディングの訓練ができるようになるために、PHPの初学のきっかけかつ、PHPでログインフォームやフォームを実装することができるようになるために

[PHP For Beginners](https://www.youtube.com/playlist?list=PLgt-G5tEOlKX4LKrBCYfjcyrp7wmnRdAL)

上記のチュートリアルを進めているのでその備忘録。

##内容

**今回のチュートリアル**

[PHPMailer Tutorial - Send Email Attachments](https://www.youtube.com/watch?v=pTLW7Ygw4K4&list=PLgt-G5tEOlKX4LKrBCYfjcyrp7wmnRdAL&index=2&t=601s)

**やったこと**

PHPMailerの設定がなんて書いてあるか、自分で打ち込んだものに注釈をつける。
また、動画では作者が独自に改良したもので説明されているので違うところは適宜自分で調べて書いていく。

**成果物**

```php:training.php
PHPMailerの基本的な設定の書き方

<?php

// use関数で必要なphpを読み込む

	use PHPMailer\PHPMailer\PHPMailer;
	use PHPMailer\PHPMailer\Exception;

	// require関数でautoloadと外部で設定ファイルを作っているならそれを読み込む
	
	require 'vendor/autoload.php';
	require 'config.php';

	// インスタンスを作る
	
	$mail = new PHPmailer(true);

	// 作ったインスタンスに対してtry-catch構文で処理を書き込んでいく

	try{

		// SMTPサーバーの設定
		
		$mail->SMTPDebug =2;　//本番環境では任意の数にする
		$mail->isSMTP();
		$mail->SMTPAuth = true;
		$mail->Host = MAIL_HOST; //SMTPのホストをいれる
		$mail->Username = MAIL_USERNAME; //本番環境では実際に使用するメールアドレスをいれる
		$mail->Password = MAIL_PASSWORD; //二段階認証ならアプリパスワードを生成していれる。それ以外は使用するメールアドレスのパスワード
		$mail->SMTPSecure = MAIL_ENCRPT; //SMTPのセキュリティ方式を入れる、tlsでOK
		$mail->Port = SMTP_PORT; //使用するPort番号をいれる

		// メールの送受信者を設定する
		
		$mail->setFrom(FROM_MAIL, FROM_MAIL); //送り主側
		$mail->addAddress(TO_MAIL, TO_MAIL); //受信側

		// メールの方式を設定する
		
		$mail->isHTML(false); //HTML方式のメール,trueでオンになる

		//メールの中身を決める
		
		$mail->Charset = "UTF-8"; //文字コードを設定
		$mail->Subject = "メールのタイトル"; //日本語の場合はmb_convert_encoding("件名です。", "UTF-8", "AUTO");と記述する
		$mail->Body = "メール本文";

		// HTML方式のメールの場合は下記と入れ替える

		// $mail->Charset = "UTF-8"; //文字コードを設定
		// $mail->Subject = mb_convert_encoding("件名です。", "UTF-8", "AUTO");
		// $mail->Body = "<html>メール本文</html>"; //HTMLマークアップ形式で書く
		// $mail->AltBody = "メール本文";
		
		// 送信コマンド

		$mail->send();
		echo "Message has been sent";

		//catchで以上の処理のどこかでエラーが出て、送信できなかった場合エラーメッセージを出す

	 } catch(Exception $e) {
	 	echo "Eroor:".$mail->ErrorInfo;



}
```

##広がった知見

PHPは書き方以外はまだ条件分岐やfor文がわかるくらいで、クラスの概念やオブジェクトなどはJavaScriptでのごく基本的な部分の理解しかない中、早くもクラスの概念が出てきたのでその重要性を知る。

try~catch構文の使い方を知る。
Swift：なんか組み合わせ全パターン出すやつ

```swift
func output(num: Int) {
    for n in (0 ..< Int(pow(2.0, Double(num)))) {
        var d = [Int]()
        for m in (0 ..< num) {
            if n / Int(pow(2.0, Double(m))) % 2 == 0 {
                d.append(0)
            } else {
                d.append(1)
            }
        }
        Swift.print(d)
    }
}
```

```plaintext:num=4の時の出力結果
[0, 0, 0, 0]
[1, 0, 0, 0]
[0, 1, 0, 0]
[1, 1, 0, 0]
[0, 0, 1, 0]
[1, 0, 1, 0]
[0, 1, 1, 0]
[1, 1, 1, 0]
[0, 0, 0, 1]
[1, 0, 0, 1]
[0, 1, 0, 1]
[1, 1, 0, 1]
[0, 0, 1, 1]
[1, 0, 1, 1]
[0, 1, 1, 1]
[1, 1, 1, 1]
```
Dockerとは

#Dockerとは

Dockerについての忘備録です。

むずかしいことは苦手なので、シンプルにかきます。

Docker公式サイト＆インストールはこちら
-> [Enterprise Container Platform for High-Velocity Innovation](https://www.docker.com/)

参考サイト1：[Docker入門（第一回）～Dockerとは何か、何が良いのか～](https://knowledge.sakura.ad.jp/13265/https://knowledge.sakura.ad.jp/13265/)
参考サイト2：[Docker入門 #1 【Dockerとは】](https://qiita.com/wMETAw/items/b9bc643ded4b92bf6add)
参考サイト3：[超入門Docker：第1回　Dockerとは](https://www.atmarkit.co.jp/ait/articles/1701/30/news037.html)

##1.Dockerとは
コンテナ型の仮想環境を、作成・配布・実行するためのプラットフォーム。


##2.Dockerの構成
![IMG_3948.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366833/6326a0ef-1466-69a9-004f-b61b578b75ad.jpeg)
図では、右側がDockerの構成です。


##3.Dockerの利点
・コンテナ ->サーバのカーネル（OSの中核となる部分）を利用し、
　　　　　　プロセスやユーザなどをサーバごとに隔離している。
　　　　　　＝ <b>軽量で高速に起動、停止などが可能</b>です。

・ミドルウェアのインストールや、各種環境設定をコード化して管理する
　= コード化されたファイルを共有することで、どこでも誰でも同じ環境が作れる
　-> <b>開発環境では動いたが、本番環境では動かなかった、ということを防ぎやすい</b>
　-> <b>開発工程の中で使っていた環境を、そのまま本番環境に持っていくことも可能</b>


##4.Dockerをインストールする
Docker公式サイト＆インストールはこちら
-> [Enterprise Container Platform for High-Velocity Innovation](https://www.docker.com/)
参考：[DockerをMacにインストールする（更新：2019/7/13）](https://qiita.com/kurkuru/items/127fa99ef5b2f0288b81)

<img width="399" alt="スクリーンショット 2019-07-15 3.17.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366833/d00eda1e-7ec0-15c3-9161-382f0d6f6677.png">
インストールして、PCの上の方にDocker Desktop is runningと表示されていれば
Dockerが走っている状態です。

##5.docker用語一覧
####【ファイル系】
①Dockerイメージ：OSとアプリがインストールされた環境を閉じ込めたファイル
②コンテナ：解放されたOSとアプリの環境
③Dockerfile：Dockerイメージ作成時に、実行するコマンド等を列挙したダイル
　（参考：[Dockerfileを書いてみる](https://qiita.com/nl0_blu/items/1de829288db2670276e8)）


####【サービス・ツール系】
①[DockerHub](https://hub.docker.com/)：ベースとなるDockerイメージがあるサイト
②DockerCompose：複数のコンテナを同時に扱うためのツール
　（参考：[docker-compose とは/Qiita](https://qiita.com/saekom/items/db701f795718a2364222)）

####【コマンド系】
|コマンド|コマンドの内容|
|:-----------|:------------|
|docker build 〜|Dockerfileをビルドして、Dockerイメージを作成する|
|docker run 〜|Dockerイメージをrunしてコンテナを立ち上げる|
|docker pull 〜|Docker HubからDockerイメージをダウンロードする|
|[ctrl - d]|起動中のコンテナの中から外に出る&コンテナを停止する|
|[ctrl - p] [ctrl - q]|コンテナを起動したままコンテナの中から外に出る|
|docker exec 〜|起動中のコンテナの中に入る|
|docker start 〜|停止中のコンテナを起動する|
|docker stop 〜|起動中のコンテナを停止する|
|docker restart 〜|コンテナを再起動する|
|docker images 〜|Dockerイメージの一覧を表示する|
|docker rm 〜|コンテナを削除する|
|docker rmi 〜|Dockerイメージを削除する|
|docker ps 〜|起動中のコンテナ一覧を表示する|
|docker ps -a 〜|停止中のコンテナも含めて全てのコンテナ一覧を表示する|
|docker commit 〜|コンテナをイメージ化する|
|docker save 〜|Dockerイメージをtar.gz形式で保存する|
|docker load 〜|tar.gz形式で保存されたDockerイメージをインポートする|
※参考：[Dockerについてなるべくわかりやすく説明する](https://qiita.com/rawHam/items/80ba13d2d2d56dba411e)
　自分で書きながら覚えたくて、
　こちらのページを見ながら写経させていただきましたm(__)m


##6.ざっくり図でまとめるとこんな感じ
![IMG_3961.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366833/07b3770d-d6a3-418e-6d32-06c4446ba8c3.jpeg)
[WIP]SQLアンチパターン-12章 インデックスショットガン-まとめ

## インデックスはただ貼れば良いということではない
結論としてはこうなります。
自分はインデックスについてきちんと分かっていなかったのですが、
調べてみるとインデックスって色々な種類があります。（インデックスで一般的によく使われているのが、`B木インデックス`というものです。）
本も読んだりして、万能なインデックスなんて存在しないのだな、という認識に至りました。
DBの設計、取り出すデータの種類、アプリケーションレベルでのデータ扱いのロジック、実際に使用するクエリ構文によって有効なインデックスって変わるのだなと。

今回はそのインデックスについて、実際インデックスってなんなんですか？
それを少しでもわかりやすく書ければと思います。

（まだ十分に把握していない知識が多いので、今は必要な知識を全ては書けていません。それだけは分かっています。笑）

### インデックスってそもそもなに？
このページが簡単に理解できるのかなと思います。
[インデックスについて](https://wa3.i-3-i.info/word11906.html)

ここも多分知っておくべき情報がいくつかあると思います。（筆者はまだ全部読みきっていませんのであとで読みます）

[DBのインデックスについて調べてまとめた](https://qiita.com/_somary/items/8e966887db13009ceae0)


ある値を検索しようとなった時に、
その値がテーブルの何行目に格納されているのか、
それを示しているのがインデックスです。
そしてそのインデックスもまたテーブル構造で表されるので
DBにテーブルが1つ増えたような感じになるんですかね。

### インデックスを貼りすぎるとどうなるのか
(自分、インデックスを`貼る`という言い方がまだしっくりきていないです)
インデックスって要は1つのデータファイルです。
メモリ上に保存されることもあります。
（例えば使うかわからないけどとりあえず作っておこう！みたいなテンションで）インデックスファイルを作成しすぎるとどうなるでしょうか。
サーバー内の容量が圧迫されてしまうだけになります。SQL文を回す上でも余計なオーバーヘッドが出てきてしまうこともあります。

### クエリとインデックスの正しい関係について
例えば、以下のようなテーブルがあったとしましょう

服(Clothes)テーブル

|name|maker|created_at|
|:--:|:--:|:--:|
|タートルネック|アディダス|2019-01-01|
|カーディガン|ユニクロ|2018-01-01|
|Tシャツ|ナイキ|2017-01-01|

インデックスを作成する際は下記のようなコードになります。

```sql
CREATE INDEX MakerName ON Clothes(maker, name);
```

このインデックスは`maker`と`name`が両方ある複合インデックスになります。

下記のように検索方法したらどうなるでしょうか
- 名前が`タートルネック`の服を探したい

この場合、クエリはこうなります

```sql
SELECT * FROM Clothes WHERE 'name' = 'タートルネック';
```

このクエリを回す際に、先ほど作成した複合インデックスは使われません。
まずそもそも複合インデックスとはつまりどういうことか、認識を改める必要が自分にはありました。
複合インデックスはあくまで両方のデータを扱って検索した場合に使われます。
今回は検索するための条件として`name`しか使っていないので、インデックスは利用されません。

また、

```sql
SELECT * FROM Clothes WHERE 'name' = 'タートルネック' AND maker = 'アディダス';
```

としても、これも実はインデックスは利用されません。
なぜなら作成した複合インデックスは、最初に`maker`、次に`name`という順番だからです。
複合インデックスでは定義の順番が実は重要ということになります。


### インデックスが有効なケースを知ろう
まず、単純にインデックスを貼っただけではパフォーマンスが上がるということには繋がりません。
例えば、データの数が10個とか、そのくらいの数だとインデックスを作成したところで劇的にパフォーマンスが上がるということはありません。どのくらいの数からインデックスを作成することでパフォーマンスが上がるのかは私にもわかりませんが・・・。

つまりインデックスが有効かどうか、必要なのかどうか、知る手段を知る必要があります。
その中で使われるのが`EXPLAIN`構文です。

#### EXPLAIN構文について知ろう
`EXPLAIN`構文は、簡単にいうと、あるクエリを叩いた時に、
- そのクエリはどのような検索方法を使っているか(単純に`WHERE`構文なのか、インデックスを使っているのか）
- インデックスが有効であろうカラムはあるのか（あったらどれなのか）
- どのようなインデックスの種類を使われているのか

などがわかるようになります。

この`EXPLAIN`構文を使って、最適なインデックスなどを見つけて行くのが良さそうですね。
下記のような感じになります。

```sql
EXPLAIN SELECT * FROM Clothes WHERE 'name' = 'タートルネック';
```

[MySQLのEXPLAIN](https://qiita.com/mucho0623/items/fa575002bf0ade699e2f)
ここのページではパラメータが表す意味が記載されているので参考にどうぞ。



### インデックスが意味をなさないってどういう時？
- そもそも検索で条件として利用されないカラムでインデックスを作成している
- もともと登録している（つまり重複してインデックスを作成している）（主キーは自動的にインデックス作成されることが多いらしいので気をつけましょう）
- 長い文字列に対するインデックス（それに対応するインデックスの種類もあるみたいです）
- 複合インデックスと検索条件で利用するカラムの順番が違う
- データの数が少ない（インデックスで絞っても意味のないくらいのパフォーマンスの改善しか見込めない）

これって、例えば`name`に`タートルネック`であるデータの数が10件しかない時と10000件ある時とで、だいぶ変わってきます。条件の組み合わせ条件によっては、`maker`でソートをしてから`name`を調べて検索する、といったことも考えられます。
この際、検索する値として`name`が10件しかなく、かつ`maker`が10000件あったとしたら、まずは`name`から複合インデックスを定義して、クエリもそれに合わせて作成するのが良いです。
欲しいデータとして該当する行が1行しかない時に

1. `maker`で探して10000件 => 該当の行を見つける
2. `name`で探して10件 => 該当の行を見つける

では明らかに2の方法で探したほうがコストが少なくて楽です。
これを`選択性が良い`と表します。（間違っていたらすいません。）
インデックスを作成して、クエリを回す際はこの`選択性`を考える必要があるんですね・・・。


執筆途中
kerasのbackendをプログラム上で変更する

kerasのバックエンドは.keras/keras.jsonで変更することができる．
しかし，毎回バックエンドを変えるのは面倒である．

そのため，プログラム上でバックエンドを変更できるようにした．

以下はバックエンドをtensorflowからtheanoに変更したもの．


```python

from keras import backend as K
import os
from imp import reload



def set_keras_backend(backend):

	if K.backend() != backend:
		os.environ['KERAS_BACKEND'] = backend
		reload(K)
		assert K.backend() == backend

set_keras_backend("theano")

```



set_keras_backend("theano")の部分を"tensorflow"に変えればバックエンドをtensorflowにすることができる．
初めてのサーバ構築(GitLab)

# はじめに
サーバ構築をしてみたくなったので、一番イメージのしやすいGitlabサーバを立ててみることにしました。
大したことは書けないので、何か間違いなどあればご指摘いただけたらと思います！

# OSのインストール
ubuntuが好きなので[ubuntu-server](https://ubuntu.com/download/server)を使用することにした。

## インストールメディアの簡単な作り方
1. 上記のURLページから`download`を押す
2. UbuntuのPCにUSBを刺す
3. ubuntuのランチャーを開いて`usb`と入力してエンターを押す
4. `make up...`みたいな方を選択

Ubuntuの入っているUSBを持っていない人は[UUI](https://universal-usb-installer.jp.uptodown.com/windows)を使うとよい。

# ubuntu-serverのインストール
- 基本的には道なりに進めた
- キーボードの選択は、Japaneseを選択（検出を押すと日本キーにならなかった）
- ネットワーク選択の際にはLANケーブルを刺して対処

# 初期設定
- 自分のGithubアカウントから`dotfiles`をクローンした
- `capslock`は嫌いなので、`/etc/default/keyboard`内に`XKBOPTIONS="ctrl:nocaps"`を記述

# Gitlabのセットアップ
主に[こちら](https://www.yokoweb.net/2018/05/04/ubuntu-18_04-server-gitlab-install/#toc2)のページの通りにした。以下、入力コマンドを抜粋したものである。詳しくはリンク先を見てもらうとよい。

```sh:setup_gitlab.sh
sudo apt install curl openssh-server ca-certificates
sudo apt install postfix
curl -sS https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh | sudo bash
sudo apt install gitlab-ce
sudo gitlab-ctl stop unicorn
sudo gitlab-ctl stop sidekiq
sudo gitlab-ctl reconfigure
```

今回は、サーバを立てて終了するため、ページの`Gitlabサーバの名前解決`以降はやらなかった。

# Gitlabにlogin
ubuntu-serverを起動しているPCのターミナルで

```sh:check_ipaddress
$ ifconfig
```

と入力して上から２行目あたりに出てくる`inet 192.168.*.*`がPCのIPアドレスである。
1. 好きなブラウザを開く
2. アドレス入力欄に`192.168.*.*`を入力
3. rootのパスワードを設定する
4. ログイン完了
5. `new project`をクリック
6. `project name`に好みのリポジトリ名を入力して作成
7. gitのインストールされたPCのターミナルから`git clone http://192.168.*.*/root/repository-name.git`と実行

# 困った間違い
- `http`を間違えて`https`と入力していた
- リポジトリ名に`.git`とつけるのを忘れていた
- アドレスとリポジトリ名の間に`root`とユーザ名をつけるのを忘れていた

# おまけ

```sh:
$ ssh <username>@192.168.*.*
```

とするとサーバへssh接続する事ができる。「サーバを立てたんだなあ」と実感した。

```sh:iyagarase.sh
while :
do
  mkdir test
  cd test
done
```

と、フォルダを作って潜り続けるスクリプトを実行したらサーバ側のPCがめちゃくちゃ熱くなった。

# おわりに
今回初めてサーバ構築してみたのですが、ネットに情報を後悔してくれている人のおかげで無事成功しました。
自宅サーバは火災などの危険があるようなので、今後は実際に運用することを前提にクラウドサーバを構築したいなと思いました。
JavaScriptでパイプライン演算子が欲しい余り頭がおかしくなった人間の末路

```javascript:未実装のパイプライン処理
"hoge" |> plusA |> plusB |> plusC; // "hogeABC"
```

```javascript
["hoge"].map(plusA).map(plusB).map(plusC)[0]; // "hogeABC"
```


多分これが一番早いと思います
Rubyのシンタックス勉強用（繰り返し処理の制御 編）

Rubyのシンタックスを息を吸うように書くために、少しでも理解が怪しいシンタックスを繰り返したくために書きます。

# 繰り返し処理の脱出

1から10までを出力する`upto`メソッドの繰り返し処理の中に5以上で繰り返し処理を抜ける条件文を書いてください。

## 正解

```ruby
1.upto(10) do |i|
  p i
  break if i >= 5
end
```

`break`は`upto`や`each`、`while`などでも使えます。

参考: [プロを目指す人のためのRuby入門_138p](https://ruby-book.jnito.com/)

# 繰り返し処理をネストさせた場合の break の挙動

内側に`break`があるので、内側だけ抜けます。外側は全て実行されます。

```ruby
areas = ['tokyo','chiba','osaka']
numbers = [1,2,3,4,5]

areas.each do |a|
  numbers.shuffle.each do |n|
    p n
    break if n == 5
  end
  p a
end
```

return

```
3
2
1
5
"tokyo"
5
"chiba"
4
2
5
"osaka"
```

`shuffle`メソッド : 配列の要素の順番をランダムに入れ替えた新しい配列を返すメソッド。このメソッドを使用しているため、必ずこの結果になるとは限りません。

参考: [プロを目指す人のためのRuby入門_139p](https://ruby-book.jnito.com/)

# throwとcatchを一気に全ループを抜ける処理

2つの繰り返し処理を一気に抜ける処理を書いて覚えてください。

```ruby
areas = ['tokyo','chiba','osaka']
numbers = [1,2,3,4,5]

catch :done do
  areas.shuffle.each do |area|
    numbers.shuffle.each do |number|
      p "#{area}==#{number}"
      if area == 'tokyo' && number == 1
        throw :done
      end
    end
  end
end

p '脱出'
```

`area == 'tokyo' && number == 1`だったら脱出します。

return

```
"chiba==3"
"chiba==4"
"chiba==5"
"chiba==2"
"chiba==1"
"osaka==5"
"osaka==2"
"osaka==3"
"osaka==1"
"osaka==4"
"tokyo==4"
"tokyo==2"
"tokyo==1"
"脱出"
```

`shuffle`メソッド : 配列の要素の順番をランダムに入れ替えた新しい配列を返すメソッド。このメソッドを使用しているため、必ずこの結果になるとは限りません。

参考: [プロを目指す人のためのRuby入門_140p](https://ruby-book.jnito.com/)

# 繰り返し処理における break と return の違い

- break: 繰り返しだけ抜ける
- return: メソッドごと抜ける

```ruby
def greeting(name)
  numbers = [1,2,3,4,5]
  numbers.shuffle.each do |number|
    p "こんにちは、#{name} No.#{number}さん"
    break if number == 1
  end
  p 'どうぞ'
end

greeting('sato')
```

return

```
"こんにちは、sato No.4さん"
"こんにちは、sato No.5さん"
"こんにちは、sato No.1さん"
"どうぞ"
```

`shuffle`メソッド : 配列の要素の順番をランダムに入れ替えた新しい配列を返すメソッド。このメソッドを使用しているため、必ずこの結果になるとは限りません。

繰り返しだけ抜けているので、文字列（`どうぞ`）も出力されます。

ですが、`return`は、メソッドごと抜けるので、文字列`どうぞ`が出力されません。

```ruby
def greeting(name)
  numbers = [1,2,3,4,5]
  numbers.shuffle.each do |number|
    p "こんにちは、#{name} No.#{number}さん"
    return if number == 1
  end
  p 'どうぞ'
end

greeting('sato')
```

return

```
"こんにちは、sato No.3さん"
"こんにちは、sato No.1さん"
```

`shuffle`メソッド : 配列の要素の順番をランダムに入れ替えた新しい配列を返すメソッド。このメソッドを使用しているため、必ずこの結果になるとは限りません。

参考: [プロを目指す人のためのRuby入門_142p](https://ruby-book.jnito.com/)

# next

繰り返し処理を途中だけ抜ける`next`の処理を書いて覚えてください。

```ruby
areas = ['tokyo','chiba','osaka']

areas.each do |area|
  (1..5).each do |n|
    next if n.even?
    p "id:#{n} is #{area}"
  end
end
```

偶数の時だけ、内側の繰り返し処理を脱出しています。

return

```
"id:1 is tokyo"
"id:3 is tokyo"
"id:5 is tokyo"
"id:1 is chiba"
"id:3 is chiba"
"id:5 is chiba"
"id:1 is osaka"
"id:3 is osaka"
"id:5 is osaka"
```

入れ子になった場合、一番内側に`next`があるなら、`break`と同じで、一番内側だけ処理を抜けます。

参考: [プロを目指す人のためのRuby入門_140p](https://ruby-book.jnito.com/)
postmanでPUT,DELETE送信したものを取得できない時

laravelでUpdate,destroyを行う時、送信形式を「form-data」にしていると、
php artisan route:listで表示されているルーティングには、

```shell
$ php artisan route:list

 PUT|PATCH | api/user/{app_user} | user.update  | App\Http\Controllers\UserController@update  | api 

```

このようにHTTPメソッドは、「PUT|PATCH」と書かれているが、PostManなどで、PUTリクエストを送信すると、リクエストの中身が取得できない。

(まあ、laravelだけに限らないかもしれないが、、、、)

#原因
送信形式を「form-data」にしていることが原因。
HTMLのformがPUTとPATCHをサポートしていないため,form-dataでPUTやDELETEを送っても中身を取得できない。


#対策
対策は二つ。
1,HTTPメソッドはPostで,bodyパラメーターで、[_method:PUT]を指定する
これは送信形式はform-dataのママでOK

2,内容をjsonで送る
そもそもform-dataでなければいいので、jsonで送信する。
そうすると、PUTやDELETEでも通る

<img width="956" alt="スクリーンショット 2019-07-02 12.41.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/388525/fca443e6-2afe-4f56-110c-247f37e96eb8.png">
SceneBuilder 11 の文字化けを直す

JavaFX アプリを作るときに便利な SceneBuilder。
しかし [GLUON のサイト](https://gluonhq.com/products/scene-builder/) から SceneBuilder 11.0.0 を Windows Installer でインストールすると、日本語メニュー等が文字化けするという問題があります。

[タツノオトシゴさんのブログ](http://moondream.hatenablog.com/entry/2018/10/31/224908) が大変参考になりますが、バージョン相違のためでしょうか、パスなどが若干異なるため、本記事では改めて SceneBuilder 11.0.0 の文字化け解消手順を紹介したいと思います。

# 問題の再現手順

以下の手順で SceneBuilder 11.0.0 をインストールすると、日本語メニューが文字化けします。

1. [GLUON のサイト](https://gluonhq.com/products/scene-builder/) から SceneBuilder 11.0.0 の Windows Installer をダウンロードする
![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84939/ad8b89c3-450e-7354-a635-efe154f442bd.png)
2. インストーラに従ってインストールする
3. インストールされた「C:\Program Files\SceneBuilder\SceneBuilder.exe」を実行する
![図2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84939/3d09f31d-a3b5-c08e-44ff-e5975177463d.png)
メニュー等が文字化けしています。

# 原因

「C:\Program Files\SceneBuilder\app\scenebuilder-11.0.0-all.jar」というファイルに含まれている「\com\oracle\javafx\scenebuilder\app\i18n\SceneBuilderApp_ja.properties」というファイルが壊れてしまっているようです。

# 直し方

## 1. 正しいファイルの取得

[GLUON の SceneBuilder の GitHub リポジトリ](https://github.com/gluonhq/scenebuilder) から、次のファイルをダウンロードします。

- [scenebuilder/app/src/main/resources/com/oracle/javafx/scenebuilder/app/i18n/SceneBuilderApp_ja.properties](https://github.com/gluonhq/scenebuilder/blob/master/app/src/main/resources/com/oracle/javafx/scenebuilder/app/i18n/SceneBuilderApp_ja.properties)

ダウンロードしたファイルが UTF-8 で保存されていることを確認します。そうなっていない場合は、メモ帳などを使って UTF-8 で保存します。
![図3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84939/78828c38-7064-3760-276e-c26a757beb07.png)

※注意：
本記事の執筆時点では、SceneBuilder 11.0.0 のソースが master ブランチで管理されています。
リポジトリ上のバージョンが進んだ場合には、取得先のブランチに注意する必要があると思われます。

## 2. インストールされたファイルの置き換え

上記1.で取得したファイルで、次のファイルを上書きします。

- C:\Program Files\SceneBuilder\app\scenebuilder-11.0.0-all.jar\com\oracle\javafx\scenebuilder\app\i18n\SceneBuilderApp_ja.properties

Windows 10 の場合、以下の手順で jar ファイル内のファイルを上書きすることができます。

1. 「scenebuilder-11.0.0-all.jar」ファイルの拡張子を「.zip」に変更する
2. エクスプローラで「scenebuilder-11.0.0-all.zip」ファイルの中身を表示する
3. コピー＆ペーストなどで「SceneBuilderApp_ja.properties」ファイルを上書きする
4. 「scenebuilder-11.0.0-all.zip」ファイルの拡張子を「.jar」に戻す

## 3. 文字化け解消の確認

「C:\Program Files\SceneBuilder\SceneBuilder.exe」を実行すると、文字化けが解消されていることを確認できます。
![図4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84939/9002cd66-a603-25ba-093c-0d8251663677.png)

めでたし、めでたし。
因子分析の理論とPythonでの実装

# はじめに
初めまして、コジコジと申します〜。
20歳で学生やってます、大学では数学の勉強やってます。
最近は主に機械学習の勉強をしています、進捗のまとめしたいと唐突に思い立って初投稿です笑

さて、初投稿ということで、ちょうど今日本読んで出てきた因子分析のことにしようと思います。拙い文章ですが、よろしくお願いします。

# 因子分析とは

前置きはここまでにして、本題に入ろうと思います。
因子分析というのは、簡単にいえば「いくつかのデータの関係性を少ない情報量で表してグループ分けする」手法です。簡単な例で見てみましょう。

## 相関行列

| 　 |国語|英語|社会|化学|物理|数学|
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|国語 |　|.7|.69|.03|-.9|.34|
|英語 |.7|　　|.53|-.14|-.33|.06|
|社会|.69|.53|　　|.11|.06|.38|
|化学|.03|-.14|.11|　|.57|.46|
|物理|-.09|-.33|.06|.57|　|.66|
|数学|.34|.08|.38|.46|.66|　　|



上の行列は相関行列というものです。各セルには-1から1の範囲の数が入っていて、一つ一つを相関係数といいます。この数字は2つの教科の関係性を表しています。例えば、英語と国語に当たるセルを見てみると、0.7という比較的大きめの数が入っています。これは、「英語の点数が高い生徒は国語も高い傾向にある」ということを表しています。
では国語と物理のセルを見てみましょう。数字は-0.9でかなり小さいですね。これは「国語の点数が高い生徒は物理はできない傾向にある」ということを表しています。
理系ですね（は?）

とまあこの通り、この表をちょっと眺めてみると、「理系科目できるやつは文系科目できない」、逆に「理系科目できるやつは文系科目できない」という傾向があるということが何となく分かります。現実では知らないです、はい。
このことから、この６科目はn
何となく「文系科目」と「理系科目」に分類できるということがわかります。




## 因子分析
上で説明した通り、相関行列見れば何となく「理系科目」と「文系科目」に分類はできます。でも、上の行列だと数字多くてなんか見づらいですよね。そんな時に役に立つのが因子分析です。
因子分析を行うと以下のような行列ができます。

|   | I | II |
|:-:|:-:|:-:|
|国語|.9|.2|
|英語|.8|-.1|
|社会|.7|.3|
|化学|-.1|.6|
|物理|-.3|.9|
|数学|.2|.8|

おお、数字が少ない！これなら見やすそうですね。こんな少ない数字でも教科の関係性を表せています。
まず、Iの行をみると先ほどの「文系科目」の数字が大きく、「理系科目」の数字が小さいことがわかります。IIの方では逆ですね。このI、IIのことを因子負荷数って言ったりします。
このように、因子分析を行うと相関行列の次元を小さくできます。要するに次元削減ってやつですね、PCAとかで有名なアレです。

さて、じゃあどうやって次元削減してるかってことなんですけど、ちょっと初投稿で疲れてきたんで割愛ってことで（本音はめんどくさい）。割とめんどくさい計算してるですけど、気が向いたらまた書きます笑

## Pythonでの実装
では、因子分析をPythonで実装してみましょう。本当はこういう統計解析的なのはRの方がいいみたいなんですけど、調べたらsklearnにモデルあったのでとりあえずPythonで。ついでにPCAと結果を比較してみます。
データセットは、みんな大好きIrisデータを使いましょう。

```
# 必要なものをimport
from sklearn import datasets
import numpy as np
from sklearn.decomposition import FactorAnalysis
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA


# irisデータをロード
iris = datasets.load_iris()
y = iris.target


#　変換器を作成
pca = PCA(n_components=2)
fa = FactorAnalysis(n_components=2, max_iter=5000)
sc = StandardScaler()
transformers = [pca, fa]


# ２種類のプロットを実行する関数
def compare_plot():
    y = iris.target
    colors = ["red", "blue", "green"]
    fig, ax = plt.subplots(1, 2, figsize=(10, 4))
    for i in range(2):
        for j in np.unique(y):
            X = iris.data
            sc.fit_transform(X)
            X = transformers[i].fit_transform(X)
            ax[i].scatter(X[y==j, 0], X[y==j, 1],
                            color=colors[j])

 
# 処理を実行           
compare_plot()
```

実行結果は以下です。
右のグラフがPCA、左が因子分析によるプロットです。

![fapca.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/461848/136cf691-4a01-9ce7-61a5-89c5ccbad778.png)

これは...どうなんでしょうか...？
この後で線形分離とかすること考えるとPCAの方がいい感じもしますね...


# まとめ
初投稿は因子分析についてまとめましたが、変換器としての優秀さは用いるデータセットにもよるので一概には言えませんね。そういうのを見分けられるように精進していこうと思います。
気が向いたらちょこちょこ投稿すると思います。読んでいただきありがとうございました。
sklearnでも特徴量の重要度を見たい

# 概要
lightgbmには特徴量の重要度を出す[plot_importance](https://lightgbm.readthedocs.io/en/latest/_modules/lightgbm/plotting.html)という関数がある。
![Python: LightGBM を使ってみる](https://cdn-ak.f.st-hatena.com/images/fotolife/m/momijiame/20180501/20180501073242.png)
> [Python: LightGBM を使ってみる](https://blog.amedama.jp/entry/2018/05/01/081842) より

sklearnでも特徴量の重要度を可視化したい、という気持ちになるのでやります。

# ソースコード
みんな大好きirisデータセットを使っていきます。

```python
from pprint import pprint

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.linear_model import SGDClassifier

iris = load_iris()
```

## irisの情報を見る 
irisについてもう少し情報を得ましょう。
irisは3クラス、特徴量は4種類あることがわかります。

```python
pprint(iris)
{'DESCR': '.. _iris_dataset:\n'
          '\n'
          'Iris plants dataset\n'
          '--------------------\n'
          '\n'
          '**Data Set Characteristics:**\n'
          '\n'
          '    :Number of Instances: 150 (50 in each of three classes)\n'
          '    :Number of Attributes: 4 numeric, predictive attributes and the '
          'class\n'
          '    :Attribute Information:\n'
          '        - sepal length in cm\n'
          '        - sepal width in cm\n'
          '        - petal length in cm\n'
          '        - petal width in cm\n'
          '        - class:\n'
          '                - Iris-Setosa\n'
          '                - Iris-Versicolour\n'
          '                - Iris-Virginica\n'
          '                \n'
          '    :Summary Statistics:\n'
          '\n'
          '    ============== ==== ==== ======= ===== ====================\n'
          '                    Min  Max   Mean    SD   Class Correlation\n'
          '    ============== ==== ==== ======= ===== ====================\n'
          '    sepal length:   4.3  7.9   5.84   0.83    0.7826\n'
          '    sepal width:    2.0  4.4   3.05   0.43   -0.4194\n'
          '    petal length:   1.0  6.9   3.76   1.76    0.9490  (high!)\n'
          '    petal width:    0.1  2.5   1.20   0.76    0.9565  (high!)\n'
          '    ============== ==== ==== ======= ===== ====================\n'
          
```

## irisのデータを学習する
特徴の名前やデータを取得しておきましょう。
なにも考えずにfitします。

```python
feature_names = iris.feature_names
data = iris.data
target = iris.target
target_names = iris.target_names

clf = SGDClassifier()
clf.fit(data, target)
```

## 重みを確認する
重みはcoef_を見ることでわかります。
shapeは(n_classes, n_features)になっています。

```python
print(clf.coef_)

array([[  9.76085896,  30.74670571, -48.80429478, -27.33040508],
       [  9.51335529, -73.66752043,  28.90596414, -68.17904623],
       [-89.68307485, -84.96291301, 151.2699483 , 135.31130591]])
```

## 特徴量の重要度を描画する
ここまできたら後は描画するだけです。
出力結果は以下の画像です。

petal lengthとpetal widthが重要な変数であることがわかります。
これは、先ほどみたirisの情報の中でClass Correlationが高いと書かれていることからもわかると思います。

```python
df = pd.DataFrame(clf.coef_.T, columns=target_names, index=name)

df.plot.bar()
```
![coef.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121870/ab26ddf9-83c7-ad77-8c56-b9089c4fac96.png)

# まとめ
* coef_を見ることで特徴量の重要度がわかる
* pandasを使うと見やすく簡単に描画できる
ローカルブランチを最新に更新し反映するまで

ローカルとリモート(origin)にmasterの情報がある
この情報は常に同じとは限らない。

開発はlocalのmasterを参考にして開発をするので、checkoutするときや開発を始める時は
ローカルのmasterを最新に更新してから始めなければいけない。

#ローカルのmasterを最新に更新する方法

以下の2つのステップを踏む必要がある。
1,更新
2,反映

####ローカルのmaster「情報」を更新

```shell 
$ git fetch -p
```

####そのローカルのmaster情報を最新に更新したものをローカルのmasterに反映
[参考](https://qiita.com/takakuda/items/2123e37733445f69f0ff)


```shell 
$ git merge origin/master
```


# その合体バージョンがこれ

上の二つのコマンドを一発でやってくれるのが以下

```shell 
$ git pull origin master
```
Flutter Pluginの利用でSwiftエラーが出る場合の対処方法

# 背景

自分は、[image_downloader](https://pub.dev/packages/image_downloader)という「指定したURLの画像を端末に保存する」Pluginを作っていて、嬉しいことにまあまあ利用されているようです。
しかし、Flutterの問題でPlugin自体のバグではないのにissueでバグとしてたびたび報告されるので、それの対処方法と何故、それが起きるのか記述しておきます。(たとえ、トラブルシューティングに書いても読まない人が多いのかも)

これは、Swiftで作成されているFlutterのPluginを利用し、且つ、プラットフォームチャンネル言語でSwiftを選択しなかった場合に起きます。

# エラー内容

以下のようなエラーが表示されます。

```
=== BUILD TARGET image_downloader OF PROJECT Pods WITH CONFIGURATION Debug ===
The “Swift Language Version” (SWIFT_VERSION) build setting must be set to a supported value for targets which use Swift. Supported values are: 3.0, 4.0, 4.2. This setting can be set in the build settings editor.
```

```
=== BUILD TARGET image_downloader OF PROJECT Pods WITH CONFIGURATION Debug ===
~/.pub-cache/hosted/pub.dartlang.org/image_downloader-0.11.2/ios/Classes/ImageDownloaderPlugin.m:2:9: fatal error: 'image_downloader/image_downloader-Swift.h' file not found
#import <image_downloader/image_downloader-Swift.h>
```

```
[!] Unable to determine Swift version for the following pods:

- `image_downloader` does not specify a Swift version and none of the targets (`Runner`) integrating it have the `SWIFT_VERSION` attribute set. Please contact the author or set the `SWIFT_VERSION` attribute in at least one of the targets that integrate this pod.
```

# 理由

この問題はフラッター側にあるため、swiftで作成されたすべてのプラグインに同じ問題があります。

https://github.com/flutter/flutter/issues/25676#issuecomment-449543241

#　対処方法

これを解決するためにいくつかの設定をする必要があります。

1. ブリッジングヘッダーを作成する必要があります。 XCodeでプロジェクトを開きます。
2. File -> New -> File -> Swift Fileを選択し、Runnerディレクトリに作成します。それからBridging Headerも作成し、ダイアログ上でクリックします。
 <img src="https://raw.githubusercontent.com/wiki/ko2ic/image_downloader/images/faq/create_bridging_header.png">

 (これはXCode - > Build SettingsでSWIFT_VERSION、SWIFT_OBJC_BRIDGING_HEADERなどを設定しているのと同じことです。)
 <img src="https://raw.githubusercontent.com/wiki/ko2ic/image_downloader/images/faq/complete_swift_setting.png" >

3.ios/PodfileのRunnerブロックに```use_frameworks!```があることを確認してください。 

```Podfile
target 'Runner' do
  use_frameworks!
```

4.基本的にはこれで問題ありませんが、うまくいかない場合は次のようにします。

```
$ flutter clean
$ cd ios
$ rm -rf Podfile.lock
$ rm -rf Pods
$ pod install --repo-update 
```

これで動作するはずです。
プチコン3号経験者によるプチコン4まとめ (3) SPVARが連想配列っぽく拡張されている！

私は普段は JavaScript でプログラミングする機会が多いのですが、連想配列(Dictionary)は好きでよく利用します。これと JSON (もしくは XML) 形式を併用したコードは、拡張性が高いのがメリットのひとつです。

プチコン4のマニュアルを眺めていたら、限定的ですが連想配列チックな命令を見つけたので、これから活用していきたいと思います。

# SPVAR のすごさ

プチコン3号で、[SPVAR](http://petitcom.net/manual/spvar) という命令があり、驚かされたのを覚えています。

> スプライト毎に持っている内部変数を設定・取得します。
> １つのスプライトにつき、0~7までの8個の変数を持っています。

というもので、凄くないですか？ゲーム、特にシューティングゲームなどを作った経験があれば、この機能の利便性は理解できると思います。画面上を飛び交う敵機や、弾の全てが、簡易的でありますがオブジェクト指向言語のインスタンスのように、自身に関する値を格納しているわけです。

ただ変数を番号で管理するのが原始的なので、プチコン4では CONST 定数で管理しようかな… なんて思って調べてみたら、さすがはスマイルブームです、あっさりと進化していました！プチコン4では変数キーが以下のように拡張されています

>スプライト変数の名前
>・文字列または整数を名前として付ける事ができる

これって連想配列(Dictionary)的な拡張ではないですか！管理し易いですし、さりげなく上限の8個という制限も解除されています。素晴らしい！

JavaScript の言語でいう `for (key in obj)` 的な、既に設定されたキーの一覧が得られないのが残念ですが、そこは運用でカバーってやつで！

ちなみに同様に拡張されたものに、テキストスクリーンごとに変数を利用できる TVAR という命令もあります。それに対して BGMVAR という命令は従来どおり 0～7 の番号で変数を指定する、のが謎なところです。

## 具体的な使い方

例えば敵キャラをスプライトで動かす際、倒した時のスコア値とか、残り体力などを SPVAR でスプライトに関連付けて記録しておけば、敵の種類によらず処理を汎用化できます。自機の弾が命中したら、弾のほうのスプライトに保存されたダメージ値を、敵のスプライトに記録された残り体力から引いて、体力がマイナスになったら敵はやられて、スプライトに保存されたスコア値がスコアに加算される、みたいな。

敵キャラに自機の弾が命中した、は一般的なものですから、敵機ごとの差はスプライトに SPVAR で保存した値で管理しておく。そうすれば、その処理を抽象化できるわけです。

これまでも 0～7 の変数で実現はできていましたが、自由に定義できる名前方式のほうが拡張性がありますし、他人のロジックとの衝突も少なそうです。

SPFUNC と組み合わせると、スプライトで動作する対象は全て、オブジェクト指向的な抽象化されたプログラミングができそうですね。CALL SPRITE で一斉に呼び出して、大域変数で状況をみて固有の処理 (初期化やゲームオーバー時の後処理など) を実施すれば、かなり効率的な処理が書けそうです。

## マルチプログラムに関して

プチコンには [マルチプログラム](https://qiita.com/yamachan360/items/51443d766e04985ab4ad#%E3%83%9E%E3%83%AB%E3%83%81%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0) の機能があり、各スロットで変数などは共有されません。

TVAR などはハードウェアに紐づいた変数なので、マルチプログラム環境での動作はどうなるかな？と試したところ、SPVAR 変数、TVAR 変数、共に各スロットで共有されているような動作でした。つまり、あるスロットで SPVAR, TVAR 変数をセットすると、他のスロットからでもその変数にアクセスできた、ということです。

これは便利な反面、このことを理解したスロットの使い方が必要になりそうです。

# というわけで

[前々回](https://qiita.com/yamachan360/items/63a4019f85ac67a777b9)、[前回](https://qiita.com/yamachan360/items/2576fdb6ae392247c8a9) とバックグラウンド(BG)周りを試していましたが、今回は趣向を変えて、言語仕様について気になった点をまとめてみました。

ゲームを作りやすい方向に、地道に進化してるなぁ、と改めて感じました。さすがスマイルブームです。

ではまた！
Arch Linux で Failed to start Networking for netctl profile wlp3s0

Arch Linux で無線接続できなくなった時に、下記のようなメッセージが出ている場合がある。


```
Failed to start Networking for netctl profile wlp3s0
```

特徴は、 Boot 時に1分30秒、ここで止まる。

自分の場合、下記で解決した。

```
sudo systemctl disable netctl-auto
sudo reboot
```

ただ、起動時に毎回 `wifi-menu` で指定しないといけないため、根本的な解決をした方が良さそう。

# 参考

- https://bbs.archlinux.org/viewtopic.php?id=226010
- https://www.reddit.com/r/archlinux/comments/216afg/wifi_problem_using_netctl_and_wifimenu/
- https://wiki.archlinux.jp/index.php/%E3%83%AF%E3%82%A4%E3%83%A4%E3%83%AC%E3%82%B9%E8%A8%AD%E5%AE%9A


最後の表がわかりやすかった。あとこの言葉。

> どの方法を選ぶにせよ、まずは手動で接続を試行するべきです。問題がおこったときに必要なことは何でどのようにデバッグすればいいかを知るのに役に立つでしょう。
Node.jsでGoogle Drive上のファイルを複製（copy）する (Google Drive API v3)


前に書いた[Node.jsでGoogle Driveの指定フォルダからファイル一覧を取得メモ](https://qiita.com/n0bisuke/items/ff1479cd14e7a0c0be0c)の続きです。

メソッドはこちらの[copy](https://developers.google.com/drive/api/v3/reference/files/copy?authuser=1)を使います。

## スコープ

```
https://www.googleapis.com/auth/drive
https://www.googleapis.com/auth/drive.file
https://www.googleapis.com/auth/drive.appdata
https://www.googleapis.com/auth/drive.photos.readonly
```

の四つを許可する必要があるみたいです。

公式チュートリアルのコードを元に編集します。

> https://developers.google.com/drive/api/v3/quickstart/nodejs

```copy.js
省略

const SCOPES = [
    `https://www.googleapis.com/auth/drive`,
    `https://www.googleapis.com/auth/drive.file`,
    `https://www.googleapis.com/auth/drive.appdata`,
    `https://www.googleapis.com/auth/drive.photos.readonly`,
];


省略
```

みたいに記述しましょう。

## drive.files.copy()

チュートリアルコードのlistFiles関数をmain関数として定義しなおして以下のように呼び出します。

```copy.js
//省略

function main(auth) {
    const targetFileId = `xxxxxxxxxxxxxxxxxxxxxxx`; //コピーしたいファイルID
    const drive = google.drive({version: 'v3', auth});
    const params = {
        fileId: targetFileId
    };

    drive.files.copy(params)
    .then(res => console.log(res))
    .catch(err => console.log(err));
}
```

## 試してみる

実行すると

> ![](https://i.gyazo.com/adc57834d9b89dd9d3f2e006c7e484a7.png)

こんな感じで同じフォルダーにコピーされます。

```
GaxiosError: Insufficient Permission: Request had insufficient authentication scopes.
    at Gaxios.request (/Users/n0bisuke/dotstudio/playground/gdrive/node_modules/gaxios/build/src/gaxios.js:70:23)
```

的なエラーがでる場合がありますが、token.jsonがすでに別のスコープで作成されてるときは公式チュートリアルのコードだと再認証されないので、token.jsonを一回削除してから試してみましょう。

別フォルダにコピーするのは別のメソッドが必要な模様なので調べて別記事にしてみます。
チョコチョコMySQLを勉強する「3回目」トランザクション紹介＆何故MySQLのデフォルト分離レベルはRepeatable Read

# はじめに
トランザクションといえば知ってる人は多いと思います。一言いうと「分けることのできない一連操作」。一番よくある例は振り込みです。
A口座からB口座へ１万円を振り込み場合、DBを使えば少なくとも下記２ステップは必要
①A口座の残高レコード１万を引く
②B口座の残高レコード１万を加える
もし①を終わる瞬間にシステム障害になって②を実行できなくなってしまうと大変な事になります。故に①と②は分けることのできない二つ操作です。
全て成功するか失敗するしかできません。
トランザクションはすごく難しいくて面白い話題だと思います。
今回はMySQLのトランザクションにサッポートする機能を踏まえて簡単な紹介及びタイトルについた面白そうな問題を解いてみましょう。

# InnoDBのみ
MySQLの使用でトランザクションをサッポートされているが、全てのストレージエンジングではく、現時点までInnoDBのみサッポートされています。これもデフォルトストレージエンジングはMyISAMからInnoDBに変更する最も重要な理由である。

# ACID
トランザクションの話になるとACIDも自然にでる。ACID（Atomicity、Consistency、Isolation、Durability）は信頼性のあるトランザクションシステムの持つべき性質です。具体的な説明はここに展開しないので、[ウィキペディア](https://ja.wikipedia.org/wiki/ACID_(コンピュータ科学))に割愛します。今の例はAtomicity（原子性）です。

# 分離レベル
ACIDのACDは紛れもなく満足しないといけないが、I（分離性）は厳しく従うとシステムの並行処理もできなくなってパフォーマンスは大幅減になってしまいます。故に、一般的にデータベースのトランザクション機能は分離性を一部犠牲してパフォーマンスを増える選択も提供されている。MySQLの場合は分離レベルというものです。
分離レベルはRU(Read Uncommitted)、RC(Read Committed)、RR(Repeatable Read)及びSI (Serializable)四つがあって、違うレベルによりダーティリード、ファジーリードやファントムリードという問題が出てきます。具体的説明な記事は一杯あるのではここも展開しませんが、もし興味があればあるいは試したければや[@PruneMazuiの記事](https://qiita.com/PruneMazui/items/4135fcf7621869726b4b)と[@song_ssさんの記事](https://qiita.com/song_ss/items/38e514b05e9dabae3bdb)はオススメです。

# 何故MySQLのデフォルト分離レベルはRR？
そろそろ本番に入りましょう。知っている通り、PostgreSQL、Oracle及びSQL Serverのデフォルト分離レベルはRCである、何故MySQLのデフォルト分離レベルはRCにしませんか？
RUはデータの分離性に対して悪くすぎ、SIはパーフォマンスに対して悪くすぎのでまず話から外す。
RRを使わない理由は前回に紹介したバイナリログに関わっています。正確的には昔のバイナリログに関わっています。
バイナリログのフォーマットは下記３種類があります
・STATEMENT  ー実行されたSQL文をそのまま記録する。
・ROWS       ー実行されたSQL文によるデータの変化を記録する。
・MIXED      ーSTATEMENTとROWを組み合わせたもの。
が、MySQL5.0以前はSTATEMENTしかサポートされていなかった。
で、バイナリログには何か問題がありますか。
MySQLのスレーブレプリケーションはダンプ＋バイナリログの実行で実装されています。
トランザクションの分離レベルをRead Committedにすれば、STATEMENTフォーマットのバイナリログでレプリケーションをする時マスターとスレーブデータ不一致な不具合が出て来る。

下記の例を見てください。(上からは時間順)
<img width="758" alt="session.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449627/6d6fe332-f87a-0833-3851-5040f1410908.png">
もしMySQLはマスタースレーブ構造であって、binlog_format=STATEMENTであれば、
マスターとスレーブにそれぞれ
<pre>mysql> select * from t;</pre>
を実行すれば
マスターは
<pre>
+---+---+
| c1 |c2
+---+---+
| 2 | 2
+---+---+
1 row in set 
</pre>
スレーブは
<pre>
Empty set
</pre>
になってしまいます。
セッション2の挿入データは分離レベルはRCのためセッション１が見えない（詳しいは後程紹介）のでセッション1の削除範囲外です。しかし、マスターのコミット順はセッション2→セッション１ので、バイナリログはスレーブに同じ順番で実行されます。
故に、セッション2に挿入されたレコードはセッション1に削除されしまう。

この問題を避ける方法は２つある、
1.バイナリログのフォーマットをROWやMIXEDにする。SQL文の代わりにデータの変化でレプリケーションすれば上記データ不一致の問題はなくなる。
2.トランザクションの分離レベルをRepeatable Readにする。
Repeatable Readにある(GAPロック)という機能でセッション2の挿入操作をブロックして、コミット順をセッション1→セッション2。GAPロックについては後ほど展開しますので、今回はスルー。
歴史的にはMySQL(5.0以前)のバイナリログフォーマットはSTATEMENTしかなかったので、2番目の方法で問題を避けます。

# まとめ
今回はトランザクション及び分離レベルについて紹介しました。
分離レベルはRU(Read Uncommitted)、RC(Read Committed)、RR(Repeatable Read)及びSI (Serializable)四つがあります。MySQLのデフォルト分離レベルはRepeatable Readです。
原因としてはRead Committedとbinlog_format=STATEMENT組み合わせてスレーブレプリケーションによりデータ不一致な不具合が出てしまうです。解決する方法はRepeatable Readにある(GAPロック)あるいはバイナリログのフォーマットをROWやMIXEDにします(MySQL5.1以降サッポート)。
Raspberry pi3でVPNサーバー

# iOS12用のVPNサーバ

海外や公衆Wi-fi接続用でVPNが必要になったため、インストールの備忘を書いておきます。

## やること
* SoftEther VPN（VPN Server, Linux ARM EABI 32bit）をmakeしてinstallする
* Tapの作成
* bridge-utilsをaptでインストールする

## 前提条件
有線LAN接続で行う。(eth0)

# softetherインストール

以下より、ダウンロードリンクをコピーする。
http://www.softether-download.com/ja.aspx

* ソフトウェア:SoftEtherVPN(Freeware)
* コンポーネント:SoftEther VPN Server
* プラットフォーム:Linux
* CPU:ARM EABI(32bit)

## ダウンロード
``` bash:bash
$ cd /tmp
$ wget https://github.com/SoftEtherVPN/SoftEtherVPN_Stable/releases/download/v4.30-9696-beta/softether-vpnserver-v4.30-9696-beta-2019.07.08-linux-arm_eabi-32bit.tar.gz
$ tar zxvf softether-vpnserver-v4.30-9696-beta-2019.07.08-linux-arm_eabi-32bit.tar.gz
```

## make

``` bash:bash
$ cd /tmp/vpnserver
$ make
$ sudo mv vpnserver /usr/local/
$ cd /usr/local/vpnserver
$ sudo chmod 600 *
$ sudo chmod 700 vpncmd
$ sudo chmod 700 vpnserver
```

## 自動起動設定

``` /etc/systemd/system/vpnserver.service
[Unit]
Description=SoftEther VPN Server
After=network.target network-online.target

[Service]
User=root
ExecStart=/usr/local/vpnserver/vpnserver.sh
ExecStop=/usr/local/vpnserver/vpnserver stop
Type=forking
RestartSec=3s
WorkingDirectory=/usr/local/vpnserver/
ExecStartPre=/sbin/ip link set dev eth0 promisc on

[Install]
WantedBy=multi-user.target
```

起動時にTapデバイスが、ブリッジされないため、Sleep用のスクリプトを作成

参考サイト：
https://www.unknownengineer.net/entry/2018/09/16/153738

``` bash:/usr/local/vpnserver/vpnserver.sh
#!/bin/bash

/usr/local/vpnserver/vpnserver start

sleep 5
tap=$(/sbin/ifconfig -a| awk '$1 ~ /^tap/ {print $1}')
/sbin/brctl addif br0 $tap
```

自動起動有効化

```
$ sudo systemctl enable vpnserver.service
```

# bridge-utilsのインストール

* ブリッジ用のユーティリティのインストール

```
sudo apt-get install -y bridge-utils
```

# Tapデバイスの追加
Windowsにて、Softether管理ツールでVPN用の仮想ハブを追加

ローカルブリッジ設定で、Tapデバイスを新規作成
Tapデバイス名：softether
※tap_softetherでLinuxOS上で認識できます。

* ブリッジインターフェースのIP固定

``` bash:/etc/dhcpcd.conf
denyinterfaces eth0
interface br0
static ip_address=xxx.xxx.xxx.xxx/xx
static routers=xxx.xxx.xxx.xxx
static domain_name_servers=xxx.xxx.xxx.xxx
```

* ブリッジ設定

``` bash:/etc/network/interfaces
auto eth0
iface eth0 inet manual

auto br0
iface br0 inet manual
bridge_ports eth0 tap_softether
bridge_stp off
bridge_maxwait 10
```

以上、備忘でした。
SoftetherでのL2TPの設定等は、いろんなサイトに書いているため省略しています。
G検定

##2019年7月12日 JDLA Deep Learning for GENERAL 2019#2 合格発表

###【　合　格　】

####総受験者数　5,143名
####合格者数　3,672名

#####■ まとめ
　感想：
　　試験対策は十分にしたものの合格基準が判らなかったので、結果発表までは受かっているとは思いませんでした。
　　出題傾向も変更されるようなので、シラバスを参考にまんべんなく学習する必要があります。
　　試験の前半で時事問題が大量に出題されました。
　　最近の話題まで出題されるため、試験中に調べる(ググる)能力も必要ですが、
　　私はあまり解けなかったので、思ったより合格点が低く設定されているかもしれません。
　学習期間：
　　ＡＩについて全く知識がない状態からスタート。
　　ゴールデンウィーク明けから１月程度勉強しました。
　　試験前は体調不良と言いつつゲームに没頭する余裕はありました。


#####■ 試験対策法
１. 参考書を読む

　・後輩から勧められた三種の神器
　　<img width="100" alt="qiita-square" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/462015/fa8f0938-316c-82f5-c32a-32fe6f6334b5.jpeg">　[人工知能は人間を超えるか ディープラーニングの先にあるもの](https://www.amazon.co.jp/%E4%BA%BA%E5%B7%A5%E7%9F%A5%E8%83%BD%E3%81%AF%E4%BA%BA%E9%96%93%E3%82%92%E8%B6%85%E3%81%88%E3%82%8B%E3%81%8B-%E3%83%87%E3%82%A3%E3%83%BC%E3%83%97%E3%83%A9%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0%E3%81%AE%E5%85%88%E3%81%AB%E3%81%82%E3%82%8B%E3%82%82%E3%81%AE-%E8%A7%92%E5%B7%9DEPUB%E9%81%B8%E6%9B%B8-%E6%9D%BE%E5%B0%BE-%E8%B1%8A/dp/4040800206)
　　<img width="100" alt="qiita-square" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/462015/0ba8daa6-f82c-c3cf-41e8-ae1417f54eae.jpeg">　[深層学習](https://www.amazon.co.jp/深層学習-機械学習プロフェッショナルシリーズ-岡谷-貴之/dp/4061529021/)　
　　<img width="100" alt="qiita-square" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/462015/454eafd2-e5ac-dfe7-f741-bb05ac1b9dc5.jpeg">　[AI白書 2019](https://www.amazon.co.jp/AI白書-2019-独立行政法人情報処理推進機構-AI白書編集委員会/dp/4049110148/)　注意：暗記は無理なボリューム。流し読みでOK！

　・実用的だった参考書
　　<img width="100" alt="qiita-square" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/462015/1cdaab48-d147-e505-4e63-be435f42d681.jpeg">　[深層学習教科書 ディープラーニング G検定(ジェネラリスト) 公式テキスト](https://www.amazon.co.jp/深層学習教科書-ディープラーニング-G検定-ジェネラリスト-公式テキスト/dp/4798157554)
　　注意：必需品。座右に置いて読み込んで理解する。
　　<img width="100" alt="qiita-square" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/462015/87d7c773-368b-a401-b48f-afe9796d49e7.jpeg">　[ゼロから作るDeep-Learning-―Pythonで学ぶディープラーニングの理論と実装](https://www.amazon.co.jp/ゼロから作るDeep-Learning-―Pythonで学ぶディープラーニングの理論と実装-斎藤-康毅/dp/4873117585)
　　注意：補足資料。座学で理解できない場合は手を動かして理解する。

２. 過去問を解く

　・会員登録すれば無料で過去問が使えます
　　[過去問サイト](http://study-ai.com/generalist/)
　・過去問題集を解く
　　[徹底攻略 ディープラーニングG検定 ジェネラリスト問題集](https://www.amazon.co.jp/%E5%BE%B9%E5%BA%95%E6%94%BB%E7%95%A5-%E3%83%87%E3%82%A3%E3%83%BC%E3%83%97%E3%83%A9%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0G%E6%A4%9C%E5%AE%9A-%E3%82%B8%E3%82%A7%E3%83%8D%E3%83%A9%E3%83%AA%E3%82%B9%E3%83%88%E5%95%8F%E9%A1%8C%E9%9B%86-%E3%82%B9%E3%82%AD%E3%83%AB%E3%82%A2%E3%83%83%E3%83%97AI%E6%A0%AA%E5%BC%8F%E4%BC%9A%E7%A4%BE-%E6%98%8E%E6%9D%BE/dp/4295005665/)

３. 機械学習で遊ぶ
　・VGG16でファインチューニングして遊んでみました
　　[「まどか☆マギカ」のキャラを見分ける](https://qiita.com/God_KonaBanana/items/2cf829172087d2423f58)

４. 学習した内容を記憶する
　　私は本を読んだだけでは記憶できないのでテキストファイルに人名、用語などを自分なりに纏め
　　持ち歩いて隙間時間に覚えてました。

■ お世話になったサイト
　[twitter](https://twitter.com/hashtag/g%E6%A4%9C%E5%AE%9A?f=tweets&vertical=default)
lsdをインストールしてlsをかっこよくするメモ(ホストWin、リモートUbuntu、フォントConsolas)

# 環境

- ホスト
    - 	Windows 10
    - 	Rlogin
- リモート
    - 	Ubuntu 18.04
    - 	zsh

# やること

SSHターミナルのフォントを元々Consolasを使用していた。そのままConsolasで[lsd](https://github.com/Peltoche/lsd)）を使うまでのメモ

![ScreenClip.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50690/944577dd-e386-9324-7ba6-65ba979f4243.png)


# 手順
## lsdインストール

```
$ sudo snap install lsd
```

## フォントインストール

アイコンを正しく表示するには[Nerd Fonts](https://github.com/ryanoasis/nerd-fonts)なるものをインストールする必要があり、インストールされていないとアイコン部分が正しく表示されない。

> Install the patched fonts of powerline nerd-font and/or font-awesome. Have a look at the Nerd Font README for more installation instructions. Don't forget to setup your terminal in order to use the correct font.
https://github.com/Peltoche/lsd

今回は表示するのはWindowsなので[Nerd Fonts](https://github.com/ryanoasis/nerd-fonts)から適当なものをインストールして表示してもいいのだが、Consolasは気に入っていたので変えずに使えないかと思って探したところ、以下公開されているものを使用したところいい感じに使えた。感謝。
（Powerline もそのまま使える）

Consolas Nerd Font Complete Mono Windows Compatible.ttf
https://github.com/whitecolor/my-nerd-fonts/blob/master/Consolas%20NF/Consolas%20Nerd%20Font%20Complete%20Mono%20Windows%20Compatible.ttf
Ubuntu 18.04にCUDA9.0を入れてPyTorchを動かす

# このドキュメントの内容

* `ubuntu18.04`, `CUDA9.0`の環境下に、`torch==1.0.1`を入れる手順のメモ.

# 前提

* OS: Ubuntu 18.04
* GPU: GeForce GTX 1080
* CUDA9.0:
    * [この手順](https://qiita.com/sabaku20XX/items/7f559dd46357cc5adf1e)でインストールした.
* python3.7
* pip3
* pipenv

# 手順

python3.7の仮想環境を作る。

```bash
$pipenv install --python 3.7
```

pipenvでインストールを行う。
コマンドは[公式サイト](https://pytorch.org/)参照。

```bash
$ pipenv install torch==1.0.1
```

# 動作確認

```bash
$ pipenv shell
$ python3
Python 3.7.3 (default, Apr  3 2019, 19:16:38) 
[GCC 8.0.1 20180414 (experimental) [trunk revision 259383]] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 
```

```python
>>> import torch
>>> torch.cuda.current_device()
0
>>> torch.cuda.device(0)
<torch.cuda.device object at 0x7f7e55f3e128>
>>> torch.cuda.device_count()
1
>>> torch.cuda.get_device_name(0)
'GeForce GTX 1080'
>>> torch.cuda.is_available()
True
```

以上.
エクセルから各行をdictとしてデータを読み込み、新規データのみ書き込む

# メモ

pythonの辞書でユニークなキーの情報を管理して、差分情報のみ追記していく想定の処理。
(javaのhashmapみたいな使い方なのかなと思ってるけど合っているのかな。)

# Pythonコード

```python
'''
指定のエクセルファイルに更新情報を保存する
'''
import datetime
import os
import time
from collections import OrderedDict
# Excel用ライブラリ読込
import openpyxl

# reading excel file path
excel_file_path = r'test3.xlsx'

# Excel Workbookオブジェクトを取得
if not os.path.exists(excel_file_path):
    wb = openpyxl.Workbook()
else:
    wb = openpyxl.load_workbook(excel_file_path)

# アクティブなシートを変数へ
ws = wb.active
dict_table = {}
base_ws_list = []
for i, row in enumerate(ws.rows):
    row_list = []
    for cell in row:
        row_list.append(cell.value)
    base_ws_list.append(row_list)
    if not i == 0:
        dict_table[(row_list[0], row_list[1])] = row_list

# for row in base_ws_list:
#    print(row)
print(base_ws_list[0])
od = OrderedDict(sorted(dict_table.items()))
# debug
# for key, value in od.items():
#     print("{}, {}".format(key, value))
# print(len(dict_table))

for key, value in od.items():
    datestr = value[2]
    if isinstance(value[2], datetime.datetime):
        datestr = value[2].strftime('%Y/%m/%d')
    print("{}, {}, {}".format(value[0], value[1], datestr))

line_count = len(base_ws_list)+1
print('base lines = {}'.format(len(base_ws_list)))

while True:
    append_dict = {}
    # 新規アイテムがあれば追加
    add_item = ('a', 'c')
    if add_item not in dict_table:
        print(add_item)
        dict_table[add_item] = list(add_item)
        append_dict[add_item] = list(add_item)
    # od[('a','b')] = hoge
    # is data in dict
    # print(('fuga', 'y') in od)

    if append_dict:
        for key, value in append_dict.items():
            for col, val in enumerate(value, 1):
                ws.cell(column=col, row=line_count).value = val
            line_count += 1
        print('current lines = {}'.format(line_count-1))
        # Excelファイルを保存
        try:
            wb.save(excel_file_path)
        except Exception as saveExcep:
            print('excel file save failed, exception = {}'.format(saveExcep))
        else:
            print('excel file save success.')
    else:
        print('no need to update.')

    dt_now = datetime.datetime.now()
    print('processed time: ' + dt_now.strftime('%Y-%m-%d %H:%M:%S'))

    interval_in_sec = 10
    time.sleep(interval_in_sec)
```