OmniAICreator/Qiita-1.07M huggingface dataset:
【Swift】継承と拡張

# 型・クラスのカスタマイズ
型やクラスをカスタマイズすることで、コーディングがかなり楽になるので、その方法について書いていこうと思います。

その便利な機能こそが、題にものってますが、**継承と拡張**です！
それぞれ簡単に説明すると

>継承：親クラスを基につくる。親クラスのプロパティやメソッドを引き継ぐ
拡張：今ある、クラスや型に新たな機能を追加（拡張）する

# 継承

```Swift
//親クラス
class parent:NSObject{
    
    func date(){
        print(Date())
    }

}
//サブクラス
class child: parent{
    override func date() {
        //親クラスのメソッドを呼ぶ
        super.date()
        //1分前の日時を出力
        print(Date(timeInterval: -60, since:Date()))
    }
}

//サブクラスのインスタンス
let calender = child()
calender.date()
```

```text:出力
//親クラスの処理
2020-04-18 06:20:59 +0000
//サブクラスの処理
2020-04-18 06:19:59 +0000

```

>**Point**
overrideで親クラスのメソッドにアクセスし、super.メソッドで呼び出す



# 拡張(extension)
エクステンションの実装には、いくつか種類があります！

- 計算型メソッド
- イニシャライザ
- メソッド
- サブスクリプト
- ネスト型
 


## 計算型メソッド

```Swift
//計算型プロパティ

//Int型に拡張
extension Int {
    //2倍
    var twice:Int{
        return self*2
    }
    //3倍
    var triple:Int{
        return self*3
    }
    //2乗
    var sqaure:Double{
        return pow(Double(self),2)
    }
}

let num:Int = 24
print(num.twice)
print(num.triple)
print(num.sqaure)

//クラスに拡張
extension NSObject{
    class var className:String{
        return String(describing: self)
    }
    var className:String{
        return self.className
    }
}
```

## イニシャライザ
イニシャライザは、元々型やクラスに実装されています。
それとは別に自由にイニシャライザを追加できます！

```swift

//イニシャライザ
extension CGRect{
    //中心材表とサイズからCGRectのインスタンスを作る
    init(center:CGPoint,size:CGSize){
        let originX = center.x - (size.width/2)
        let originY = center.y - (size.height/2)
        self.init(origin: CGPoint(x: originX,y:originY), size:size)
    }
}

let centerRect = CGRect(center: CGPoint(x:4.0,y:4.0), size: CGSize(width: 4.0, height: 4.0))
```

## メソッド

```swift
//メソッド
extension Int {
    
    func rep(task:() -> Void){
        for _ in 0..<self{
            task()
        }
    }
}
3.rep{
    print("Hello,world")
}
```
## サブスクリプト

配列で使われる[]を用います。

```swift

//サブスクリプト
extension String{
    //サブスクリプトを使う際のメソッドを見やすくするため関数化
    //indexで指定した桁数を返す
    func id(index:Int)->Index{
        return self.index(self.startIndex, offsetBy: index)
    }
    
    //サブスクリプトの指定。idのメソッドを読んでいる。
    subscript(index: Int) -> String {
        return String(self[id(index: index)])
    }
}

let hello:String = "Hello, world"
print(hello[3])

```

```text:出力
l
```

##ネスト型

内部に列挙型の定義をおこない、処理を作ることが可能です。

```Swift
extension Int{
    //enumの定義
    enum Kind {
        case negative, zero, positive
    }
    
    //Int型の種類を判別する処理
    var kind: Kind{
        switch self{
        case 0:
            return .zero
        case let x where x>0:
            return .positive
        default:
            return .negative
        }
    }
}

let numbers : [Int] = [0,1,-1,2,-2,100,-100,0]
for number in numbers{
    switch number.kind {
    case .negative:
        print("- ", terminator:"")
    case .positive:
        print("+ ", terminator:"")
    case .zero:
        print("0 ", terminator:"")
    }
}
```
Laravel 7.4で認証関連機能を認証を含むアプリケーションを構築する方法


## 参照

* 公式マニュアル
	* [Laravel 7.x 認証](https://readouble.com/laravel/7.x/ja/authentication.html)

* Laravelは[古いバージョン](https://qiita.com/LowSE01/items/0014ffea28e4adcada9d)の時代から認証関連機能を容易に構築できたが、最近のバージョンではもっと簡単になっているらしい。

	``` 公式マニュアルより抜粋
	Tip!! さくっと始めたいですか？ 
	真新しくインストールしたLaravelアプリケーションにlaravel/ui Composerパッケージをインストールし、php artisan ui vue --authを実行してください。
	データベースをマイグレーションし、http://your-app.test/registerかアプリケーションに割り付けた別のURLをブラウザでアクセスしましょう。
	これらのコマンドが、認証システム全体のスカフォールドの面倒を見ます。
	```
* マニュアルの頭にこう書いてあるものの、もう少し読んでいくと、プロジェクト作成時にオプションを指定するだけで良いことがわかる。


## アプリケーションの作成
* laravelコマンドを使って新規アプリケーションを生成する際に、--authディレクティブを使用する。
	
	``` console
	laravel new your-project-name --auth
	
	(実行結果)
	Crafting application...
	Loading composer repositories with package information
	Installing dependencies (including require-dev) from lock file
	Package operations: 93 installs, 0 updates, 0 removals
	  - Installing doctrine/inflector (1.3.1): Loading from cache
	  - Installing doctrine/lexer (1.2.0): Loading from cache
	  
	  ...
	  
	Package manifest generated successfully.
	Application ready! Build something amazing.
	```

	* 以上。まさにamazing!!
	
## 確認

* [http://your-app.url/](http://your-app.url/)
	![root.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102123/da2c51c8-6735-3c1c-234e-ff0f9ad9d4c0.png "root.png")
	
* [http://your-app.url/login](http://your-app.url/login)
	![root-login.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102123/bcb3e3d3-9d2a-d9d9-29a0-de37e5453bb0.png "root-login.png")

* [http://your-app.url/register](http://your-app.url/register)
	![root-register.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102123/f976c35c-767d-a02b-04f6-ee3a452c84ff.png "root-register.png")

* [http://your-app.url/password/reset](http://your-app.url/password/reset)
	![root-password-reset.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102123/906a9a68-fbac-026a-7dcc-3e7ae1b4a7c3.png "root-password-reset.png")
SQLが…。

とりあえず、結論からいうと『myaql.server stop』は必ずしろよ！！
https://qiita.com/madai0517/items/4df3ac0ce002301c7059

ある日、というか今日。
きょうもSQLの勉強頑張っちゃうぞ〜！ぐへへh
mysql.server start→USE hoge→SELECT * FROM hioge ぽちっとな！
ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 102

なんでやねん！！

とりまググるか…。
https://qiita.com/hachiya/items/a496cd2ec4ac3be4ea84
ふむふむ。…わからん。←クソ雑魚初心者
（今思えば答え書いてあるぞ…と。。）

画面と睨めっこしつつ、/etc/hosts.allowってどこにあるんや…。とサーフィンしていると最上の記事に行き当たり、ここでようやく..
あれ、「mysql.server stop」してなくね? あれ、これきたんじゃね？
mysql.server stop ポチッとな！
からのmysql.server start

USE hoge==~~|{_CBZSHBetc…

できた…（魂

PCとは…魔界。

はい、雑魚すぎ乙。
GETとPOSTの違い

##GETとPOSの違いについて超簡単にまとめた

どちらもサーバに値を渡す時に使う。

###GET
URLにパラメータを付加して、渡す。そのため、文字制限があったり、共有や保存ができる。
安全性に弱いため、大切な情報は扱わない。

###POST
パラメータが見えづらく、データ量も多い。
GETより安全であるため、フォームなどの情報を渡すときは使う。
【Python】行列の90度右回転、90度左回転、180度回転【AtCoder】

行列の回転のやりかたで、**感動**したことがあったので記事にしてみる。
この知識を、今後応用できるかは謎w

#[行列の90度右回転！！ ABC036B]( https://atcoder.jp/contests/abc036/tasks/abc036_b)

いろんな解き方があると思うけど、俺がはじめにACをゲットした時のコードがこちら。
ノートと紙で一生懸命、インデックスをどうすればうまくいくかなぁ・・・
と考えながらやった。

```python:test.py
def I(): return int(input())
N = I()
S = [input() for _ in range(N)]
ans =[['']*N for _ in range(N)]
for i in range(N):
    for j in range(N):
        ans[j][N-1-i] = S[i][j]
for x in ans:
    print(*x,sep='')
```

つよい人のコードをみて、**びっくり！感動！**
**90度右回転は、
①上下逆にさせた後、
②転置
すればいいんだって！！！**

![IMG_3975.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183481/31842fce-660f-5e38-94d7-6b23c5219648.jpeg)

この考えを参考にしたコードがこちら！
`S`は2次元配列なので、`S[::-1]`で上下逆にできる！
転置については、わからなければ、
「転置 zip python」とかでググってください（難しくない）！

```python:test.py
def I(): return int(input())
N = I()
S = [input() for _ in range(N)]
for x in zip(*S[::-1]):
    print(*x,sep='')
```

ACになった！
**すごい！**


#行列の90度左回転！！
90度右回転と逆で、
**90度左回転は、
①転置して、
②上下逆
にすればよさそう！！！**

```python:test.py
def I(): return int(input())
N = I()
S = [input() for _ in range(N)]
T_S = list(zip(*S))
for x in T_S[::-1]:
    print(*x,sep='')
```
本当に90度左回転になってる・・・？
<img width="592" alt="スクリーンショット 2020-04-18 21.44.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183481/5d97fed4-3b0c-e917-98fe-a53398f9bbba.png">

**90度左回転になってる！！！！！！**
**すごい！**

#[行列の180度回転！！ ABC004B](https://atcoder.jp/contests/abc004/tasks/abc004_2)
**180度回転は、
①左右逆
②上下逆
にすればよさそう！！！**

```python:test.py
def LS(): return list(input().split())
A = [LS()[::-1] for _ in range(4)]
for x in A[::-1]:
    print(*x,sep=' ')
```
入力時に、`LS()[::-1]`で左右逆にしちゃう！
ACになった！
**感動しました〜**

おわり！
応用情報技術者試験の過去問と解説の文字列をスクレイピングするGAS-PGM

<h1>応用情報技術者試験の過去問と解説の文字列をスクレイピングするGAS-PGM</h1>

応用情報技術者試験の過去問のサイトをスクレイピングして問題と解説がかかれているページから問題文と解説文を抽出して指定のフォルダに出力するGASのプログラムを作成しました。
サンプルスプレッドシートのスクリプトエディタのページからscraping1()のメソッドを実行することで処理を行います。抽出した問題・解説文は本スプレッドシートのoriginURLシート内で指定したフォルダIDのフォルダにoutput1.txt, output2.txt, ...のように連番で出力されます。
実行前にスクレイピング元のURLを本スプレッドシートのoriginURLのシートに書き込んでおく必要が
あります。

<hr>
サンプルスプレッドシートURL:https://drive.google.com/open?id=1WqLCLSj0lnvPCYX48j-S65HHuBI-NI4-ZTe42I9sLgk


GASPGM: https://github.com/NanjoMiyako/SampleGasScripts1/blob/main/OuyoJoho.txt

<hr>
スクレイピング元サイト
<a href="https://www.ap-siken.com/">応用情報技術者試験ドットコム</a>

<hr>
参考にしたサイト
<a href="http://mmorley.hatenablog.com/entry/2016/05/26/010042">replace()の機能のまとめ！『正規表現、function()、arguments、RegExp()』：JavaScript - モーリーのメモ</a>
<a href="https://qiita.com/anqooqie/items/191ad215e93237c77811">[正規表現] .*?は最短マッチではない - Qiita</a>
［機械学習］Transformerモデルを使ったテキスト分類（Attentionベースの識別器）

# ゴール
Tensorflowのチュートリアルにある「言語理解のためのTransformerモデル」の一部を修正して、
テキスト分類のタスクができるようになることです。

# Notebook
NotebookをGithubにアップしてあります。
[transformer_classify](https://github.com/raidenn-gh/transformer_classify)

# 解説
チュートリアルとの主な差分を以下に記載します。

### 使用データはlivedoorニュースコーパス
- 本記事で紹介した分類タスクは、業務に活用する場合には日本語の文書分類になると想定しています。
- そのためデータは機械学習でよく利用されるlivedoorニュースコーパスを利用させていただきました。

### 文章の分かち書きにJumanを使用
- 日本語の分かち書きに定評のあるJumanを使っています。
- Jumanのダウンロード、インストールを自動化したDockerfileは[こちら](https://github.com/raidenn-gh/dockerfile_tf2_py3_jpt_juman)

### Decoderの削除
- DecoderはEncoderのアウトプットを受け取り他言語ベクトルに変換する仕組みです。
- 今回は他言語ベクトルへの変換ではなく分類タスクであるため、Decoderは利用しません。

### Transformerの修正
- Decoderを削除する代わりに、Encoderで得られたアウトプットにDenseレイヤーを重ね、これを出力層として追加します。
- インプットとなるテキストベクトルが、どのクラスに分類されるかを確率的に表現した値に変換するため、
活性化関数にはSoftmax関数を用いています。

```ruby:transformer_classify.ipynb
NUMLABELS = 9

class Transformer(tf.keras.Model):
  def __init__(self, num_layers, d_model, num_heads, dff, input_vocab_size, 
               target_vocab_size, pe_input, pe_target, rate=0.1):
    super(Transformer, self).__init__()

    self.encoder = Encoder(num_layers, d_model, num_heads, dff, 
                           input_vocab_size, pe_input, rate)
    self.dense1 = tf.keras.layers.Dense(d_model, activation='tanh')
    self.dropout1 = tf.keras.layers.Dropout(rate)   
    self.final_layer = tf.keras.layers.Dense(NUMLABELS, activation='softmax')
        
  def call(self, inp, tar, training, enc_padding_mask):

    enc_output = self.encoder(inp, training, enc_padding_mask)  # (batch_size, inp_seq_len, d_model)
    enc_output = self.dense1(enc_output[:,0])
    enc_output = self.dropout1(enc_output, training=training)
    final_output = self.final_layer(enc_output )  # (batch_size, tar_seq_len, target_vocab_size)
    
    return final_output
```

### 損失関数
- 出力層の活性化関数をSoftmax関数を用いているため、損失関数には多クラス交差エントロピーを使います。
- One-hotベクトル化していないので、SparseCategoricalCrossentropy()を利用しています。

```rubuy:transformer_classify.ipynb
loss_object = tf.keras.losses.SparseCategoricalCrossentropy()

def loss_function(labels, pred):
  loss_ = loss_object(labels, pred)
  return loss_
```

### val_stepの追加
- train_stepの後にvalidデータを用いたval_stepを追加しています。
- validationであるため、dropoutレイヤーをスキップさせるためにtraininngはfalseにセットしてます。

# 結果
あまりよい精度は出せませんでした。

![img.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543267/0b1a3e5e-2442-893f-39ab-f34d642f41f4.png)

# 参考URL
[tf2_classify](https://github.com/kswamy15/tf2_classify)
[BERT with SentencePiece for Japanese text.](https://github.com/yoheikikuta/bert-japanese)
[作って理解する Transformer / Attention](https://qiita.com/halhorn/items/c91497522be27bde17ce#transformer-%E3%82%92%E4%BD%9C%E3%82%8B)
[Transformer model for language understanding](https://www.tensorflow.org/tutorials/text/transformer?hl=ja)
Big Queryでデータセットのデータの総容量・総レコード数を出す方法

今回はBigQuery上の「データセットの総容量と総レコード数を調べる方法」をご紹介します。

#クエリ構文

今回使うクエリ元は以下の通りです。これらを少しいじっていきます。

<b>①指定したテーブルの容量を出す</b>

```
SELECT  
SUM(size_bytes)  / 1000000000 AS GBs
FROM Dataset.table
```
<b>②指定されたテーブルの行数を出す</b>

```
SELECT  
SUM(row_count) AS Rows
FROM `Dataset.table`
```
以上の二つで簡単にテーブルの容量と行数が出ます。

#データセット全体の容量と総レコード数を算出する

データセット全体(Datasetsに含まれるテーブル全て)のサイズと行数を知りたいときは、「ワイルドカード」を使用すると簡単に調べる事ができます。

Dataset.table1、Dataset.table2、Dataset.table3、Dataset.table4・・・とテーブルが大量に存在するときは「*」を使うことで全てのテーブル指定できます。つまり、

Dataset.* = Dataset.table1、Dataset.table2、Dataset.table3、Dataset.table4・・・ 
となります。なので、

<b>①指定したDatasetの容量を出す</b>

```
SELECT  
SUM(size_bytes)  / 1000000000 AS GBs
FROM `Dataset.*`
```
<b>②指定されたDatasetの行数を出す</b>

```
SELECT  
SUM(row_count) AS Rows
FROM `Dataset.*`
```
となります。シンプルですね。ワイルドカード便利。

##DatasetにViewが含まれている時は注意

先ほどのワイルドカードを使用したクエリ、実は弱点があります。それは、

<b>「DatasetにViweが含まれる場合は、クエリはエラーを返す」</b>です。

Google Cloudの公式にもあるように、

>制限事項
ワイルドカード テーブルクエリには、次の制限が課されます。
ワイルドカード テーブルの機能はビューをサポートしません。ワイルドカード テーブルがデータセットのビューと一致すると、クエリはエラーを返します。クエリの WHERE 句に _TABLE_SUFFIX 擬似列を使用してフィルタを除外していても同様です。

どういう事でしょう。実験します。

##Viewにワイルドカードを使えないとはどういう事か
今回はこの「Tableau」というデータセットで実験します。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548159/92b42515-101e-f779-58a3-1036acb774c8.png)

二つのテーブルと二つのViewが入っています。

先ほどの記載の通りクエリを走らせようとすると・・・
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548159/80f0dec5-a2af-d2af-91d2-e9289aaf2c9a.png)

走りませんね。エラーの通り、「*はViewを含む、テータセットでは使えません」とあります。

「View1」と「View2」が邪魔しているみたいです。

残念ながら、Viewを含むDatasetを調べる際には他の方法でやる必要があります。

##メタテーブルを使ったクエリで解決する

ワイルドカードを使わない方法も勿論あります。さすがBig Query大先生。

それは「メタデータ」を使用するクエリです。こちらもGoogle Cloudのヘルプにあるように、

><b>メタテーブルを使用する</b>
BigQuery では、内容がメタデータ（テーブルの名前など）を表す特別なテーブルがいくつか提供されます。メタテーブルは読み取り専用です。通常、メタテーブルを使用するには SELECT ステートメントでメタテーブルを参照します。
メタテーブルは、クエリジョブだけでなく、tables.get や tabledata.list などの他の API オペレーションでも使用できます。メタテーブルは tables.insert をサポートせず、宛先テーブルとしては使用できません。また、テーブル デコレータもサポートしていません。 メタテーブルは、データセットの tables.list には表示されません。

><b>データセット内のテーブルに関するメタデータ</b>
データセット内のテーブルに関するメタデータには、__TABLES__ または __TABLES_SUMMARY__ メタテーブルを使用してアクセスできます。

つまり、

from Dataset.__TABLES__

とすることで、Dataset内にあるテーブルを全て指定することになります。
なので、

```
SELECT
SUM(size_bytes)  / 1000000000 AS GBs,
SUM(row_count) AS Records
FROM `Dataset.__TABLES__`
```
とすれば良さそうです。

##実際にやってみた

実際に入力画面がこちら。エラー出ていませんね。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548159/ce642271-507c-4519-dc8b-2d9850d129c9.png)
そして結果がこちら。
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548159/42b5798a-d68c-48fb-a9b1-8808d4d38ac4.png)

5.5GB、2億行でした。(適当なデータセットだったんですが、結構なボリューム)

#まとめ
BigQuery上の「データセットの総容量と総レコード数を調べる方法」ですが、

- データセットに含まれるのがテーブルのみならば、ワイルドカード(*)を使えば算出できる
- Viewを含む場合はワイルドカードは使えず、「from Dataset.__TABLES__」を使う必要がある

でした。
よく使うLinuxコマンド

##よく使うLinuxコマンドについて

###そもそもLinuxとは
LinuxとはMacやWindowsなどと同じOSで、コンピュータを管理しているハードウェアのこと。主にサーバー用として使われ、無料である。

###よく使うコマンド

```
$ls //フォルダ一覧

$cd　//ディレクトリ移動
$cd 移動したいディレクトリ

$cp　//コピー
$cp コピー元ファイル/ディレクトリ コピー先ファイル/ディレクトリ

$mv　//移動
$mv 移動元ファイル/ディレクトリ 移動先ファイル/ディレクトリ

$vi  //ファイルを開く　
//開いたあと、iでインサートモード、:wqで保存して出るなどがある

$mkdir  //ディレクトリ作成

$touch  //ファイル作成

$rm   //ファイル/ディレクトリ削除
// -f（警告メッセージを表示しない)などのオプションもある

$pwd　　//現在いる位置

$cat　　//ファイルの内容表示
```
簡単なポアソン分布まとめ（Rでの出力付き）

###### tags: `緑本`
# ポアソン分布
## 1. ポアソン分布とは
二項分布で, nが大きくpが小さい時, ポアソン分布に従う.

## 2. ポアソン分布の確率の定義
ポアソン分布の確率は, 以下のように定義される.
$$
p(y | \lambda) = \frac{\lambda^{y}\exp(-\lambda)}{y!}
$$
平均が$\lambda$である時, 確率変数が$y$という値になる確率.

## 3. ポアソン小数の法則
$np → \lambda$となるように, $n → \infty$, $p → 0$となる極限においては, 以下が成り立つ. 
$$
    {}_n \mathrm{C} _y\, p^y(1 - p)^{n - y} → \frac{\lambda^{y}\exp(-\lambda)}{y!}
$$

## 4. ポアソン分布の期待値と確率変数
ポアソン分布を, $Po(\lambda)$で表す.
確率変数$Y$がポアソン分布$Po(\lambda)$に従うならば, 期待値と分散は等しくなる.
$$
E(Y) = \lambda, V(Y) = \lambda\\
(\lambda\fallingdotseq np, 1 - p \fallingdotseq 1 \Longrightarrow E(y) = np → \lambda, V(y) = np(1 - p) → \lambda)
$$

##  5. ポアソン分布を使う場合
主に, 以下のような場合ポアソン分布を使う.

1. カウントデータである
2. 平均と分散が概ね等しい
3. 標本が大きく, 確率が小さい時

##  6. ポアソン分布の例
#### プロシア騎兵連隊において馬に蹴られて亡くなった兵士の数
$\lambda = 0.61, E(Y) = 0.61, V(Y) = 0.61, \sqrt{V(Y)} = 0.77$ 

| 死亡数 | 0     | 1    | 2    | 3   | 4   | 5   |
|--------|-------|------|------|-----|-----|-----|
| 観測数 | 109   | 65   | 22   | 3   | 1   | 0   |
| 理論値 | 108.7 | 66.3 | 20.2 | 4.1 | 0.6 | 0.1 |
##  7. ポアソン分布の出力
###  7-1. ポアソン分布の確率の出力
ポアソン分布の確率の出力は, `dpois(x, lambda = "")`を用いて行う. 6. での例を用いると, 以下のように出力できる.

```r
y <- c(0, 1, 2, 3, 4, 5)
prob <- dpois(y, lambda = 0.61)
prob %>% round(digits = 2)
```
```r
> prob %>% round(digits = 2)
[1] 0.54 0.33 0.10 0.02 0.00 0.00
```
###  7-2. ポアソン分布のグラフの出力
`plot()`を用いて, グラフを出力させると, 以下のようになる.

```r
y <- c(0, 1, 2, 3, 4, 5)
prob <- dpois(y, lambda = 0.61)
plot(y, prob, type="o")
```
![](https://i.imgur.com/wUdPzFh.png)
##  8. 参考文献
・久保拓弥（2012）『[データ解析のための統計モデリング入門](https://www.amazon.co.jp/%E3%83%87%E3%83%BC%E3%82%BF%E8%A7%A3%E6%9E%90%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E7%B5%B1%E8%A8%88%E3%83%A2%E3%83%87%E3%83%AA%E3%83%B3%E3%82%B0%E5%85%A5%E9%96%80%E2%80%95%E2%80%95%E4%B8%80%E8%88%AC%E5%8C%96%E7%B7%9A%E5%BD%A2%E3%83%A2%E3%83%87%E3%83%AB%E3%83%BB%E9%9A%8E%E5%B1%A4%E3%83%99%E3%82%A4%E3%82%BA%E3%83%A2%E3%83%87%E3%83%AB%E3%83%BBMCMC-%E7%A2%BA%E7%8E%87%E3%81%A8%E6%83%85%E5%A0%B1%E3%81%AE%E7%A7%91%E5%AD%A6-%E4%B9%85%E4%BF%9D-%E6%8B%93%E5%BC%A5/dp/400006973X)』 岩波書店．
・東京大学教養学部統計学教室 (編集)（1991）『[統計学入門 (基礎統計学Ⅰ)](https://www.amazon.co.jp/%E7%B5%B1%E8%A8%88%E5%AD%A6%E5%85%A5%E9%96%80-%E5%9F%BA%E7%A4%8E%E7%B5%B1%E8%A8%88%E5%AD%A6%E2%85%A0-%E6%9D%B1%E4%BA%AC%E5%A4%A7%E5%AD%A6%E6%95%99%E9%A4%8A%E5%AD%A6%E9%83%A8%E7%B5%B1%E8%A8%88%E5%AD%A6%E6%95%99%E5%AE%A4/dp/4130420658/ref=pd_sbs_14_t_0/355-2445844-0692628?_encoding=UTF8&pd_rd_i=4130420658&pd_rd_r=c4369746-d1fc-4cb4-a701-9f90aa21925f&pd_rd_w=sZuSt&pd_rd_wg=g8G8l&pf_rd_p=ca22fd73-0f1e-4b39-9917-c84a20b3f3a8&pf_rd_r=JP47VQXC3CKFJQ8WE9TH&psc=1&refRID=JP47VQXC3CKFJQ8WE9TH)』 東京大学出版．
Ubuntu18にVisual Studio Codeをインストールする最も簡単な手順


こちらのサイト「[UbuntuにVSCodeをインストールする3つの方法](https://qiita.com/yoshiyasu1111/items/e21a77ed68b52cb5f7c8)」は、UbuntuにVisual Studio Codeをインストールする手順を調べると上位にくるけど、Microsoftのリポジトリを手動登録するのは公式の.debが自動でやってくれることを手動でやっているだけで無駄な手順だ。公式debファイルを使おう！

[Visual Studio Code公式サイト](https://code.visualstudio.com/)の![deb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38675/bdd843dc-756f-bdef-6518-f98e5b08c1fc.png)ボタンからダウンロードした.debファイルを使って、
必要なコマンドはたった3つ。


```bash
$ sudo apt install ./公式サイトからダウンロード.debファイル
$ sudo apt install -y apt-transport-https
$ sudo apt update
```

起動

```
$ code
```

もし万が一インストールされていないなら追加でこちらのコマンド。

```
$ sudo apt install -y code
```


**Appendix**

[Visual Studio Code公式サイト https://code.visualstudio.com/](https://code.visualstudio.com/)
![vsctop.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38675/54943e85-e7db-9222-a637-30d1f6a286d2.png)
GetComponentとは

#Componentとは
UnityのInspectorについている。部品と化した。スクリプトのパッケージ。
##GetComponentとは
ScriptからComponentの内容を変更しようとするときに,getcomponentを使って得る。

[参考　:  UnityでGetComponentを使って"参照"を得るということ。Unityにおけるオブジェクト指向とは、的な。](https://unity-indie-dou.hatenablog.com/entry/2017/08/19/100000)
OpenVINOのIR(Intermediate Representation)に、できれば、詳しくなりたい

#目的
OpenVINOにおいて、**IR(Intermediate Representation)**というのがある。
中間表現。
**xmlとbinファイルのペア**である。
中間と言われるが、わりと、最終的なファイルのイメージが、個人的にはする。

#IRファイルについて
##xmlについて
ここでのxmlは、（想像されるとおり）ネットワークモデルの情報が格納されている。OpenVINOのツール群で、このxmlをビジュアルに表示できるのがあるようだが、使い方がわからないので、xmlを直接みてみる。

##xmlを見た結果
squeezenet1.1のxmlをみた。
（ここでは、最初のレイヤ以外は、表示を畳んでいます。）

<img width="511" alt="squeeze_xml.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342207/aa8067bd-0818-3b1c-e903-05bb06b3d5a4.png">

#まとめ
IRのxmlで、欲しい情報を確認できることもあるのではないでしょうか。

#今後
ビジュアルな表示も示さないと、あまり、、、、記事にする価値がなかったかも。。。（よって、いつかは、それとかそれに類することをやります。）
Pythonで毎日AtCoder #40

### はじめに
[前回](https://qiita.com/taxfree_python/items/74913af0b53676d48618)
今日はDPContestのA~Cをやります

### A問題
[問題](https://atcoder.jp/contests/dp/tasks/dp_a)

**考えたこと**
dp[i]は$dp[i-1]+abs(h[i]-h[i-1]) or dp[i-2]+abs(h[i]-h[i-2])$になります。この二つの最小値を更新していって求めます。

```python
n = int(input())
h = list(map(int,input().split()))

dp = [0] * n  #infの方がいい気がする

for i in range(1,n):
    if i == 1:
        dp[i] = abs(h[i]-h[0])
        continue
    dp[i] = min(dp[i-1]+abs(h[i]-h[i-1]),dp[i-2]+abs(h[i]-h[i-2]))
print(dp[-1])
```

### B問題
[問題](https://atcoder.jp/contests/dp/tasks/dp_b)

**考えたこと**
Aと違うのは選択肢がふたつからK個になったことですが、その分minを取る部分を増やすだけです。

```python
n, k = map(int,input().split())
h = list(map(int,input().split()))

dp = [float('inf')] * n
dp[0] = 0
dp[1] = abs(h[1]-h[0])
for i in range(2,n):
    for j in range(k+1):
        if i - j < 0:
            continue
        dp[i] = min(dp[i-j]+abs(h[i]-h[i-j]),dp[i])
print(dp[-1])
```

### C問題
[問題](https://atcoder.jp/contests/dp/tasks/dp_c)

**考えたこと**
A,Bと違ってdp[i-1]がdp[i]の選択肢に関わってきます。ですので、dp[i-1]でなにを選んだのかを記録するためにdp[i][j]というようにdpの要素を一つ増やします。あとは、選択肢の3つ全て計算して最大値を取ります。

```python
n = int(input())
abc = [list(map(int,input().split())) for _ in range(n)]

dp = [[0 for _ in range(3)] for _ in range(n+1)]

for i in range(1,n+1):
    for j in range(3):
        for k in range(3):
            if j == k:
                continue
            dp[i][k] = max(dp[i][k],dp[i-1][j] + abc[i-1][k])

ans = 0
for i in range(3):
    ans = max(ans,dp[n][i])
print(ans)
```

### まとめ
dpって名前がかっこいいですよね。使いこなせるようにがんばります。明日のABCがんばりましょう! 
ではまた、おやすみなさい。
ROSでpythonのパスがどのようにセットされているのか調べた

# 概要
- ROSでpythonスクリプトを実行するとき、importの探索パスは
    - 普通にpythonを使ったときのパス
    - ROS packageのscriptディレクトリたちのパス
- になる。特に後者はどのように読み込まれているのか気になったので調べた。

# 環境
| 項目 | バージョン |
| --- | --- |
| OS | Ubuntu 18.04 |
| ROS | melodic |
| Python | 2.7.17 |
| bash | 4.4.20 |

# 本題
- まずpythonのパスは`sys.path`に格納されており、`print`(ROSなら`rospy.loginfo`など)で確認することが出来る。実際に確認してみると、
    - rosrunやroslaunchを実行したカレントディレクトリ
    - スクリプトファイルがあるディレクトリ
    - 環境変数`PYTHONPATH`で指定したディレクトリ
    - 標準ライブラリのためのディレクトリ
    - pipでインストールしたライブラリが入っているsite-packagesなどのディレクトリ
- になっている。
- 今回調べたいROS packageのscriptたちは3つめの`PYTHONPATH`を経由して読み込まれている。しかし単純に実体が存在するディレクトリが`PYTHONPATH`に羅列される仕組みにはなっていない。
- ではどうなっているかと言うと、`/opt/ros/${ROS_DISTRO}/setup.bash`や`~/catkin_ws/devel/setup.bash`を読み込んだときに`PYTHONPATH`に`/opt/ros/melodic/lib/python2.7/dist-packages`や`~/catkin_ws/devel/lib/python2.7/dist-packages`が追加される。
- それらのディレクトリの中にはビルドされたパッケージの名前のディレクトリたちが入っている。例えば`hoge`というpackageを作り、`script/`にpythonスクリプトを配置してcatkin buildすると、以下のような内容の`.../dist-packages/hoge/__init__.py`が自動生成される。

```python
# -*- coding: utf-8 -*-
# generated from catkin/cmake/template/__init__.py.in
# keep symbol table as clean as possible by deleting all unnecessary symbols

from os import path as os_path
from pkgutil import extend_path
from sys import path as sys_path

__extended_path = '/your/ros/path/hoge/scripts'.split(';')
for p in reversed(__extended_path):
    sys_path.insert(0, p)
    del p
del sys_path

__path__ = extend_path(__path__, __name__)
del extend_path

__execfiles = []
for p in __extended_path:
    src_init_file = os_path.join(p, __name__ + '.py')
    if os_path.isfile(src_init_file):
        __execfiles.append(src_init_file)
    else:
        src_init_file = os_path.join(p, __name__, '__init__.py')
        if os_path.isfile(src_init_file):
            __execfiles.append(src_init_file)
    del src_init_file
    del p
del os_path
del __extended_path

for __execfile in __execfiles:
    with open(__execfile, 'r') as __fh:
        exec(__fh.read())
    del __fh
    del __execfile
del __execfiles
```
- というわけで、これがimportされたときに読まれるので`pkgutil.extend_path()`によって実体が存在する箇所が無事読み込まれるわけだ。
    - pkgutilや`__init__.py`については参考に載せたリンクを参照。
    - この仕組みになっているせいでVSCodeなどのIDEで開いたときにIDEが`__init__.py`までしか読みに行ってくれないのでちょっと面倒。
- `/opt/ros`以下のaptで入れたパッケージについても`__init__.py`が置いてあるのは同じだが、こちらは自動生成とかではなくパッケージに実際にそのファイルが置いてある。
    - importされる実体もその階層に置いてある。`__init__.py`にはそれらのファイルをimportする内容が書いてあったり、簡単な実装なら直接書いてあったりする。
    - `/opt/ros/${ROS_DISTRO}/share/packagename/scripts`以下にもpythonスクリプトが置いてあって`rosrun`などで実行できるが、こちらにはnodeになるスクリプトが置いてあって、パスは通っていない(importはする必要もないし、できない)。

# おわりに
- これがわかったから何かできるのかというと何もできないが、勉強になった。
- 余談だが、最初`rosrun`や`roslaunch`側でpythonを実行するときにパスが読み込まれていたりするのかと思ってそっちのソースを読みにいくなど迷走し、結構時間がかかってしまった。

# 参考
- [note.nkmk.me様のsys.pathなどの解説](https://note.nkmk.me/python-import-module-search-path/)
- [Python の \_\_init\_\_.py とは何なのか - Qiita](https://qiita.com/msi/items/d91ea3900373ff8b09d7)
- [pkgutilの公式ドキュメント](https://docs.python.org/ja/2.7/library/pkgutil.html)
Indexページにいいね機能をつける

#目的
ここでは、indexページにいいね機能を付ける方法とその仕組みを解説したいと思います。railsにおけるいいね機能を解説してくれている多くの記事はshowページのみに対応しています。それをindexページで使う場合、注意点が1つあるのです。

**※showページにおけるいいね機能は実装できている前提で話します。
参考**
https://qiita.com/nojinoji/items/2c66499848d882c31ffa

#概要
1. indexページ
2. 解説

#1. indexページ
indexページにいいね機能を付けるときは、任意の場所に下記の真ん中の5行を追記してください。多くの場合はeach doの中に入るはずです。

```views/tweets/index.html.erb
<% @tweets.each do |t| %>
・
・
  <% if current_user.already_liked?(t) %>
    <%= button_to 'いいねを取り消す', tweet_like_path(id: t.id, tweet_id: t.id), method: :delete %>
  <% else %>
    <%= button_to 'いいね', tweet_likes_path(id: t.id, tweet_id: t.id) %>
  <% end %>
・
・
<% end %>
```

#2. 解説
showページに書かれたいいね機能とindexページに書かれたいいね機能の大きな違いは、パラメーターとして送られる変数の違いです。

**showページ**
```<%= button_to 'いいねを取り消す', tweet_like_path(@tweet) %>```

**indexページ**
```<%= button_to 'いいねを取り消す', tweet_like_path(id: t.id, tweet_id: t.id) %>```

likeモデルは、tweet_idを保存する必要があります。showページにおいてはURLの中にtweet_idがすでに埋め込まれているので、@tweetを送信してあげれば、tweet_idのパラメーターを送ることができます。

しかし、indexページでは、tweet_idはeach doで書かれた```t```から引っ張ってくる必要があります。これを次のように実現します。
①```id: t.id```で本来URLに埋め込まれるidの部分にt.idを代入する
②```tweet_id: t.id```でパラメーターのtweet_idを指定してあげる。

このように、2段階の工程として2つのパラメータを記述してあげれば、とりあえず辻津を合わせることができます。

①の記述がないと例えばlikeのdestroyアクションで下記のようなエラーが出ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614347/c634d3a1-f71c-fada-0975-c893e8a3798c.png)
これは、indexページのURLの中にtweet/**:id**の記述がないという意味です。destroyアクションはtweetのidがURL中に存在しないとエラーを起こす仕様になっているんですね～。これは多分、ルーティングでtweetの中にlikeを入れ子にしていることが関係してるんだと思います。

(ちなみにlikeのcreateアクションはpathの部分を```(t)```のように書いても動きます。この違いは何でなんでしょう？それとcommentをindexページで扱う際にも同様のことに気を付ける必要がありそうな？)
カスタムユーザーでdjango-rest_framework_simple-jwtを使用してユーザー認証しようとした時にハマった話

#エラーが出た！！

DjangoREST Frameworkのプロジェクトにdjoserを導入し、api/auth/jwt/createに対してPOSTしてもトークンが発行されず、何事かと思いひとまずコンソールにアクセスしてアクティブなユーザーでPOSTしたところ、以下のようなエラーが出ました。


```
"detail": "No active account found with the given credentials"
```


与えられた情報ではアクティブユーザー見つけられません！ってことなので早速エラー文でググってみると以下の記事が

[Django drf simple-jwt authentication“detail”: “No active account found with the given credentials”](https://stackoverflow.com/questions/55906891/django-drf-simple-jwt-authenticationdetail-no-active-account-found-with-the)

どうやらパスワードがDBに入る前にハッシュ化されておらず、シリアライザーに以下を追加すればちゃんと動いてくれるようになる様子。
なので同記事の中にある関数を追加。

```Python:serializers.py
from django.contrib.auth.hashers import make_password #追加
from djoser.serializers import UserSerializer

from .models import User

class CustomUserSerializer(UserSerializer):
    """
    ユーザー情報獲得のためのシリアライザー
    """
    class Meta:
        model = User
        fields = '__all__'
    
　　# 追加
    def validate_password(self,value:str) ->str:
        """
        ハッシュ値に変換する
        """
        return make_password(value)
```

すると・・・

![スクリーンショット 2020-04-18 21.07.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412789/e6bb49f9-8763-0bd7-551b-84446eaa5163.png)

無事トークンが発行されました。

ハマったときはびっくりしましたがなんとかなりました、良かったです。
Vuetify の v-btn をラップして、フォームの多重送信を防止するコンポーネント


下記、すばらしい２記事のtipsを合わせただけです。

Vue.js の inheritAttrs に関する大きな勘違い
https://qiita.com/mpyw/items/d3dc2745b6808b0158c3

[Vue.js] フォームの多重送信を防止する
https://qiita.com/ryo511/items/2563bb61b4b4d1be9619

---

* コンポーネント

```html:VButtonProcessing.vue
<template>
  <v-btn
      :disabled="disabled || processing" 
      :loading="loading && processing"
      @click="handleClick"
      v-bind="$attrs">
    <slot />
  </v-btn>
</template>

<script>
export default {
  name: 'VButtonProcessing',
  inheritAttrs: false, 
  props: {
    // A function which returns Promise.
    onclick: {
      type: Function,
      required: true,
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    loading: {
      type: Boolean,
      default: true,
    }
  },
  data() {
    return {
      processing: false,
    };
  },
  methods: {
    handleClick(event) {
      if (this.processing) return;
      this.processing = true;
      this.onclick(event)
        .finally(() => {
          this.processing = false;
        });
    },
  },
};
</script>
```

* 使う側の例

元記事の通り、`:onclick` に、`Promise`返す関数指定します。

```html:使う側の例
<template>
  <div>
    <VButtonProcessing :onclick="samplePromise"
      large color="primary" elevation="5">
      Button
    </VButtonProcessing>
    <VButtonProcessing :onclick="asyncFunc" :loading="false"
      large color="primary" elevation="5">
      no loading
    </VButtonProcessing>
  </div>
</template>

<script>
import VButtonProcessing from './path/to/VButtonProcessing';
export default {
  name: 'ProcessingButtonSample',
  components: {
    VButtonProcessing,
  },
  methods: {
    // Promiseを明示的に返す関数
    samplePromise() {
      return new Promise((resolve) => {
        setTimeout(() => {
          console.log(`samplePromise ${new Date()}`);
          resolve();
        }, 1000);
      });
    },
    // async Function でPromise返す
    async asyncFunc() {
      return;
    }
  },
}
</script>
```
パラメーターで条件分岐

受け取ったパラメーターによって条件分岐する機能を実装する必要があったのでメモ
###状態
Wordsテーブルにcompleteカラム。
completeカラムはtrueかfalseの値が入る。
送られてくるパラメーターがtrueかfalseによってリダイレクトする場所を変えたい。
下記はword入力フォーム

```ruby:_word.html.erb
<%= form_for(word) do |f| %>
   <div class="d-flex flex-row pull-left">
     <%= f.check_box :complete, {}, checked_value = "true", unchecked_value = "false" %>
     <%= f.submit "保存", class: "btn btn-primary btn-xs" %>
   </div>
<% end %>
```

ちなみに`words.html.erb`にはチェックボックスが未チェック状態（つまり初期がfalse）、`practice.html.erb`にはチェックボックスがチェック状態（初期がtrue）。
これらを未チェック時にはチェックをして保存→`wordsページ`にリダイレクト、チェック時には未チェックにして保存→`practiceページ`にリダイレクトしたい。
要約すると、words=>words、practice=>practiceと同じページにリダイレクトしたい。

このフォームをコントローラーに渡す

```ruby:words_controller.rb
def update
  word = Word.find(params[:id])
    if word.complete?
      word.update_attributes(word_params)
      redirect_to "/words"
    else !word.complete?
      word.update_attributes(word_params)
      redirect_to "/practice"
    end
  end
end

private

    def word_params
      params.require(:word).permit(:english, :japanese, :complete)
    end
```

すでに存在している値なのでupdateに送られます。
上記のコードの書き方でupdateに送られるとリダイレクトされるページが真逆になりました。
未チェック時にはチェックをして保存→`completeページ`にリダイレクト、チェック時には未チェックにして保存→`wordsページ`にリダイレクトされるハメに。
というのも、考えてみると

```ruby:words_controller.rb
def update
  word = Word.find(params[:id])
    if word.complete? #=>保存する前の値がtrueつまりすでにチェック済が当てはまる。
      word.update_attributes(word_params) #=>ここでチェック済から未チェックへと保存される。
      redirect_to "/words" #=>チェック済ページ(practice)からwordsページへ
    else !word.complete? #=>保存する前の値がfalseつまり未チェックが当てはまる。
      word.update_attributes(word_params) #=>ここで未チェックからチェック済へと保存される。
      redirect_to "/practice" #=>未チェックページ(words)からpracticeページへ
    end
  end
end
```

という仕組みになっていたのである（自己解釈）
この問題を解決するため、保存の動作を先に用意し、保存後の値を参照して条件分岐させるようにすると、希望通りのページへリダイレクトしてくれる。

```ruby:words_controller.rb
def update
  word = Word.find(params[:id])
  if word.update_attributes(word_params)
    if word.complete?
      redirect_to "/words"
    else !word.complete?
      redirect_to "/practice"
    end
  end
end
```

これでできました。とりあえず調べに調べた結果がこれです。まだまだ簡単に書けるかは分かりませんが現段階の知識をメモ。
C# 基礎プログラミング100本ノック～6-10本目～

#こんばんは

本日も基礎プログラミング100本ノックやっていきます！
そろそろウォーミングアップ終わりそうだなぁ...

前回→[1-5本目](https://qiita.com/K_Hisui/items/e950e60bb0d25d437a9b)
次回→[11-15本目](https://qiita.com/K_Hisui/items/9e41d70a085f6efdaf2b)

#6本目
>整数値を入力させ、値が0ならzeroと表示するプログラムを作成せよ。

~~~Sample.cs
Console.Write("input num：");
string inputNum = Console.ReadLine();

string result;

if(inputNum == "0")
{
    result = "zero";
}
else
{
    result = "any";
}

Console.WriteLine(result);
~~~

プログラム初学者であればこれで十分かと思いますが、3項演算子を使って簡略化しましょうね！

~~~Sample.cs
string result;

if(inputNum == "0")
{
    result = "zero";
}
else
{
    result = "any";
}
~~~

上記が3項演算子を使わない書き方です。

~~~Sample.cs
string result = (inputNum == "0") ? "zoro" : "any";
~~~

if 文で同じ変数に別々の値を格納したい場合などに使うと可読性が向上するでしょう。

構文としては以下の通りです。

~~~
代入したい変数 = (条件式) ? trueの時代入する値 : falseの時代入する値;
~~~

#7本目
>整数値を入力させ、値が0ならzero、0でなければnot zeroと表示するプログラムを作成せよ。

あ、やっちゃった...。

#8本目
>整数値を入力させ、値が正であればpositiveと表示するプログラムを作成せよ。ただし0は正には含まない。

~~~Sample.cs
Console.Write("input num：");
int inputNum = int.Parse(Console.ReadLine());

string result = (inputNum > 0) ? "positive" : "negative";

Console.WriteLine(result);
~~~

6本目の条件文と代入の値を変えるだけですね！

#9本目
>整数値を入力させ、値が正であればpositive、負であればnegative、0であればzeroと表示するプログラムを作成せよ。

~~~Sample.cs
Console.Write("input num：");
int inputNum = int.Parse(Console.ReadLine());

string result = (inputNum > 0) ? "positive" : 
    (inputNum == 0) ? "zero" : "negative";

Console.WriteLine(result);
~~~
ちょっと可読性が落ちる様な気がしますが三項演算子で書いてみました。

普通にif文書いた方がいいような...
ただ、この場合「0」だけ特別扱いなんですよね。
後々、「0」以外も特殊な数字が出るのであれば、switchを使ってこんな感じにした方が保守性が上がるかも？

~~~Sample.cs
string result;
switch (inputNum)
{
    case 0:
        result = "zero";
        break;

    default:
        result = (inputNum > 0) ? "positive" : "negative";
        break;

}
~~~
冗長にはなりますが、例外の値が増えた際はこちらの方が保守しやすいですよね？

そして、Switchを使うにあたって調べているとbreak,goto,returnのいずれかは必須なのですね。
デフォルトでbreakにしていいと思ってますけど有難い機能でもあります。

#10本目
>整数値を入力させ、その値を絶対値にして表示するプログラムを作成せよ。（できれば変数の値を絶対値に変えるようにせよ）

絶対値計算には[Math.Abs](https://docs.microsoft.com/ja-jp/dotnet/api/system.math.abs?view=netframework-4.8)メソッドというものが用意されているようです。
では使っていきましょう。

~~~Sample.cs
Console.Write("input num：");
int inputNum = int.Parse(Console.ReadLine());

inputNum = Math.Abs(inputNum);

Console.WriteLine(inputNum);
~~~

Math.Absメソッドではほぼ全ての数値型の絶対値が求められるようなので便利？ですね！

では今宵はこの辺りで終了！

#リンク
[基礎プロI 100本ノック 基礎編](http://www.cc.kyoto-su.ac.jp/~mmina/bp1/hundredKnocksBasic.html)
SqueezeNetに詳しくなる。

#◆概要
深層学習において、**SqueezeNet**に出会うことがある。
少し、情報を整理する。

#◆SqueezeNetとは
wikipediaによると、
https://en.wikipedia.org/wiki/SqueezeNet

>SqueezeNet is the name of a deep neural network for computer vision that was released in 2016. SqueezeNet was developed by researchers at DeepScale, University of California, Berkeley, and Stanford University. In designing SqueezeNet, the authors' goal was to create a smaller neural network with fewer parameters that can more easily fit into computer memory and can more easily be transmitted over a computer network.

Google翻訳(ママ)
>SqueezeNetは、2016年にリリースされたコンピュータービジョン用のディープニューラルネットワークの名前です。SqueezeNetは、カリフォルニア大学バークレー校およびスタンフォード大学のディープスケールの研究者によって開発されました。 SqueezeNetの設計において、著者の目標は、より少ないパラメーターでより小さなニューラルネットワークを作成し、コンピューターのメモリに簡単に適合し、コンピューターネットワーク上でより簡単に送信できるようにすることでした。

#◆ソースなど
引用元：wikipedia
SqueezeNet was originally released on February 22, 2016.

ここで、参照されている先は、
以下のgithub。
**https://github.com/forresti/SqueezeNet**

とりあえず、**上記のgithubをスタートとする**のがいいと思います。

#◆基本情報

## サイズなど
最初のレイヤのサイズは、**227 x 227**（※ not 224)

##SqueezeNet1.1とは
**この1.1をよくみるが、**
以下のとおり。

（出典：https://github.com/forresti/SqueezeNet/blob/master/SqueezeNet_v1.1/README.md）

<img width="496" alt="squeeze.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473789/34a822d3-4c52-ef7d-0455-c9772f26465b.png">

#◆補足など
特にありません。
情報などあれば、お願いします。
ハイパーパラメータの選択について (E資格対策)

では書きます。


#ハイパーパラメータとは
学習時に訓練データによって自動的に取得されない値を指します。
例えば正則化であれば

```math
E=E_0+\lambda E_w(w)
```

の$\lambda$が該当します。
このハイパーパラメータの決め方をハイパーパラメータチューニングといいます。


#ハイパーパラメータチューニングの手法
ここではハイパーパラメータチューニングの手法を紹介します。


![20151223151040.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604787/f3e98b3a-4e84-6ccf-3ec8-ca17918cc1f4.png)


引用：http://olanleed.hatenablog.com/entry/2015/12/23/180457

##グリッドサーチ
図の左側に該当する手法。
あらかじめパラメータの探索候補を与え、そのすべての組み合わせでモデルを評価する手法。
例えば

```math
E=E_0+\lambda E_w(w)
```

なら

```math
\lambda =0.1, 0.01, 0.001, 0.0001
```
のように探索候補を作り、その数値ごとのモデルを評価し、一番良い値をモデルに用います。


##ランダムサーチ
探査候補をある分布に従って与える手法。
パラメータに連続量が含まれる場合、性能をグリッドサーチを超える場合がございます。統計の知識やドメインの知識がある方はこっちを使った方が良いかもしれません。



余談ですがハイパーパラメータチューニングをするライブラリも現在発展途中です。
Hyperoptなどがあります。


#グリッドサーチの実装
せっかくなのでグリッドサーチを実装します。

使うのはアヤメデータ、分析手法はSVCです。
ハイパーパラメータチューニングの対象はCとgammaになります。

```python
from sklearn.datasets import load_iris
iris = load_iris()

from sklearn.svm import SVC
from sklearn.model_selection import train_test_split
X_train, X_test,y_train,y_test=train_test_split(
    iris.data, iris.target, random_state=0
)
print("Size of trainig set:{} Size of test set:{}".format(
    X_train.shape[0], X_test.shape[0]
))

# パラメータグリッドの設定
param_grid_svm = {'gamma':[0.001,0.01,0.1,1,10,100],
                       'C':[0.001,0.01,0.1,1,10,100]}

from sklearn.model_selection import GridSearchCV
grid_search=GridSearchCV(SVC(),param_grid_svm, cv=5)

grid_search.fit(X_train, y_train)

print("Best parameters:{}".format(grid_search.best_params_))
print("Best cross-validation score:{}".format(grid_search.best_score_))
print("Best estimator:\n{}".format(grid_search.best_estimator_))

```




結果

```
Size of trainig set:112 Size of test set:38
Best parameters:{'C': 10, 'gamma': 0.1}
Best cross-validation score:0.9731225296442687
Best estimator:
SVC(C=10, break_ties=False, cache_size=200, class_weight=None, coef0=0.0,
    decision_function_shape='ovr', degree=3, gamma=0.1, kernel='rbf',
    max_iter=-1, probability=False, random_state=None, shrinking=True,
    tol=0.001, verbose=False)
```
Cは10,gammaは0.1がよいとわかりました。
せっかくなので可視化してみましょう。

```python
import pandas as pd
import numpy as np
import mglearn

results=pd.DataFrame(grid_search.cv_results_)

scores=np.array(results.mean_test_score).reshape(6,6)
mglearn.tools.heatmap(scores, xlabel='gamma', xticklabels=param_grid_svm['gamma'],
                      ylabel='C',yticklabels=param_grid_svm['C'],cmap='viridis')
```


結果

![heatmappp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604787/977910af-dad9-ad50-f154-c1a40e17a5d5.png)


ほかのパラメータに対しても可視化できました。


参考文献

Pythonではじめる機械学習――scikit-learnで学ぶ特徴量エンジニアリングと機械学習の基礎
Vue CLI導入メモ

#1.Node.jsのインストール

###1. Homebrewのインストール
ターミナルに下記のコマンドを打ち込んでMacOS用のパッケージマネージャー「Homebrew」をインストールする。

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

###2. nodebrewを使ってNode.jsをインストールする
下記のコマンドでNode.jsのバージョン管理ツール「nodebrew」をインストール

```terminal:nodebrewのインストール
$ brew install nodebrew
```

nodebrewを使って安定版のNode.jsをインストールし、有効化

```terminal:Node.jsのインストール
#安定版のインストール
$ nodebrew install-binary stable

#インストール確認
$ nodebrew list

v16.12.2

current: none

#安定版を有効化
$ nodebrew use stable
```

###3.環境変数の設定
nodebrewのsetupでパスを確認

```terminal:環境変数設定
#nodebrewのセットアップ
$ nodebrew setup

Fetching nodebrew...
Installed nodebrew in $HOME/.nodebrew

========================================
Export a path to nodebrew:

export PATH=$HOME/.nodebrew/current/bin:$PATH
========================================
```


ターミナルでzshを使っている場合、「~/.zshrc」に上記の`export PATH=$HOME/.nodebrew/current/bin:$PATH`を追記して保存

最後にターミナルで下記を実行

```terminal:環境変数設定の適用
$ source ~/.zshrc
```

#2.VueCLIプロジェクトの作成
###1.VueCLIのインストール

```terminal:VueCLIのインストール
$ npm install -g @vue/cli
```

###2.VueCLI新規プロジェクトの作成
任意のプロジェクトフォルダに移動して下記を実行

```terminal:新規VueCLIプロジェクト作成
$ vue create プロジェクト名
```

#3.VScodeとGithub連携
###1.GithubのリモートリポジトリにSSHキーを追加
[ここの記事を参照](https://qiita.com/suthio/items/2760e4cff0e185fe2db9)

###2.VScodeとの連携
VScodeでプロジェクトフォルダを開き、ターミナルウィンドウを開いて下記のコマンドを実行

```terminal:リモートリポジトリの設定
$ git remote set-url origin SSH版リポジトリURL
```


#4.その他
リモートからcloneするときはnode_moduleを下記のコマンドでインストールする

```terminal:プロジェクトのセットアップ
$ npm install
```
SNSのブランドカラーとロゴのダウンロードURL（2020年4月）

シェアボタンを自作したついでにサービスのカラーコードとロゴのURLをまとめておく。
（毎回調べるの面倒なんですよね…）

## Twitter

`#1DA1F2`

[Twitterのブランドリソース](https://about.twitter.com/ja/who-we-are/brand-toolkit)

## Facebook

`#3b5998`

[Facebook Brand Resources](https://ja.facebookbrand.com/facebookapp/assets/%E3%80%8Cf%E3%80%8D%E3%83%AD%E3%82%B4/)

## LINE

`#00b900`

[LINE APP ICON GUIDELINE](https://line.me/ja/logo)

## はてなブックマーク

`#00a4de`

[素材集 - 株式会社はてな](https://hatenacorp.jp/press/resource)

## Pocket

`#d3505a`

[Press | Pocket](https://blog.getpocket.com/press/)
Djangoにおけるモデル

# はじめに

ここでは、Djangoのモデルの基本について解説します。


# models.pyの設定

```python:models.py
from django.db import models


class SampleModel(models.Model):
    # id = models.AutoField(primary_key=True)
    char_sample = models.CharField(max_length=200)
    char_with_null = models.CharField(max_length=10, blank=True, null=True)
    char_options = models.CharField(choices=(('one', 1), ('two', 2)))
    text_sample = models.TextField()
    bool_sample = models.BooleanField(default=False)
    datetime_created = models.DateTimeField(auto_now_add=True)
    datetime_updated = models.DateTimeField(auto_now=True)
    date_sample = models.DateField()

    def __str__(self):
        return self.char_sample
```

## Primary key

primary keyは明示しなくても、自動的に設定されます。
ビューなどでは、`pk`などといった形で参照することができます。


## CharField

文字を入力するフィールドです。HTMLタグでは`<input type="text">`に対応します。
`max_length`（最大文字数）は必ず明示する必要があります。
また、`blank=True`とすると、バリデーション時にblankを許容し、`null=True`とすると、データ登録時にnullが許容されます。
`blank=`や`null=`は、他のフィールドでも使うことができます。


## TextField

こちらも文字を入力するフィールドです。HTMLタグでは`<textarea>`に対応するもので、大量の文字も入力することができます。


## BooleanField

真偽値を受け付けるフィールドです。
`default=False`とすると、データ登録時に指定がなかった場合は`False`として扱われます。
`default=`は他のフィールドでも使うことができます。


## DateTimeField

日時を入力するフィールドです。
`auto_now_add=True`とすると、最初の1回だけそのタイミングの日時を登録し、その後は更新されません。
`auto_now=True`とすると、登録タイミングの日時が自動的に更新されます。


## DateField

日付を入力するフィールドです。


## __str()__関数

最後の`__str__`関数は、管理画面でモデルを参照するときに、レコードの名前をprimary keyではなく、指定したフィールドをタイトルとして参照するために書いています。


# admin.pyの設定

```python:admin.py
from django.contrib import admin

from .models import SampleModel


admin.site.register(SampleModel)
```

管理画面でモデルを参照するために、`admin.site.register(モデル名)`を追記します。


# まとめ

ここでは、モデル関連の設定について解説しました。
次回は、ビュー関係について解説する予定です。
ベジェ曲線を考えてみる

# はじめに

以前の投稿（[ベジェ曲線を描いてみる](https://qiita.com/Rahariku/items/295b1062b77ed9c96d9c)）を同僚に見せたところ、「制御点にかけるパラメータの式が理解できませんでした。。。」と言われました。

ベジェ曲線は以下の式で表現されますが、確かに数式の各部品ははどのように作用するのかはっきり答えれませんでした。:sweat_smile:

```math
P(t) = \sum_{i=0}^{N}B_{N,i}(t)Q_i \tag{1}
```
```math
B_{n,i}(t) = \begin{pmatrix}n\\i\end{pmatrix}t^i(1-t)^{n-i}　\tag{2}
```

なので、一つ一つちょっと詳しく確認してみます。

# ベジェ曲線を考える

流れとしては、数式$(1)$を分解して各項がどんな作用があるか確認します。
また、数式だけではよくわからないので具体的に値を入れて計算結果を確認していきます。
それでは確認していきましょう。

## 二項係数
式$(2)$に使われている2項係数についてです。
$N$個の中から$k$個を選ぶ時の組み合わせ数で、$N$は制御点数で$k$は制御点のインデックスです。

```math
\begin{pmatrix} n\\k \end{pmatrix} = {_n\mathrm{C}_k=\frac{n!}{k!(n-k)!} } \tag{3}
```

具体的に数値を入れて計算してみます。
- $N=3$の場合

```math
{_3\mathrm{C}_0=1},　 
{_3\mathrm{C}_1=3},　
{_3\mathrm{C}_2=3},　
{_3\mathrm{C}_3=1}
```

- $N=4$の場合

```math
{_4\mathrm{C}_0=1},　
{_4\mathrm{C}_1=4},　
{_4\mathrm{C}_2=6},　
{_4\mathrm{C}_3=4},　
{_4\mathrm{C}_4=1}
```
このように、二項係数の値は$k=0$から$k=N/2$へ向けて増加して、$k=N/2$から$k=N$に向けて減少する。
まぁ組み合わせ数なのでこのような結果になりますね。
これらの値が各制御点の係数として掛かってくることで、第1制御点$P_0$から中間の制御点へ向けて引っ張られ、最終制御点$P_N$へ向けて減衰していく様子を曲線形状に反映しているのだと思います。

試しに、ベジェ曲線の数式から二項係数部分を除外して曲線形状を描きました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536019/1490c25f-be64-16ee-b811-d12102254343.png)

第2, 3番目の制御点への重み付けがなく、始点から少し曲線を描いた後に直線的に終点へ向かっていることがわかります。

## パラメータ

パラメータ$t$はベジェ曲線を表現するための媒介変数で、1次元空間を0 - 1 の範囲で値をとります。
パラメータ空間上の$t$は写像関数$f(t)$を用いることで曲線が描かれる空間の座標へ変換されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536019/ce8aca7e-432f-9d08-d963-3214e25f258e.png)


この写像関数が数式$(1)$のことで、そこから係数と座標値をとると以下のパラメータについての式が残ります。

```math
g(t) = \sum_{i=0}^{N}t^i(1-t)^{n-i}　\tag{4}
```

これはどんな気持ちを表しているのでしょうか？
$(4)$はベルヌーイ分布の確率密度関数と似ているのですが、この投稿でその説明は控えておきます。
とりあえず実際に値を代入してどんな値になるか確認してみます。
ここで、$n$は制御点数-1で、i は制御点のインデックスです
- $t = 0.8$, 制御点数4の場合

```math
\begin{align}
g(0.8) &= 0.8^0*0.2^3 + 0.8*0.2^2 + 0.8^2*0.2 + 0.8^3*0.2^0 \\
       &= 0.008 + 0.032 + 0.128 + 0.512
\end{align}
```

- $t = 0.5$, 制御点数4の場合

```math
\begin{align}
g(0.8) &= 0.5^0*0.5^3 + 0.5*0.5^2 + 0.5^2*0.5 + 0.5^3*0.5^0 \\
       &= 0.125 + 0.125 + 0.125 + 0.125
\end{align}
```

- $t = 0.2$, 制御点数4の場合

```math
\begin{align}
g(0.8) &= 0.2^0*0.8^3 + 0.2*0.8^2 + 0.2^2*0.8 + 0.2^3*0.8^0 \\
       &= 0.512 + 0.128 + 0.032 + 0.008
\end{align}
```

値を見てみると、$t$の値が大きければ終点側の項、$t$の値が小さければ始点側の項の値が大きくなっていることがわかります。
これは、パラメータ$t$の値によってどの制御点の座標値を強く反映するかを表していると思います。

## まとめると

最終的には数式$(1)$の通り、この計算結果と二項係数、制御点ベクトルの積和を計算してベジェ曲線上の1点が決まります。

つまり、ベジェ曲線上の1点は以下の図のように原点から制御点への各ベクトルを式$(3),(4)$で重み付けして足し合わせることによって求めています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536019/a5ad2b8f-6c2f-4aa4-b097-8c6cb8f625b7.png)

# おわりに

ベジェ曲線の数式について、各計算がどのようなことを表現しているのかを確認してみました。
今回は説明ばかりなのでプログラム載せてないですが、プログラムも後々Githubで公開していこかなと思います。
また、「～だと思う」とかぼやかしちゃってたりなど怪しい部分もありますが、間違ってるところなどあれば指摘は大歓迎です！

# 参考文献
- [3次元形状処理入門](https://www.amazon.co.jp/3%E6%AC%A1%E5%85%83%E5%BD%A2%E7%8A%B6%E5%87%A6%E7%90%86%E5%85%A5%E9%96%80%E2%80%953%E6%AC%A1%E5%85%83CG%E3%81%A8CAD%E3%81%B8%E3%81%AE%E5%9F%BA%E7%A4%8E-Information-Computing-%E4%BB%8A%E9%87%8E-%E6%99%83%E5%B8%82/dp/4781910483)
GitHub+Nuxt.js+NetlifyでNintendo Switchの抽選・販売情報を一覧サイトを作ってみた

# 作ったもの
Nintendo Switch欲しかったんです。でも、日々ニュースで抽選や販売の情報は更新されるものの、更新が多すぎて同じ情報を何回も何回も見ることになって来てしまっています。

今日もSwitchの抽選販売の情報出てたのかー。
あれ？これ昨日見たやつと同じじゃん。っていうか出荷情報だけで抽選開始とかじゃねえじゃん…。

などなど、情報がかなり見づらい情報だったのでまとめたページを作ってみました。

![switch-calendar.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77514/100eedbf-da35-a7af-4722-4089608d7a23.png)


# 使用技術
 - フロントエンド: Nuxt.js + Vuetify
 - ドメイン: お名前.com
 - リポジトリ: GitHub
 - サーバー: Netlify

# 参考にした情報
それぞれの技術については、既に素晴らしい解説記事がいろいろな所で書かれているため、その情報をまとめる形とさせて頂きます。
主にデプロイ周りについての情報が中心となります。


・ローカルを汚さないNuxt開発環境構築
[【VSCode Remote】10秒でNuxt環境を構築【脱WebStorm】](https://qiita.com/relu/items/defde8de8c4d21af662f)

・Nuxt.js×GoogleTagManagerでの計測設定
[Nuxt SPAのPVを @nuxtjs/google-tag-manager を利用して計測する](https://tech.actindi.net/2018/11/02/084447)

 
・GitHubでpushしたらNelifyで自動ビルド・サイト更新をする設定
[GitHubとNetlifyで静的サイトをホスティングするまでの流れとやり方まとめ！](https://daikimochizuki.com/netlify-static-site/)

・独自ドメイン設定
[Netlify にお名前.com で取得したドメインを設定する](https://contentful-explore.netlify.app/how/netlify-domain-setting)

・SearchConsoleの連携設定
[お名前.com: TXT レコード – G Suite 管理者 ヘルプ](https://support.google.com/a/answer/1659753?hl=ja)
RAK5205 LoRa Tracker Board用　モバイルケースを作ったよ

RAK811 LoRa Tracker Board用のケースを作ったよ
の続きとして、RAK5205 LoRa Tracker Board用のケースを作りました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/e4c3b733-420b-fec7-2d29-68a8b3ba5bc3.png" alt="" width="300" height="">
RAK5205とRAK811 TrackerBoardです。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/fc5f884d-1094-50d2-c398-89b800288c99.jpeg" alt="" width="1000" height="">

組み立ては、Lipoバッテリーを両面テープで止めています。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/7e3be90d-b7a1-81bd-65f6-777b4d16efe6.jpeg" alt="" width="1000" height="">

上蓋の中に8㎜程度のバッテリーを搭載可能です。
蓋は2種類用意しています。
たいていのLipoバッテリーは薄いものでも入ります(参考400mAh）が、
バッテリーの膨張を考慮した場合は、厚みの厚い方をご使用ください。

3DデータはGithubからダウンロードください。
https://github.com/taisirou/RAK5205-MobileCase

使用部品
タッピングネジ
φ2　3本(長さは2種類）
# Vagrant環境でMySQLに接続できない時

# Vagrant環境でMySQLに接続できない時


#### Vagrantを使った仮想サーバーの中のMySQLが接続できないので困った。
---


ホスト環境下で接続コマンドを実行すると

```
 mysql -u root -p
```

普通に接続可能だが、

```
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 48
Server version: 5.7.29 Homebrew

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>
```

同じことをVagrantの中でやってみる

```
$vagrant ssh
//　仮想サーバーに入る

$mysql -u root -p
// サーバー内でMySQLに接続

```

すると

```
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
```
こんな感じでエラーが出る。
困った。
完全リモートで新卒研修の講師をやってみた

こんにちは。@illyponです。
カレンダーを振り返ってみると2月からリモートワークをする日を増やしていったようで、
もうすぐリモワ歴3か月と言えそうです。だいぶ自宅設備が強化されました。

さて、今週でちょうど私が講師として担当する領域の新卒研修が終わったところでして、
5時間×4日間の受け持ちはなかなかにタフでした笑

今回は講師陣も新卒社員も全員自宅からMeetに参加して行うはじめてのケースとなりましたが、
その中で大事だと思ったポイントをQiitaにもフィードバックしたいと思います。
ご参考になったら幸いです。

# ①Good & New を毎日行う

アイスブレイクの手法の一つである[Good & New](https://note.com/smartcamp_design/n/n6b51611f7173)を毎日行いました。
工夫した点は以下の通りです。

- 流れを作るために講師から先にやる
- しゃべる人は必ずカメラをその時だけONにする
- どんな話をしたのかはGoogleスプレッドシートに残して全社共有
- ついつい長話をしてしまう性格の人もいるが責めないように

もしこれをやらなかったら、なかなか新卒社員の人柄を把握できなかっただろうと思います。
リモートでやっているからこそ、アイスブレークが大事になってきますね。
雰囲気づくりには全力を注いだほうがよさそうです。

# ②講師側から指名をして無理やり話をさせる

リモートだと本来積極的な性格だったとしても新卒社員からの質問やリアクションはほとんど出てきません。
また、あまりにも講師だけが話していると、話しているほうも聞いているほうもつらくなってきます。
これをどうにかするため、講師側から指名をして無理やり話をさせることを一定時間ごとに繰り返すのが効果的でした。

- 新卒社員リストをもとに全員をまんべんなくあてるのが大切
- 「何か質問ある？」という聞き方は、本当に質問がない人もいるのであまりよくない
- 「一緒に受講しているほかのグループやほかの人のワークショップ成果を見て気づいた点ある？」という感じで問いかけると、かなりたくさん話してくれるし退屈しないのでおすすめ
- 「講師の説明に対して相槌をうつだけの役割」を指名して与えるのも効果的（実際やってみた）
- 講師はちゃんとリアクションを大きめにとる、拍手をするなどを忘れずに

# ③駆け足で講義しない、無理に詰め込まないこと

リモートでの研修はF2Fでの研修と比べて段取りに時間がかかるので、従来の感覚でカリキュラムのタイムテーブルを作ってしまうと、基本的に予定時間に収まらなかったです。そこで開き直って以下の対応をしました。

- 時間通りにやるのではなく、納得いくまでやって、タイムテーブルは動的に変更する
- 実際に優先度の低い講義は講師陣で相談の上、キャンセルしました
- リモートでの研修はうまくできなくて当然なので、講師は時間通りに進められないことを後ろめたく感じないようにする

# ④休憩は講師側が意識して頻繁にとる

リモートなので各自ご家庭で勝手にいい感じに休んでくださいと言いたいところだが、実際にはかなり難しいようです。
講師の側からこまめにたくさん休憩時間を取るようにアナウンスすることが必要だと思いました。
以下が実際にやってみてちょうどよさそうな時間の目安です。

- 20分続けてやったら5分
- 30分続けてやったら10分
- 40分続けてやったら15分