OmniAICreator/Qiita-1.07M huggingface dataset:
Composerとか入れたくないので簡単に使えるフレームワークを作った

そういえば僕も3ヶ月くらい前にComposerとかに依存したくなくて1ファイルで完結するフレームワークを作ってた。ソースコードは[zonuexe/hogephp](https://github.com/zonuexe/hogephp)にある。

こういう雰囲気でコードが書ける。

```index.php
<?= (require __DIR__ . '/../Hoge.php')(function (Hoge\Framework $php) {
    $php->get('/', function () { ?>
<!DOCTYPE html>
<html>
<title>Hoge index</title>
<h1>The Hoge PHP Framework</h1>
</html>
    <?php });
}) ?>
```

トップページのルーティングしか定義していないが、これで起動スクリプトのコード全部だ。ほかにディスパッチ処理などのボイラープレートは要らない。

たわむれに作ったものなのでセキュリティは万全に考慮できているわけではない。

## コンセプト

 * フレームワーク本体は1ファイルで完結する
 * ユーザーに無駄なボイラープレートは書かせない
 * 副作用を容易に分離可能にし、ユニットテスト可能にする

最後の項目はまだ実装してないのだけれど、実際簡単にできる。

## ファイル配置

```
.
├── Hoge.php ← フレームワーク本体
└── public ← ドキュメントルート
    ├── .htaccess ← Apacheの設定ファイル
    ├── favicon.ico ← 静的ファイル
    └── index.php ← 起動スクリプト
```

PHPのビルトインHTTPサーバで起動するには`php -S localhost:3939 sample/index.php -t sample`だ。

## テンプレートエンジン

そんなものはない。PHPはテンプレートエンジンだ。

## ルーティング

`GET /phpinfo` というルーティングを追加したければ、こうする。

```php
    $php->get('/phpinfo', function () {
        phpinfo();
    });
```

ルーティングに登録する関数は「HTMLを出力する」か「`[int $status, array<string,string|array<string>> $headers, string $body]`の形式の配列を返す」か、どちらか。

3ヶ月前に書いた時点ではだるかったので静的ルーティングしか対応していなかった。[超簡易ルーターを作成しました。](https://qiita.com/KuroPanda63/items/d205b08478cbcab52713#comment-b44845e24f4c945fd25b)の`*`を使ったパターンの書きかたがおもしろかったので、暇なときに真似しようと思う。

それはそうと、パラメータを埋め込める動的ルーティングも[半年くらい前に一度実装した](https://github.com/zonuexe/oiraphp/commit/18649aa99f927da4a7bb61d2f1f1f7d808e08a3d)らあまり難しくなかった。

## 今後の展望

 * PDOを統合して簡単に使いたい気がする
 * この形式ではPSR-7と同じく`setcookie`相当の操作がしにくいのでヘルパー関数を提供したい気がする

このまま忘れてしまう可能性も高い気がしますね。。。

## おまけ: いままで作ったやつ

 * [シンプルなルーティングがしたかった - Qiita](https://qiita.com/tadsan/items/bcaa14504d0ecdd9e096)
 * [インスパイヤされて掲示板を作りたくなった(3) - Qiita](https://qiita.com/tadsan/items/498710c5199349e6d7a8#_reference-326c292af150bcbdd31a)
 * [PHP構築メモ: ライブラリのデモ用PHPアプリ - Qiita](https://qiita.com/tadsan/items/607b1972ebddc274a3bc)
    * リバースルーティングの話とかもしてる
 * [DocCommentでPHPのユニットテストの書きやすさを劇的に改善する手法](https://devpixiv.hatenablog.com/entry/2016/10/25/093000)
    * リバースルーティングの話とかもしてる
 * [OiraPHP/riha-saru](https://github.com/zonuexe/oiraphp/tree/riha-saru)
 * [phperkaigi-golf](https://github.com/phppg/phperkaigi-golf/blob/master/app/routes.php)
    * これは[Aura.Router](https://github.com/auraphp/Aura.Router)に依存している
GitHub の「Fork」ボタンを「Fork is パクる」にする UserCSS

# User.css
CSSでは元のテキストが消せないので
『Fork is パクる』
で妥協

※2020/04/16(木) CSSのセレクタが誤っていたので修正。

```user.css
@-moz-document domain("github.com") {
form.btn-with-count[action$="/fork"] button::after {button::after {
    content:" is パクる";
}
}
```



# ~~元ネタ~~ パクリ元
パクリ元に敬意を評して載せます。
謝辞。

・GitHub の「Fork」ボタンを「パクる」に置き換える UserScript - Qiita
https://qiita.com/foooomio/items/27429f0b136d0debe25b
からネタを頂きました。
@foooomio さんに謝辞。


・Toshihide Ii (BitByte) @IiToshihide - Twitter
https://twitter.com/IiToshihide/status/1246487047545556992
を参考にさせて頂きました。
@IiToshihide さんに謝辞。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">えっ、丸パクリじゃん。<br>せめてどこから取ってきたかぐらい<br>もっと書くべき。<br>学生だからって、何でも許されるわけと<br>ちゃうやろ・・・<br>高専生って基本こういうイメージ、怖い・・・<a href="https://t.co/YKoOvgGplg">https://t.co/YKoOvgGplg</a></p>&mdash; Toshihide Ii (BitByte) (@IiToshihide) <a href="https://twitter.com/IiToshihide/status/1246487047545556992?ref_src=twsrc%5Etfw">April 4, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
Arch Linuxで音楽CDのリッピング(取り込み)

AsunderというCDリッパーを使います。

# インストール方法

```bash
$ sudo pacman -Syuu asunder
```

# 使い方

1. `asunder`を起動する。

    ```bash
    $ asunder
    ```

2. 音楽CDをCDドライブに挿入する
3. 数秒待つとアーティスト名とタイトルが認識される
4. 設定(Preference)ボタンを押してエンコードから好きなものを選び(迷ったらMP3にチェック入れる)、OKを押す
4. 右下の取り込み(Rip)ボタンを押す

取り込みが終わると、ホームディレクトリにアルバム名のディレクトリができていると思います。
Laravel 自作コマンド内でログ出力

```
    public function handle()
    {
        $this->info('infoです');
        $this->error('errorです');
        $this->line('lineです');
    }
```

結果
<img width="83" alt="スクリーンショット 2020-04-07 2.37.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278474/629b6f90-eecf-4253-8af1-39ee0d1b46bb.png">

参照
https://laravel.com/docs/7.x/artisan#writing-output
RustでgRPCで簡易マルチプレイサーバー書いてUnityで動かしてみた

こんにちは、あんはるです！

コロナで暇なので、紹介してなかったプロジェクトを紹介したいと思います.

突然ですけど、このGIF見てみてください.
右のウィンドウと左のウィンドウはサーバー経由で座標を共有しあっています〜
これが簡易マルチプレイです！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188304/b210aa24-5ba0-27fb-5780-b4b56270f7f2.png)

# きっかけ・目的

荒野行動を始めると、100人のユーザーがリアルタイムに走っててすごいなぁと思いました。どうやったらこんなサーバ作れるのだろうという興味がきっかけです。

とりあえず、自前で実装してみたい！となったのでやってみます。

#　このプロジェクトの構成

バックエンド 

- gRPC
- MongoDB

フロントエンド

- Unity



です。
上のデモはローカルで完結させてます。

## なぜgRPC？
Unityで、リアルタイムに処理したいという時に、[MagicOnion – C#による .NET Core/Unity 用のリアルタイム通信フレームワーク](https://tech.cygames.co.jp/archives/3181/)がよく記事に書かれています。

MagicOnionの通信は、gRPCを用いています。

また、Protocol BufferでRPCの定義をするだけで、ホスト、クライアントのコードが生成されることに無駄のなさを感じでクールだなと感じだので、使ってみたいと思いました。

## なぜMongoDB?

速度が求められるので。


# マルチプレイサーバー

ソースコードは、https://github.com/anharu2394/multiplay-grpc-server
### Rustで書いてみた

このプロジェクトを書いた当時、一番Githubスター数が多かったgrpc-rsを使いました。


Protocol Bufferでマルチプレイサーバーの使用を定義。
UserPositionは、ユーザーのidとどこにいるかを表しています。
ConnectPositionで双方向ストリーミングで座標を同期しています。

```proto:multiplay.proto
syntax = "proto3";
package anharu;

service Multiplay {
  rpc GetUsers(GetUsersRequest) returns (stream GetUsersResponse);
  rpc SetPosition(stream SetPositionRequest) returns (SetPositionResponse);
  rpc ConnectPosition(stream ConnectPositionRequest) returns (stream ConnectPositionResponse);
}

message GetUsersRequest {
  string room_id = 1;
}

message GetUsersResponse {
  repeated UserPosition users = 1; 
}

message UserPosition {
  string id = 1;
  double x = 2;
  double y = 3;
  double z = 4;
}

message SetPositionRequest {
  string id = 1;
  double x = 2;
  double y = 3;
  double z = 4;
}

message SetPositionResponse {
  string status = 1;
  string id = 2;
  string error = 3;
}

message ConnectPositionRequest {
  string id = 1;
  double x = 2;
  double y = 3;
  double z = 4;
}

message ConnectPositionResponse {
  repeated UserPosition users = 1; 
}

service User {
  rpc Create (CreateUserRequest) returns (CreateUserResponse);
}

message CreateUserRequest {
  string name = 1;
}
message CreateUserResponse {
  string id = 1;
}
```

そして、protoから生成されたコードを使って、それぞれ実装していきました。


## マルチプレイクライアント

ソースコードは、　https://github.com/anharu2394/multiplay-grpc-client
Unityなのでc#で書いてます。

Unityはそもそも、gRPCを使う環境を整えるのに時間がかかりました...

https://note.com/npaka/n/n050b1aba7772
これを参考にすると分かりやすいと思います！

ストリーミングして、サーバーから座標が送られてくるごとに、キャラクターの座標を更新するという感じでやりました！

サーバーの動作確認がしたいだけなので、UIや見た目などは超手抜きですが、ジャンプのアニメーションをつけたり少しゲームっぽくして見ました！

#　まとめ
おそらく、本番環境では使い物にはならないかもしれませんが、ローカルの中でもgRPCの双方向ストリーミングが体感できてよかったです〜〜

RustもgRPCも頑張ります〜〜！
[Rails]JS(jquery)が動かない　初歩的ミス

jquery使用の際、同じコード引用下のに別アプリで
***なぜか動かない。***
と言う原因の一例です。

##確認した場所
■Gemfile→jqueryがインストールされているか
■application.jsにjqueryの記述があるか。
■js内に`turbolinks:load`が入っているかどうか

##原因
コメントアウトされているコードの並び順
＊これ、すごく大事でした。
初歩の初歩でテキストに書いてあった気がする。。。


`//= require_tree .`が、最初はこの位置におりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540209/a3e2de31-3044-e6df-1a06-69c083689698.png)
***移動！！最下部へ***
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540209/81a43b90-4e17-c8df-f08b-a8275e0e2dcb.png)
***こちらでjqueryが動かない問題は解決いたしました。***

##require_tree .とは？
[参考資料](https://railsguides.jp/asset_pipeline.html)によると以下の記載があります（ちなみに`require_tree`はcssにも記述あります）
そして`アセットパイプライン`と言うそうです。
application内にあるcssやjsの読み込み順を司るものです。

```
require_treeディレクティブは、指定されたディレクトリ以下の
すべての JavaScriptファイルを再帰的にインクルードし、出力に含めます。
このパスは、マニフェストファイルからの相対パスとして指定する必要があります。
require_directoryディレクティブを使用すると、指定されたディレクトリの
直下にあるすべてのJavaScriptファイルのみをインクルードします。
この場合サブディレクトリを再帰的に探索しません。
```
日本語難しい(´・ω・)
少し簡単な説明

***require の部分は ディレクティブ （何種類かあります）***
`require_directory`
→与えられたディレクトリ以下のファイルを、
自身よりも前に挿入する。
順番はアルファベット順（さらに大文字→小文字）になる

`require_tree`
→require=directory と同じ動きをするが、再帰的に読み込む
読み込みはコードの 上から順番に 読み込まれます。

上記より考えると、`require_tree`より下に書かれていたjqueryが読み込まれなかったため動かなかった（と、解釈いたしました。）

[備考]
require_treeには引数として与えられたディレクトリ以下のファイルをアルファベット順に全て読み込むという意味があります。
現在require_treeの引数には`.(ドット)`が渡されています。
引数`.(ドット)`はカレントディレクトリを表します。
つまり、この記述によってapp/assets/javascriptsというディレクトリにあるファイルは全て読み込まれることになります。

##参考ページ
[Rails のアセットパイプライン（Asset Pipeline）について](http://mizukmb.hatenablog.com/entry/2016/05/19/223802)

[RailsでCSSの読み込む順番を制御する方法](https://qiita.com/takish/items/c5f264577d2db75fd10c)

##終わりに
こちらは、個人的解釈をもとに解決した方法を備忘録として書いております。
プログラミング初学者ゆえ、
誤記や不備、アドバイス等ございましたら御指摘いただけると幸いです。
最後まで読んでいただきありがとうございます。
PowerShellでExcelの条件付き書式を設定する

PowerShellでExcelの条件書式を追加する処理のメモ

# スクリプト
``` ExcelFormatConditions.ps1
using namespace System.Runtime.InteropServices;
using namespace Microsoft.Office.Interop;

# -------------------------------
# Excel起動
# -------------------------------
Add-Type -AssemblyName "Microsoft.Office.Interop.Excel";

$ExcelApp               = New-Object -ComObject Excel.Application;
$ExcelApp.Visible       = $true;                      # Excel画面表示
$ExcelApp.DisplayAlerts = $false;                     # 警告メッセージ非表示
$WorkBook               = $ExcelApp.Workbooks.Add();  # Bookの追加処理

# -------------------------------
# テストデータ作成
# -------------------------------
# 1つ目のシート取得
$Sheet = $ExcelApp.WorkSheets.Item(1);

# 適当な値を設定
$Sheet.Range("A1:D5") = "=ROW() + COLUMN()";

# -------------------------------
# 条件書式の追加
# -------------------------------
# 書式追加１(3と一致するものに罫線)
$FormatCondition1 = $sheet.Range("A1:D5").FormatConditions.Add([Excel.XlFormatConditionType]::xlCellValue,[Excel.XlFormatConditionOperator]::xlEqual,3);
$FormatCondition1.Borders.LineStyle   = [Excel.XlLineStyle]::xlContinuous; # 罫線

# 書式追加２(5～7の間となるものを文字・背景色変更)
$FormatCondition2 = $sheet.Range("A1:D5").FormatConditions.Add([Excel.XlFormatConditionType]::xlCellValue,[Excel.XlFormatConditionOperator]::xlBetween,5,7); 
$FormatCondition2.Font.Bold            = $true; # 太字
$FormatCondition2.Interior.ColorIndex  = 6;     # 背景色黄色
$FormatCondition2.Font.ColorIndex      = 3;     # 文字色赤

# -------------------------------
# 条件書式の削除
# -------------------------------
# 1つ目の書式削除
$sheet.Range("A1:D5").FormatConditions(1).Delete(); 
# 全て削除
$sheet.Range("A1:D5").FormatConditions.Delete();

# -------------------------------
# 解放処理
# -------------------------------
$ExcelApp.Quit();
[Marshal]::ReleaseComObject($Sheet);
[Marshal]::ReleaseComObject($WorkBook);
[Marshal]::ReleaseComObject($ExcelApp);
```


# 引数の設定値

- 1つ目の引数(XlFormatConditionType)

|定数名|値|説明|
|:---|:--|:--|
|xlCellValue|1|セルの値が|
|xlExpression|2|数式が|
|xlColorScale|3|カラー スケール|
|xlDatabar|4|データバー|
|xlTop10|5|上から 10 個の値|
|xlIconSets|6|アイコン セット|
|xlUniqueValues|8|一意の値|
|xlTextString|9|テキスト文字列|
|xlBlanksCondition|10|空白の条件|
|xlTimePeriod|11|期間|
|xlAboveAverageCondition|12|平均以上の条件|
|xlNoBlanksCondition|13|空白の条件なし|
|xlErrorsCondition|16|エラー条件|
|xlNoErrorsCondition|17|エラー条件なし|


- 2つ目の引数(XlFormatConditionOperator)

|定数名|値|説明|
|:---|:--|:--|
|xlBetween|1|次の値の間|
|xlNotBetween|2|次の値の間以外|
|xlEqual|3|次の値に等しい|
|xlNotEqual|4|次の値に等しくない|
|xlGreater|5|次の値より大きい|
|xlLess|6|次の値より小さい|
|xlGreaterEqual|7|次の値以上|
|xlLessEqual|8|次の値以下|

3つ目と4つ目の引数は他の引数に合わせて設定。
(参考：[XlFormatConditionType](https://docs.microsoft.com/ja-jp/dotnet/api/microsoft.office.interop.excel.xlformatconditiontype?view=excel-pia)）
(参考：[XlFormatConditionOperator](https://docs.microsoft.com/ja-jp/dotnet/api/microsoft.office.interop.excel.xlformatconditionoperator?view=excel-pia)）
Python3.9の新機能(1) - 辞書型で和集合演算子が使えるようになる

## はじめに

2020年10月にリリースが予定されているPython3.9で新たに加わる変更を[Python3.9の新機能 (まとめ)](https://qiita.com/ksato9700/items/d5df9d36147796c86c77)という記事でまとめ始めました。その中で比較的分量のある項目を別記事に切り出すことにしましたが、その第一弾として辞書型で和集合オペレータを使えるようになる変更を取り上げてみたいと思います。



## 辞書型の統合

辞書型はPython組み込みの標準データ型の一つです。他の言語だとハッシュ型・マップ型・連想配列型など様々な呼ばれ方をしていますが、要は名前と値のペア (key-value pair)を格納するためのデータ型です。

この辞書型のデータ(d1, d2) が二つあり、それを混ぜ合わせて一つの辞書型データにすることを考えます。これまでも幾つかやり方がありました。

#### 1) `update`メソッドを使う

d1.update(d2)`とすれば統合された辞書型データがd1に上書き格納されます。もしd1をそのまま取っておきたい場合には

```python
e = d1.copy()
e.update(d2)
```

と一度コピーを作ってから`update`メソッドを呼ぶ必要があります。微妙に面倒ですね。

#### 2) 中身を取り出して並べちゃう

`{**d1, **d2}`として、それぞれの辞書型から中身のデータを取りだし、新たな辞書型に並べて返します。中間変数なしに統合した辞書型データを得られるけど、パット見で何やっているかわかりにくいですね。Pythonのオリジナルの作者の Guidoさんですら「こういうやり方あったって忘れてたよ」って言うくらい、わかりにくいです（笑）

#### 3) `collections.ChainMap`を使う

`collections`モジュールには `ChainMap`というクラスがあって、`dict(ChainMap(d2, d1))`とすると統合した辞書型データが得られる。ややこしいのは、上の例と違って、同じキーがあった場合、左側に来る方が優先されるということ。標準とは言え、`collections`モジュールをインポートしなければならないし、この方法もあまり直感的では無いですね。

#### 4) 辞書型のコンストラクタを使う

辞書型のコンストラクタで `dict(mapping, **kwarg)`というのがあるので、これを使って `dict(d1, **d2)`とすると統合した辞書型データが得られる。`**d2` とすることで`d2`の中身がキーワード引数として与えられて、第1引数の内容に追加されていきます(`d1`は変化しません) 。このやり方の問題は、`d2`の中身をキーワード引数として与えるので、キーが文字列な辞書型じゃないと統合できないことですね。



## 和集合演算子と辞書型

Set型で使われている演算子に`|`と`|=`があって、例えばこんな感じで使えます。

```python
>>> a = set((1,2,3))
>>> b = set((3,4,5))
>>> a | b
{1,2,3,4,5}
>>> a |= b
>>> a
{1,2,3,4,5}
```

二つの集合の「和」を計算するので、和集合演算子ですね。この和集合演算子を辞書型データの統合に使っちゃいましょうというのが、今回 3.9に入る予定の変更です。

仕様はとても単純で、Set型と同じように二つ辞書型データの和を取ります。Setと違うのはキーが重なった時の対応で、Setは重なっても2重カウントしなければ良いだけだけれども、辞書型の場合はキーだけじゃなく値もあるのでそれのどちらを採用するかが問題になる。今回の変更では「あと勝ち」つまり式の上で右側の方の値が優先されます。左から順番に重ね合わせて同じキーのものは上書きするイメージですね。

例で見た方が早いですね。

```python
>>> c = {'a': 1, 'b': 2}
>>> d = {'b': 3, 'c': 7}
>>> c | d
{'a': 1, 'b': 3, 'c': 7}
>>> d | c
{'a': 1, 'b': 2, 'c': 7}
>>> c |= d
>>> c
{'a': 1, 'b': 3, 'c': 7}
```

ここの `c | d`の結果と `d | c`の結果が違う（可換でない）というのは「和」の演算子としては気持ち悪いところですが、まあこういうものだと思うしか無いでしょう。

## まとめ

Python 3.9で辞書型に導入される予定の和集合演算子について [PEP-584](https://www.python.org/dev/peps/pep-0584/)の内容を元に解説してみました。これまで `dict.update`を使うことが多かったと思いますが、元の辞書型を壊しちゃうので、immutableな演算をわかりやすい記法で描けるのは色々と使い所があると思います。
BigBlueButtonでWEB会議システム構築

# はじめに

WebRTCを使ったWEB会議システムが無料で作れちゃうオープンソースWEB会議システム  [BigBlueButton](https://bigbluebutton.org/) をご紹介します。


## 機能

- WEB会議・WEBセミナー
- グループチャット
- 共有メモ
- 資料アップロード
- ホワイトボード
- デスクトップ共有

## メリット

- WebRTC対応のブラウザさえあればつながる
- HTML5対応なのでスマホやタブレットでも使える

## デメリット

- skype や zoom のような専用クライアントを使うタイプのものより通話品質が劣る
- 画面レイアウトのカスタマイズ性が低い

# 環境

- Ubuntu 16.04
- BigBlueButton 2.2
- Greenlight 2.5.6
- グローバルIPアドレスを持ったサーバー

# ！注意！

## スムーズに導入できるパターン

- サーバーのNICにグローバルIPアドレスを割り当てることができる
- IPv6が有効になっている

## スムーズに導入できないパターン

- AWS や Azure に代表されるIaaSのようにグローバルIPアドレスは持っていても、BigBlueButtonを導入するサーバーがプライベートIPアドレスしか持っておらず、NATされている場合
- IPv6が無効化されている または 仕様上利用ができない
- LXC/LXDコンテナを使っている場合

**(2020/4/27追記)**
サーバーのIPがプライベートアドレスで、ルーターやFirewallでグローバルIPアドレスにNATされているの場合は [Configure Firewall](https://docs.bigbluebutton.org/2.2/configure-firewall.html) にある設定変更をすれば使えるようになります。

**(2020/5/15追記)**
「[BigBlueButtonでWEB会議システムを構築＝NAT環境編＝](https://qiita.com/hatayan1126/items/df167125c1dd888ed934)」を書きました。


# 他システムとの連携ソリューション
mattermost や moodle は BigBlueButton プラグインがあるので簡単にAPI連携ができる。  

- オープンソースチャットツール [mattermost](https://mattermost.com/) + [BigBlueButton](https://github.com/blindsidenetworks/mattermost-plugin-bigbluebutton) プラグイン
- オープンソース学習管理システム(LMS) [Moodle](https://moodle.org/) + [BigBlueButtonBN](https://moodle.org/plugins/mod_bigbluebuttonbn) プラグイン

# そのた

~~- 現時点で Ubuntu16.04 のみ対応で、次期バージョン 2.3 で Ubuntu 18.04 に対応するっぽいです。~~

**(2020/7/22追記)**
バージョン 2.3-alpha-1 が出てました。
- https://github.com/bigbluebutton/bigbluebutton/releases
- https://docs.bigbluebutton.org/dev/dev23.html  

**(2021/9/7追記)**
Ubuntu18.04で動くバージョン 2.3 が出てました。
- https://bigbluebutton.org/2021/05/27/bigbluebutton-new-release-announcement/
- https://docs.bigbluebutton.org/2.3/new.html
初心者がスッキリわかるシリーズでJavaを学んでみた

# はじめに
プログラミング初心者のスッキわかるシリーズのレビューです。
これからJavaの勉強をする方の参考になれば幸いです。

##読んだ本
スッキリわかるJava入門　第3版
スッキリわかるJava実践編　第2版
スッキリわかるSQL　第2版
スッキリわかるサーブレット＆JSP入門　第2版

#スッキリわかるJava入門　
###**おすすめ度　◎**

###良かった点
新入社員の男の子が先輩社員と一緒にRPGゲームを作っていくという流れで学習が進む。コンパイルや実行など、プログラミングのプの字も知らないような初心者向けに丁寧に書かれており、とても分かりやすかった。
ページ数は７００ページを超えており、中々のボリュームだが、その分細かく、丁寧に解説してくれたのでスラスラと読むことができた。
理解が難しいと言われているオブジェクト指向を特に丁寧に解説しており、イメージを持ちながら学習することができた。
docojavaという開発環境を整えなくてもJavaを使える機能もあり、本を買っていきなりプログラミング学習を開始できるのも、この本の強みだと思う。
そもそもは、通販サイトやほとんどのまとめサイトでこの本はおすすめしていたことから、購入を決めたのだが、最初にこの本を買ってよかったと思っている。
###悪かった点
ない。
が、強いて言うなら本が分厚いので持ち運びには適さない。
あと、ページ数が多いので、薄い本を何冊もやって達成感を得たい派には合わないのかな、と。


#スッキリわかるJava実践編
###**おすすめ度　△**
###良かった点
スッキリわかるjava入門編の続編。
jarファイルの利用やジェネリクス、ファイル・データベースとのやり取りなど、入門編では書ききれなかった、（おそらく）実際の現場で多用するであろう技術を多く取り扱っていた。一つ一つが入門編よりも難しくなっており、一つずつ理解しながら丁寧にやっていたら、読むのに結構時間がかかった。が、以前よりもjavaでできることが増え、有意義な時間だったと思う。


###悪かった点
より実践的・応用的な内容を学べると思って購入したが、実際は
「javaではこれが大事だよ！」
「これも大事！」
「あと、これも！」
みたいな感じで、各章で関連性が薄い知識を小出し小出しにしたような。
java初心者の重要な技術まとめ、の本。
もちろん全部大事なのは分かってる。
が、そうなるとわざわざ”この本”を買う理由はないのかな、と。
あと、載っているサンプルコードがエラーを起こすことが数回あり、その都度ネットで原因を調べる必要があった。（そのおかげで、自分で調べる力がついた。）
本の内容自体はとても分かりやすいが、超おすすめ！ではないかな。

#スッキリわかるSQL　
###**おすすめ度　○**
###良かった点
今回読んだ4冊の中で、圧倒的に分かりやすかった。
実践的な技術はともかく、SQLの基礎自体がそこまで難しくないので、内容も比較的わかりやすくなっているんだと思う。（初心者の推測です）
また、”この本”では、javaと絡めてSQLを利用することは一切なかった。
他の3冊と”この本”は、関連性が薄いことから、SQLの基礎を勉強するなら別の書籍でもいいのかな、と思った。SQLは必要な技術なので何らかの形で勉強した方がいいとは思う。

##悪かった点
私は最初からPostgreSQLをインストールしていたので、一切使わなかったが、レビューによると、docoQLが使いにくいらしい。
といっても、上記2冊をやってからこの本をやれば、SQLのインストール自体はそこまで難しくないと思う。（本を進めると色々とインストールする機会がある）
あと、巻末の練習ドリル。全部やったらSQLのいい復習になると思う。
が、私は実際にデータベースを作って、データを入れてやりたい派なので、いちいちデータを打ち込むのがめんどくさくて、途中で投げました。



#スッキリわかるサーブレット＆JSP入門　
###**おすすめ度　◎**
###良かった点
実際にwebアプリケーションを作るところまでいきます。
上記3冊の中で一番達成感がありました。
すべての章に関連性があり、これまでの知識を結集してアプリケーションを作るので、”開発している感”が持てた。本のサンプルといえど、一から何かを作ることは大事だと思った。
Pleiades(プレアデス)というwebアプリケーション開発に必要なソフトのインストールする必要があるが、インストール方法やその操作方法など、この本の専用サイトで丁寧に解説しているので、心配ないと思う。



###悪かった点
ない。
ただ、サーブレット、jsp等のwebアプリケーションの知識・技術は奥がとてつもなく深くて、この本ではさわりの部分だけをやってるんだな、となんとなく感じた。
非再帰BFSでトポソから木DPをする

# 非再帰 BFS
Python で非再帰 BFS を書きます。ついでにトポロジカルソート（トポソ）もできます。トポロジカルソートを知らない人は適当に <a href = "https://www.google.com/search?q=%E3%83%88%E3%83%9D%E3%83%AD%E3%82%B8%E3%82%AB%E3%83%AB%E3%82%BD%E3%83%BC%E3%83%88"> ググって </a> ください。

トポロジカルソートを使うと、木 DP が簡単にできます。

## 目標
木の問題は基本的にトポソすればなんとかなります <font color = "a0a0a0"> （本当？） </font> 。みんな大好き 木DP もトポソ順に処理すればその都度 BFS / DFS する必要ないのでらくちんです。この記事では BFS で木のトポソを求めて、木 DP をやるのが目標です。

### 入力
まずは入力部分。1-indexed で辺リストを `X` に格納しています。

```test.py
N = int(input()) # 頂点数
X = [[] for i in range(N)] # 辺リスト
for i in range(N-1):
    x, y = map(int, input().split())
    X[x-1].append(y-1)
    X[y-1].append(x-1)
```

### BFS / トポロジカルソート
ここからトポソゾーン。
基本的には BFS です。別に DFS でもほとんどコード変わんないのでどっちでもいいけど。非再帰で BFS をするには deque を使うのが簡単です。順に各頂点を見て、その子リストを queue に追加します <font color = "a0a0a0">（通常、入力から作られるのは子リストではなく隣接頂点リストだと思います。この場合、隣接頂点リストのうち親でないものを子リストだと思えばよいです。また、追加のたびに、追加されたものの親を記録していきます） </font> 。追加は右から、取得は左からすることによって BFS になります。

```test.py
from collections import deque

P = [-1] * N # P[i] はiの親。iが根なら-1
Q = deque([0]) # queue。根にするやつを最初に追加
R = [] # トポロジカルソート
while Q:
    i = deque.popleft(Q)
    R.append(i)
    for a in X[i]:
        if a == P[i]: continue
        P[a] = i
        X[a].remove(i) # ☆☆☆
        deque.append(Q, a)

print("X =", X) # 子リスト
print("P =", P) # 親
print("R =", R) # トポロジカルソート
```

### 隣接頂点リスト から 子リスト に
ところで、隣接頂点リストより子リストになっている方が使いやすくないですか？私は使いやすい気がします。つまり、親に伸びる辺を削除したいです。これはコード中 ☆☆☆ のところで remove 関数で行っています。
勘のいい方は remove の計算量が気になるかもしれません。 Python の remove は O(要素数) なので2乗にならないか心配ですが、辺の数の合計は O(N) なので、全体の計算量は O(N) から変わりません。

でも remove はあまり行儀がよくない気がしますね。

### 木 DP
木 DP の定義はよく知らないのですが、根からまたは葉から順に決めていくような DP でしょうか。
具体的には、頂点 $i$ が $k$ 個の子 $j_0,\ ...,\ j_{k-1}$ を持つときに、 `dp[i]` が `dp[j]` たちから計算できるときにこれを使います。ここでは簡単のため `dp[i]` を <font color = "FF0000"> 頂点 $i$ を根とする部分木のサイズ </font> として木 DP をします。この場合、 `dp[i] = 1` で初期化して、各 i の子 j について `dp[i] += dp[j]` をすればよいです。ただし更新の順番が大事で「葉」側から順に処理を行う必要があります。この場合、トポソを逆順に見ればよいです。簡単ですね。逆に「根」側から処理したいときはトポソを前から見ればよいです。


```test.py

dp = [1] * N
for i in R[::-1]: # トポロジカルソートを逆順に（「葉」側から処理）
    for j in X[i]:
        dp[i] += dp[j]
```

### 全方位木 DP

気が向いたら全方位木 DP も書きます。


2020/04/08 追記
<a href = "https://qiita.com/Kiri8128/items/a011c90d25911bdb3ed3"> 書きました </a>
iOS app開発 習得日記 (3) 

(https://qiita.com/gomi_ningen/items/4e0e5bd98f08c4bcf93d)

続き

4.6.2 
まで行くが、つまづく

エラーが理解できない

viewDidLoadにdelegateプロパティを設定するところ
```
addTaskTextField.delegete = self
```
ここで、Use of unresolved identifier とでる。
tableViewと同じように宣言しなければならないのはわかっているのだが、
どうすればいいのか？
接続するのか？

誰か教えてください！！


```
import UIKit
import Foundation

class TODOMainViewContorller: UIViewController {

    @IBOutlet weak var dismissButton: UIBarButtonItem!
    
   @IBOutlet weak var tableView: UITableView!
    
    @IBOutlet weak var textField: UITextField!
    
    fileprivate var tasks:[String] = ["go to school", "go back home"]
    
    override func viewDidLoad() {
        super.viewDidLoad()
        dismissButton.target = self
        dismissButton.action = #selector(TODOMainViewContorller.dismissButtonTapped(_ :))
        tableView.delegate = self
        tableView.dataSource = self
        
        addTaskTextField.delegete = self
        
    }
    
    @objc func dismissButtonTapped(_ sender: Any) {
        dismiss(animated: true, completion: nil)
    }
    
}
    
    extension TODOMainViewContorller: UITableViewDataSource {
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return tasks.count
    }
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            if let cell = tableView.dequeueReusableCell(withIdentifier: "TODOMainViewTableCell") as? TODOMainViewTableCell {
                cell.taskLabelText = tasks[indexPath.item]
                return cell
            } else {
                return UITableViewCell()
            }

        }
        
}

extension TODOMainViewContorller: UITableViewDelegate {
    
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 1
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        NSLog("selected row at: \(indexPath.item)")
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 30
    }

    func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        return true
    }
    
    func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
        let action = UITableViewRowAction(style: .destructive, title: "Delete") {[weak self] _,_ in self?.tasks.remove(at: indexPath.item)
            tableView.reloadData()

    }
        return[action]
}
    
}

extension TODOMainViewContorller: UITextFieldDelegate {
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        if let task = textField.text, task != "" {
            tasks.append(task)
            textField.text = ""
            tableView.reloadData()
        }
        return true
    }
}
```
GitHubでゼロからコードを公開するまで【初心者】

#はじめに
　この記事ではwindows環境において、Git、GitHubを用いたコードの公開までの流れをまとめます。
#GitHubのアカウント作成
・GitHubの公式からアカウントを作成する (https://github.co.jp/)
#Gitのダウンロード
・「git for windows」の公式サイトよりインストーラーのダウンロードを行う(https://gitforwindows.org/)
・インストーラーの指示に従いダウンロードを完了させる
　ここからはダウンロードしたファイル内の「Git Bash」を使用していきます。
#Gitの設定
・Git Bashを起動し、まずはGitで使用する名前とメールアドレスを設定する

```
$ git config --global user.name "名前"
$ git config --global user.email "メールアドレス"
```

#SSH Keyの設定
・次のように実行してSSH Keyを作成する

```
$ ssh-keygen -t rsa -C "メールアドレス"
```

```
Generating public/private rsa key pair.
Enter file in which to save the key
(Users/ユーザーネーム/.ssh/id_rsa):
```

・上のようなメッセージが出たら、Enterキーを押す
・その後にパスワードを入力する (このパスワードは後に使用するので忘れないようにする)
　パスワードの入力後、randmart image が表示されたら成功です。
#公開鍵の登録
・GitHubのアカウント → setting → SSH and GPG keys →SSH keys よりNew SSH Keys ボタンを押す
・タイトルをつけ、Keyの部分には公開鍵の内容をコピー&ペーストする
　公開鍵の内容は以下のようにして参照できます。

```
$ cat /c/Users/ユーザーネーム/.ssh/id_rsa.pub
ssh-rsa (公開鍵の内容)= メールアドレス
```
・登録が完了するとメールが届く
　以上の設定を行えば、先ほど自分で設定したパスワードを用いて、GitHubに向けた認証と通信が可能になります。

・次のように実行する
　下のようなメッセージが表示されたら成功です。

```
$ ssh -T git@github.com
```
```
Hi 名前! You've successfully authenticated, 
but GitHub does not provide shell access.
```

#コードの公開
 コードの公開は次の3ステップで完了します。
###①clone
・GitHubでリポジトリを作成する
・cloneする際の指定パスをSSH形式で控えておく

・次のように実行する。

```
$ git clone 指定パス
$ cd リポジトリ名
```

完了すると、PC内(ローカル)にフォルダが生成されます。

###②commit
・公開したいファイルまたはフォルダを、クローンしたローカルのフォルダに移動させる
・次のように実行する、任意のメッセージの箇所は"Add ファイル名"などとする

```
$ git add ファイル名、または、"フォルダ名"
$ git commit -m "任意のメッセージ"
```

###③push
・次のように実行する

```
$ git push 
```

この操作によってGitHub側のリポジトリが更新されます。

これでGitHubにコードが公開されました！
Moq で ref を持つメソッドの参照渡しの値をモック化する

# 概要
C# のモックライブラリ Moq を用いて ref を持つメソッドの参照渡しの値をモック化する方法になります。

# 参考情報
丁寧に解説されていたため、参考になりました。
https://dontcodetired.com/blog/post/Setting-Up-Mock-ref-Return-Values-in-Moq

# 解説
Moq の バージョン 4.8 以降にて、refパラメータに対する対応が実施されています。
その際、作成したモックにて参照渡しの値を設定するコードサンプルをメモとして残します。

```c#
    /// <summary>
    /// テスト対象となるインターフェースです
    /// </summary>
    public interface ITestTarget
    {
        void DoSomething(string value1, ref string value2);
    }

    /// <summary>
    /// コールバック用のデリデートを定義します
    /// </summary>
    /// <param name="value1"></param>
    /// <param name="value2"></param>
    delegate void DoSomethingCallback(string value1, ref string value2);

    [TestClass]
    public class UnitTest
    {
        [TestMethod]
        public void TestMethod()
        {
            // Arrange
            var mock = new Mock<ITestTarget>();
            // モックの振る舞いを登録します
            // ref参照の変数で値を変更します
            mock.Setup(_ => _.DoSomething(It.IsAny<string>(), ref It.Ref<string>.IsAny))
                .Callback(new DoSomethingCallback((string value1, ref string value2) => value2 = "This is output value."));
            var target = mock.Object;

            // Act
            var input = "This is input value.";
            target.DoSomething("", ref input);

            // Assert
            Assert.AreEqual("This is output value.", input);
        }
    }
```

まず、テスト対象メソッドが呼ばれた際のコールバック用のデリゲートを定義しておきます。
そして、``Callback``にて ref に設定する変数を変更するように記載すれば OK です。
Perl による next_prime の実装

# はじめに
アルゴリズムの勉強に、*[もっとプログラマ脳を鍛える数学パズル アルゴリズムが脳にしみ込む70問](https://www.amazon.co.jp/dp/B078LMFXXC)* を解いています。
『Q53 重さが素数の荷物を運ぶエレベーター』で素数の話が出てきました。
（Q53 は、素数＋二分探索の良問です）
# Ruby の 素数クラス
***Ruby*** では標準で素数を順に抽出するクラス **Prime** が用意されています。

```ruby.rb
require 'prime'

primes = Prime.each(100).to_a # => [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
```
上記のコーディングで、100以下の素数の配列が生成されます。
***Perl*** では標準モジュールが用意されていないので、~~*Ruby*に乗り換えましょう~~自作する必要があります。
# Perl による実装
```primes.pl
my @primes = (2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97);
sub prime {
  my $n = shift;
  return $primes[$n] if defined $primes[$n];
  my $newprime = $primes[-1] + 2;
  while ($n + 1 > @primes) {
    my $f = 1;
    for my $i (@primes) {
      if ($newprime % $i == 0) {
        $f = 0;
        last;
      } elsif ($i ** 2 > $newprime) {
        last;
      }
    }
    if ($f == 1) {
      $primes[@primes] = $newprime;
    }
    $newprime += 2;
  }
  $primes[$n];
}
sub next_prime {
  my $n = shift;
  my $i = 0;
  while (1) {
    if ($primes[$i] == 0) {
      prime(scalar @primes);
      last if $n < $primes[$i];
    }
    $i++;
  }
  $primes[$i];
}
```
```perl.pl
print prime(80);       # => 419　81番目の素数
print next_prime(743); # => 751
```
~~怠慢なので~~ 予め100以下の素数を用意しておきます。
それ以降の素数は必要に応じ、随時追加する仕様にしました。
# まとめ
+ ***Ruby*** は *prime や permutation や gcd* 等が標準で用意されてます
+ 今回は ***Perl*** で *next_prime* を実装しました
+ 数学パズルはためになります

参照したサイト
*[class Prime](https://docs.ruby-lang.org/ja/latest/class/Prime.html)*
*[初学者によるプログラミングMemo　#22 素因数分解](https://qiita.com/Ikuy_h/items/4644ff903329c808dbae)*
SourceTreeやIDEのプラグインでも.gitmessageのコメントアウトを使用できるようにする

## 背景
チーム開発をしていると、コミットメッセージにもルールを設けておきたくなる。
そういう時に便利なコミットテンプレート。
`.gitmessage`を追加すれば、コミット時に定型文を表示してくれる。



プロジェクトで[Emoji Prefix](https://qiita.com/Jung0/items/0a9a7a97a2c17f92d3c5)を導入したため、
文化に慣れるまでは絵文字の役割や入力方法などを覚えるのが手間だったこともあり、テンプレートを設定しておきたくなった。

しかし、（普段僕はCLIでGitを操作するので知らなかったのだが）SourceTreeやIDEプラグインといった、
GUIでのコミットには`.gitmessage`のコメントアウトが反映されないとのこと。
参考：https://qiita.com/mfks17/items/e68adc058e1a9e519807#-todo

チーム内ではGUIでGit操作を行っているメンバーもいるため、環境に依存してテンプレートが使えない人が出てくるのを避けたい。
何とかできないか調査した。

## 結論

↓を、`.git`が格納されているディレクトリで入力する。

```bash
git config --add commit.cleanup strip
```

グローバルに設定したくなければ`--local`オプションをつけるなり、`includeIf`セクションで分岐させるなりすればよい。
もちろん`.gitconfig`に直接書いてもよい。

```.gitconfig
[commit]
        cleanup = strip
```

## 何をやっているのか？

`--cleanup=<mode>`オプションは、コミットする前にコミットメッセージを整形する方法を指定する。

[Git | git-commit-Documentation](https://git-scm.com/docs/git-commit)

### 変数の種類

#### `strip`

先頭と末尾の空白行、末尾の空白、コメント（`#`が前頭についた行）を削除する。

#### `whitespace`

先頭と末尾の空白行、末尾の空白を削除。ただし、コメントを削除しない。
SourceTreeの設定はデフォルトでコレか`default`になっている可能性がある。

#### `default`

メッセージを編集するときは`strip`、それ以外の時は`whitespace`が適用される。

#### `verbatim`

メッセージを変更しない。

#### `scissors`

基本的に`whitespace`と同じだが、

```bash
# ------------------------> 8 ----------------------- -
```

というコメント以下の行がすべて削除される。

## SourceTreeで設定する方法

GUIツールでGitを操作している人の中にはCLIに苦手意識を持っている人もいるので、操作手順をまとめた。

1. 作業するリポジトリをSourceTreeで開く
2. 右上の「設定」＞「コミットテンプレート」からコミットテンプレートを設定。設定する範囲はプロジェクトや開発ルールに合わせて
3. CLIでリポジトリの場所まで移動
4. `git config --add commit.cleanup strip` を入力

```SHELL
cd path/to/dir # path/to/dir をテンプレートを適用するリポジトリの場所に変更する
```

## 最後に

コミットメッセージはキレイにしましょう:smile:

## 参考
[Gitのコミットコメントを絵文字Prefixにして楽しく開発する | Qiita](https://qiita.com/mfks17/items/e68adc058e1a9e519807)
[Emojiで楽しく綺麗なコミットを手に入れる | Goodpatch Blog](https://goodpatch.com/blog/beautiful-commits-with-emojis/)
AWS ALBの認証機能でGoogleアカウント認証を設定する (OpenIDConnect)

![oidc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/339816/320ccbe7-ba92-992d-6404-117417ac852d.png)

## About
* 社内用のシステムやリリース前の機能を限定公開したい場合新規にログイン機能を実装するのは非効率です。
* AWSにはALBの認証機能としてOpenIDConnectをサポートしています。
* Facebook,Yahoo,Googleなどを利用している場合、ALBをアプリケーションとして登録するだけで簡単に認証機能が実装できます。
* リモートワークが推奨されている昨今、突然社内用の管理画面にログイン機能が必要になってお困りになっている方もいらっしゃるのではないでしょうか？
* 今回はGoogleのOauthクライアントIDを利用してOIDCする方法を説明します。

## 利点
* アプリケーション毎に管理機能を実装する必要がなくなる。

## 認証のフロー
1. ALBにアクセス
2. ログイン状態をGoogleAPIに問い合わせる
3. 非ログイン状態であればGoogleの認証画面を表示、ログイン状態ならALBにリダイレクト
4. ALBからはターゲットグループ(EC2など)にリクエストを振り分ける。<br>
   X-Amzn-Oidc-DataヘッダーにALBによって署名されたJWTのトークンが入るので、<br>
   アプリケーション側でペイロード(ユーザークレーム)を取得してユーザを判定する事も可能。
5. EC2からアプリケーションのレスポンス
6. ユーザからはどこのレイヤーで認証されているかを意識する事はないし、いつも使っているアカウントで入れて幸せ


## 認証設定
### GoogleOauth2.0クライアントID を取得する
#### 1. GoogleCloudPlatformにアクセス
* [Google Cloud Platform](https://console.cloud.google.com/?hl=ja)にアクセス
* 左ナビから [APIとサービス] > [認証情報] を選択

#### 2. Oauth同意画面設定
* 左ナビから OAuth同意画面を選択（プロジェクトを作成していない場合は新規に作成）
* UserType > 内部 > 作成
* Oauth同意画面で下記項目を入力して保存

| 項目 | 内容 |
| :--- | :--- |
| 名前 | 任意 |
| 承認済みドメイン | ALBのDNS名 |

#### 3. 認証情報を作成
* 左ナビから [認証情報] を選択
* 画面上部の [認証情報を作成] > [OauthクライアントIDの作成]
* 下記項目を入力して保存

| 項目 | 内容 |
| :--- | :--- |
| アプリケーションの種類 | ウェブアプリケーション |
| 名前 | 任意 |
| 承認済みのリダイレクトURI | https://ALBのDNS名/oauth2/idpresponse |

<img width="512" alt="スクリーンショット_2020-04-06_23_02_44.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/339816/0989244e-dbb6-9595-329b-57b785da9586.jpeg">
* 上記ダイアログが出るのでクライアントIDとクライアントシークレットをコピーしておく

### AWSのロードバランサー上で認証の設定を行う
<img width="1460" alt="スクリーンショット_2020-04-06_23_22_45.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/339816/01c8a3db-bdff-7f65-1f73-cae00efa169b.jpeg">

#### 1. ロードバランサーの設定画面
ALBは既に作成済みの前提

* [EC2](https://ap-northeast-1.console.aws.amazon.com/ec2/v2/home) > [ロードバランサー](https://ap-northeast-1.console.aws.amazon.com/ec2/v2/home?region=ap-northeast-1#LoadBalancers:)
* 認証設定したいALBを選択
* リスナータブを開いて [ルールの表示/編集] を選択
* ルールの編集タブを選択 <img width="395" alt="スクリーンショット 2020-04-06 23.31.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/339816/fad38a11-459b-1938-3984-fe7a7c73bb0e.png">
* デフォルトアクションの左のペン（編集ボタン）を選択
* [アクションの追加] > [認証]
* 下記項目を入力して更新

| 項目 | 内容 |
| :--- | :--- |
| 認証 | OIDC |
| 発行者 | https://accounts.google.com |
| 認証エンドポイント | https://accounts.google.com/o/oauth2/v2/auth |
| トークンエンドポイント | https://www.googleapis.com/oauth2/v4/token |
| ユーザー情報エンドポイント | https://www.googleapis.com/oauth2/v3/userinfo |
| クライアントID | 発行したクライアントID |
| クライアントシークレット | 発行したクライアントシークレット |
<img width="829" alt="スクリーンショット_2020-04-06_23_37_53.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/339816/80f6a5db-2894-0c6b-da77-ca5aaeb7cfff.jpeg">

### ロードバランサーにアクセスする
* Googleに非ログインの状態でロードバランサーにアクセスするとGoogleの認証画面にリダイレクト
* 認証を行うとアクセスしたURLにリダイレクトされる

参考記事は[こちら](https://dev.classmethod.jp/articles/add-google-authenticate-your-webapp-on-alb/)。
TensorFlow - keras でやるMNIST

##はじめに
プログラミング初心者なんで、自分が理解するための記録として書いていきたいと思います。
まず、今回やるのはMNISTを使った学習です。

##MNISTデータ
MNISTデータは、手書きの数字が書かれた白黒画像（28×28ピクセル）です。
学習データ（60,000枚）、テストデータ（10,000枚）のデータセットです。

##データの読み込み
MNISTデータを読み込みます。
データはタプル型で代入されます。

```python3
from keras.datasets import mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()

print(type(mnist.load_data()))
#class <'tuple'>
```

##データの前処理
###・入力データの形を変換 
入力データを
・学習データ　：60000×784
・テストデータ：10000×784
の形に変換します。

```python3
x_train = x_train.reshape(60000, 784)
x_test = x_test.reshape(10000, 784)
```

一枚のデータを横一列に並べて、それを縦に60,000（10,000）枚並べた感じになるのかな??
図のイメージ。実際には二次元配列になってると思うけど、、、

<img width="450" alt="MNIST_1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614282/e3cd495d-b1c7-e328-7217-3b4aca598033.png">

###・入力データの正規化
学習精度を高めるために、入力データを0〜1の間になるように正規化を行います。
データはfloat型に変換します。

```python3
x_train = x_train.astype("float32") / 255
x_test = x_test.astype("float32") / 255
```

厳密には以下の式で正規化を行っています。
X：入力データ(0〜255)
M：正規化後の最大値1
m：正規化後の最小値0

```math
Y = \frac{X - X_{min}}{X_{max} - X_{min}} (M - m) + m
```
　

###・教師データをダミー変数に変換（one_hot_encoding）
教師データをダミー変数に変換します。
二つ目の引数に値を渡すと、0からnb_classesまでの要素で変換するらしい。

```python3
y_train = to_categorical(y_train, 10)
y_test = to_categorical(y_test, 10)

#to_categorical(y, nb_classes = None)
#4 = [0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
```

##モデルの構築
Sequentialモデルで学習をします。
層を追加する時は、addメソットでどんどん追加していくと見易くなります。

Denseの最初の引数はユニット数、activationは活性化関数です。
活性化関数は他にもたくさんあります。
活性化関数は各層でどのように学習して次の層に伝えるを決める結構重要なもの
なのかなって認識しています。

input_dimは隠れ層の一層目に書くもので、入力のユニット数なのかな??

ちなみに、ReLUは0以下の値だと0で、1以上だとそのままの値を出力するような関数です。

softmaxは、出力層で使われます。
使い所としては、分類で識別率を出したいときに使います。
だから、回帰とかの時には使わない認識です。

```python3
model = Sequential()
model.add(Dense(64, activation='relu', input_dim=784))
model.add(Dense(10, activation='softmax'))
```
##モデルの最適化
optimizerはRMSpropというものを使います。
optimizerは損失関数を最小にするような重みを算出するアルゴリズムで
その手法は他にもたくさんあります。
ですが、どの手法が優れているのかについてはしっかりとたエビデンスがまだ出ていないらしいです。
ただ、RMSpropはパラメーターが多く、最適なパラメーターを設定しないと他の手法に劣るらしい。
（ここらへんについてはもっと勉強します、、、）

lossは損失関数です。損失関数は、予測と実測値とのズレを評価します。
回帰と分類で、用いる関数が異なります。

metricsは評価関数です。損失関数と似ていて、予測値と実測値とのズレを評価します。
戻り値には、評価した値の平均を返します。

```python3
model.compile(
                optimizer='rmsprop',
                loss='categorical_crossentropy',
                metrics=['accuracy']
            )
```

##学習
ここでは、ミニバッチ学習（学習データの半分以下のバッチサイズで学習）をしていきます。
バッチサイズは1グループに対する個数のことです。つまり、バッチサイズが100なら、
600グループができるということになります。ちなみに、グループのことはバッチ数といいます。
グループを分けて学習を行うことで、一部のデータに対してのみ最適化してしまうのを
防ぐ役割をします。そのため、データの動きが激しい場合には、バッチサイズを大きく設定し、
あまり変動がないようなデータにはバッチサイズを小さくするのが望ましいようです。
損失関数の更新はバッチ数毎に行います。（多分、、、）

エポック数は学習回数です。全てのバッチ数を学習し終えると、データをシャッフルします。
この工程がエポック１となります。


```python3
model.fit(
            x_train, y_train,
            batch_size=100,
            epochs=12,
            verbose=1
        )
```

##モデルの評価
97.4%の識別率が出ました。

```python3:qiita.rb
score = model.evaluate(x_test, y_test)
print(score[0])
print(score[1])

#output
#0.0918885813294677
#0.9739000201225281
```

##終わりに
次回はデータの可視化をしたりとか色々やっていきたいと思います。
JOI予選突破するため

これは数ヶ月前の独り言

難易度6~7が解けるかがポイント

難易度5までのDPなら確実解ける。

二次は５問
難易度の予想としては
3-4-6-8-10
4-6-7-8-10

なのでやっぱり6,7が解けるどうか。

## 6,7を解くには

- dp
- DSF/BDS
- 座圧
- ダイクストラ

あーdpばっかり練習してたからグラフ問題出たら死ぬ。

https://twitter.com/Pro_ktmr/status/1203516306575646720?s=20
【Swift】データ型簡易まとめ

## 概要
Swiftの学習中の備忘録です。
ここではデータ型について出来るだけ簡単にまとめておきます。

## 筆者環境
- MacBook Pro (13-inch, 2019)
- macOS Catalina（Version 10.15.4）
- Xcode(Version 11.4) 
- Swift5.2

## データ型とはなんぞや
変数を定義する時に
「この変数は文字列ですよ！」とか「数値ですよ！」みたいな感じで
カテゴリ分けをするためのものとして一旦理解をしておくことにします。

## Int型（整数型）
正と負の整数を扱う場合のデータ型です。

```swift

var i: Int = 54 
//Int型（データ型）のi(変数名)に54(初期値)を代入

var i = 54 
//データ型を省略して書くことも出来る（型推論）
```

## Double型（浮動少数点型）
小数を扱う場合のデータ型です。
浮動小数点型には「Float型」もありますが、「Double型」の方が精度の高い数値を扱えるとのこと。
基本は「Double型」を使っていくこととします。

```swift

var d: Double = 5.987 
//Double型（データ型）のd(変数名)に5.987 (初期値)を代入

var d = 5.987 
//データ型を省略して書く場合、自動的にDouble型になる。
```

## String型（文字列型）
文字列を扱う場合のデータ型です。

```swift

var s: String = "Hello" 
//String型（データ型）のs(変数名)に文字列"Hello"(初期値)を代入

var s = "Hello" 
//データ型を省略して書くことも出来る（型推論）
```

## Bool型（真偽値）
論理演算で「true（真）」「false（偽）」を扱う場合のデータ型です。

```swift

var b: Bool = true 
//String型（データ型）のs(変数名)に文字列"Hello"(初期値)を代入

var b = true
//データ型を省略して書くことも出来る（型推論）
```

## （ちなみに）一度データ型を宣言すると、その他のデータ型は受け付けなくなる 
たとえ同じ数値というものを扱うデータ型であっても、
Int型の変数にDouble型の値を入れることはできません。

```swift

var i = 5 
i = 3.4

//エラー文
Cannot assign value of type 'Double' to type 'Int'
//Double型の値をInt型に割り当てることは出来ません！と怒られます。
```




## 最後に
以上、簡単ですがデータ型についてでした。
学習を進める中で、追加したい内容が出てきたら都度追記していきます。
データ型と関係の深いオプショナル型については別記事にて投稿したいと思います。
Pythonで毎日AtCoder #28

### はじめに
前回
今日はABC140の問題を解きました。50分でA~Cでした。

### A問題
[問題](https://atcoder.jp/contests/abc140/tasks/abc140_a)     0diff

**考えたこと**
3桁のパスワードなので使える数字の3乗を出力すればいい。

```python
n = int(input())
print(n**3)
```

### B問題
[問題](https://atcoder.jp/contests/abc140/tasks/abc140_b) 58diff

**考えたこと**
for文とif文で計算するだけ。リストの要素とindexが混ざらないように気を付ければいい

```python
n = int(input())
a = list(map(int,input().split()))
b = list(map(int,input().split()))
c = list(map(int,input().split()))

ans = 0
f = 10**9
for i in range(n):
    ans += b[a[i]-1]
    if a[i] - f == 1:
        ans += c[a[i-1]-1]
    f = a[i]
print(ans)
```

### C問題
[問題](https://atcoder.jp/contests/abc140/tasks/abc140_c) 136diff

**考えたこと**
$A$の要素の合計値が最大になるのは$B$から与えられる$A$の要素が最大になるときである。最大になるのは、$a[0]$が$b[0]$と同じ値、$a[-1]$が$b[-1]$と同じ値になるとき。それ以外の$A$はmin(b[i-1],b[i])で決定する。


```python
n = int(input())
a = list(map(int,input().split()))
b = list(map(int,input().split()))
c = list(map(int,input().split()))

ans = 0
f = 10**9
for i in range(n):
    ans += b[a[i]-1]
    if a[i] - f == 1:
        ans += c[a[i-1]-1]
    f = a[i]
print(ans)
```

### まとめ
D(1110diff)は解けませんでした。Cもdiffの割に苦戦したのが悔しい。ではまた。おやすみなさい。
OBSで録画したmkvファイルをmp4ファイルに変換する方法

今回はZoom上のオンラインイベントをyoutubeにアップする目的で、

配信せず録画だけ行い後日アップロードしようとした時に、

mkvという見慣れない形式の動画だったため、

それをmp4に変換したお話。

#mkv →　mp4

OBSはデフォルト設定で録画するとmkv形式で録画されます。

youtubeにアップロードする場合mp4にしたいので、その方法を覚え書きします。

方法は大きく２つ。

##そもそもmp4形式で録画する

私はAdobe納税者なのでPremireProが使えます。

なので、premireに取り込んで書き出せばいいのかなと思ったらまさかの未対応ファイル形式。ぴえん。

そこで、OBSの録画設定はデフォルトがmkv形式になってるためそこをmp4にしよう、という方法。

これが一番お手軽なので「設定 > 出力　>　録画タブ」から設定変更しようとしたところ、

気になる注意書きが。

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273740/537c8d17-c044-5338-0b4b-8ecee8ced1cc.png)

**警告：「例えば、ブルースクリーン、電力損失などの結果として」ファイルをファイナライズできない場合はMP4/MOVに保存された録画は回復不能になります。**

ちょうどファイナライズしてる時に酒をこぼしてPCぶっ壊してしまうような僕のような人は最初からmp4で録画するとやばいです。（危機一髪でした）

なのでその後に書いてあるように一旦、mkv形式で録画して「録画の最多重化」を行いmp4形式に変換したほうが無難です。


##録画の最多重化

「ファイル > 録画の最多重化」のウィンドウに録画したmkvファイルをペーストします。

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273740/13fad1b3-334e-df49-9cfd-dc840e04efbe.png)

すると勝手にmp4形式が選択されてるので、そのまま「最多重化」。

十数秒で完了します。


あとはyoutubeにアップするなり、動画編集ソフトで編集するなりお好きにできます。

（追記：mkvファイルをそのままyoutubeにアップすることは可能のようです）
【Rails】whenever によるバッチ処理（runner編）

# はじめに

whenever が使いやすいと書かれていたにもかかわらず、少しはまってしまったのでまとめます。
特に、runner について書きたいと思います。

# GemFile

GemFile に whenever を追記して ```bundle install```

```ruby:GemFile
gem 'whenever', :require => false
```

```
$ bundle install
```


# 自動化したいソースを記述

と、その前に準備があります。
config/application.rb に 以下の2行を追記してください。
lib のディレクトリの内容を反映させるようです。

ここがはまってしまったポイントです。

```ruby:config/application.rb
class Application < Rails::Application
  # 追記
  config.autoload_paths += Dir["#{config.root}/lib"]
  config.eager_load_paths += Dir["#{config.root}/lib/**/"]
end
```

lib/batch/hoge.rb に自動化したいソースを記述してください。

```ruby:lib/batch/hoge.rb
class Batch::Hoge
  def self.hoge
    puts "Hoge!"
  end
end
```

ターミナル上で実行できるかどうかを確認。

```
$ bundle exec rails runner Batch::Hoge.hoge
=> "Hoge!"
```

# 自動化のスケジュールを作成

下記コマンドを実行することで、config/schedule.rb を作成。

```
$ bundle exec wheneverize .
```

config/schedule.rb に、下記を記載。
自動化させたい頻度と実行したいメソッドを指定してください。

```ruby:config/schedule.rb
set :output, 'log/crontab.log'
set :environment, :development
set :runner_command, "rails runner"

every 1.day, at: '9:00 am' do
  runner "Batch::ManHoursToBacklog.send_backlog"
end
```


# 作成した自動化ソースをcronへ反映・確認・削除



```
# cron への反映
$ bundle exec whenever --update-crontab 
```

```
# cron へ反映した内容の確認（どちらの行でも確認できる）
$ bundle exec whenever 
$ bundle exec crontab -e
```

```
# cron へ反映した内容を削除
$ bundle exec whenever --clear-crontab
```


# まとめ
以上が whenever を使ったバッチ処理反映方法でした。
少しでも参考になる方がいれば嬉しいです。

# 参考
* Railsで定期的にバッチ回す「Whenever」
    * https://qiita.com/yumiyon/items/388fbb84450f49a6ab0d
* Rails runnerを使ってファイルを実行しました
    * https://qiita.com/pugiemonn/items/e402b8b73a6569bfc044
* javan/whenever (GitHub)
    * https://github.com/javan/whenever
* dignoe/whenever-elasticbeanstalk (GitHub)
    * https://github.com/dignoe/whenever-elasticbeanstalk

---
### 会社紹介

**株式会社 Mosaica**  
最先端テクノロジーで社会課題を解決し、持続可能な未来を創造する IT カンパニー。
AI ソリューション、クラウド統合、DX 推進、経営コンサルティングなど包括的なサービスでビジネス変革を支援しています。  

詳しくは [公式サイト](https://mosaica.co.jp/) までお気軽にご相談ください。
公式サイト： https://mosaica.co.jp/
webpack使ってるReactをNetlifyに上げたら環境変数が読めなくて困った

## 環境
react: 16.13.1
webpack: 4.42.0
dotenv: 8.2.0

## webpack設定ファイル内でのdotenvをいい感じに設定する

参考までに`package.json`のscriptを置いておきます。

```package.json
  "scripts": {
    "start": "webpack-dev-server --hot --inline --config webpack.development.js",
    "build": "webpack --config webpack.production.js",
```

こんな感じで、開発環境と本番環境でwebpackの設定ファイルを分けていました。参考: https://webpack.js.org/guides/production/

で、開発環境だと`.env`の内容が読めているのに、本番ではNetlifyのGUIで設定した環境変数が読めてなくて困ってました。というのも、Dotenvは`.env`を探しにいくけど、`.env`はgitで管理しないので本番に上がらず…という次第ですね。

設定をこんな感じに変えたら読めました。

```webpack.production.js
const Dotenv = require('dotenv-webpack');

module.exports = {
  mode: 'production',

略

  plugins: [
    new Dotenv({
      systemvars: true
    })

```

`systemvars: true`が肝です。

`systemvars`の他にもオプションがありました。とかとか、Dotenvについての詳細はこちら。
https://www.npmjs.com/package/dotenv-webpack#properties
(Python)HTMLの読み取りと正規表現でつかえたところメモ


PythonにてHTMLファイルに正規表現を施す時、
エンコーディングやその他諸々の箇所でつかえてしまったので、メモとして残します。


## I. HTMLファイルの読み取り

```codecs``` ライブラリーを使いましょう。Pythonの標準ライブラリなので(Appx. 1)、インストールいらずにimportだけで使用できます。

```
import codecs
f = codecs.open("hoge.html","r", encoding="utf-8")
```
### 注意
- codecs.open関数には必ず```encoding```引数を指定しよう
    - Windows環境下だと、Shift-JISと明示されたファイル以外はうまく読み取れないそうです。支(つか)えていたところ先人がいました(Appx. 2)。

## II.正規表現を施す

```re``` ライブラリを使いましょう。こちらも標準ライブラリ(Appx. 1)なのでimportのみで使えます。

```
# (前章のつづき)
import re
str = f.read()
regex = '[abc]'
sample = re.findall(regex, str)

```
### 注意
- 前章で読み取ったhtmlファイルを ```re```の各関数に渡す際には、事前に必ず```codecs.read()```関数を用いましょう

### 代表的な正規表現

以下、Appx. 3より```re```の関数として汎用性の高そうなものを列挙します。```regex```には正規表現が入るものとします。

- 前方検索: ```re.search(regex, string)```
    - regexパターンがstring内にあるか調べてきて、存在した場合はその文字列(=regex)を返す
    - サーチに失敗した場合Noneを返すので、例えば```if not re.search(regex, string):```などで簡単に条件分岐に用いることが出来る
- 全検索: ```re.findall(regex, string)```
    - regexパターンがstring内にあるか調べてきて、一致箇所すべてを含んだリストを返す
    - この関数から別のre処理を行いたい時は、(文字列にするために)str関数を用いて文字列化させましょう(Appx. 4)。
- 置換: ```re.sub(regex, replace, string, count=0)```
    - regexパターンがstring内にあるか調べて、replaceに置換する
    - countに1以上の自然数を入力すると、stringの前方からregex該当箇所を何回置換するか指定できる。デフォルト値の0だと全箇所置換する
        - 「JavaScript等で正規表現を記述する際のグローバルサーチ(```/g```)ってPythonでどうやって表現するのかな?」と思っていたのですが、どうやらこのcount=0の状態で表現されているようです(Appx. 5)

なお、正規表現そのものについてはAppx. 6に詳しいです。

(以上)

## 参考 (Appendix / Appx.)
- 1. [Python 標準ライブラリ](https://docs.python.org/ja/3/library/index.html)
- 2. [WindowsでCP932(Shift-JIS)エンコード以外のファイルを開くのに苦労した話](https://qiita.com/Yuu94/items/9ffdfcb2c26d6b33792e)
- 3. [re --- 正規表現操作](https://docs.python.org/ja/3/library/re.html)
- 4. [re.sub erroring with “Expected string or bytes-like object”](https://stackoverflow.com/questions/43727583/re-sub-erroring-with-expected-string-or-bytes-like-object)
- 5. [Python RegExp global flag
](https://stackoverflow.com/questions/11686516/python-regexp-global-flag)
- 6. [基本的な正規表現一覧](https://murashun.jp/blog/20190215-01.html) 
    - 正規表現を調べるのにいつも使用させていただいております。
[Arduino] delayの使い方を考える。 

#効率の良いdelayの使い方。
とても簡単なことではあるが、自分にとってはとても大切なことだと思うのでまとめておく。delayで長時間動作を止めない方が良いという内容。

##点滅のプログラム
```c++
void setup() {
  pinMode(13, OUTPUT);
}

void loop() {
  digitalWrite(13, HIGH);
  delay(1000);
  digitalWrite(13, LOW);
  delay(1000);
}
```
これはArduinoのLチカのプログラムである。1秒ごとに点滅を繰り返す。
ここでは**delay(1000)**を用いて1秒間動作を停止させることで点滅動作を行っている。しかし他の動作も組み合わせたいとき（例えばセンサーの読み取りなど）、1秒間動作を止めると不都合が生じる場合がある。**delay**の時間を細かくする手法を取ると改善できる。

##点滅のプログラム2
```c++
int i = 0;
int state = 0;

void setup() {
  pinMode(13, OUTPUT);
}

void loop() {
  if (i >= 1000) {
    i = 0;
    if (state == 0) {
      state = 1;
      digitalWrite(13, HIGH);
    }
    else {
      state = 0;
      digitalWrite(13, LOW);
    }
  }
  i++;
  delay(1);
}
```
先ほどのプログラムに比べて長くなってしまったが、同様の点滅の動作を行う。今回は**delay(1)**を使っており、1ループにつき1ミリ秒しか動作を止めていない。この場合他の動作を行うときにも問題が生じない。プログラミング原理は1ミリ秒の**delay**を1000回実行することで、1秒間を測っている。処理の量によっては1秒以上になってしまう場合もありそうなので、その場合は調整が必要かもしれない。このほかタイマー割込みなどでdelay中に処理する方法もあるようだが、難しそうなので自分はこの方法をよく使っている。

##ローカル変数とグローバル変数
2つ目のコードではグローバル変数で宣言を行っているが、関数内に宣言したい場合は**static int i = 0**のように書く。**static**をつけないとループする毎に初期化されてしまうので注意。

##まとめ
**・delayの時間は短い方が他の動作に影響しない。**
**・ローカル変数に宣言するときはstaticをつける。**

簡単な内容だが、自分にとってはこれでできることが大きく広がったのでまとめてみた。
スクロールダウンの線を落ちるように表示　CSS

##スクロールダウンの線を落ちるように表示させます

最終的な完成型はこれです
![ezgif.com-video-to-gif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589877/17d254dd-6c05-e72c-0a34-b5c17617cca1.gif)

####コード紹介
htmlはこんな感じです<img width="747" alt="スクリーンショット 2020-04-06 23.04.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589877/1e09535a-a932-841a-c359-37419998fa22.png">
divタグがあり、idがline-bgとあるだけです


次にCSSがこちら<img width="500" alt="スクリーンショット 2020-04-06 23.11.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589877/94bf76a3-6db6-3d30-f718-0c614b32346a.png">

##解説
id名line-bgに対してoverflow-hideで飛び出たやつを消して、

その後line-bg::afterで疑似要素をつくり、contetsの中は""で空欄とします

@keyframesで動きをつけて、終了といった形です

ポイントとしてはoverflowで余分なところを隠すところです。

以上になりますが、なにか間違いや訂正箇所等あれば教えていただけると幸いです。