OmniAICreator/Qiita-1.07M huggingface dataset:
Google Analytics から読み込むデータを条件で絞ったメモ

日付で絞ったときのメモ

1. モデルを開き、対象のデータを選択後にリボンメニューから [データの変換] をクリック
2. 読み込んでいる PowerQuery に、`Table.SelectRows` を使って絞り込む

```qml:日付で絞り込んだ例
= Table.SelectRows(
    Cube.Transform(#"xxxxxxxxx",{
        {Cube.AddAndExpandDimensionColumn, "ga:pagePath", {"ga:pagePath"}, {"Page"}},
        {Cube.AddAndExpandDimensionColumn, "ga:date", {"ga:date"}, {"Date"}},
        {Cube.AddAndExpandDimensionColumn, "ga:hour", {"ga:hour"}, {"Hour"}},
        {Cube.AddMeasureColumn, "Pageviews", "ga:pageviews"}
    }),
    each [Date] > Date.FromText("2020-01-31")
)
```
Laravelでアップロード画像を自動リサイズする

## やること

####ユーザーがプロフィール画像をアップロードした際に正方形に自動整形するよう設定します。

途中で発生したエラーの対処法も残しています。

### 環境

- mac OS Catalina 10.15.6
- Docker version 19.03.12, build 48a66213fe
- Docker Image  php:7.3-fpm-alpine
- Laravel 7.22.4

## 方法

Laravelで使いやすいと言われているIntervention Imageという画像処理ツールを使います。

[Intervention Image](http://image.intervention.io/getting_started/introduction)

###1. Intervention Imageを公式サイト通りに導入

- インストール
   
   ```php:terminal
        $ php composer.phar require intervention/image
   ```

   - ####`config/app.php`でプロバイダーとエイリアス設定

       `providers`部分に一行追加します。
  
       ```php:config/app.php
        'providers' => [ 
                Intervention\Image\ImageServiceProvider::class, //追加
            ],
       ```

       `aliases`部分に一行追加します。

       ```php:config/app.php
        'aliases' => [
                'Image' => Intervention\Image\Facades\Image::class, //追加
            ],
       ```

###2. コントローラーに記述

  - **画像がアップロードされた際に300*300pixelにリサイズされるように設定します。**

       わかりやすい使い方はこちらが参考になると思います。

       [完全網羅！Intervention Image（PHP）で画像を編集する全実例](https://blog.capilano-fw.com/?p=1574#GD)

       ```php:UserController.php
        use Intervention\Image\ImageManagerStatic as Image; //追加します。

        public function update(Request $request, $userName)
            {
                $user = User::where('name', $userName)->first();
                if ($request->image) {
                    $filePath = $request->file('image');
                    Image::make($filePath)->fit(300, 300)->save($filePath); //ファイルを読み込んでリサイズ、上書き保存しています。
                    $filePath = $filePath->store('images/profile');
                }
                $user->save();

                return redirect('/profile/' . $userName);
            }
       ```

       これでスムーズに行けば完了ですが、エラーが出たので以下はその対処法です。

###3. エラー対処
   - ####エラーメッセージ

       ```php
        Intervention\Image\Exception\NotSupportedException
        GD Library extension not available with this PHP installation.
       ```

    ####[GDライブラリ](https://www.php.net/manual/ja/book.image.php)という画像処理のライブラリが無いようなので導入します。

       Docker環境でAlpine Linuxという軽量リナックスのコンテナでの方法です。

       ```php:Dockerfile
        FROM php:7.3-fpm-alpine
        LABEL maintainer "hiro"

        ENV COMPOSER_HOME /composer

        RUN set -eux && \
          # Intervention Image時に必要なパッケージ　以下３行追加
          apk add --no-cache libpng libpng-dev libjpeg-turbo-dev freetype-dev && \
          docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ && \
          docker-php-ext-install -j$(nproc) gd && \
      ```

       更新してビルドしましたが、他にも足りないものがエラー出たので`libjpeg-turbo-dev` と`freetype-dev`を追加で導入しました。

       同じ環境でもし

       ```php
       configure: error: jpeglib.h not found.
       ```

       のようにパッケージが足りずにビルドできない場合は、こちらで名前検索をかけると必要なパッケージが見つかるはずです。

       [Alpine Linux packages](https://pkgs.alpinelinux.org/packages)
連想配列には.lengthが使えない話

#lengthはオブジェクトには使用できない！！
先日社内での新規プロダクト開発案件にて起きた出来事。

```
<div v-if="feature.length　> 0">{{ feature }}</div>

-------------------------------------------------------------------------------------------------
<script>
const vm = new Vue({
feature: <?php echo !empty($feature) ? Format::forge($feature)->to_json() : 'null'; ?>,
})
</script>
```
上記のような変数の中身が入っていれば表示、なければ表示しないというありがちな処理をvueで記述した際に間違いなく値が入っているのに何故か表示されないという場面に遭遇。
なぜだ。。と数時間ハマってしまいました。
結論からいうと変数が連想配列としてフロントに渡されておりそれをjsonに変換→オブジェクト化→lengthは配列にのみ使用でき連想配列（オブジェクト）には使用できない、という単純なオチでした。。
情けない。。

#一応配列と連想配列（オブジェクト）についてまとめてみる
オブジェクトとは、複数の値を名前で区別し管理します。オブジェクトに入っているこれらデータはプロパティと呼ばれます。
そしてjavascriptではオブジェクトと連想配列は同じものとして扱われます。（その他言語では明確に異なるものとして扱われることがあります。）

一方配列は複数の値を名前ではなく番号で区別し管理します。
そしてJavaScriptでは、配列は「特殊なオブジェクト」です。単なるオブジェクトでもobj[1]=5;のようにセットできてはしまいますが、配列の場合は書き換えることでlengthが自動更新されたり、pushやsliceといった、配列操作に便利なメソッドが用意されています。

そして今回の問題のオチとしましては上述したlengthは配列に用意されたメソッドでありオブジェクトには使うことができなかったというものです。
#おわりに
思いも寄らないところでつまずいてしまいましたがオブジェクトと配列の違いについては今までなんとなくしか理解できていなかったので非常に良い学びになりました。
疲れたマン。
AtomicReference について私的なメモ

コードリーディングをしていると、`AtomicReference` というクラスに当たったので、調べてみた。

# AtmoicReference とは

[リファレンス](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicReference.html)によると

> アトミックに更新されるオブジェクトのリファレンス

との事。これだけだとわからないけど、コンカレントプログラミングを実施する際に、シェアするオブジェクトで更新したいものを保持しておく。`syncronize` はコスト高だし、`violatile`キーワード は書き込みを同時にされたら破綻する。

## volatile 

脱線するが、　`volatile` キーワードの意図するところは、変数の参照を、CPUキャッシュではなく、メインメモリを参照することを保証することにある。このキーワードがない変数は、通常、CPUキャッシュを参照する。複数のCPUがあるシステムの場合、同じ値を参照するとは限らない。そこで、`volatile` キーワードをつけると、実行しているCPUが違っても、メインメモリを参照するので、同じものをリファレンスすることが保証される。よって、「可視性の保証」ともいわれる。ちなみに`volatile` の意味は移り変わりやすい的な意味合い。

```java
private volatile int counter = 0;
```
* [Java Volatile Keyword](http://tutorials.jenkov.com/java-concurrency/volatile.html)

ちなみに、理解するのに、このサイトの説明は最高だった。 `Java Concurrency` というサイトなので、ほかの記事も期待できそう。

## AtomicReference

一方、AtmoicReference は、`synchronized` でロックをがっつりかけることなく、複数のスレッドから参照、更新をするための仕組みです。

### get()

```java
	    AtomicReference<Integer> atomic = new AtomicReference<>();
	    System.out.println("atomic: "+ atomic.get());

	    atomic = new AtomicReference<>(10);
	    System.out.println("atomic: " + atomic.get());
```

#### result

```bash
atomic: null
atomic: 10
```

こんな感じで、型を指定しておくと、その値を保持したり、`get()` メソッドで参照したりできます。コンストラクタはなにも渡さなければ　`null` で初期化されます。

## set()

値のセットです。

```java
	    atomic.set(100);
		System.out.println("atomic: " + atomic.get());
```

#### result

```bash
atomic: 100
```

### getAndUpdate()

通常は、`set()` はそんなに使わないと思います。２つのスレッドで更新されたら、後で更新した値になってしまいます。それでよければそれでよいのですが。そこで、`getAndUpdate()` のようなメソッドがあります。ラムダ式を渡して、現在の値をもとに更新をかけます。`update`と`get` の順番が逆のメソッドもあります。

```java
		UnaryOperator operator = (v) -> (Integer)v + 1;
		System.out.println("atomic getAndUpdate: " + atomic.getAndUpdate(operator));
		System.out.println("atomic after getAndUpdate: " + atomic.get());

		System.out.println("atomic updateAndGet: " + atomic.updateAndGet(operator));
```

#### result

```bash
atomic getAndUpdate: 20
atomic after getAndUpdate: 21
atomic updateAndGet: 22
```

### compareAndSet()

想定している値だった時のみ書き込むメソッドもあります。戻り値は`boolean` なので、期待されている値だったかはわかります。これによって、ほかのスレッドで更新されていないことが保証されます。

```java
                # この時点で、値は 22 
		atomic.compareAndSet(23, 100);
		System.out.println("compareAndSet maybe not updated: " + atomic.get());
```

#### result

```bash
compareAndSet maybe not updated: 22
```

ちなみに、`weakCompareAndSet` というメソッドがあって、結果も同じだったのでなんだろう？と思ったら、Java8までは実装は`compareAndSet`と同じで、Java9 から、deprecated らしいので忘れてよさげです。

* [what's the difference between compareAndSet and weakCompareAndSet in AtomicReference?](https://stackoverflow.com/questions/36428044/whats-the-difference-between-compareandset-and-weakcompareandset-in-atomicrefer) 

# Reference

* [Java - AtomicReference使用方法](https://codechacha.com/ja/java-atomic-reference/)
JavaScriptのfilter,reverse,splitを理解するための自分用メモ

#はじめに
filter,reverse,splitの記事を一つ一つ検索して、開くことがめんどうなのでひとつにまとめておこうと思いました。

参考URL:
filter
[filterMDN](developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)

reverse
[slice().reverse()の説明](https://qiita.com/seltzer/items/2f9ee13cf085966f1a4c)
[reverseMDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse)
[sliceMDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/slice)

split()
[splitMDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/split)

##filterの例
配列の中にあるオブジェクトの要素の`isDone`が`false`の要素だけを`return`で返す処理です。

```javascript

    data: {
        items: [],
    },
```
Vueのデータの中です。

```javascript

var item = {
    isDone: false,
};
this.items.push(item);
```
関数が呼び出されたときに、行われる処理の一部です。
`item`を`items`という配列に追加しています。

```javascript

remaining: function () {
            return this.items.filter(function (residue) {
                return !residue.isDone;
            });
        },
```
`items`の中の`isDone`が`false`の要素だけを返しています。
逆に言うと`filter`は`isDone`が`true`の要素を削除しています。

##reverseの例

配列を逆順にしたいときに使用する。

```javascript
const numbers = [1, 2, 3];
console.log(numbers.reverse()); //[3, 2, 1]
console.log(numbers.slice().reverse()); //[1, 2, 3]
```
`reverse()`のみを使ってしまうと配列自体を変更してしまうため、その後、もう一度`reverse()`を使うと反転の反転となる。

```javascript

const numbers = [1, 2, 3];
console.log(numbers.slice().reverse()); //[3, 2, 1]
console.log(numbers.reverse()); //[3, 2, 1]
```
`slice()`を使うことで、元の配列は変更されずに反転処理を行うことができる。
その結果、配列の操作が非破壊的になる。

#splitの例

```javascript

const str = 'The quick brown fox jumps over the lazy dog.';

const words = str.split(" ");
console.log(words); //["The", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog."]
console.log(words[3]); //fox
```
`split`は何で区切るかを指定する。
上記の場合だと、空白で区切っていることになる。

#最後に
学習を進めていく中で、調べれば簡単にわかることだが、それらの情報がまとまっていると有難いと思うことが多かったので、自分なりにだがまとめることができて良かったと思う。
この記事を見て、役に立てば幸いです。
画像を円形表示する方法

<h3>手順</h3>
**<p>①HTMLを記述する</p>**
**<p>②CSSを記述する</p>**
**<p>③プレビューで表示を確認する</p>**


<h4>CSSの記述をする</h4>

```CSS:copy_practice.css
/*main_picture(親要素)のデザイン*/

.main_picture {
  
  width: 100px;
  height: 100px
  
}

/*mainのロゴ写真の円形の表示(子要素の設定)*/

.main_picture img {
  
  width: 100px;
  height: 100px;
  border-radius: 100px;
  
}
```
**ポイント!**
①画像を円形にして縦横比を維持したい場合は親要素の`width`と`height`と子要素の`width`と`height`には同値を指定する必要があります。
②`border-radius`プロパティでは`width`と`height`の値と同値を指定します。


<h4>HTMLの記述を行う</h4>

```HTML:copy_practice.html

<div class="main_picture">
  <img src="flower_picture.jpg" alt="花畑の風景">
</div>
```

<h4>完成図</h4>

下記のような画像の状態になります。

![円形写真](https://gyazo.com/3238a6a33c512015a524d89c228756f8.jp)


<h4>参考サイト</h4>

以下のサイトを参考にさせて頂きました。

・[CSSで画像を切り抜く方法](https://biroku.popmedia.tokyo/maru/)

・[画像を丸く円形にくり抜いて表示するCSS](https://www.nishishi.com/css/trim-image-to-circle.html)
解像度の異なるモニタでデイジーチェーン

デイジーチェーンできずに困ったけど設定いじっていたら表示できた。
絶対忘れそうなので思い出せるようにメモ。

# デイジーチェーンとは
例えば2台のモニタにPCから接続する場合、
PCから2本ケーブルを出してモニタにそれぞれつなぐのではなく
PCから中継モニタに1本、中継モニタから終端モニタに1本、という形で数珠つなぎに接続する方式。
配線がシンプルになり、
インターフェースが少ないノートPCなどの場合はインターフェースの使用を節約できたりするなどのメリットがある。
https://www.eizo.co.jp/support/compati/monitor/ev2457_daisychain_guide/index.html

# 終端モニタが表示されずに困った
以下のようなエラーが終端モニタに表示されて映像出力されないという状況でした。
「input signal out of range change mode to 1920x1080 60hz」

## 環境
端末

- ノートPC(Windows10)
- 中継モニタ：DELL U2520D(QHD)
- 終端モニタ：HP P224(FHD)

ケーブル

- ノートPC　⇒　中継モニタ　：　USB type-C
- 中継モニタ　⇒　終端モニタ　：　Display Port


# 対応手順
- デスクトップ右クリックでディスプレイ設定を表示
- ディスプレイの詳細設定を選択
- 中継ディスプレイを選択
- ディスプレイXのアダプタのプロパティを表示
- モードの一覧を選択
- 一覧の中から上記エラーメッセージの「1920x1080 60hz」を選択

これで終端モニタにも映像が出力される。
ただし、中継モニタもFHDにダウンしてしまうのでそれが嫌な場合はモニタの解像度を統一するしかなさそうですね。。
windowsでiverilog その66

#概要　

windowsでiverilogやってみた。
遅いモジュールをfifoでつなぐ方法を考察してみた。

#閃き

fifoを挟んで、agentとagent2を並列に実行させる。
但し、バッファは、３２文字までは、速い。

#サンプルコード


```
module fifo(input clk, input rst, input put, input get, input [7:0] data, output reg [7:0] data2, output empty);
	reg [7:0] mem[32:0];
	reg [4:0] rd_pos;
	reg [4:0] wr_pos;
	assign empty = ((wr_pos - rd_pos) == 0) ? 1'b1 : 1'b0;
	assign full = ((wr_pos - rd_pos) == 32) ? 1'b1 : 1'b0;
	always @(posedge clk or negedge rst)
	begin
		if (!rst)
		begin
			wr_pos <= 0;
			rd_pos <= 0;
		end
		else
		begin
			if (put & full == 1'b0)
			begin
				mem[wr_pos] <= data;
				wr_pos <= wr_pos + 1;
			end
			if (get & empty == 1'b0)
			begin
				data2 <= mem[rd_pos];
				rd_pos <= rd_pos + 1;
			end
		end
	end
endmodule

module agent2(input clk, input rst, input empty, output reg get = 0, output reg start = 0);
	reg [3:0] state;
	reg [23:0] wait_time;
	always @(posedge clk or negedge rst)
	begin
		if (!rst)
		begin
			state <= 0;
			get <= 0;
			start <= 0;
		end
		else
		begin
			case (state)
			0:
			begin
				if (empty == 0)
				begin
					get <= 1;
					state <= 1;
				end
			end
			1:
			begin
				wait_time <= 16'd4000;
				get <= 0;
				state <= 2;
				start <= 1;
			end
			2:
			begin
				wait_time <= wait_time - 1;
				if (wait_time == 0)
				begin
					state <= 3;
				end
			end
			3:
			begin
				start <= 0;
				state <= 4;
				wait_time <= 16'd60000;
			end
			4:
			begin
				wait_time <= wait_time - 1;
				if (wait_time == 0)
				begin
					state <= 5;
				end
			end
			5:
			begin
				state <= 0;
			end
			endcase
		end
	end
endmodule

module agent(input clk, input rst, output reg put = 0, output reg [7:0] char);
	reg [3:0] n = 0;
	reg [3:0] state;
	always @(posedge clk or negedge rst)
	begin
		if (!rst)
		begin
			state <= 0;
			n <= 0;
		end
		else
		begin
			case (state)
			0:
			begin
				if (n != 10)
				begin
					char <= 8'h30 + n;
					put <= 1;
					n <= n + 1;
					state <= 1;
				end
			end
			1:
			begin
				put <= 0;
				state <= 0;
			end
			endcase
		end
	end
endmodule

module test2(input clk, input rst, output tx);
	wire put;
	wire [7:0] char;
	wire [7:0] data2;
	wire empty;
	wire get;
	putc p(.clk(clk), .rst(rst), .start(start), .char(data2), .tx(tx));
	fifo f(.clk(clk), .rst(rst), .put(put), .get(get), .data(char), .data2(data2), .empty(empty));
	agent a(.clk(clk), .rst(rst), .put(put), .char(char));
	agent2 b(.clk(clk), .rst(rst), .empty(empty), .get(get), .start(start));
	initial
	begin
		$monitor("%s", char);
	end
endmodule

module test;
	reg clk,
		rst;
	test2 u(.clk(clk), .rst(rst), .tx(tx));
	initial
	begin
		clk = 0;
		rst = 1;
		#2
			rst = 0;
		#4
			rst = 1;
		#200000
			$finish;
	end
	always
		#1
			clk = ~clk;
	initial
	begin
		$dumpfile("test.vcd");
		$dumpvars(0, test);
	end
endmodule


```

以上。
Python初心者がバブルソートを使ってCpawCTF Q14に挑戦した

# はじめに
最近、CTFの勉強としてCpawCTFの問題を解いています。
今回はPythonの勉強も兼ねて、Pythonでバブルソートを実装してCpawCTFのQ14を解いてみました。
https://ctf.cpaw.site/questions.php?qnum=14

# バブルソートの勉強で参考にしたもの
http://algorithm.wiki/ja/app/
「アルゴリズム図鑑」というアプリを利用しました。
グラフィカルにソート方法が勉強できて分かりやすかったです。オススメ。

# コード
```python
sortDataList = [15,1,93,52,66,31,87,0,42,77,46,24,99,10,19,36,27,4,58,76,2,81,50,102,33,94,20,14,80,82,49,41,12,143,121,7,111,100,60,55,108,34,150,103,109,130,25,54,57,159,136,110,3,167,119,72,18,151,105,171,160,144,85,201,193,188,190,146,210,211,63,207]

for i in range(len(sortDataList)):
  for j in range(len(sortDataList) - 1, i, -1):
    if sortDataList[j] > sortDataList[j - 1]:
      sortDataList[j], sortDataList[j - 1] = sortDataList[j - 1], sortDataList[j]

flag = map(str, sortDataList)
print(''.join(flag))
```

# 所感
アルゴリズムをコードとして実装するのが苦手なので、これを機に色々なソート法を実装していきたいと思いました。
Nuxt.js + LINE LIFF アプリをローカル環境にて httpsで実行してDX を向上する

# やりたいこと

[LINE のLIFF アプリ](https://developers.line.biz/ja/docs/liff/) を開発していると、手元の環境で試してみたいと思うのですが、https での実行が必須なので [ngrok](https://ngrok.com/) などのトンネリングツールを使ってhttps でアクセスできるようにしていたのですが、ngrok を使うとどうしても転送速度が遅くなってしまいます。

特に最近はNuxt.js などのフレームワークを使ったSPA アプリを作る機会が多いです。SPA アプリでは初回ロード時に多くのファイルをロードしなければならず、そうなるとngrok の転送速度では起動開始から確認できるまでに時間がかかってしまいます。
アプリや開発環境によっては数十秒から1分程度かかることもあり、とてもDX: Developer Experience （開発体験） が良い開発とは言えません。

というわけで、LIFF アプリ開発でのDX を向上するためにもローカル環境にてhttps で実行できるようにしてみました。

# 設定手順

大げさに書きましたが、公式ドキュメントの「[HTTPS 設定を用いた例](https://ja.nuxtjs.org/api/configuration-server/#https-%E8%A8%AD%E5%AE%9A%E3%82%92%E7%94%A8%E3%81%84%E3%81%9F%E4%BE%8B)」にあるとおり、自己署名入り証明書（いわゆるオレオレ証明書）を作り、その証明書を使ってNuxt.js の アプリケーション・サーバーをhttps で実行できるようにするだけです。

試した環境は以下となります。

- macOS Catalina 
    - Version 10.15.5
- Nuxt.js
    - Version 2.14.1

## 自己署名入り証明書を作成する

自己署名入り証明書の作成には [mkcert](https://github.com/FiloSottile/mkcert) を使います。

```shell
$ brew install mkcert
$ mkcert -install
$ mkcert localhost
```

上記のコマンドを実行すると証明書ファイルが作成されるので、Nuxt.js アプリのルートディレクトリ（`nuxt.config.js` ファイルがあるディレクトリ）に配置します。

## Nuxt.js アプリでサーバー接続設定を追加する

次にNuxt.js アプリでサーバー接続設定を追加するため `nuxt.config.js` ファイルに追記します。
なお、ローカル環境でのhttps 接続設定は開発時のみとします。

```js:nuxt.config.js
import path from "path";
import fs from "fs";

let serverConfig = {};
if (process.env.NODE_ENV === "development") {
  // 開発時のみHTTPS 接続設定を構成する
  serverConfig = {
    port: 3000,
    host: "0.0.0.0",
    https: {
      // 作成した証明書ファイルを読み込む
      key: fs.readFileSync(path.resolve(__dirname, "localhost-key.pem")),
      cert: fs.readFileSync(path.resolve(__dirname, "localhost.pem"))
    }
  };
}

export default {
// 中略
  // HTTPS 接続設定を反映する
  server: serverConfig
};
```

アプリの起動はいつものとおり `yarn dev` もしくは `npm run dev` コマンドを使えばhttps で実行できるようになります。

## LINE Developers のLIFF エンドポイントURL にローカル環境のIP アドレスを設定する

あとは下図のように[LINE Developers](https://developers.line.biz/) にあるLIFF エンドポイントURL 項目にローカル環境のIP アドレスを設定するだけです。

![スクリーンショット_2020-08-16_14_32_22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154381/f573dae8-8a6b-821a-f65a-cce8b3b4749a.png)

これで開発環境のPC ブラウザや、同じネットワークにあるスマートフォンのブラウザでLIFF アプリを利用できるようになりました。

![IMG_C08D6CD842BF-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154381/fb84c5ad-3fc9-ae16-a38d-403e41148de1.png)

ブラウザのアドレス欄に鍵マークがついていることからhttps でアクセスできていることが分かりります。

# まとめ

分かってしまえばとても簡単なことでした。昔からWeb アプリの開発時には開発サーバーのHTTP サーバーにオレオレ証明書を入れていましたよね。
ほんの一手間で無用のイライラも無くなってサクサク開発できるようになりますので、お困りの方はぜひとも試してみてください。
【テストコード学習・アウトプット】

▼今回のカリキュラムでは前章のカリキュラムで作成したアプリケーションのテストコードを記述。

・前回は簡易Twitterを作成したのでそのテストコードを学びました。
エンジニアの仕事で駆け出しに任されることが多いそうなので気合を入れて取組ました。

・describe　it exampleの整理　expect(X).to eq Y
・FactoryBotでインスタンスの整理
その他には、before、Fakerでの生成方法。
contextの状況整理。

◆単体と結合のテストコードの作成。
・最初に単体でモデル、コントローラーを作成。
・その後に上記で学んだインスタンスや文字列、gemを使い結合テストコードを作成。
・ユーザー、ツイート、コメントの結合テストコードを作成。
・最後にサポートモジュールでログインの簡略化。

▼まとめ
・文字にしてみると量やボリュームが少なく感じましたが、実際に一からファイルを作成してテストコードを書いていく作業は、初心者の私にはものすごく大変でした。。。。
ただ、ターミナルでその都度コードを入力した後に作動する動きをみると自身の成長やプログラミングへの興味、関心が高まっていきました。
今も早く次のカリキュラムに行ってもっともっと学びたいです。
来年、エンジニア転職を成功させるためにも楽しんで学んでいこうと思います。
PSPNetで脳腫瘍を検出してみた(colab環境)

<p>広島大学で社会基盤(土木)を専攻している３年生です。<br>
現在は１年間休学して建設系のIT企業でインターンをしています。<br>
今回はSemantic SegmentationのPSPNetで脳のMRI画像のデータセットを学習させ可視化まで行いました。</p>

#今回学習に使ったデータセットについて
kaggeで公開されている脳のMRIデータセット(https://www.kaggle.com/mateuszbuda/lgg-mri-segmentation) を使用しました。
PSPNetで脳の腫瘍を検出します。

#PSPNet(Pyramid Scene Parsing Network)とは
<p>PSPNetはセマンティックセグメンテーションのモデルの一つです。<br>
簡単にモデルの概要を説明すると</p>
- Feature Map (今回Resnet50を使用)で3×475×475にリサイズした画像の特徴量を抽出。
- 抽出された2048×60×60の特徴マップを５つに分岐させ１つはそのまま残りは４つは
以下の処理を行う。
 - 1.異なるサイズのカーネルでプーリング
 - 2.畳み込みでチャンネル数を2048から512に削減
 - 3.アップサンプリングを行い4つの特徴マップを512×60×60にする
- 一つとっておいた2048×60×60の特徴マップと４つの512×60×60のマップを結合させ4096×60×60の特徴マップにする。
- Decoderモジュールで特徴マップから推論結果(クラス数+1, 475, 475)を出す
<p>これらの処理が推論処理で行われます。</p>
![pspnet_model_image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677912/bda4a44f-c233-6229-337d-d3f1ffd89276.png)

今回の概要説明では不十分だと感じる方も多いと思います。
詳しいモデルの内容はこちら(https://arxiv.org/pdf/1612.01105v2.pdf) と「つくりながら学ぶ！PyTorchによる発展ディープラーニング」 (https://www.amazon.co.jp/%E3%81%A4%E3%81%8F%E3%82%8A%E3%81%AA%E3%81%8C%E3%82%89%E5%AD%A6%E3%81%B6%EF%BC%81PyTorch%E3%81%AB%E3%82%88%E3%82%8B%E7%99%BA%E5%B1%95%E3%83%87%E3%82%A3%E3%83%BC%E3%83%97%E3%83%A9%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0-%E5%B0%8F%E5%B7%9D-%E9%9B%84%E5%A4%AA%E9%83%8E-ebook/dp/B07VPDVNKW) が大変参考になりました。

# 実装について
実装も「つくりながら学ぶ！PyTorchによる発展ディープラーニング」を参考にしました。
自分が実装したコードのgithubリンクがこちらです。
(https://github.com/Akito-Fujihara/MRI-Brain-PSPNet475-model)
jupyter notebookとpyファイルを載せています。
データセット、weightファイルなどはダウンロードして以下の構成にしてください。

MRI-Brain-PSPNet475-model/
┣ kaggle_3m(kaggleからダウンロードしたデータセット※https://www.kaggle.com/mateuszbuda/lgg-mri-segmentation)
┣ log_output.csv(学習のlossを記録)
┣ PSPNet_test.ipynb(推論・可視化)
┣ PSPNet_train.ipynb(学習)
┣ result_image(推論結果を可視化した画像を保存するファイル)
┣ utils
┃&emsp;┣ __init__.py(このファイルが存在するディレクトリをパッケージとなる。)
┃&emsp;┣ data_augumentation.py(前処理)
┃&emsp;┣ dataloader.py(pytorchのdataloaderを作成)
┃&emsp;┣ pspnet.py(モデル)
┃&emsp;┗pspnet475_show.py(可視化)
┗weights(weightファイルを保存)
&emsp;&emsp;&ensp;┗pspnet50_ADE20K.pth(https://drive.google.com/file/d/12eN6SpnawYuQmD1k9VgVW3QSgPR6hICc/view からダウンロード)

# 学習・推論結果と考察
可視化した画像のは水色が教師データ、黄色が推論結果です。

上手く推論できている例
![TCGA_HT_8563_19981209_10_result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677912/3a2a8ee1-99ad-5913-8ae8-51893b7ca273.png)&emsp;&emsp;![TCGA_HT_8106_19970727_14_result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677912/7826c17c-d394-ac93-bd67-8658777670fb.png)
上手く推論できなかった例
![TCGA_HT_8105_19980826_20_result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677912/a273f8a0-b5b0-8cdf-b642-55001575dad2.png)&emsp;&emsp;![TCGA_HT_A61B_19991127_42_result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677912/5e55f2e0-4ed5-5e0a-ecc7-b7756f9bd391.png)

結果から画像の濃淡が少ないものの結果が特に悪いことがわかりました。(当たり前ですが、、、)
(https://paperswithcode.com/paper/torchio-a-python-library-for-efficient など)前処理についてもいろいろ調べてみたいと思います。
また、(https://www.slideshare.net/mitmul/unofficial-pyramid-scene-parsing-network-cvpr-2017) にも書かれていますがcrop size, batch size(colabだと変えられないかも、、), などパラメータが重要らしいので変えてみるのも面白いのではないかと思います。(https://www.st-hakky-blog.com/entry/2017/11/16/161805 参考までに)
solidityのassertとrequireの使い分けかた

# 何をする関数か
assertとrequireの引数がfalseの場合、例外をスローする。
例外をスローした場合、データの原子性(一連のやりとりが全て実行されるか、1つも実行されない状態になること)を守るため、revertされる。

# 例

```js

pragma solidity ^0.5.0;

contract Sharer {
    function sendHalf(address payable addr) public payable returns (uint balance) {
        require(msg.value % 2 == 0, "Even value required.");
        uint balanceBeforeTransfer = address(this).balance;
        addr.transfer(msg.value / 2);
        // Since transfer throws an exception on failure and
        // cannot call back here, there should be no way for us to
        // still have half of the money.
        assert(address(this).balance == balanceBeforeTransfer - msg.value / 2);
        return address(this).balance;
    }
}
```

# require

`require(msg.value % 2 == 0, "Even value required.")`
requireは例では入力チェックを行っている。
requireは例外が投げられた時にエラー文を与えることができる。
基本的には<font color="red">外部からの入力値をチェックするのに使う。</font>


# assert

`assert(address(this).balance == balanceBeforeTransfer - msg.value / 2)`
assertは例では内部のエラーチェックに使用している。
<font color="red">assert は内部エラーのテストと不変条件のチェックのためだけに使用するべき。</font>

# より深いことを言うと...

例外をスローした際、revert操作(`0xfd`)が実行される.
assertでは例外にガスが発生するが、
Metropolisからrequireにはガスが発生しなくなった。
【Drupal】Drupal8のナリッジ収集にGoodなサイト4選

業務でDrupalを扱う時、わからないことを調べることが多々あります。
そんな時に使える4つのサイトをご紹介します。

Drupalを最近使い始めた人は、是非参考にしてみてください。

# 1. Drupal公式ドキュメント
![スクリーンショット 2020-08-16 13.53.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622183/f7c0d3f8-6743-001c-ba6d-2d938c346b61.png)
[Drupal公式ドキュメント](https://www.drupal.org/docs/official_docs/en/_local_development_guide.html)は最も信頼できるサイトだと思います。
（それもそのはず、公式ですから（笑）。）
Drupalに関することならここを見ればとりあえず良いでしょう。
ただし日本語の資料があまり多くないです。


# 2. Annai株式会社「Drupal8初心者講座」
![スクリーンショット 2020-08-16 13.54.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622183/f0678a51-222f-e4d1-6f80-753ee7641689.png)
AnnaiさんはDrupal開発専門の老舗です。
Drupal8を初めて扱う人はまず、Drupal8初心者講座に目を通すと良いでしょう。
「Drupalとは何か？」から実際にDrupalをインストールしたり、テーマを導入したり、というところまで書いてあります。


# 3. Studio Umi「Drupal BLOG」
![スクリーンショット 2020-08-16 13.54.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622183/ba0eaa0c-f56b-39be-ff43-acc6e067856f.png)
こちらもDrupal開発専門の会社、Studio UmiさんのDrupal専門の技術ブログ「[Drupal BLOG](https://www.studio-umi.jp/blog)」です。
Annaiさんと同様に基本的なことももちろん、セキュリティに踏み込んだ記事や最新のバージョンであるDrupal9に関する記事など、かなり技術に特化した内容が多いです。
そのため常にDrupalに関する最新の情報を常に手に入れることができるサイトかと思います。

# 4. NTTデータ先端技術株式会社「Drupal翻訳サイト」
![スクリーンショット 2020-08-16 13.54.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622183/6bbaf7d5-f01d-1efe-f552-931d023a21d5.png)
NTTデータのグループ会社であるNTTデータ先端技術株式会社さんの「[Drupal翻訳サイト](http://www.intellilink.co.jp/drupal)」です。
Annaiさんと同様に初心者向けの話であったり、概要的な話が多いです。
公式ドキュメントを日本語に翻訳して発信しているため、内容の信憑性はかなり高いです。



---

以上がDrupalについて調べる際にオススメしたいサイト4つでした。
皆さんのDrupal開発の役に立てれば幸いです。
【Git】現場で初心者が覚えるべきGitコマンド

##はじめに
　2020年3月に、私はITエンジニアへ転職しました。現場で、gitを用いてシステムバージョンが管理されています。
　私はインタネットでgitを調べると、コマンドがたくさんあります。([Git ドキュメント　日本語版](https://git-scm.com/book/ja/v2))
　どこまでわかれば現場で働けるかという不安がありました。
　私みたい**初心者**に対しては、逆引きでコマンド調べ、使うのは一般だと思います。
　でも、仕事の効率良くなるために、gitの基本コマンドを覚えるべきです。
　下記のコマンドが分かれば、仕事がなんとかできると思います。

##Git基本コマンド
　開発担当により、使われるコマンドは違います。
　プログラマーである私はよく使うgitコマンドを下記にまとめました。

|コマンド|意味|
|:--|--:|
|git branch|ブランチ一覧|
|git branch ブランチ名|ブランチ作成|
|git checkout|ブランチの移動|
|git checkout -b|リモートブランチに紐づ、け新しいローカルブランチを作成、チェックアウトする|
|git add .|全てのファイル、ディレクトリの追加|
|git commit -m “コミット内容”|ファイルのコミット|
|git push|ファイルの更新|
|git pull|ローカル情報を更新|
|git fetch|リモートから最新情報をローカルに持ってくる|
|git cherry-pick|他ブランチの特定コミットのみを反映する|

##コマンドの説明
####ブランチについての操作
　1. ブランチ一覧を表示、および操作位置を確認する

```
　   $ git branch
```

　2. 新しいブランチを作成
　　「apple」という新しいブランチを作成する(操作位置を移動しない)

```
　   $ git branch apple
　   $ git branch
```  
　3. ブランチの移動
　　操作位置(＊)を「apple」ブランチに移動する

```
　   $ git checkout apple　
　   $ git branch
```
####編集ファイルについての操作
　図でファイルのアップデートや更新など操作をイメージしました。
![屏幕快照 2020-08-02 下午12.11.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684879/9ac1ea65-370a-4814-2dee-caa6d4097cbc.png)

####補足
* リモートにおいて、ブランチ(banana)が先に作成された場合、  
  ローカルで新しいブランチ(peach)を作成、リモートのブランチ(banana)に接続、  
  操作位置（＊）新ブランチへ移動する場合には「git checkout -b 新ブランチ名 origin/ブランチ名」を使います。  

　例えば、

```
　   ＄ git fetch  #ブランチ情報を更新する
　   ＄ git checkout -b peach origin/banana 
```
　
##終わり
　とりあえず、上記の基本コマンドを覚えれば、現場ではgitを使えると思います。
　gitコマンドを使うほどgitの魅力を感じられます。
　満足せずに、gitコマンドを多く勉強しましょう。

###雑談
　私は記事と通して、皆さんと交流したいです。また自分の成長と記録したいです。
　記事の内容、あるいは文章の書き方について、ご意見がありましたら、
　是非、コメントをお願いします。
Flutterでクイズアプリを作成〜Flutter勉強会アウトプット〜

先日2020/8/14に参加したFlutter勉強会についてアウトプットします。
勉強会URL(connpass)：[はじめてのFlutter！ - connpass](https://crowish.connpass.com/event/185529/)

# Flutterの概要
**Flutter**は Google 製のオープンソースのモバイル開発フレームワークであり、iOS,Androidごとに開発言語等を使い分けることなく、1つのコードベースで両方のプラットフォームに対応させることができます。
また、最近ではWebアプリへの対応も進められているようです。
Flutterの開発には**Dart**という言語を使用し、あらかじめ用意されたウィジェットを使用して、ボタンやテキスト、アイコンの表示といったGUIデザインを作ることができます。

# 勉強会で作成したアプリ
勉強会ではサンプルとして、ボタンを押下するごとにランダムに文字列を表示する占いアプリを作成したほか、サンプルを改造したアプリを参加者各自で作成しました。
作業には**DartPad**というブラウザ上で稼働するエディタを使用しました（本格的な開発の場合Xcode,Android Studioなどを使用する模様）。

私は1つだけ表示していたボタンを4つに増やした上で、ボタンごとに表示文字列を出し分けることで**クイズアプリ**を作成しました。

クイズアプリのコードを入力したDartPadには以下のURLでアクセスできます。
勉強会で即興で作成した後、若干不備修正・コメント追加を行っています。
**Gist**というGitHubのサービスによって、Gistで共有したコードをDartPadに表示させています。
https://dartpad.dartlang.org/a4cdb87971eef02b8ad63d59b876818c


クイズアプリの画面写真は以下の通りとなります。

**初期表示**
![スクリーンショット 2020-08-16 13.41.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409123/779e3aef-a282-7752-67d7-98e7386ec8cd.png)
**不正解（B以外をタップ）**
![スクリーンショット 2020-08-16 13.42.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409123/a5adf561-3f25-5f77-198b-6a081f874769.png)
**正解（Bをタップ）**
![スクリーンショット 2020-08-16 13.42.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409123/d5d8b43d-90e2-9131-c1bd-6993ef7b1646.png)

# 最後に
Flutterについて、比較的簡単にスマホ用のGUIアプリを作成できることに興味を持ちました。現在Googleが力を入れて開発しているようなので、今後もFlutterの動向に目を配りたいと考えております。
本記事内の記述に誤り等ございましたらご連絡をお願いいたします。
「usort」自分のルールでソートする

# usort
[PHP公式サイト](https://www.php.net/manual/ja/function.usort.php)
>usort — ユーザー定義の比較関数を使用して、配列を値でソートする
>usort ( array &$array , callable $value_compare_func ) : bool

# 使い方の例

```php:rsort.php
$data = ['Thomas Jefferson','Andrew Jackson','John Adams','George Washington','James Monroe'];

usort($data,'usortPre');

print_r($data); //Array ( [0] => George Washington [1] => John Adams [2] => Thomas Jefferson [3] => James Monroe [4] => Andrew Jackson )


function usortPre($a,$b){
    $presidents = ['George Washington','John Adams','Thomas Jefferson','James Madison','James Monroe','John Quincy Adams','Andrew Jackson','Martin Van Buren'];
    return array_search($a,$presidents) <=> array_search($b,$presidents);
}
```

usortPreの返り値によって、$dataを並び替える

|$a  |$b  |array_search(_$a_,_$presidents_)  |array_search(_$a_,_$presidents_)  |array_search(_$a_,_$presidents_) <=> array_search(_$b_,_$presidents_)|
|---|---|---|---|---|
|Thomas Jefferson  |Andrew Jackson  |2  |6 |-1
|Andrew Jackson  |John Adams  |6  |1 |1
|Thomas Jefferson  |John Adams  |2  |1 |1
|Andrew Jackson  |George Washington  |6  |0 |1
…省略

<=> : 左辺が大きいと、1を返す。右辺が大きいと、-1を返す。等しいと0を返す

帰ってきた値(0,-1,1)をもとに、usortでは
0の場合は並び替えなし。
1の場合は_$a_の順番を_$b_より繰り下げる.
-1の場合は_$a_の順番を_$b_より繰りあげる.

#参考
[【 php 】usort関数の使い方](https://qiita.com/soft-drink/items/2f6860a6767f2d15a56e)
DockerでMySQL立ち上げようとするとMySQL init process failed.となる

## Docker関連ファイルの設定
以下で設定。

* docker-compose.yml

```
version: '3'
services:
  db:
    container_name: mysql-test-db
    build:
      context: .
      dockerfile: ./Docker/mysql/Dockerfile
    volumes:
      - ./Docker/mysql/sqls:/docker-entrypoint-initdb.d
      - ./Docker/mysql/data:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=secret
      - TZ=Asia/Tokyo
    ports:
      - '13310:3306'

```

* Dockerfile

```
FROM mysql:5.7

ADD ./Docker/mysql/conf.d/my.cnf /etc/mysql/conf.d/my.cnf
```

* my.cnf

```
[mysqld]
character-set-server = utf8mb4

[mysql]
character-set-server = utf8mb4

[client]
character-set-server = utf8mb4
```

## 発生事象
以下を実行。

```
docker-compose up -d
```

Mysqlに接続しようとするとできない。

```
mysql -u root -h 127.0.0.1 -P 13310 -p 
Enter password: 
ERROR 1130 (HY000): Host '192.168.32.1' is not allowed to connect to this MySQL server
```

以下でログを確認すると`MySQL init process failed.`が発生している。

```
docker-compose logs -f
(略)
mysql-test-db | MySQL init process in progress...
mysql-test-db | MySQL init process in progress...
mysql-test-db | MySQL init process in progress...
mysql-test-db | MySQL init process failed.
mysql-test-db exited with code 1
```

bashでコンテナに入ってmysqlを叩くとエラーが表示される。

```
docker container exec -it mysql-test-db bash
root@b50bff16a01d:/# mysql
mysql: [ERROR] unknown variable 'character-set-server=utf8mb4'
```

## 修正後ファイル

* my.cnf

```
[mysqld]
character-set-server = utf8mb4

[mysql]
default-character-set=utf8mb4

[client]
default-character-set=utf8mb4
```

単純にコピペミスでした。悲しい。。

## 修正後ファイル2

さらに半角スペースが入っていると正しく動作しないことがわかりました。。
以下で正常にログインまでできました。
（どこかでハマるとトライ＆エラーでさらにハマってしまう悪い例です。元々はスペース無しでやっていたみたいです。）

* my.cnf

```
[mysqld]
character-set-server=utf8mb4

[mysql]
default-character-set=utf8mb4

[client]
default-character-set=utf8mb4
```


## 参考
https://www.ilovex.co.jp/blog/system/cat818/mysqldefault-character-set.html
AnsibleでWindowsの共有フォルダを操作する

こんにちわ！ @ktoshi です！

今日は Ansible で Windows Server を触る機会があり、
その際のことを備忘録として記載します。

少し、設定に困った個所もあったので皆さまの参考になればと思います。

# 概要
Ansible で Windows Server に共有フォルダを作成する

# 環境
* 実行環境
 * OS: Ubuntu 18.04.4 (Windows 10 WSL 利用)
 * python 3.8.3
 * ansible 2.9.12

* Windows Server側
 * Windows Server 2012 R2 Standard

# 事前準備
事前に Windows Server を Ansible で操作できるようにしておいてください。
[こちら](https://qiita.com/ksawada1979/items/31214d147277042f1e32)などをご参考ください。

# Let's Enjoy!!!
## 共有フォルダの作成

```yaml
- name: フォルダの作成
  win_file:
    path: D:\Shared
    state: directory

- name: 共有設定
  win_share:
    name: Shared
    description: Shared Folder
    path: D:\Shared
    read: Everyone
    full: Administrators
``` 
これで共有フォルダを作成できます。簡単ですね。
え？何に困ったの？と思われる方もおられるでしょう。
そうです、別にここで困ったわけではないのです。

一応、各コマンドの説明だけ記載しておきます。
### win_file
Windows 上でファイルやフォルダを操作するコマンドです。
今回は共有フォルダを作成する際に利用しています。
[公式ドキュメント](https://docs.ansible.com/ansible/latest/modules/win_file_module.html)

### win_share
Windows 上のフォルダに対して共有設定を行います。
なお、フォルダが無い場合に作成などの処理はないので、事前にフォルダを作成しておく必要があります。
[公式ドキュメント](https://docs.ansible.com/ansible/latest/modules/win_share_module.html)

## サブフォルダの共有設定
ここからが本題です。
社内で Active Directory を使って共有をされておられる場合、
共有フォルダ自体は全ユーザが参照でき、その下のサブフォルダで組織ごとに
権限を分けられる運用をされるのではないでしょうか。

今回、それを設定する際に継承の無効化などの設定に困ったので
同じような方の手助けになればと思います！

今回は共有フォルダ配下に「Development」というフォルダを作成し、下記のような権限を付与します。

* フルコントロール
 * Administrators グループ
 * Dev グループ
* 読み取り権限
 * Sales

ひとまず、例のごとく Playbook はこんな感じです。

```yaml
- name: サブディレクトリを作成
  win_file:
    path: D:\Shared\Development
    state: directory

- name: サブディレクトリに権限を追加
  win_acl:
    user: "{{ item.name }}"
    path: D:\Shared\Development
    type: allow
    rights: "{{ item.rights }}"
  with_items:
    - name: Administrators
      rights: FullControl
    - name: Dev
      rights: FullControl
    - name: Sales
      rights: Read,ListDirectory

- name: 上位フォルダからの権限継承を無効化
  win_acl_inheritance:
    path: D:\Shared\Development
    reorganize: no
    state: absent
```
いざ、書けてしまえば簡単なのですが、なにせ英語が不自由でどのコマンドが意図したいものかわからず苦労しました。。。

### win_acl
フォルダに対して権限の設定を行います。
なお、「user」についてはグループの指定も可能です。

### win_acl_inheritance
上位フォルダからのアクセス権の継承を設定するコマンドです。
オプションは下記のとおりです。

* state
 * absent: 無効化（デフォルト）
 * present: 有効化
* reorganize
 * no: 継承されている権限を残さない。（デフォルト）
 * yes: 継承されている権限を明示的にこのフォルダへの権限として設定する。

なお、今回の例では上位からの継承を無効化した上で既存の権限は一度削除するようにしています。

# まとめ
最近、ますますTerraform や Ansible を使う機会が増えてきて、今まで使ったことのなかったプロバイダやモジュールを利用することが増えてきました。
今回は Windows を初めて Ansible で使ってみましたが、非常に楽でありがたい。

ちなみにADアカウントなども今Ansibleで作業を行うように準備を進めているのですが、
ADのOUを作成する用の Ansible のコマンドってないんでしょうか。。。
いい感じにADグループ操作ができたのですが、その先に進めず少し困っています。

では皆様！引き続き、素晴らしき Ansible ライフをお送りください。
STM32のUSARTでDMA受信

# はじめに
STM32のUSARTでHAL関数を使ってDMA受信する方法をまとめました。
単純にHALの受信関数のみ使うと受信するデータ列のサイズは固定長である必要が有ります。
ここでは可変長サイズでも対応可の方法を集めました。

# 環境
OS：Windows10 Pro 2004
IDE:STM32CubeIDE 1.3.0
デバイス：STM32F407 Discovery kit

# 循環バッファ方式
[Topic: 'Best' way to load UART data to ring buffer with STM32/HAL  (Read 25675 times)](https://www.eevblog.com/forum/microcontrollers/_best_-way-to-load-uart-data-to-ring-buffer-with-stm32hal/)

## DMA設定
USART受信のDMAをCircularモードに設定します。
これにより、バッファの末端を超えると先頭からデータを格納する循環バッファになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120192/c9e2ea93-dc8c-9b1d-07a3-d0eb02c13f64.png)

## 実装
データ受信をポーリング監視する場合の実装です。

```
#define USART_RX_BUFFSIZE 128

static UART_HandleTypeDef* pHuart;
static uint8_t RxBuff[USART_RX_BUFFSIZE];
static uint32_t rd_ptr;

#define DMA_WRITE_PTR ( (USART_RX_BUFFSIZE - pHuart->hdmarx->Instance->NDTR) % (USART_RX_BUFFSIZE) )

void USART2_Init(void)
{
	pHuart = &huart2;
	memset(RxBuff, 0, sizeof(RxBuff));
	rd_ptr = 0;

	__HAL_UART_DISABLE_IT(pHuart, UART_IT_PE);
	__HAL_UART_DISABLE_IT(pHuart, UART_IT_ERR);
	HAL_UART_Receive_DMA(pHuart, RxBuff, USART_RX_BUFFSIZE);
}

int USART2_RX_IsEmpty(void)
{
	return (rd_ptr == DMA_WRITE_PTR);
}

uint8_t USART2_RX_Read(void)
{
	uint8_t c = 0;
	if(rd_ptr != DMA_WRITE_PTR) {
		c = RxBuff[rd_ptr++];
		rd_ptr %= USART_RX_BUFFSIZE;
	}
	return c;
}
```

DMA_WRITE_PTRがDMAによる次書き込み位置を表し、rd_ptrが次読み取り位置を表しています。
なお、バッファサイズ指定を柔軟にする為に、参考記事からは終端越えの処理を変えています。

# IDLEイベント方式
データ受信後、一定時間経過した時に発生するイベントです。
[参考](https://www.st.com/content/ccc/resource/training/technical/product_training/4f/cc/bb/f7/04/99/41/66/STM32L4_Peripheral_USART.pdf/files/STM32L4_Peripheral_USART.pdf/jcr:content/translations/en.STM32L4_Peripheral_USART.pdf)

受信データがパケット形式で間隔を空けて送られてくる場合などに使えます。

## 設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120192/49d74bbe-c952-7bf1-8960-541747d58cfd.png)

## 実装

```
#define USART_RX_BUFFSIZE 128  // 受信パケットサイズより大きくします

static UART_HandleTypeDef* pHuart;
static uint8_t RxBuff[USART_RX_BUFFSIZE];
static uint32_t rd_ptr;

#define DMA_WRITE_PTR ( (USART_RX_BUFFSIZE - pHuart->hdmarx->Instance->NDTR) % (USART_RX_BUFFSIZE) )

void USART2_Init(void)
{
	pHuart = &huart2;
	memset(RxBuff, 0, sizeof(RxBuff));
	rd_ptr = 0;

	__HAL_UART_DISABLE_IT(pHuart, UART_IT_PE);
	__HAL_UART_DISABLE_IT(pHuart, UART_IT_ERR);
	__HAL_UART_ENABLE_IT(pHuart, UART_IT_IDLE);  // <= 追加
	HAL_UART_Receive_DMA(pHuart, RxBuff, USART_RX_BUFFSIZE);
}
・・・
void USART2_EventHandler(void)
{
	int rxlen = 0;

	if(__HAL_UART_GET_FLAG(pHuart, UART_FLAG_IDLE) != RESET)
	{
		__HAL_UART_CLEAR_IDLEFLAG(pHuart);
		HAL_UART_DMAStop(pHuart);

		// データ受信処理
		rxlen = DMA_WRITE_PTR;  // 受信データ長(受信データ長がバッファサイズと同じ場合は0に戻る為注意)

		HAL_UART_Receive_DMA(pHuart, RxBuff, USART_RX_BUFFSIZE);  // DMA受信再スタート
	}
}

```

stm32f4xx_it.c

```
void USART2_IRQHandler(void)
{
  /* USER CODE BEGIN USART2_IRQn 0 */
  USART2_EventHandler();  // <= 追加
  /* USER CODE END USART2_IRQn 0 */
  HAL_UART_IRQHandler(&huart2);
  /* USER CODE BEGIN USART2_IRQn 1 */

  /* USER CODE END USART2_IRQn 1 */
}
```
AtCoder Problems Training Easy まとめ

#はじめに
[AtCoder Problems Training](https://kenkoooo.com/atcoder/#/training/Boot%20camp%20for%20Beginners) の Easy が全部解けたので自分なりの解法をざっくりまとめました。
使用言語は全てPython、10 問ずつまとめています。
自分なりに解いたつもりですが、公式解説と同じ場合は申し訳ないです。

#目次
[1~10](https://qiita.com/tnodino/private/fe81289a78c79c53e41e)
[11~20](https://qiita.com/tnodino/private/a2f1118ad8276de714e2)
[21~30](https://qiita.com/tnodino/private/bdce8619699fc9cb3110)
[31~40](https://qiita.com/tnodino/private/426ea11e1509bbe282d8)
[41~50](https://qiita.com/tnodino/private/3e92afbd7fd8396a8118)
[51~60](https://qiita.com/tnodino/private/62637218c5884b2af10d)
[61~70](https://qiita.com/tnodino/private/0997709fa992e538ed36)
[71~80](https://qiita.com/tnodino/private/1249d60df34c0fda8e6e)
[81~90](https://qiita.com/tnodino/private/83c4a61a0361b8995983)
[91~100](https://qiita.com/tnodino/private/88bacef44c037dc9fc89)
S3の画像をCloudFrontを使ってWordpressに配信する

[以前の記事](https://qiita.com/kenjinnnn/items/b7b5f7e9d39b96c9a869)で、Wordpressの画像をS3に移行しました。

これでWordpressの移行や、静的サイトジェネレータへの移行ができると思っていたのですが、s3に画像を移行して数日で、s3の無料枠である20000requests/monthをあっという間に超えてしまうと思ったので、CloudFront(CDN)で配信することにしました。
※s3のpostは、2000req/monthです。移行画像数が多すぎると2000を超えてしまいますが、これは仕方ありません。

参考にした記事は、[こちら](https://blog.lawrencemcdaniel.com/integrating-aws-s3-cloudfront-with-wordpress-2/)です。

## s3のアクセス権を確認する

S3のBlock public accessがすべてoffになっていることを確認します。 

## cloudfrontを作成する

[参考にした記事](https://blog.lawrencemcdaniel.com/integrating-aws-s3-cloudfront-with-wordpress-2/)通りに、cloudfrontを作成します。

![Screen Shot 2020-08-16 at 11.42.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236231/952b1545-9656-1313-860e-2b1d1de9e233.png)
cloudfront作成画面で、s3バケット名を選択する

![Screen Shot 2020-08-16 at 11.42.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236231/1337fa0d-c122-5776-a9fa-df7ebbc30520.png)
redirect HTTP to HTTPSを選択

![Screen Shot 2020-08-16 at 11.43.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236231/c5e97890-1066-dffc-16cc-88a1c8c79e9e.png)
画像を圧縮したい場合は、compress objects automaticallyをyesにする。

![Screen Shot 2020-08-16 at 11.44.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236231/132ef358-edf8-1359-16cc-f974b84f8cbd.png)
Create Distributionをクリックして作成。

![Screen Shot 2020-08-16 at 11.47.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236231/742983d8-bee8-1ced-fbeb-df55bb9274e1.png)
statusがDeployedになれば作成完了。

僕はサブドメインは設定しませんでしたが、設定したい方は、CNAME設定にサブドメインに置き換えてください。

## wordpressでcroudfrontURLを設定する

![Screen Shot 2020-08-16 at 11.50.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236231/cf9fa810-703b-c90d-3611-191b3f8853fa.png)
WP Offload Media LiteプラグインのProvideのchangeをクリック。

![Screen Shot 2020-08-16 at 11.50.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236231/c23c883c-19df-34a5-3816-a49df0754307.png)
croudfrontを選択。

![Screen Shot 2020-08-16 at 11.51.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236231/75288e18-2969-921c-f413-50e0b2867a86.png)
croudfront画面から、CNAMEURLをコピーして貼り付ける。

![Screen Shot 2020-08-16 at 11.51.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236231/8ef865e0-180d-4ed4-6df2-cf1a121c0e93.png)
Force HTTPSをONにする。

以上で設定完了です。

画像URLをcroudfrontのCNAMEURLに変更して、画像が表示されるか確認してみましょう。

## 記事内URLを置き換える

search regexプラグインで記事のURLをCNAMEURLに置き換えます。

### サイト全体の画像URLを変更しておく

メディアライブラリなどは、まだサーバ画像URLになっているので、これをcroudfrontのCNAMEURLに変更しておきます。

`https://your-domain-name/wp-admin/options.php`にアクセスしてください。

command+Fで`upload_url_path`を検索します。

![Screen Shot 2020-08-16 at 13.04.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236231/878044ce-734c-9f6f-1029-e1ebc4040d3e.png)

upload_url_pathフォームにcroudfrontのCNAMEURLを入力します。

これで、メディアライブラリなどの画像URLもすべてcroudfrontから画像が配信されるようになるはずです。
※これを設定すれば、記事内のURLもすべて変更されるかもしれません。置き換える前に試してみてください。
正規表現について基礎から学習したので、自分の言葉で一覧としてまとめておく

Rubyチェリー本の著者の方が4回にわたりハンズオンで理解できる正規表現に関する記事をQiitaに公開してくださっており、無料でいいのかレベルでわかりやすかったので記録として残しておく

・[初心者歓迎！手と目で覚える正規表現入門・その１「さまざまな形式の電話番号を検索しよう」 - Qiita](https://bit.ly/3fYE8Qr)

正直まとめてないものもあるので、詳しくは↑の記事参照

#エスケープについて
後述するが「エスケープ」という単語が出てくる。
正規表現のメタ文字なのか、それとも文章中の純粋な文字として扱うのかを伝える為に`\`を使う事がある。
それをエスケープというらしい。

正規表現の`[]`ではなく純粋に検索したい文章の中の"[ ]"を検索したい時に`\[ \]`と書くと、文章中の"[ ]"が検索できるといった仕組み。


#一覧


 
・`*` :  0文字以上
・`+` : 1文字以上
・`?` : 直前の文字が0もしくは1字。
・`d\` : 
・`w\` :
・`/\` : 最初のスラッシュ(`/`)で検索したい文字列中のバックスラッシュ(`\`)をエスケープする

・`^` : ①行頭  ②〜以外の  ③または^ 
< ex② > `[^AB]`なら「AB以外の文字列」
< ex③ > `[AB^]`なら「AかBか^」


・`$` : 行末

・`\n` : 行末＋改行列 置換してある一文を削除したい場合、`$`指定だと改行が残るが、`\n`指定なら改行を残さず削除が可能
・`\t` : タブによるスペース
・`\s` : 空白文字全般（スペース、タブ、改行文字等)
・`\b` : 単語の境界を指す。　
「bartender」と「art」を含む文章のartだけ抜き出したい時は、`\bart\b`で可能。この場合の正規表現内訳は`\b`＋`art`＋`\b` 
他にもRailsの「form_with do |f|」「f.label」や「f.text_form」のfだけ抜き出したい時などに使ったりする。

・`|` : OR(または)
・`.` : 何らかの文字

・`^.+` : 行頭からの何らかの文字が1文字以上続く
・`.+$` :行末まで何らかの文字が1文字以上続く

・`{n}` : 直前の文字が n 個
・`{n,}` : 直前の文字が n 個以上
・`{n,m}` : 直前の文字が n 個以上 m 個以下
・`{,m}` : 直前の文字がm 個以下
unity1weekに参加して得た知見

# はじめに

VTuberとして初めてunity1weekに参加しました。
ゲームを開発している時に得た知見2つについて書きたいと思います。

<details>
<summary>開発の思い出話</summary>
今回のテーマは「ふえる」でした。最初は「ふるえる」と読み間違えました。
初日に大枠のコンセプトを決め、cubeなどでコンセプトの動作を検証しました。
2日目は初日に作ったロジックだとうまくいかないことが判明したので、1から作り直しました。
3、4日目はゴリゴリと実装しました。ほとんどがUniRxの使い方を調べてた気が。
navmeshは初めて使うので、当たり判定などについても調べて実装しました。
ググれば大抵のことは分かったので、良かったです。
ただ、情報が古いこともあったので、そこは注意しました。
5日目でUI以外は完成したと思ったので、unityroomにアップロードして確認しました。
この日から断食してたので、頭が回らなかったです。早めに作ってて良かったなと実感しました。
6日目はUI追加したり、BGMつけたり、ゲームバランス整えたり。
コード書くのは得意なんですが、こーいう細かい調整は不得意ですね。
AIが良きに計らってくれる日を待ってます。
7日目は前の日に思いついたminimapを実装し、紹介動画をyoutubeにあげて、この記事を書いてます。
</details>

# キー入力が一定時間ないことを検知

「プレイヤーは一定時間キューの入力がないとウエイトモードになる」
という処理をUniRxでやる場合、以下のようなコードを書けばOKです。

```C#
this.UpdateAsObservable()
            .Where(_ => Input.anyKeyDown)
            .Timeout(TimeSpan.FromSeconds(0.5)) //0.5秒入力がなかったら、
            .OnErrorRetry((Exception e) => animator.SetBool("isWalk", false)) //アニメーションをOFF
            .Subscribe();
```

# Tweet機能

ゲームのスコアなどTweetさせる機能を入れていたのですが、unityroomで実行すると
「twitter.com で接続が拒否されました。」
というメッセーが出ました。

```C#
    void Tweet() {
        string esctext = UnityWebRequest.EscapeURL($"感染率{attak.value}%\n残り時間{remainingTime}秒\n{count}/{number.value}のぬこがお友達になったにゃん(｢ФДФ)｢");
        string esctag = UnityWebRequest.EscapeURL("unity1week");
        string url = UnityWebRequest.EscapeURL("https://unityroom.com/games/");
        string TweetURL = "https://twitter.com/intent/tweet?text=" + esctext + "&hashtags=" + esctag + "&url=" + url;

        Application.OpenURL(TweetURL);
    }
```
自分のマシンなら、windowsでもwebglでも動作するのですが、
このApplication.OpenURL(TweetURL)がunityroomのwebglでは動かないみたいです。

以下のように修正して、動くようになりました。

```C#
    void Tweet() {
        string esctext = UnityWebRequest.EscapeURL($"感染率{attak.value}%\n残り時間{remainingTime}秒\n{count}/{number.value}のぬこがお友達になったにゃん(｢ФДФ)｢");
        string esctag = UnityWebRequest.EscapeURL("unity1week");
        string url = UnityWebRequest.EscapeURL("https://unityroom.com/games/");
        string TweetURL = "https://twitter.com/intent/tweet?text=" + esctext + "&hashtags=" + esctag + "&url=" + url;

#if UNITY_WEBGL && !UNITY_EDITOR
        Application.ExternalEval(string.Format("window.open('{0}','_blank')", TweetURL));
#elif UNITY_EDITOR
        System.Diagnostics.Process.Start(TweetURL);
#else
        Application.OpenURL(TweetURL);
#endif
    }
```

# おわりに

今回は「自分のコンセプトを締め切り内で完成させる」を目標としました。
なので、かなり荒削りなゲームになりましたが、無事完成させることはできました（バグはあるかも）。
「ここをこうしたい！」という思いはあったのですが、その部分はコンセプトに影響せず、時間を考えて、バッサリなくしました。

わからないときは、ググって先人の知識をお借りしました。
この記事が、あとに続く人たちの参考になれば幸いです。

あと、UniRxはほんといいです。
MarketingCloudSDK iOSでpush通知からGAにカスタムパラメータを送信する

#環境
・xcode Version 11.3.1 (11C504)
・swift Version 5.1.3
・MarketingCloudSDK iOS (v7.2.1)
・Mac OS 10.14.6(Mojave)

#準備
1.[MarketingCloudSDK iOSでシンプルなpush通知を送信する](https://qiita.com/techman/items/a136c903ea74f065b92c)
2.[MarketingCloudSDK iOSでリッチPush通知を送信する]
(https://qiita.com/techman/items/06267ff52a2531264cac)
の続きとなります。

#Firebaseをアプリに組み込む
1. ***[firebaseのコンソール](https://console.firebase.google.com/u/0/?hl=ja)からプロジェクトを作成する***
※googleAnalyticsの設定をONにする

2. ***アプリをFirebaseに登録する***
 1. Firebaseコンソールの中央にあるiosアイコンをクリックする
![test-app_-_test-app_-_Firebase_コンソール.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246356/68be2921-42ac-f44d-e102-6473905f08d6.png)

 2. 指示通り①〜⑤まで進めていく
![スクリーンショット 2020-08-16 11.04.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246356/cd110fd4-3abb-d3dd-c041-dcc141fc2fdc.png)

　① Apple Developer Programにて登録したアプリのバンドルIDを入力。他は省略可能
　② GoogleService-Info.plistをダウンロードし、AppDelegate.swiftなどと同じフォルダに追加する
　③ podfileにFirebaseSDKの設定を追加し、```pod install```する 
　　※cocoapodsをインストールしていない場合は[MarketingCloudSDK iOSでシンプルなpush通知を送信する](https://qiita.com/techman/items/a136c903ea74f065b92c)の```SDK追加```を参照してください
　④ didFinishLaunchingWithOptionsメソッドに初期化コードを追加する
　⑤ ***アプリを実行***してインストールされたかを確認（かなり時間かかります）

#カスタムキーの設定をアプリに追加
SMC側からカスタムキーと呼ばれるパラメータをpush通知と一緒に送信することができます。
　※mobliePUsh > 管理 > 設定でカスタムキーを有効にする必要があります。

以下実装サンプルとなります

```AppDelegate.swift
// このメソッドは、ユーザーがアプリケーションを開くか、通知を破棄するか、UNNotificationActionを選択することで通知に応答したときに、デリゲートで呼び出される
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
    // tell the MarketingCloudSDK about the notification
    MarketingCloudSDK.sharedInstance().sfmc_setNotificationRequest(response.notification.request)
    // the dictionary containing custom keys    
    let userInfo = response.notification.request.content.userInfo
    let someValue = userInfo["SMCで設定した任意のキー"] as? String
    if someValue != nil {
       Analytics.logEvent("イベントの名前を設定", parameters: [
         "SMCで設定した任意のキー": someValue!
       ])
    }
    // application-specific usage follows
    print(someValue ?? "someValue is nil")
    completionHandler()
}
```

```AppDelegate.swift
Analytics.logEvent("イベントの名前を設定", parameters: [
         "SMCで設定した任意のキー": someValue!
])
```

上記部分でカスタムイベントの名前を設定し、SMC側で設定したキーと値をGAに送信します。

#GA側で確認する
1. 実機にビルドし、SMC側でカスタムキーとパラメータを送信し、デバイスに来たpush通知をタップする
2. firabaseのダッシュボードから```Google アナリティクスでデータを確認する```をクリックする
![test-app-ios_-_Dashboard_-_Firebase_コンソール_と_メモ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246356/fd1e6035-7a39-73b4-7fd5-183d40d922aa.png)
3. ホームのダッシュボードに反映されるまで24時間ほどかかるので、リアルタイムでデータを確認できる```DebugView```で確認する（今はなにも表示されてないですが、正しく送信されていればパラメータを確認できます）![アナリティクス.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246356/4daedf3c-5b32-2dd8-10fc-90f757ab3032.png)

#参考リンク(公式）
https://salesforce-marketingcloud.github.io/MarketingCloudSDK-iOS/push-notifications/custom-keys.html
https://firebase.google.com/docs/analytics/android/events?hl=ja
# Spring Bootで、thymeleaf の変更を自動でブラウザに反映する方法

spring bootで開発をしていて、Javaの変更はdevtools で自動的に変更が反映されるのに、HTML等の静的ファイルが自動で反映されないというとき。

application.yml(あるいはapplication.properties)に以下の設定を追加することで、変更がすぐにブラウザに反映されるようになります。

```yml
spring:
  thymeleaf:
    prefix: classpath:/templates/
```

もしくはこちらの書き方でも反映されます。

```yml
spring:
  thymeleaf:
    prefix: file:src/main/resources/templates/
```

こちらのサイトによると１つ目の書き方がデフォルトのようです。
https://spring.pleiades.io/spring-boot/docs/current/reference/html/appendix-application-properties.html
Arrows tab Q584/H に linux の debian をインストール

Linuxが入らないと噂の Arrows tab Q584/H に linux の debian をインストールします。

ubuntuでも32bit efiでのインストールを試みましたがどうにもインストール画面で黒くなり諦め

debian のダウンロード

Index of /cdimage/unofficial/non-free/cd-including-firmware/current-live/i386/iso-hybrid 
https://cdimage.debian.org/cdimage/unofficial/non-free/cd-including-firmware/current-live/i386/iso-hybrid/

今回ダウンロードして使用したのはこちら
debian-live-10.5.0-i386-gnome+nonfree.iso

基本的にi386系であれば、他のLinuxでもいける確率が高いです。
mxlinuxも大丈夫でした。使いにくいですが（＾＾；

BISOの設定
電源と音声Volumeの下ボタンを押す
bootの順番を指定する。CD→USB→本体

インストール作業

EFIのインストールが進められたら「はい」を選択する

Wifiはドライバが当たらないのでUSBのWifiなどを使用する。

rootのパスワードは空にしておくと既存ユーザーでもsudoができるようになる
※なぜかrootでログインができないので今回は空で設定

再起動後、apt リポジトリが少ないので追加する

~~~~
sudo nano /etc/apt/source.list
~~~~

~~~~
deb http://ftp.jp.debian.org/debian/ buster main non-free contrib
deb-src http://ftp.jp.debian.org/debian/ buster main non-free contrib

deb http://security.debian.org/ buster/updates main non-free contrib
deb-src http://security.debian.org/ buster/updates main non-free contrib

# buster-updates, previously known as 'volatile'
deb http://ftp.jp.debian.org/debian/ buster-updates main non-free contrib
deb-src http://ftp.jp.debian.org/debian/ buster-updates main non-free contrib
~~~~

これで　sudo apt update や sudo apt install する際にいろいろなアプリをインストールすることができるようになる。

参考リンク

計算機関係/Debian(buster)をインストール - PukiWiki 
http://hepl.shinshu-u.ac.jp/~hasegawa/wiki/index.php?%E8%A8%88%E7%AE%97%E6%A9%9F%E9%96%A2%E4%BF%82/Debian%28buster%29%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB