OmniAICreator/Qiita-1.07M huggingface dataset:
Docker環境でDjangoのバージョンを指定してインストール

Docker環境でDjangoのバージョン指定してインストールしてみたのでやったことをメモしておきます
pythonのバージョンが3.8.5に対してDjangoのバージョンが1.11だったんだけどpythonのバージョン対応してないっぽかったのでDjangoのバージョンを上げることにしました。(参考画像は下記)

![スクリーンショット 2020-09-05 22.48.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/544334/ec8c1818-6f0f-c36e-7a6b-71cf330d24ee.png)

## バージョン対応の参考資料
https://docs.djangoproject.com/ja/3.1/faq/install/#what-python-version-can-i-use-with-django

# やったこと
## requirements.txtを修正
Dockerfile上の`RUN pip install -r requirements.txt` にて`requirements.txt`Djangoのバージョンを指定
Djangoのバージョンを3.0に修正

```
Django==3.0
psycopg2
freeze
```

## Docker環境再構築
Docker環境を再構築
```
docker-compose down --rmi all --volumes
docker-compose up -d
```

## バージョン確認
インストールがうまくいっているかを動作確認
一応2パターンで確認

```
toruchan:~/work/py-work (master *)$ docker-compose exec web ./manage.py --version
3.0
toruchan:~/work/py-work (master *)$
```

```
toruchan:~/work/py-work (master *)$ docker-compose exec web python -c "import django; print(django.get_version())"
3.0
toruchan:~/work/py-work (master *)$
```

ついでにpythonのバージョンも確認

```
toruchan:~/work/py-work (master *)$ docker-compose exec web python --version
Python 3.8.5
toruchan:~/work/py-work (master *)$
```

これで一通りインストール周り問題なさそう
Web開発リンク集

# はじめに

ここでは開発に役立ちそうなサイトリンクをまとめます。
少しづつ増やしていこうと思っています。

# 開発

## 調査

- 最新のversion調査
 - https://verstory.com/
- ソフトウェア選定参考
 - https://www.itreview.jp/ 
 - https://www.npmtrends.com/ 
 - https://w3techs.com/

## コミュニケーション

- グラフィックレコーディング
  - https://www.1101.com/store/techo/ja/magazine/2017/graphicrecording/2017-04-04.html
- 情報共有サービス
  - notion https://www.notion.so/ 
  - hackmd(はっくえむでぃー) https://hackmd.io/
  - esa(えさ) https://esa.io/

## チームビルディング

- 基本
 - https://www.sitepoint.com/managing-a-team/
 - https://www.sitepoint.com/team-management/
- スクラムガイドライン
 - https://scrumguides.org/docs/scrumguide/v2020/2020-Scrum-Guide-Japanese.pdf
 - https://www.scrumguides.org/docs/scrumguide/v2017/2017-Scrum-Guide-Japanese.pdf
- ビデオ通話の決め事
 - https://martinfowler.com/articles/effective-video-calls.html 
- バーチャルオフィス
 - https://www.gather.town/ 

## 設計

- 図(UML)
 - Lucidchart https://www.Lucidchart.com/pages/ja 
 - draw.io https://www.draw.io

## 実装

- Docker Hub https://hub.docker.com/ 
- 正規表現テスト https://regexper.com/ 

## テスト

- PageSpeed insights
 - https://developers.google.com/speed/pagespeed/insights/?hl=JA
- モバイルサイトスピード
 - https://gweb-mobile-hub-test-my-site.appspot.com/feature/testmysite/
- google構造化データ(JSON-LD)テスト
 - https://www.google.com/webmasters/tools/testing-tools-links?hl=ja&authuser=0

# その他

## オンラインIDE

- codesandbox https://codesandbox.io/
- jsfiddle https://jsfiddle.net/
- paiza https://paiza.io/ja/projects/new

## 勉強

- オンライン学習
 - udemy https://www.udemy.com/ 
-  勉強会
 - connpass https://connpass.com/
 - doorkkper https://www.doorkeeper.jp/
 - techplay https://techplay.jp/ 
- JavaScript
 - jsprimer https://jsprimer.net/ 

## 購入

- キンセリ https://yapi.ta2o.net/kndlsl/

## 技術記事

- infoq https://www.infoq.com/jp/
- publickkey https://www.publickey1.jp/ 
- ux milk https://uxmilk.jp/

## テックブログ

- mercari https://engineering.mercari.com/
- yahoo https://techblog.yahoo.co.jp/
- クックパッド https://techlife.cookpad.com/
- smartHR https://tech.smarthr.jp/
- paiza https://paiza.hatenablog.com/
- cybozu https://blog.cybozu.io/

## IT雑学

- GIGAZINE https://gigazine.net/
- ロボスタ https://robotstart.info/

# フリーランス情報

- エージェント検索 https://freelance-start.com/
Markdownを印刷(PDF化)してみた

まだメモ書き段階ですが…。markdownで書いている手順書をまとめて印刷して配る必要性が出てきたために簡単な方法はないかなと試行錯誤をしています。

## markdown → pdf
まずは直接変換する方法を探ります。

### pandoc
汎用のドキュメント変換ツールでpdfの指定も出来そうだったので、試してみましたが、どうも中から別のエンジン(Latexとか)を呼んでいるだけのようで、次々にエラーがでます。他の情報源をあたっても、どうも残念な感じの出力しか得られそうになく断念しています。

```bash
$ pandoc title.txt chapter1.md -o chapter1.pdf
! Font T1/cmr/m/n/10=ecrm1000 at 10.0pt not loadable: Metric (TFM) file not fou
nd.
<to be read again> 
                   relax 
l.105 \fontencoding\encodingdefault\selectfont

pandoc: Error producing PDF
```

### Atom
[Markdown to PDF](https://atom.io/packages/markdown-to-pdf)拡張機能(package)で実現出来そうな雰囲気でしたが、出力されるPDFにページ番号がどうしても入れられず、利用を断念しました。また、この記事を書くためにPackageの詳細を調べようと思ったら、公式サイトが落ちてるという状況で、最近は安定性がイマイチになってきましたね。（翌日復旧してたので、名前編集しました）

![Screen Shot 2020-09-05 at 22.49.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50780/08218cfd-f349-634d-9151-57be519372a7.png)



## markdown → html → pdf
Google Chromeを使えば、htmlを印刷したりPDFに保存したり出来るということで、htmlに変換できるツールを探します。

### Atom
Markdown Previewという機能が以前のバージョンにあって、HTML出力機能が良い具合だったので使っていたのですが、いつの頃からかエラーが頻発するようになり、使えなくなってしまいました（環境の問題なのかどうかは不明です）。拡張機能(package)の中にMarkdownをサポートするものが幾つかありますが、これというものは見つかりませんでした。

### Visual Studio Code
[Markdown All in One](https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one)という拡張機能(extension)を入れたらhtml出力のコマンドがパレットに登場します。スタイルも悪くなくてお手軽に使えそうです。

---

![VSCodeの出力例](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50780/5b9e6356-3e13-6861-0864-7371f18be4f5.png)

---

### pandoc
html出力なら、最初に諦めたpandocでも出来るのでした。スタイルシートを整えてあげないと、ほとんど素のままといった見栄えですが、こちらの方が大量の文章を自動変換するような用途には適していそうです。

```bash
pandoc title.txt chapter1.md -o chapter1.html 
```

---

![pandocの出力例](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50780/9cff6af8-dc46-6421-09d0-b47a034121be.png)

---

### 次点
自動化がメインであれば、`redcarpet`、あるいは折角なのでウェブサイトとしても公開できるレベルに持っていくなら`jekyll`という選択肢もありそうです（まだ未検証）。

## とりあえずの結論
epubもpandocで管理していますので、pandocでhtml出力、必要に応じてブラウザ(Google Chrome)でPDF化や印刷をかけるという運用になりそうです。
CASE式とHAVING句の応用問題をといてみる

達人に学ぶSQLの第六章にある問題をといてみます。
なんとなく記事にしてみました。

# データ投入

```sql
CREATE TABLE TestResults 
(student_id INT, class VARCHAR(1), sex VARCHAR(4), score INT)

INSERT INTO TestResults VALUES (001, 'A', '男', 100);
INSERT INTO TestResults VALUES (002, 'A', '女', 100);
INSERT INTO TestResults VALUES (003, 'A', '女', 49);
INSERT INTO TestResults VALUES (004, 'A', '男', 30);
INSERT INTO TestResults VALUES (005, 'B', '女', 100);
INSERT INTO TestResults VALUES (006, 'B', '男', 92);
INSERT INTO TestResults VALUES (007, 'B', '男', 80);
INSERT INTO TestResults VALUES (008, 'B', '男', 80);
INSERT INTO TestResults VALUES (009, 'B', '女', 10);
INSERT INTO TestResults VALUES (010, 'C', '男', 92);
INSERT INTO TestResults VALUES (011, 'C', '男', 80);
INSERT INTO TestResults VALUES (012, 'C', '女', 21);
INSERT INTO TestResults VALUES (013, 'D', '女', 100);
INSERT INTO TestResults VALUES (014, 'D', '女', 0);
INSERT INTO TestResults VALUES (015, 'D', '女', 0);

SELECT * FROM TestResults;
+------------+-------+------+-------+
| student_id | class | sex  | score |
+------------+-------+------+-------+
|          1 | A     | 男   |   100 |
|          2 | A     | 女   |   100 |
|          3 | A     | 女   |    49 |
|          4 | A     | 男   |    30 |
|          5 | B     | 女   |   100 |
|          6 | B     | 男   |    92 |
|          7 | B     | 男   |    80 |
|          8 | B     | 男   |    80 |
|          9 | B     | 女   |    10 |
|         10 | C     | 男   |    92 |
|         11 | C     | 男   |    80 |
|         12 | C     | 女   |    21 |
|         13 | D     | 女   |   100 |
|         14 | D     | 女   |     0 |
|         15 | D     | 女   |     0 |
+------------+-------+------+-------+
```

生徒のテスト結果を保持するテーブルです。

# 問題

### 第１問 クラスの75%以上の生徒が80点以上のクラスを選択せよ。

#### 自分の回答

```sql
SELECT class FROM TestResults
GROUP BY class
HAVING COUNT(*) * 0.75 <= SUM(CASE WHEN score >= 80 THEN 1
                              ELSE 0 END);

+-------+
| class |
+-------+
| B     |
+-------+
```

#### 解説

classごとにグループ分けして、COUNT(*)でグループごとの行の数を求めています。
75%なので、0.75をかけています。
式の反対側では、80点以上の生徒にフラグをつけて、SUMで合計しています。

#### 結果

正解でした。

---

### 第2問　５０点以上をとった生徒のうち、男子の数が女子の数より多いクラスを選択せよ。

#### 自分の回答

```sql
SELECT class FROM TestResults
GROUP BY class
HAVING SUM(CASE WHEN sex = '男' AND score >= 50 THEN 1 ELSE 0 END) >
      SUM(CASE WHEN sex = '女' AND score >= 50 THEN 1 ELSE 0 END);
```

なぜかエラーになり実行できず。

#### 書籍の回答

```sql
SELECT class FROM TestResults
GROUP BY class
HAVING SUM(CASE WHEN score >= 50 AND sex = '男' THEN 1 ELSE 0 END) >
      SUM(CASE WHEN score >= 50 AND sex = '女' THEN 1 ELSE 0 END);

+-------+
| class |
+-------+
| B     |
| C     |
+-------+
```

条件逆にしただけでエラーがなくなりました。どういうことでしょうか......

#### 解説

一問目でやってることを両辺に増やしただけです。

---

### 第３問　女子の平均点が、男子の平均点よりも高いクラスを選択せよ。

#### 自分の回答

```sql
SELECT class FROM TestResults
GROUP BY class
HAVING AVG(CASE WHEN sex = '女' THEN score ELSE NULL END) >
       AVG(CASE WHEN sex = '男' THEN score ELSE NULL END);

+-------+
| class |
+-------+
| A     |
+-------+
```

#### 結果

正解！
NULLが悪影響を与えるかもと思いましたが、これで正しかったようです。

#### 解説

NULLのところを0にしてしまうと、条件と逆の性別の時に平均点を下げてしまうのを意識しました。

## 感想

パズルを組み立てているようで面白かったです。
２問目がエラーになった原因がよく分からないので、分かる方コメントお願いします。
QuickSightのDatasourceをCLIで操作した

# 背景
QuickSightで作成するAnalysis、Dashboardなどユーザによって作成したユーザでないと何も
できない。それらをCLIにて操作して変更を加えたらいろいろできることを試してみた。
以下Datasourceの権限追加した時の操作です。

# DataSourceの確認とユーザの権限追加

  - ユーザのリストを出して権限など確認する。
  
 ```
aws quicksight list-users --aws-account-id ACCOUNT_ID --namespace default  --region us-east-1　

結果：
{
    "Status": 200,
    "UserList": [
        {
            "Arn": "arn:aws:quicksight:us-east-1:ACCOUNT_ID:user/default/xxxxxxxxxxxxx",
            "UserName": "xxxxxxxxxxxxx",
            "Email": "xxxxxxxxxxxxx",
            "Role": "ADMIN",
            "Active": true,
            "PrincipalId": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
        },
    ]
}
```
（ユーザ管理は us-east-1 でしているため）

  - Datasourceのリストを表示する

```
aws quicksight list-data-sources --aws-account-id ACCOUNT_ID --region ap-northeast-1 --max-result 100
```
（--max-result は最大100まで指定できる。結果にnext-tokenが含まれると100件以上あるという意味ですので　--next-token　optionにnext-tokenの値を入れて再度実行する）

  -   Datasource のIDを持って詳細を確認する
 
```
aws quicksight describe-data-source --aws-account-id ACCOUNT_ID --data-source-id DATA_SOURCE_ID --region ap-northeast-1
 ```
  - Datasource のPermissionを確認する

```
    - aws quicksight describe-data-source-permissions --aws-account-id ACCOUNT_ID --data-source-id DATA_SOURCE_ID --region ap-northeast-1

結果：
{
    "Status": 200,
    "DataSourceArn": "arn:aws:quicksight:ap-northeast-1:ACCOUNT_ID:datasource/xxxxxxxxxx",
    "DataSourceId": "DATA_SOURCE_ID",
    "Permissions": [
        {
            "Principal": "arn:aws:quicksight:us-east-1:ACCOUNT_ID:user/default/xxxxxxxxxxxxxxxx",
            "Actions": [
                "quicksight:UpdateDataSourcePermissions",
                "quicksight:DescribeDataSource",
                "quicksight:DescribeDataSourcePermissions",
                "quicksight:PassDataSource",
                "quicksight:UpdateDataSource",
                "quicksight:DeleteDataSource"
            ]
        }
    ],
    "RequestId": "437ca48a-5f92-4ac6-a784-81d635fea74b"
}
```

- 他にユーザに権限を追加する(Full 権限の例）

```
aws quicksight update-data-source-permissions --aws-account-id ACCOUNT_ID --data-source-id DATA_SOURCE_ID --region ap-northeast-1 --grant-permissions Principal=arn:aws:quicksight:us-east-1:ACCOUNT_ID:user/default/xxxxxxxxxxxxx,Actions=quicksight:UpdateDataSourcePermissions,quicksight:DescribeDataSource,quicksight:DescribeDataSourcePermissions,quicksight:PassDataSource,quicksight:UpdateDataSource,quicksight:DeleteDataSource
```

Principalの値はlist-usersコマンドで確認したユーザのArnを指定


# 最後に
今回ユーザとDatasourceを確認してDatasourceの権限変種した例ですが、同じくCLIで実行すればいろいろば変更は簡単でできることがわかった。
新卒エンジニアが考える、プログラミング学習のコツ

#はじめに
新卒１年目の配属で社内SEという名の雑用係になってしまった。
去年まで大学生だった、なんちゃってエンジニアです。

大学時代に研究でプログラミングを行った際に感じたことについての記録です。

#使ったことのある言語（~~完全に蛇足~~）
・C/C++
・Python3
他にも触れたことがある言語はありますが（PHPとか）これからも自己学習したいと思える言語はこの2つです。（といっても現状）

#実行環境（~~こっちも蛇足~~）
・Windows、
・Mac
・Linux(Ubuntu、CentOS7)
このあたりで実行環境を作成して学習しました。(MacとLinuxはほぼ一緒だったけど)
実行環境の構築は他の記事などを参考にしてください。ここでは書きません。

#１つの目プログラミング言語の学習！
プログラミング言語の学習において**最も重要なことは書く**こと。
とにかく学習サイトや書籍のサンプルコードを自分で書いて実行してみる。

####自分で書くメリット
プログラム言語はアルファベットの羅列である。
それを眺めて理解できる人は、そもそもプログラムの取得に苦労しない超人。
凡人の自覚のある私のような人間は実際の動きをみてコードを自分の言葉で理解する必要があると思います。

また自分の手で実行まで持ってくためにsyntaxエラーやPythonの文法ではインデントによるエラーなどの複数の**エラーに対する経験値を積むことができる**。サンプルコードと自分で書いたコードを比較し、間違えている箇所を探して直すことで、今後同じようなエラーを見たときに直す箇所の予想が速くなると思います。
####プログラム改変のメリット
書いたコードを改変することが一番理解を深めるコツ。最速の方法だと思っています。
改変できるときはどんどん改変すべきだと思います。
エラーにならないように、かつ数値の変更や出力の変更によって実行結果がどう変わるかを観察することができるためコードの動作を複数の視点から見ることができる。

##最低限覚えたほうがいい概念と文法
###変数
よく数値を格納する箱と表現されるプログラムの概念。
変わる数と書いて変数と書くので**基本的に箱の中にしまわれている値は変えることができます**。
プログラミングはこの変数を変化させ、表示させることで成り立っている。プログラミングの学習の際はこの**変数の中身を意識する**と学習をしやすいと思います。
変数はプログラミング言語の基本的な概念でHTML以外の全てのプログラミング言語で見たことがあります。(HTMLがプログラミング言語かどうかはわからないけど...)
###if文
**特定の条件**でプログラムに行わせる処理を変えるとき使用する文法です。
いままで見てきたプログラミング言語の全てに登場してきた関数です。（HTML以外のプログラミング言語ですが）

```python
if hoge == "hage":
   print(hoge)
else:
   print("hige")

```
上記はPythonでのif文です。
Pythonはインデントによって処理の塊を定義しているので段落の下がっているコードの上にあるコード(例えば```if hoge == "hage"```とか)の処理の中身と考えると理解しやすい。

**処理の中身を簡単に説明すると**
hogeという**変数**に"hage"という文字（コンピュータは文字も数値で表します）が入っていた場合にhageという変数の中身を表示、中身が"hage"以外の時は"hige"という文字を表示しろという命令である。

if文は条件に当てはまったときにだけ中身が実行される。
elseはifと同時に使用され、ifの条件に当てはまらなかった時にだけ中身が実行される。

###for文
**同じ処理を何度も繰り返す**ときに使用する文法です。
いままで見てきたプログラミング言語の全てに登場してきた関数です。（HTML以外です。）

```python
for i in range(10):
   print("hage")
```
Pythonで書いたfor文の例です。
Pythonは他の言語のfor文と比べる書き方が特殊かもしれませんが。
~~配列を操作するときには使いやすいけど~~

このコードは"hage"という文字を10回表示させるコードです。（悪意はないです。）
**for文は設定した回数だけ同一の処理を行わせる**文法です。
上のコードで```print("hage")```が実行され"hage"が実行されると、```for i in range(10)```に戻って処理が再実行される。
指定の回数繰り返すと戻らずにprintの下に書かれた処理が実行される。
if文と違って必要性が浮かばないかもしれませんが、例えばHTMLで表を作りたい場合、表のセルの数だけ、セルを表示するコードを書く必要がある。
for文を使用することでセルの数にもよるが圧倒的に少ないコードで表を作ることができる。


#プログラミング学習のコツ
やっとこの記事で書きたいことが書けます。

上で書いたような、どの言語にも共通している概念は多くあると思います。
適当に上げると
・配列
・連想配列
・関数
・クラス
・変数型
少し考えただけでもこのくらいはでます。
このように共通している概念を見つけ出すことが新しい言語を読むときに大きな力になります。

また、複数の言語を学習していると（多すぎるのも良くないと思いますが）1つ目の言語では学習しなかった概念を2つ目の言語で学習したことによって1つ目の言語でも使えるか調べて使えるようになる。

1つ目の言語と同じようなアルゴリズムを2つ目の言語でさせようとしたら実行結果が1つ目の言語と異なっているため、調べたら両方の言語の処理に対しての理解が深まる

などの効果もあるように思います。
1つの言語を徹底的に極める学習法もいいかもしれませんが、２つ３つの言語をつまみ食いしながら相互に理解を深めていくことも学習としていいと思います。

#まとめ
いろいろと書きましたが、この記事をまとめると
・プログラミング言語の最初の一歩はその言語、特有の処理を学習するより処理を抽象的に理解することが大切。
・概念を理解しておけば、特定の言語でその概念をしようしたいときにスムーズに調べることができる。
・プログラミングの学習は**言語の学習**ではなく**プログラミングの使用する概念の学習と考えたほうが応用が利く**

#おわりに
プログラムの学習について感じたことをまとめました。
ご意見や変数やif文の説明に間違えなどがございましたら教えていただけると幸いです。

最後にここまで読んでいただきありがとうございます。
執筆日
2020-9-5
桁の長い数を足し算するＣ言語のプログラムを作ってみた

間違ってるかもしれないけど本を参考にしてとりあえず作ってみた。

```c:test.c
/*
 * BCD演算
 */
#include <stdio.h>
#include <string.h>

#define LEN 255      /* 最大桁数 */

void sub(char* num1, char* num2)
{
	char ans[LEN + 1];  /* 加算結果 */
	int i, sum, carry, n1, n2;
	int len1 = strlen(num1); int len2 = strlen(num2);
	char zero[LEN];
	zero[0] = '\0';

	if (len1 >= len2) {
		for (int k = 0; k < len1 - len2; k++) {
			strcat_s(zero, LEN, "0");
		}
	
		strcat_s(zero, LEN, num2);
		num2 = zero;

		carry = 0;   /* 繰り上げ */
		for (i = len1 - 1; i >= 0; i--) {  /* 下位から1桁ずつ足し算していく */
			n1 = num1[i] - '0';
			n2 = num2[i] - '0';

			sum = n1 + n2 + carry;
			if (sum >= 10) {   /* 繰り上げ発生 */
				sum -= 10;
				carry = 1;
			}
			else {
				carry = 0;
			}

			ans[i] = (char)(sum + '0');
		}
		ans[len1] = '\0';

	}
	else {
		for (int k = 0; k < len2 - len1; k++) {
			strcat_s(zero, LEN, "0");
		}
		strcat_s(zero, LEN, num1);
		num1 = zero;

		carry = 0;   /* 繰り上げ */
		for (i = len2 - 1; i >= 0; i--) {  /* 下位から1桁ずつ足し算していく */
			n1 = num1[i] - '0';
			n2 = num2[i] - '0';

			sum = n1 + n2 + carry;
			if (sum >= 10) {   /* 繰り上げ発生 */
				sum -= 10;
				carry = 1;
			}
			else {
				carry = 0;
			}

			ans[i] = (char)(sum + '0');
		}
		ans[len2] = '\0';

	}



	/* 加算数と被加算数の表示 */
	printf("  %s\n", num1);
	printf("+ %s\n", num2);

	printf(" ");

	/* 最上位桁で繰り上げが発生していたら，"1"を出力する */
	if (carry)
		printf("1");
	else
		printf(" ");

	printf("%s\n\n", ans);
}

int main(void)
{
	char num1[LEN], num2[LEN];
	printf("数値1を入力してください");
	scanf_s("%s", num1, LEN);

	int c;
	while ((c = getchar()) != '\n');

	printf("数値2を入力してください");
	scanf_s("%s", num2, LEN);
	//printf("num2->%s\n", num2);

	sub(num1, num2);

	return 0;
}

```
Pythonでファイル・フォルダを操作

#この記事の内容：pythonによるファイル・フォルダ操作について
pythonの標準モジュールos,shutilを用いて、以下のようなファイル・フォルダの操作を行う方法について調べたのでまとめました。

・ディレクトリを作成する方法
・ディレクトリを中身ごとコピーする方法
・ファイルを削除する方法
・ディレクトリを中身ごと削除する方法
・空のディレクトリを削除する方法

##ディレクトリを作成する方法
os.mkdir()関数で、ディレクトリを作成することができます。すでにそのディレクトリが存在する場合はエラーが出ます。

```python
import os
os.mkdir("fold")
```

##ディレクトリを中身ごとコピーする方法
shutil.copytree()関数で、既存のディレクトリを中身ごと他のディレクトリにコピーできます。

```python
import shutil
shutil.copytree("fold1","fold2") #fold1を中身ごとfold2としてコピー
```

##ファイルを削除する方法
os.remove()関数で、ファイルを削除できます。

```python
import os
os.remove("file.txt") #"file.txt"を削除
```

##ディレクトリを中身ごと削除する方法
shutil.rmtree()関数で、ディレクトリを中身ごと削除できます。

```python
import shutil
shutil.rmtree("fold1") #"fold1"を中身ごと削除
```

##空のディレクトリを削除する方法
os.rmdir()関数で、空のディレクトリを削除できます。

```python
import os
os.rmdir("fold1") #"fold1"を削除
```
WSL2でカーネルのビルドとデバイスドライバの作成

Linux実機が手元になかったので（実際にデバイスを制御しない）デバイスドライバ作成のための環境構築をUbuntu20.04 on WSL2上で行った。

1. システムのカーネルのバージョンの確認する。

    ```
$ uname -r
4.19.104-microsoft-standard
```
2. Githubの[microsoft/WSL2-Linux-Kernel](https://github.com/microsoft/WSL2-Linux-Kernel)から対応するバージョンのカーネルのソースコードを落とす。

    ```
$ wget https://github.com/microsoft/WSL2-Linux-Kernel/archive/$(uname -r).zip
$ unzip $(uname -r).zip
```

3. `README-Microsoft.WSL2`に従ってカーネルをビルドする。並列コンパイルのため`make -j`にしたらメモリが足らなくなったので注意。

    ```
$ sudo install build-essential flex bison libssl-dev libelf-dev
$ cd path/to/WSL2-Linux-Kernel-$(shell uname -r)
$ make KCONFIG_CONFIG=Microsoft/config-ws
```


4. 試しにinsmod/rmmod時にログに出力するだけの簡単なデバイスドライバを作ってみる。デフォルトのログレベルが1 (KERN_ALERT)だったのでここでは0 (KERN_EMERG)でメッセージを出力した。


   ```hello.c
#include <linux/module.h>

static int hello_init(void) {
    printk(KERN_EMERG "hello init\n");

    return 0;
}

static void hello_exit(void) {
    printk(KERN_EMERG "hello exit\n");
}

module_init(hello_init);
module_exit(hello_exit)
```

   ```make:Makefile
obj-m := hello.o

all:
	make -C path/to/WSL2-Linux-Kernel-$(shell uname -r) M=$(PWD) modules

clean:
	make -C path/to/WSL2-Linux-Kernel-$(shell uname -r) M=$(PWD) clean
```

```
$ make
$ sudo insmod hello.ko
$ sudo rmmod hello
$ dmesg | tail
...
[ 1313.975997] hello init
[ 1320.991808] hello exit
```
ABC126 A,B,C 解説（python)

自らの理解を深めるための修練と誰かの一抹の救いになればと令和のABCのA,B,C問題について解説を書いていきたい。

##A問題
https://atcoder.jp/contests/abc126/tasks/abc126_a

lower使用と連結ができるか

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

print(s[:k-1]+s[k-1].lower()+s[k:])
```
s[:k-1]でk字手前の文字までを出力
s[k-1].lower()でk字目を小文字にして出力
s[k:]でk以降を出力

##B問題
https://atcoder.jp/contests/abc126/tasks/abc126_b

最初の２桁後半の２桁の数字をみて判断する。
そのため、最初はstr型でデータを受け取り
１、２字目　３、４字目をまとめてint型に変換する。

```python

s = input()
a = int(s[:2])
b = int(s[2:])
 
if 1 <= a and a <= 12 and 1<= b and b <=12:
    print("AMBIGUOUS")
elif 1 <= a <=12 and (12 < b or b < 1):
    print("MMYY")
elif (12 < a or a < 1) and 1 <= b <= 12:
    print("YYMM")
else:
    print("NA")
```


##C問題

https://atcoder.jp/contests/abc126/tasks/abc126_c

出力例１にある出し方を愚直に実装しなさいと言うことだと思います。
私は、他の方の提出結果をみてなんとか実装できましたが。。。

``` python

n,k = map(int,input().split())
ans = 0
for i in range(1,n+1):
    j = 0
    if i < k:
        while i*(2**j) < k:
            j += 1
        ans += (1/n)*1/(2**j)
    else:
        ans += (1/n)
print(ans)
```
技術(単語)を要約してみる

**学んだことを理解できているか** は、**一言で言い表せられるか** で検証できると考えています。
そこで、個人的に大事と思う点や理解が難しかったこと、忘れてしまいそうなことを要約してみました。
随時更新する予定です。

(*かなり大雑把な説明のため、誤解を生むorそもそも間違っているかもしれません。
 その点はご指摘いただければ有り難いです。*)

## Git
- rebase  
コミットを別ブランチの先頭につなげる。
- pruneオプション  
pullする際に使用し、リモートで削除されているブランチをローカルで削除してくれる。
- stash  
一時保存。

## Linux
- コマンドの正体  
ファイル。
- apt  
apt-getとapt-cacheを合わせたパッケージ管理システム。
- シンボリックリンク  
別のファイルシステムも対象にできる、Windowsで言うショートカットのようなもの。
- マウント  
別のファイルシステムを管理できるように登録すること。
- バックグラウンドジョブ  
(処理に時間がかかる等の理由で)並行して処理を行う。コマンドラインの末尾に「&」を追加し実行。
- パーティション  
HDを論理的に分けた領域。

## データ構造とアルゴリズム
- 連想配列の呼び名  
ハッシュ(Ruby), 配列(PHP, 配列と連想配列の区別がない), 辞書(Python), マップ(Java)

## ネットワーク
- SSH  
安全のために公開鍵暗号方式(公開鍵をサーバに登録/秘密鍵はクライアント側保管)で通信する、遠隔操作用のプロトコル。
- ステートレス
状態を持たない(= 初対面じゃないのに、あんた誰？状態の)こと。(cookieでセッション管理する方式はあえてステートフルにしている。)
- cookie
サーバがクライアントに送付する、ユーザを識別する情報。
- キャッシュ
一度取得したリソースを、その鮮度に基づいてクライアント側で使い回すこと。

## API
### REST
- 何が嬉しい？  
ビューでなくJSON(軽いデータ)を返すため、データ量が少なく、フロント/バックエンドの分業がしやすい。

## デザインパターン
- テンプレートメソッド
親クラスで抽象(abstract)メソッドを作り、子クラスでその抽象メソッドを具体化することで、共通処理を親クラスにまとめられる。子クラス毎で、具体的な処理内容を変更できる。
- シングルトン
常に同じインスタンスを参照する。(インスタンスが1つ)

## Docker
- コンテナ  
namespaceで区切られた領域。プロセスやファイルシステム等が分離できる。
- イメージ  
コンテナの素。
- build  
(pullしたベースイメージでなくオリジナルの)イメージを作る。
- Dockerfile  
イメージ作成時に実行したいことを記載したファイル。
- docker-compose  
複数のコンテナを管理するツール。
【PHP】foreach、三項演算子

PHPについて学習内容を備忘録としてまとめます。

#foreach
配列専門のループ処理。
配列の要素が入っている分だけ繰り返し処理を行います。

例えば、実行例としては下記のようになります。

```php

<?php
$test=array("test1","test2","test3");
foreach($test as $value){
print $value."<br>";
}
?>

#実行結果
test1
test2
test3
```
このように3つの要素を繰り返し処理しました。

##連想配列
連想配列でも同様の処理をすることが可能であり、
下記のように動作します。

```php

<?php
$test = array(“test1” => “test01” ,”test2” => “test02”,”　test3” => “test03”);
foreach($test as $key => $value){
print $value . ”は” . $key . “です<br>”;
}
?>

#実行結果
test1はtest01です
test2はtest02です
test3はtest03です
```
#三項演算子
演算対象であるオペランド（被演算子）を３つとり、？と：を以下の形式で使用します。
下記は三項演算子の実行例になります。

```php

$val = 120;
$result = $val > 100 ? '100より大きい' : '100以下';
print $result;
```

先ほどの三項演算子はif文で表すと以下のようになります。

```php

$val = 120;
if( $val > 100 ){
	print '100より大きい';
}else{
	print '100以下';
}
```

#参考URL
https://blog-and-destroy.com/7118
https://techacademy.jp/magazine/4978
【Ruby on Rails】gem refileの保存先変更※備忘録

gemのrefileを使用していて、
つまずいたため、備忘録として残します。
※本来の方法ではないかもしれないため、参考程度に見ていただければと思います。
# 開発環境
ruby 2.5.7
Rails 5.2.4.3
OS: macOS Catalina

# refileの保存先変更
## 何もしていない時の保存先

tmp/uploads/store
この配下にあるものの、tmp=temporaryの字のごとく、
一時的に保存される場所です。

## 変更したい保存先
public/uploads配下に保存したい場合、
config/initializers配下にrefile.rbを作成。

```rb:config/initializers/refile.rb
Refile.backends['store'] = Refile::Backend::FileSystem.new('public/uploads/')
```
このようにすればpublic/uploads配下に保存可能。
Pythonで内外判定：任意地点の緯度経度情報から市町村名を取得

#やりたいこと
任意の地点の緯度経度情報のみから、当地点の市町村名を取得するプログラムを作りました。ポイントは、シェープファイルの読み込み、点の内外判定の2点です。
#用意するもの
pyshpとSympyという2種類のモジュールを使用しました(pipでインストール)。
・pyshp (shpファイル読み込みに使用)
・Sympy (内外判定に使用)
・市町村区界のシェープファイル
　(参考:https://www.esrij.com/products/japan-shp/)
#プログラムの作成と実行
ソースコードは以下の通りです。

```python
import shapefile
from sympy.geometry import Point, Polygon
#
LONG=140.0
LAT=36.5
RPOINT=Point(LONG,LAT)  #➀判定対象地点設定
#
src=shapefile.Reader('.\\shp\\japan_ver821.shp',encoding='SHIFT-JIS')  #ファイル読み込み
SRS=src.shapeRecords()  #➁shpデータ読み込み
for srs in SRS:
    shp=srs.shape   #➁地物情報取得
    rec=srs.record  #➁属性情報取得
    box=shp.bbox    #➁各オブジェクトを囲む矩形の取得
    #
    #➂対象地点が矩形内にあるなら、より詳細な内外判定を実施
    if box[0]<LONG<box[2] and box[1]<LAT<box[3]:  
        pnt=shp.points  #➃各オブジェクトの座標情報取得
        points=[]       #➃各オブジェクトの節点を抽出
        for pp in pnt:   
            points.append((pp[0],pp[1]))
        poly=Polygon(*points)   #➃sympyポリゴンデータを作成
        #
        if poly.encloses_point(RPOINT):  #➃内外判定を実施
            print(rec)                   #➄市町村情報を出力
            break
```

以下の処理を順番に実施しています。
① 判定対象地点設定
② shpデータ読み込み
③ 各オブジェクトの矩形範囲内に判定対象地点があるかをチェック
④ ③範囲内に対象地点があればさらに詳細に内外判定を実施
⑤ 内外判定に成功したら属性情報を出力

######実行結果

```python
Record #469: ['栃木県', '', '', '', '宇都宮市']
```

市町村名を取得することができました。

## ※注意点※
2つ以上の閉曲線から成るドーナツ型のポリゴンがshpデータに含まれている場合、この方法ではうまくいかないようです。このような場合には、以下を参考にして頂けると幸いです。
https://qiita.com/Pooh-A/items/6b4fcb15a790f6ee6e79
仮説検定を理解する

仮説検定

###　　一言でまとめると　”部分から全体（母集団）を推理する”

目的　母集団を推定する

ケース（すでに、母集団の平均・分散がわかっている場合）

１　仮説（母集団の推測）を立てる

ex ”N枚のコインを投げて、１０回表が出た”というデータ（結果）がある。
　
Q　投げたN枚の回数を推定するとして、妥当な数は？

２（区間で）検定する

普通に（確率的に）考えれば２０枚　（二分の一）　　
・・しかし、結果は常に、確率通りではなくバラつく

故に、+1,2 ２１枚、２２枚　or -1,-2 19枚、１８枚と推定しても妥当といえそう。

では・・
Q　母数Nの推定としてどこまでが妥当な数値と言えるか？
これに、答えを出すのが「区間推定」という”検定”の基本的やり方である。

そのために、９５％の予言的中区間（＝標準偏差 +=1.96の範囲）内か確かめる。


標準正規分布に変換して、以下の数式を解けば、知りたい範囲を出せる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631141/bbd66654-76b8-5d8e-f779-93decd85c1da.png)

これを解くと、
（N＝16の場合）　4.08 ≦　X　≦ 11.92
となる。

この数値から言えることは、
（N＝16）つまり１６枚コインを投げた時、　　　
表の出る枚数として 4.08枚〜11.92枚 の範囲になる確率が９５％である。

今回のデータは１０枚表が出た時
→９５％の範囲内なので、１６枚投げて表１０枚出るのは、普通によく起こること！（＝妥当）と言える。


もしN＝３６枚の場合は、計算してみると　  12.12  ≦　X　≦  23.88
となり、この範囲から外れる。つまり、 <font color="Fuchsia">想定外のこと</font>が起こったと言える。

この結果から言えることは２つ

1 母集団に対する仮説（N＝３６枚）は正しい。　しかし、想定外（５％）の滅多に起ころないことが起きてしまった。

2 母集団に対する仮説は間違っている　

ここで、統計学では、２を選択する。（区間推定の手法を使えば９５％でたまたま予想が外れるリスクは承知している上で検定しているため）

N＝３６は間違いであるため、仮説を<font color="Fuchsia">棄却する</font>


つまり、N＝１６枚は妥当であるが、N＝３６枚は想定しない。という結論を出します。




最初は”検定”の理解に苦しみましたが、まとめてみると
意外とロジカルな探偵の（コンピューター）の論理みたいで、理解してくると面白いと思います！
数式的理解も含めこれから、深めていきたいです。
Heroku×CloudflareでHTTP Origin Header didn't match request.base_urlというエラーをrailsのmiddlewareで解決する。

###背景

Herokuアプリを無料でSSL化する際に、Cloudflareと連携させる方法がある。
詳細は以下を参照。
https://qiita.com/serinuntius/items/f7f08b2221f5ad068f5d

Cloudflareはフレキシブルモードで、クライアントとhttps、herokuとはhttpで通信をしてくれる。


その状態で次のエラーになることがある。
`HTTP Origin header didn't match request.base_url`

詳しくは分からないが、httpとhttps、２つの通信形態を混在させていることが原因っぽいエラーだ。


### 類似記事
お金を払ってherokuをSSL化すれば、解決する。herokuとcloudflareの通信もSSL化すればいいという作戦。詳しくはこちら (だったらcloudflareいらなくね?)。
https://qiita.com/mzmt/items/2b44e82f2aa90ebf4623
[Heroku×CloudflareでHTTP Origin Header didn't match request.base_urlというエラーがでる]

### お金をかけずに解決するには

こちらで議論されていた。
https://stackoverflow.com/questions/55109859/trestle-http-origin-header-https-didnt-match-request-base-url-http

1 railsプロジェクト直下のlibディレクトリに`CloudflareProxy.rb`を作成

```ruby:/lib/CloudflareProxy.rb
# frozen_string_literal: true

require 'json'

class CloudflareProxy
  def initialize(app)
    @app = app
  end

  def call(env)
    return @app.call(env) unless env['HTTP_CF_VISITOR']

    env['HTTP_X_FORWARDED_PROTO'] = JSON.parse(env['HTTP_CF_VISITOR'])['scheme']
    @app.call(env)
  end
end
```

2 config/application.rb に以下の２行を、それっぽい位置に追加  

```ruby
require './lib/CloudflareProxy'

config.middleware.use CloudflareProxy
```

終了

herokuにpushして動作を確認する。
この界隈を漁ってたら`Rack`とかいうインターフェイスに出会った。勉強不足を痛感させられるエラーでした。
PythonのWithで実行時間計測

#出来るようになること
withを使用して時間計測ができるようになる。
Kaggleなどで時間を計測するときに使える。

#参考
 [メルカリコンペ１位のコード](https://www.kaggle.com/lopuhin/mercari-golf-0-3875-cv-in-75-loc-1900-s "Qiita")で使用されていました。

#使用方法
コンテキストマネージャとして使用したい関数の定義の直前に@contextmanagerと記載するだけ。

timerが呼ばれた時に初期時間がt0に格納されて、yeildで一時関数から抜ける。
time.sleep(1)の処理終了後に再びtimerに戻ってきて初期時間との差分を出力している。

```ruby:qiita.rb
from contextlib import contextmanager
import time

@contextmanager
def timer(name):
    t0 = time.time()
    print("start")
    yield
    print("end")
    print(f'[{name}] done in {time.time() - t0:.0f} s')


with timer('process train'): 
        time.sleep(1)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680528/4b89564c-f0a8-41c1-67a1-3bbbd511f74e.png)


@contextmanagerの記載がない場合はtimerはcontextmanagerとして動作できないためエラーになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680528/07522516-8bd9-f80c-f56d-3d0f29e8af94.png)


#コンテキストマネージャー
 [with分とコンテキストマネージャー]
(https://docs.python.org/ja/3/reference/datamodel.html#context-managers "Qiita")
コンテキストマネージャは、コードブロックを実行するために必要な入り口および出口の処理を扱う。

以下の例のように、コンテキストマネージャクラスには開始用の処理と終了時用の処理が記載されている。そのため、@contextmanagerでコンテキストマネージャーにすると、開始時と終了時にtimerが呼ばれることになる。@contextmanagerを記載しなかった場合は__enter__の定義がないためエラーとなった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680528/6bbf05db-7a6b-c11f-11f9-c448ad2e587c.png)
 [参考](https://python.keicode.com/lang/context-manager.php "Qiita")
[タスク②の解説記事]未経験からエンジニアがキャリア初期に、任されるあろう３つのタスクを出題してみる

## 前回の記事の解説

出題したタスクはこちら

https://qiita.com/morry_48/items/7dea1145d2db8bb7f570

##　タスク②画面上に表示文言を追加する
〜DBに保存されたデータを取得し、画面上に表示しよう〜

タスクの見通しとしては、
１．表示箇所の特定
２．表示するデータがデータベースから取得されているか確かめる（ない場合は取得する）
３．上記のデータを対象箇所に表示する
といった手順になる。

タスク①の要領でまずは表示すべき箇所を見つけることから始める。
①で使用したlist.twigを少しスクロールするとカートに入れるボタンの箇所があるのでそのすぐ上が表示箇所となる。

次にlist.twigの商品情報を表示している箇所を見るとProduct.hogehogeのようにして表示していることがわかる。(nameを表示している箇所はProduct.name)
Productの定義箇所を見ると１４５行目あたりに
 {% for Product in pagination %}
とあることからpaginagionという変数（配列）を展開して表示していることがわかるため、controllerでpagenationを返している部分を確認する。

ProductController.phpのindex()が対象箇所となるため、このfunctionのreturn部分を確認する。（このreturnのpagenationがtwig側に渡っているため）


![250行目.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378609/66326898-524d-4e0e-37db-619ebfde6860.png)
https://gyazo.com/94a3af4709d2dc5623f05fec1e15b87a

symfonyではdumpを使って変数の中身を確認できるためこちらを使ってブラウザを確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378609/947da60d-f0bd-41c7-43dc-5025ae62f839.png)

ブラウザに表示してみたところitemsの配列を展開するとProductの情報が入っていることが確認できます。
こちらにdescription_detailという項目があるのでこちらを詳細画面に表示すればいいことになります。
もし、ここに入っていなかった場合はデータベースからデータを取得している部分の条件を変えて値が渡ってくるように改修するようなタスクになります。

表示すべき項目が判明したため、先程見つけた対象箇所にコードを記述します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378609/da581a8c-797f-14c2-057c-8bfd46b993fd.png)

以上です。ブラウザを確認すると商品詳細情報が表示されました。


今回のタスクとしてはデータを取得できているか確認、表示という流れでした。
変数の中身を確認するデバッグ用のdump()はよく使います。
フレームワークによっても違いますが、実務タスクでは値が正しく取れているかなどの確認に
よく使うので使いこなせるようになるといいでしょう。
rspec実行時に "NameError:uninitialized constant ActiveSupport::ParameterFilter"

#環境
ruby 2.5.1
rails 5.2.4

#背景
1. docker環境を構築
2. CircleCIを導入
3. ローカル環境で CircleCI による rspec 実行がうまく作動するかテスト
4. falseが多く、タイムアウトになったりする
5. 問題の切り分けをするため、CircleCiではなく、普通にrspecコマンドを実行してみる
6. 一週間前はなかったタイトルのエラーが発生

```
$ bundle exec rubocop --require rubocop-airbnb

...
...
...

Failure/Error: get article_url article
     
     NameError:
       uninitialized constant ActiveSupport::ParameterFilter
     # ./spec/requests/articles_spec.rb:33:in `block (4 levels) in <top (required)>'
```

#結論
gem の"impressionist" のバージョンを変更したら、直りました。

```Gemfile
# 変更前
gem 'impressionist'

# 変更後
gem 'impressionist', '~> 1.6.1'
``` 

docker や CircleCI を導入する前は正常に作動していたので、database.yml の変更内容や追加した gem などを変更前と比較して、原因を探っていました。
しかし、エラー内容からは問題箇所の特定が難しく、検索したところ以下の記事がヒットし、試したところ直りました。

[uninitialized constant ActiveSupport::ParameterFilter](https://teratail.com/questions/269324 "uninitialized constant ActiveSupport::ParameterFilter")
>ActiveSupport::ParameterFilterはRails6以降pr#34039によって移動されたクラスです。
>impressionistのようにgemによってはrails5以前とrails6以降で追加するべきバージョンが違う場合があります。
【Rails】サイトのRSSを読み込んで、内容をフロントに返す



RSSとは

Rich Site Summaryの略で、充実したサイトの要約という意味になる。

主な特徴は、

- 内容情報のメタデータ化にRDFを使う。
- それの情報をXML言語で記述する。


|Webサイトの要素|マークアップ言語
|:--|:--
|Webページ|HTML
|RSS|XML

<details><summary>メタデータ</summary>データベースでいうカラムのこと</details>

<details><summary>RDF</summary>メタデータを統一するための規格。データベースでいうモデル？</details>

<details><summary>マークアップ言語</summary><>で表した要素を使って、データの構造を示す言語</details>


#gemを追加

```ruby:Gemfile
gem 'feedjira'
gem 'httparty'
```

```
$ bundle install
```


##対象RSSを、Railsで処理してクライアントに送るまでの流れ


1. RSSをrailsに送る
2. 受け取ったRSSを扱いやすい形になるようパースする
3. パースしてオブジェクトになったデータをJSON形式で、クライアントに返す

今回は、サーバ側の処理を書いていくので、2番目と3番目のコーディングをみていく。

#受け取ったRSSを、XML形式のデータに変換する

```ruby:

rss = Feed.new(url: params[:url])
xml = HTTParty.get(rss).body
```

##変換したXMLデータをパースして、オブジェクト形式のデータにする。

```ruby:

obj = Feedjira.parse(xml)
```

<details><summary>パースとは</summary>そのデータを解析して扱えるデータ（rssの書式データ）か判別し、扱えるデータなら変換までする処理のこと。</details>


##オブジェクトデータを分解して、記事内容を取得できるようにする

```ruby:
list = []

obj.entries.each do |item|
  list += [
    :title => item.title,
    :url => item.url,
    :title => item.summary,
    :published => item.published.to_time.strftime("%Y-%m-%d %H:%M:%S")
  ]
end
```

データを配列の要素にすることで、記事の内容を取得できる。
`obj.entries`は、オブジェクトの記事内容の塊のこと。


##クライアントに返すデータを作成する

```ruby:
data = {
  feed: {
    id: rss.id,
    url: rss.url,
    title: obj.title,
    item: list    
  }
}

render :json => data
```

クライアントに、JSON形式で返すようにする。
formボタンの使い方（PHP超初心者）

##はじめに
PHP超初心者の私が、formボタンの作成につまづき、そこから学んだことを投稿させていただきます。
##formタグとは
入力フォームなどを作成するときに使用するタグ。


##アクションとメソッドを設定する。

◉action属性 = フォームで入力したデータを処理するプログラムを指定できる。
※urlを記載すればボタンを押した時にそのページへ遷移することができる。決まっていない場合は「#」記号を設定する。

◉method属性 = フォームで入力したデータをどのように送信するかを設定できる。
値は、"get"か"post"から選択する。
※method属性を省略すると初期値として”get”が入るが、通常は"post"使用する。

###GETとPOSTの違い
・GETは情報の検索や取得処理を行う場合に使う。
・POSTは更新や、登録処理を行う場合に使う。
・機密性の高いデータの送信ならPOSTを使う。

こちらの記事がとても分かりやすかったです。
https://qiita.com/kanataxa/items/522efb74421255f0e0a1

##私がしてしまったミス

アクションとメソッド属性をよく理解していない私はウェブサイトを作成しているとき、このようなミスをしました。

```
<form  action="post">
      <input type="submit" name='message' value='送信する>
      </form>

```

全然POSTされない。。と思ったら、
method属性ではなくaction属性にPOSTを設定していました。


```
<form  actio="#" method="post">
      <input type="submit" name='message' value='送信する'>
      </form>

```

正しくはこうですね。


超初心者の皆さんも同じミスしないことを祈っています
Embree で回転のモーションブラーを行うメモ

# 背景

Embree でレイトレで回転物体(e.g. 扇風機の羽とか)のモーションブラーやりたい

## quaternion motion blur

最近(?), Embree で quaternion moton blur 機能が付きました. 少なくとも v3.11.0 では利用できます.

https://www.embree.org/tutorials.html#quaternion-motion-blur

図を見てわかるように, 線形で補間だと回転する物体はうまくいきません(十分サンプル数上げればそこそこ上手く近似できるであろうが). 

quaternion でノード行列(Transform)の回転の定義を行うことで回転のモーションブラーを扱えるようになっています.

ノード行列の指定には `rtcSetGeometryTransformQuaternion` を利用します.
`rtcSetGeometryTransformQuaternion` では, 回転と一緒に他の要素(translation, scale)も同時に扱えるようです(回転するコマが移動するとか.試してみたが一応正しそうっぽそうであった)

## その他

通常の node transform による motion blur は linear 補間だけのようです(cubic 補間は無さそうっぽい)

## TODO

回転と移動が一緒になったシーンでモーションブラーがうまくいくかためす.
(e.g.　羽が回転しつつ首を振りつつ自走する扇風機をレンダリングしたいとか)
CSSだけで中身の複数要素は左寄せに並べつつ全体は中央寄せにしたい

タイトルからだとよくわからないかもしれないですが、商品覧のようなページを作成する時に、下の図のようなレイアウトを CSS だけでうまい具合に作りたくなりました。
![matrix.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67153/df190372-01ce-b314-66f5-e761001b93ef.png)
要件は以下の通り

- 複数の要素を一覧表示になるよう並べたい
- 並べる要素数は状況に応じて変動しうる
- 親要素の幅は可変であり、親要素に収まるように子要素の列数も可変にしたい
- 全体は中央寄せ
- 子要素達は左寄せ

# 失敗

最近、 CSS の flexbox が強いという話を知ってなんでもかんでもflexで解決しようとしていたのですが、今回の用件はどんなに頑張ってもどこかに支障がでて上手くいきませんでした。[CodePenのサンプルコード](https://codepen.io/kyome22/pen/KKzZKVE)

## 例1

```css
.parent {
  display: flex;
  align-items: flex-start;
  flex-wrap: wrap;
  justify-content: left;
  margin: 0 auto;
}
```

まずは親要素の`flex-wrap`を`wrap`に指定して`justify-content: left`にした上で`margin: 0 auto`をすればいい感じになると思ったのですが、全体は中央寄席にならず、左に寄ってしまいました。
![スクリーンショット 2020-09-05 20.01.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67153/e2174d60-24bc-69c0-45e5-c9f131fbf160.png)

## 例2

```css
.parent {
  display: flex;
  align-items: flex-start;
  flex-wrap: wrap;
  justify-content: center;
}
```

続いて、`justify-content: center`にしてみましたが、全体は中央寄せになるものの、子要素も中央寄席になってしまいました。

![スクリーンショット 2020-09-05 20.00.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67153/3c5ce0bd-7c20-28bf-7dbd-21c1c931b157.png)

このほかにも3時間ほど試行錯誤しましたが、何かが上手くいけばどこかに支障がでるという感じでした。

# 上手くいく方法

結果論的には、 flexbox を捨てて、 grid を使うと良いということがわかりました。
[CodePenのサンプルコード](https://codepen.io/kyome22/pen/MWyrgOq)

```css
.parent {
  display: grid;
  grid-template-columns: repeat(auto-fit, 100px);
  grid-auto-rows: 100px;
  grid-gap: 16px;
  justify-content: center;
}
```

ここで注目すべきところは、`grid-template-columns`に`repeat()`を使った上で`auto-fit`を指定しているところです。ここが、`auto-fill`だと思ったようにはなりません。

![スクリーンショット 2020-09-05 19.40.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67153/58775eb0-270b-ba6b-aad9-a8540c59fe76.png)

# 参考

- [Flexbox Cheat Site](https://kuroppe1819.github.io/flexbox-cheat-site/)
- [Left aligned and centered grid with flexbox](https://stackoverflow.com/questions/32572347/left-aligned-and-centered-grid-with-flexbox)
- [CSS Gridを使ったレスポンシブ対応の基本レイアウト](https://www.webcreatorbox.com/tech/css-grid-basic-layout)
Laravelでmockeryを使ったユニットテスト

# この記事を読んでできること
LaravelでMockeryを使用したUnitTestができるようになる。
※結構前に作ったものなので、ご指摘あれば気軽にくださいmm

## そもそもMockeryって何？
PHPUnitでモックを作りやすくしてくれるPHPモックオブジェクトフレームワークのこと。
https://readouble.com/mockery/1.0/ja/index.html

# 環境
laravel 5.3
phpunit 5.7.3
mockeryを使用

# やりたいこと
- Test::getInfo()という未実装のstaticメソッドをMock化してphpunitテストしたい
- post送信でlaravelのバリデーションを通して確認も同時に行いたい

下記コードのstore(IdRequest $request)の部分でlaravel既存のバリデーションを行なっている。
ここのテストをするために$this->call()を使用したPOST送信を行っている。
その一連の処理の一部に当たるTest::getInfo()が外部接続で未実装というシチュエーション。

# 手順
## 1. ルーティング設定

```routes/api.php
Route::resource('info', 'info@store');
```

## 2. $this->callするController呼び出し

```App/Http/Controllers/InfoController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Requests\Rlog\IdRequest;
use App\Http\Models\InfoLogic;
     
class InfoController extends Controller{
    public function store(IdRequest $request){
            $info = new InfoLogic($request)
            $info->setInfo();
            return $info->getInfo();
    }
}
```

## 3. IdRequestでvalidate

```App/Http/Requests/IdRequest.php
<?php
namespace App\Http\Requests;
 
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Contracts\Validation\Validator;

class IdRequest extends FormRequest
{
    public function authorize()
    {
        return true;
    }
    public function rules()
    {
        return [
            'id' => 'required|max:255|alpha_num',
        ];
    }
}
```

## 4. ModelからIDに紐づいた情報呼び出し

```App/Models/Infologic.php
<?php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Infologic extends Model{
    public function __construct($request){
        $this->id = $request['id'];
    }
    public function setInfo(){
        $this->info = Test::getInfo($this->id);
    }
    public function getInfo(){
        return $this->info;
    }
}
```

## 5. 情報をDBから呼び出す(Test::getInfo($this->id);のこと、未実装)

この部分をモック化します。

## 6. 上記を踏まえたテストコード書く

```Tests/InfoValidateTest.php
<?php
use Mockery as m;
use App\Models\InfoLogic;
class InfoValidateTest extends TestCase
{
    public function tearDown()
    {
        parent::tearDown();
        m::close();
    }
    /**
     * @runInSeparateProcess
     */
    public function test_id_name()
    {
        // id取得のmock作成
        $mocker = m::mock('alias:App\Models\Test');
        $return = 123456;
        $argument = 'yamada';
        $mocker->shouldReceive('getInfo')->andReturn($return);
        $expected = 123456;
        $actual = $this->call('POST', 'info', array('id' => 'tanaka'));
        $this->assertEquals($expected, $actual);
    }
}
```

## 7. テストコマンド実行

```
$ cd [Laravelのプロジェクト]
$ ./vendor/bin/phpunit tests/InfoValidateTest.php
```
TypeScript のための ValueObject レシピ

## TypeScript で ValueObject を作る時の問題点

### thisは宣言されたclassを返す

多くは共通の関数が存在しますので、基底クラスを作成して、継承することを考えると思います。ですが、typescriptのthisは宣言されたclassを返します。
なので、 `abstract` にするのが良いと思います。 `abstract` にしたclassは初期化を禁止されます。

また、typescriptでファクトリーを作成するときstaticを採用することでしょう。
その際、function句を使用することでthisを定義することができます。

```typescript
export abstract class ValueObject<T> {
  constructor(protected value: T) {}
  public get() {
    return this.value;
  }
  public eq<Instance extends ValueObject<T>>(
    this: Instance, 
    valueObject: Instance
  ): boolean {
    return valueObject.get() === this.value;
  }
  public static of = function <T, Instance extends ValueObject<T>>(
    this: new (value: T) => Instance,
    value: ReturnType<Instance['get']>
  ) {
    return new this(value);
  };
}
```

### typescriptはメンバーが同じなら同等に評価する

基底クラスを使用して、価格と金額を作成して、矛盾した代入をしてみると、lintは何も反応してくれません。これは初期化した後にオブジェクトの構造が同じだから起こります。
理想はエラーを出してほしい！

```typescript
import { ValueObject } from './ValueObject';

/**
 * 価格
 */
class Price extends ValueObject<number> {}

/**
 * 金額
 */
class Amount extends ValueObject<number> {}

const amount: Amount = Price.of(100);

```


## 解決 エラーを出してもらう

この記事では、 `unique symbol` を使用する事で、この問題を解決します。

下記のコードは強引ですが、目的を確実に果たしてくれます。
説明すると、 `private` にすることで露出させず、class内部で参照がないことでlintがエラーを検出するため、 `@ts-ignore` を指定して、無視することをしています。Uniqueは再利用可能ですので、テンプレートとしても利用可能です。

```typescript
import { ValueObject } from './ValueObject';

declare const Unique: unique symbol;

/**
 * 価格
 */
export class Price extends ValueObject<number> {
  // @ts-ignore
  private [Unique]: void;
}

```

## ビルド後に残る？
`private [Unique]: void;` の部分は定義のみですので、コードには残りません。
下記ビルド後のコード

```javascript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const ValueObject_1 = require("./ValueObject");
class Price extends ValueObject_1.ValueObject {}
exports.Price = Price;
```

## Reactのプロジェクトでの話

### ReferenceError: Unique is not defined
`index.html` に `Unique` 変数を定義することで回避できる

```html
<script>
  var Unique = undefined;
</script>
```

### メンバーが残ってる

整合性を取るか、無駄をなくすかのトレードオフ。。。

```
undefined: undefined
value: 100
__proto__: ValueObject
```
JavaScriptのclassについて学んだことメモ(随時追記)

オブジェクト指向プログラミングにあこがれ、JavaScriptのclassを勉強しているので発見をメモ。随時追記します。

## コンストラクタ
コンストラクタはクラスからインスタンスを生成したときに実行される関数。
平たく言えば"関数"なので関数でできることはだいたいできる。

#### 定数・変数を定義

```js:js
class Hoge {
  constructor() {
    const a = 'AAA';
    console.log(a); 
  }
}

const hoge = new Hoge(); // AAA
```

コンストラクタ内で定義した定数・変数はコンストラクタ内でしか使えない。
コンストラクタの外、例えばメソッドでつかったり、インスタンス化したあとインスタンスプロパティとして呼び出すことなどはできない。


```js:js
class Hoge {
  constructor() {
    const a = 'AAA';
    console.log(a); 
  }
}

const hoge = new Hoge();
console.log(hoge.a) // undefined
```
this.a(≠ const a)を呼び出しているためundefinedとなる

```js:js
class Hoge {
  constructor() {
    const a = 'AAA';
    console.log(a); 
  }

  run() {
    console.log(this.a);
  }
}

const hoge = new Hoge();
hoge.run(); // undefined
```

定数a (const a) とプロパティa (this.a) は異なる。
さらにプロパティthis.aは未定義なのでundefinedとなる。

```js:js
class Hoge {
  constructor() {
    const a = 'AAA';
    console.log(a); 
  }

  run() {
    console.log(a);
  }
}

const hoge = new Hoge();
hoge.run(); // エラー
```
コンストラクタ内の定数aではなく、グローバル変数aを呼び出すが未定義なのでエラー。

### 関数の定義・実行

```js:js
class Hoge {
  constructor() {
    function b() {
      console.log('BBB')
    }

    const c = () => {
      console.log('CCC');
    };

    b();
    c();
  }
}

const hoge = new Hoge();
// BBB
// CCC
```
この場合コンストラクタ内で定義した関数は、コンストラクタ内でしか実行できない。

ただし次のようにプロパティに関数を格納すればコンストラクタ内に加え、メソッドのように実行したり、他のメソッドから呼び出すことができる。

```js:js
class Hoge {
  constructor() {
    this.b = function() {
      console.log('BBB')
    }

    this.c = () => {
      console.log('CCC');
    }

    this.b();
    this.c();
  }

  run() {
    this.b();
  }
}

const hoge = new Hoge();
// BBB
// CCC

hoge.b(); // BBB
hoge.c(); // CCC
hoge.run(); // BBB
```
slack通知でユーザーグループに対してメンションを付ける方法、ユーザーグループのidを確認する方法

# slack通知の方法
方法はいくつかの方法がありますが、自分は以下記事の「[やりかた2（app経由）]([pythonでslackに通知する方法まとめ](https://qiita.com/Ikki_U/items/cd3ab65e25cb7021aa0a))」を使うことが多いです。
[pythonでslackに通知する方法まとめ](https://qiita.com/Ikki_U/items/cd3ab65e25cb7021aa0a)

#ユーザーグループに対するメンションの付け方
textパラメーターの中に以下のように書くとメンションが付けられます。
`<!subteam^id>`

上記記法のうち、`id` がユーザーグループのidとなり、仮にユーザーグループのidが「A123BCDEFGH」だとしたら
`<!subteam^A123BCDEFGH>` と書くことになります。


（ユーザーグループはslackから「メンバーディレクトリとユーザーグループ > ユーザーグループ」で確認できます）

## id を確認する
slack API の以下のページへ行き、Requiredの箇所のValueを埋めて「Test Method」を押します。
このときのValueは、idを確認したいユーザーグループが設定されているワークスペースのValueを使います。
https://api.slack.com/methods/usergroups.list/test

すると以下のような結果が返ってきます。
その中の"name"からメンション設定したいユーザーグループ名を探し、そのオブジェクト内のidが対象となります。

表示される結果すべてユニコード表記となっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503434/70503248-690b-4cac-5a14-ec19e170907b.png)


#補足 ー 基本的なメンションの付け方
基本的なメンション先の記法は以下記事の通りとなります。
[SlackのAPI経由でのメンションの仕様変更(2018/9/12～)](https://qiita.com/gimKondo/items/99ba9b05d14a6b49df68)

`<@表示名>`、`<!channel>`、`<!here>`、`<!everyone>`を使うとメンションを付けることができます。

# 参考文献
[pythonでslackに通知する方法まとめ](https://qiita.com/Ikki_U/items/cd3ab65e25cb7021aa0a)
[Python3でslackに投稿する](https://qiita.com/shtnkgm/items/4f0e4dcbb9eb52fdf316)
[SlackのAPI経由でのメンションの仕様変更(2018/9/12～)](https://qiita.com/gimKondo/items/99ba9b05d14a6b49df68)
cygwinでlapack/blasを動かす

#インストール方法
```
apt-cyg install liblapack-devel
```

※ ヘッダファイル`cblas.h`は、`liblapack-devel`に含まれています。
https://cygwin.com/packages/summary/liblapack-devel.html

#コンパイル方法
```
gcc -o dgemm_demo dgemm_demo.c -lblas
g++ -o dgemm_demo dgemm_demo.cpp -lblas
```

#サンプルコード
```C:dgemm_demo.c
#include <stdio.h>
#include <cblas.h>

void print_matrix(double *data,int row,int col){
    for (int i = 0; i < row; ++i){
        for (int j = 0; j < col; ++j){
            printf("%6.1f", data[i*col + j]);
        }
        printf("\n");
    }
}

int main(void){

    double alpha, beta;
    int M = 3, N = 4, K = 2;
    // A[MxK] , B[KxN] , C[MxN]
    double A[3*2] = {
      1, 2,
      3, 4,
      5, 6};
    double B[2*4] = {
      1, 2, 3, 4,
      5, 6, 7, 8};
    double C[3*4];

    // C = alpha * A * B + beta * C
    alpha=1; beta=0; // C = A*B
    cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, M, N, K,
    alpha,  A,K,  B,N,  beta,  C,N);

    print_matrix(C,M,N);

    // C = alpha * A * B + beta * C
    alpha=1; beta=1; // C = A*B + C
    cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, M, N, K,
    alpha,  A,K,  B,N,  beta,  C,N);

    print_matrix(C,M,N);

    return 0;
}

/*========================
$ ./dgemm_demo.exe
  11.0  14.0  17.0  20.0
  23.0  30.0  37.0  44.0
  35.0  46.0  57.0  68.0
  22.0  28.0  34.0  40.0
  46.0  60.0  74.0  88.0
  70.0  92.0 114.0 136.0
 */
/*========================
$ octave -q --no-gui
octave:1> A=[1 2; 3 4; 5 6]; B=[1 2 3 4; 5 6 7 8];
octave:2> C=A*B, C=A*B+C
C =
   11   14   17   20
   23   30   37   44
   35   46   57   68

C =
    22    28    34    40
    46    60    74    88
    70    92   114   136
 */
```
#エラー例とその原因
```
$ gcc -o gemm gemm.c
/usr/lib/gcc/x86_64-pc-cygwin/9.3.0/../../../../x86_64-pc-cygwin/bin/ld: /tmp/ccCjV9aP.o:dgemm_demo.c:(.text+0x235): undefined reference to `cblas_dgemm'
/tmp/ccCjV9aP.o:dgemm_demo.c:(.text+0x235): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `cblas_dgemm'
collect2: エラー: ld はステータス 1 で終了しました
```
`-lblas`の付け忘れ。
VScode スニペット登録 【JavaScript】

##活用するメリット:point_up:

- 　 ```clickEvent() =>```などの、記述が長く、クセのある構文が、改行込みで設定可能

-  　```console.log()``` など使用頻度の高いメソッドを、任意のキーワードで素早く呼び出せる

- 　```文字列の空白```も調整可能。

- 　設定は、```基本設定 → 　ユーザースニペット  →　 検索窓[javascript.json]```





##【Javascript.json】


```java
"clickEvent": {
 "prefix": ".adc",  //.adcと入力すれば、"body"の中身が出力される
 "body": [
 ".addEventListener('click', () => {",
  " $1",   //[$1] = スニペット実行後、始めにカーソルが当たる位置を指定。 $2 も設定可能
   "});"
 ],
},
```

##【JavaScript】


```javascript

 const button = document.querySelector('button');  //button要素を取得

  // button に続けて .abcと打てば、入力補完に、「ユーザースニペット」が出現。
  button

  //確定をすると、
  button.addEventListener('click', () => {
   //字下げ + カーソルがここに当たっている。
  });

```
:point_down:コチラに詳しく載ってます:point_down:
<b>[参考:lisz-works] https://www.lisz-works.com/entry/vscode-snippets
<b>[参考:スニペット作成] https://vscode-doc-jp.github.io/docs/userguide/userdefinedsnippets.html
【Windows10ユーザー向け】超便利！仮想デスクトップの使い方

よくIT勉強系Youtuberの方の動画などで、**デスクトップを横にスワイプさせて複数の画面を行き来させながら説明される場面**を見た方いないでしょうか？

Windowsユーザーの自分としては、「あれはMacユーザーの特権なのかなぁ」と思い込み勝手にあきらめていたのですが（勉強不足）、偶然YoutubeでWindows10でその機能が提供されていることを知りまして、早速便利に利用しています。

今回はその設定方法についてまとめてみました。まだ利用されていない方は簡単なので試してみてください。

最後にお好みで使ってもらえる簡単なTipsも用意しました。

#対象
- Windows10ユーザーで**仮想デスクトップ**をまだ使っていない方

#仮想デスクトップとは？
- デスクトップを仮想的に複数持てる機能です。画面が広く使える感じがします。
- デュアルディスプレイの場合ではその組み合わせが複数持てます。私はノートPC＋ディスプレイで2画面構成ですが、仮想デスクトップを1つ増やせば、2×2=4画面、2つ増やせば2×3=6画面使えます。
- 仮想デスクトップ間の移動もショートカットでラクチンです。
- 仮想デスクトップ間でクリップボードは共有されます。つまり仮想デスクトップ間でもコピペができます。（これ重要）
- 仮想デスクトップ上のファイルやフォルダは仮想デスクトップ間で共有されているので、ある仮想デスクトップにショートカットやファイルを置くと全ての仮想デスクトップに表示されます。

#Alt+Tabの切り替えとどう違うの？
- 複数のアプリを組みあわせたデスクトップ構成自体を複数持つことができるので、マルチタスク時にもとっても便利です。
- 好みの問題かもしれませんが、私は仮想デスクトップの方が圧倒的に使いやすいです。（もちろんAlt＋Tabも使います！）

#やり方
ずばり、この動画見てください。めちゃくちゃわかりやすいです。
[仮想デスクトップの使い方【覚えないと損】 - YouTube](https://www.youtube.com/watch?v=VFD1vhBo_uc)

ポイントだけ書くとこんな感じです。

1.タスクバーで【タスクビューボタン】を追加（タスクバーを右クリックして表示できます）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131112/9425ccce-9ead-dc1b-2697-150a7633a5b9.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131112/e25e0f4e-2e76-917b-ce41-1c001c702383.png)
これが【タスクビューボタン】です。

2．【タスクビューボタン】を押下します。するとこんな画面が開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131112/309989e1-7a15-97ec-22fd-1048caee9307.png)
現在仮想デスクトップが2つ（デスクトップ1とデスクトップ2）用意されている状態です。

3．上部の【新しいデスクトップ】を追加すると、デスクトップ3が追加されます。

#ショートカット
仮想デスクトップの便利さや快適さは**ショートカット利用時に最大化される**ので、是非これは覚えましょう。
めちゃくちゃ簡単です！一般的なキー配置だと**左下のボタンを2つ＋〇〇**って感じですね！

|振舞い|ショートカットキー|
|:--|:--|
|仮想デスクトップ間を移動する|【Ctrl】＋【Windows】＋【←（左）】or【→（右）】|
|仮想デスクトップを追加する|【Ctrl】＋【Windows】＋【D】|
|仮想デスクトップを閉じる|【Ctrl】＋【Windows】＋【F4】|

#お好みで
仮想デスクトップ間で壁紙が同じだとちょっと見間違うことがあったりするので、「仮想デスクトップ間で壁紙を変えたいなぁ」という方もいるかと思います。ただWindows10の標準仕様では仮想デスクトップはすべて同じ壁紙になります。

ただSylphyHornというツール（ Microsoft ストアにて提供されているので安心です）を利用することで、異なる壁紙を設定することができます。やり方は[Windows 10 必見！仮想デスクトップ毎に違う壁紙を設定する方法 | Tanweb.net](http://tanweb.net/2017/06/26/15219/)をご覧ください。

私は壁紙にカレンダーを設定したい人なので、[ANAさんの壁紙サイト](https://www.ana.co.jp/ja/jp/share/wallpaper/calendar.html)を利用させていただいています。
6種類ほどあるので毎月全部ダウンロードし、名前を1.jpg～6.jpgに変更して指定のフォルダに配置しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131112/6f4f8647-55ba-3eef-60e4-d5c6eeb2187b.png)

「別に壁紙なんて同じでもいいよ」という方は特にこの設定はしなくてもよいかと思います。

#参考
[仮想デスクトップの使い方【覚えないと損】 - YouTube](https://www.youtube.com/watch?v=VFD1vhBo_uc)
[Windows 10 必見！仮想デスクトップ毎に違う壁紙を設定する方法 | Tanweb.net](http://tanweb.net/2017/06/26/15219/)
[壁紙カレンダー シンプルに使える飛行機画像をダウンロード | ANA](https://www.ana.co.jp/ja/jp/share/wallpaper/calendar.html)