OmniAICreator/Qiita-1.07M huggingface dataset:
ASP.NET Coreで、HTMLレンダリング時に2byte文字がエンコーディングされないよいうにする


以下のようなTag Helperを書いたとします。


```html
<label asp-for="Name" class="col-md-2 control-label"></label>
```

Nameプロパティで以下ような属性を付加した時に、

```c#
[DisplayName("氏名")]
```

次のように、日本語がHTMLエンコードされてしまいます。cshtmlに埋め込んだJavaScriptでも、エンコードされてしまいます。
このままでも動作に支障はないですが、デバッグするときに不便です。


```html
<label class="col-md-2 control-label" for="Name">&#x6C0F;&#x540D;</label>
```

こんな時な、Startup.csに、`ConfigureServices`メソッドに、以下のようなコードを追加します。

```c#
using System.Text.Encodings.Web;
using Microsoft.Extensions.WebEncoders;
using System.Text.Unicode;

…
    services.Configure<WebEncoderOptions>(options => {
        options.TextEncoderSettings = new TextEncoderSettings(UnicodeRanges.All);
    });
```

こうすることで、以下のような見慣れたHTMLにレンダリングされるようになります。

```html
<label class="col-md-2 control-label" for="Name">氏名</label>
```

`UnicodeRanges.All` を指定しているので、すべてのコードがエンコード対象外になります。

UnicodeRanges.Allじゃやだ！という方は、

```cs
        options.TextEncoderSettings = new TextEncoderSettings(
            UnicodeRanges.CjkUnifiedIdeographsExtensionA,
            UnicodeRanges.CjkCompatibility,
            UnicodeRanges.Hiragana,
            UnicodeRanges.Katakana,
            ...            
            );
```

とか書けば良いのですが、面倒なので、`UnicodeRanges.All`　でいいのかなと思います。

もちろん、`<>&` などは、エンコードされます。

`WebEncoderOptions`は、`HtmlEncode`、`JavaScriptEncode`、`UrlEncode`の３つのエンコードに共通のオプションを指定するものです。
Linux　コマンド　３２　手順書フォルダ（完了）

# 概要
Progateを参考に今の自分にとって必要なコマンドをノートしました。
32 選びました。
# 課題
scpの使い方。
scp -i "./test-key.pem" test-db-key.pem ec2-user@XX.XXX.XX.XXX:/home/ec2-user/
解決済み
# TakeAway
.コマンドは必ず半角英数字
.コマンドを実行後、 キーボードの入力は画面に表示されるが、プロンプトが表示されない
→ [control]+[d]
.コマンドを実行後、 キーボードの入力は画面に表示されず、プロンプトも表示されない
 [control]+[c]
.コマンドと引数の間には必ず半角スペースを1つ以上入れます
# コマンド 
mkdir  ディレクトリ作成
cd     ディレクトリの移動
pwd　　カレントディレクトリを確認する
ls　　　ディレクトリの中身を確認する
 　　　ls -l　詳細な情報が確認できる
 　　　ls -a  隠れているファイルも表示される
 　　　ls -l *.conf
 　　　ls -l s?????
 　　　ls -l [ps]?????
 　　　ls -l [f-h]*
 　　　ls -l {sh,ho}*
○less　　テキストファイルを1画面ずつ表示する　
　　　　←スペース   改ページ q 終了　Ctrl + L クリア
/　　　　前から検索
　　　　←Enterで繰り返し
?　　　　後ろから検索
　　　　Enterで繰り返し
○Shift + >　ファイルの最後
Shift + <　　ファイルの先頭
touch ファイルの作成
cp　　　　コピーする
    cp -r mysite/ myprofile
mv       移動する
chmod 　　権限を変える　例）chmod 777
tail -f ttt.dat    追記を監視する
　　　　←　Ctrl　＋　C　終了
ps aux プロセスを表示する
mkdir ディレクトリを作成する
 mkdir -p mysite/css
rmdir　ディレクトリを削除する
○rm -rf test　　ファイルやフォルダを強制的に削除する
vi      viエディタを起動する。（本項の手に余るので詳細はご容赦を）

# 番外
現場に出た時必要なもの参考アドレス
https://satton-infra.com/sekkeikochiku-kihon/
VIについて
https://language-and-engineering.hatenablog.jp/entry/20121207/p1
https://github.com/IBMDeveloperTokyo/DojoBasicLab/tree/master/Lab2_Editor/Lab2-1_vi
コマンドについて
Dojo Basic: Lab1-1 コマンドの基礎
https://github.com/IBMDeveloperTokyo/DojoBasicLab/tree/master/Lab1_ShellCommand/Lab1-1_CommandLineBasic

エクササイズ
コマンドを実行後、 キーボードの入力は画面に表示されるが、プロンプトが表示されない
→　
テキストファイルを1画面ずつ表示する　→　
ファイルの最後　→　
ファイルやフォルダを強制的に削除する　→
MicroPythonのWebREPL試した話

# はじめに
MicroPythonにはWebREPLと呼ばれる、ブラウザ上でPythonプロンプトを使える機能があります。ESP32ボードで使用したのでやり方を残しておきます。

# 環境
- ESP32開発ボード(https://www.amazon.co.jp/dp/B0718T232Z/ref=cm_sw_em_r_mt_dp_U_F6ZwEbQRHH53S)
- MicroPython v1.12
- 作業PC Windows10

# やり方
MicroPythonのファームウェアを書き込んでいる状態で進めます。
シリアル通信で接続を確認したらwebrepl_setupをインポートします
Would you like to (E)nable or (D)isable it running on boot?はEと入力して続いてパスワードを入力します。その後リブートするか聞かれるのでyと入力してリブートします。


```
MicroPython v1.12 on 2019-12-20; ESP32 module with ESP32
Type "help()" for more information.
>>> import webrepl_setup
WebREPL daemon auto-start status: disabled

Would you like to (E)nable or (D)isable it running on boot?
(Empty line to quit)
> E
To enable WebREPL, you must set password for it
New password (4-9 chars): hoge
Confirm password: hoge
Changes will be activated after reboot
Would you like to reboot now? (y/n)
```

自分の場合は何故か起動時にアクセスポイントにならないので、一度webreplを手動でスタートします。
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211264/95b6c354-6bec-34b6-eba5-3c08aa1caf5b.png)

PCからアクセスポイントに接続し、https://github.com/micropython/webrepl からwebreplクライアントをダウンロードしてwebrepl.htmlを開きます。Connectボタンを押してパスワードを入力したらWebREPL接続完了です。
起動時にスタートすると同時に別のネットワークに接続する処理を追加して作業PCをインターネットに接続できるようにするためにboot.pyに次のコードを書き込みます。

```Python:boot.py
import network
import webrepl
import utime


sta = network.WLAN(network.STA_IF)
sta.active(True)

sta.connect("SSID", "PASSWORD")
start_time = utime.time()
while utime.time() - start_time < 10:
    if sta.isconnected():
        print("connect")
        webrepl.start()
        break
else:
    print("Timeout")
    sta.active(False)
    ap = network.WLAN(network.AP_IF)
    ap.active(True)
    webrepl.start()
```

デバイスの接続が成功するとLAN内でWebREPLと接続することができます。10秒以上かかっている場合は失敗とみなして自身をアクセスポイントとして動作させてWebREPLをスタートします。
webreplクライアントからboot.pyをデバイスに送信して再起動します。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211264/ae8850ce-0025-7628-f4a7-ed58dc432bee.png)

起動するとwebreplがスタートしてIPアドレスが表示されるので、クライアントで接続確認して完了です。
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211264/e3e906eb-a926-d2f0-e35d-c57ac1d25e27.png)
![MicroPython WebREPL](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211264/aca8816c-5a40-9baa-b813-e7f1ee4ac3f9.png)

# 参考サイト
- 公式リファレンス(https://micropython-docs-ja.readthedocs.io/ja/latest/esp32/quickref.html)
- https://learn.adafruit.com/micropython-basics-esp8266-webrepl/access-webrepl
VPCのログをLambdaで読み込む

やりたいこと
・クロスアカウント環境下で他アカウントのVPCログを特定アカウントに集約する
・S3にログを集約してファイル作成ごとにLambdaでファイルを読み込む
　（外部への一定バイト以上の通信を検知して通知するような監視に利用する）

別記事でクロスアカウントにおけるログ集約は記載しましたので
その部分は割愛し、ファイル作成時にLambdaで読み込む部分を記載します。

```:ファイル出力するS3のバケットとキー
kaikusakari-test-vpc/AWSLogs/123456789012/vpcflowlogs/ap-northeast-1/	
```

## Lambdaの設定
**イベントのトリガー**
イベントタイプ: PUT
バケット名：kaikusakari-test-vpc
プレフィックス: AWSLogs/123456789012/vpcflowlogs/ap-northeast-1/
（vpcのログはバケット名のみ指定してキー階層はデフォルトです）

**ロール**

```json:Lambdaの実行
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "arn:aws:logs:ap-northeast-1:123456789012:log-group:/aws/lambda/test:*"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": "logs:CreateLogGroup",
            "Resource": "arn:aws:logs:ap-northeast-1:123456789012:*"
        }
    ]
}
```

```json:S3アクセス用ポリシー
{
   "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:GetLifecycleConfiguration",
                ・・・中略・・・
                "s3:GetObjectVersion"
            ],
            "Resource": "arn:aws:s3:::kaikusakari-test-vpc/*"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "s3:GetAccessPoint",
                "s3:GetAccountPublicAccessBlock",
                "s3:ListAllMyBuckets",
                "s3:ListAccessPoints",
                "s3:ListJobs",
                "s3:HeadBucket"
            ],
            "Resource": "*"
        }
    ]
}
```

言語でAWS SDKを使ってS3のオブジェクトを読み込み可能です。
Unityで動画を再生する方法（備忘録）

### Unityにおいて動画を再生する方法
今回の目的は、2Dにおいて一画面に複数の動画を再生するということを目的としている。

### 手順
1. HierarchyからPlaneを作成する。
2. PlaneのInspectorにおいてVideoPlayerのcomponentの追加を行う。
![コメント 2020-03-01 144508.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199067/d4854347-6e41-a306-a688-c8cf556f70e2.png)
3. Video Clipに目的の動画を追加する。
4. AssetsにRender Textureの作成を行う。
![コメント 2020-03-01 144723.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199067/dcd93cfe-cd6b-ce30-40f1-86f97a43edde.png)
5. HierarchyにおいてRawImageの作成を行い、RawImageのHierarchyのTextureに作成したRender Textureを追加する。
![コメント 2020-03-01 145505.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199067/9c52c82f-5e80-8616-d152-ced19ab4c074.png)

6. PanelにおけるHierarchyのVideoPlayerのTarget Textureを4で作成したRender Textureを追加する。
![コメント 2020-03-01 150315.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199067/3ef3702f-8463-3c07-ee82-212e9111ac64.png)



これによって動画を再生することが出来るようになる。

### 音声の追加する方法
PlaneにAudio Sourceのコンポーネントを追加して以下のようにVideoPlayerのコンポーネントに追加する。
![コメント 2020-03-02 143633.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199067/13a48cf8-3655-9311-9d14-45562f7143e6.png)


参考にしたURL
https://gametukurikata.com/basic/videoplayer
https://note.com/yukyu/n/ncdf99123eebd
git: 一般的なコマンド

設定ファイル：

.git
.gitignore


コマンド：
1. git config --global user.name "USER NAME" : ユーザー名の設定
2. git config --global user.email "EMAIL ADDRESS" : ユーザーの電子メールアドレス
3. git config -l : 設定確認
4. git init : フォルダをgitの作業フォルダへ初期化
5. git status : 今の編集状況を確認
6. git diff : ワーキングディレクトリ内の編集の差分確認
7. git diff --cached : ステージングエリア内の編集の差分確認
8. git checkout -- {filename} : 編集のロールバック
9. git add {filename} :  ステージングエリアへ追加
10. git commit -m "MESSAGE" : リポジトリへ移動
11. git log -- stat : 履歴確認
12. git branch : ブランチリスト表示
13. git branch {BRANCHNAME} : 新規ブランチを作成
14. git checkout {BRANCHANKE} : 希望のブランチへ移動
15. git merge {ReferredBranch} : 別のブランチからマージする
16. git branch -d {BRANCHNAME} : ブランチを削除
17. git remote add {repo name} {repo path} : リモートリポジトリの登録
18. git remote rm {repo name} : リモートリポジトリの削除
19. git push {repo name} {branchname} : ブランチの内容をリモートリポジトリにアップロード
20. git clone {repo path} {working directory} : リポジトリの内容をワーキングディレクトリへコピー
21. git pull {repo name} {branchname} : リポジトリの内容をブランチへダウンロード



```bash

git config --global user.name "Jon Star"
git config --global user.email "xxxxx.aaa.com"
git config -l
git init
git diff
git diff --cached
git status
git checkout -- {filename}
git add {filename}
git commit -m "MESSAGE"
git log --stat
git branch
git branch {BRANCHNAME}
git checkout {BRANCHNAME}
git merge {ReferredBranch}
git branch -d {BranchName}
git remote add {repo name} {repo path}
git remote rm {repo name}
git push {repo name} {branchname}
git clone {repo path} {working directory}
git pull {repo name} {branchname}
```
ドリルTX７　（200301実施）

①コードは基本上から順番に実行される
なんとなく「上からざっと読まれてメソットじゃないところから読まれる。」
捉えていた


②コードが読まれる順番について
はじめに読まれる、配列に全てのレビューの情報が格納される。
・スコープに違いによってメソット内から直接アクセスできない。
・そのため、各メソッドに引数としてpostsを渡して、その返り値をpostsに再代入しています。
・各メソッドでは、仮引数がa_postsという名前で定義されています。そのため、渡されたpostsをa_postsという変数にコピーして、メソッド内で使用することができます。

。。。えっと、、、日本語話してもらっても大丈夫ですか？

③メソットが何をしているのか
・65行目でpost_review(posts)という記述があります。
そのため、今までのレビュー全件が入ったpostsという配列が引数で渡されてpost_reviewが呼び出されます。

・仮引数の名前はa_postsなので、post_reviewのメソッド内ではa_postsという配列にレビュー全件が入っていることになります。

・メソッドの中で、postというハッシュを定義し、その中に最新のレビュー情報を格納しcwます。

・最後にa_postsにpostを追加し、その結果を返り値として返しています。


キーワード
スコープ、ハッシュ、本引数、仮引数、代入、返り値
田周り最短経路アプリ

#田周りするときの最短経路を求めたい！

手順：

１．SiCroFをインストール（Ubuntu推奨！）

2. ディレクトリSiCroFでインタラクティブモードを起動

```
➜  SiCroF ✗ python3 SiCroF.py
Detecting OS type...
OS : Linux
>
SiCroF >> Fortran Interactive mode for Linux & OS X... 
Here, fortran script runs with  SiCroF-kernel.
You can debug your code with SiCroF-API
  
>
>
Initializing ...
Please input fortran script *.f90 | or check manual by 'man'  
  
>>> 
```

3. スクリプトファイル(Tutorial/RouteOptimization/RouteOpt1.f90)を呼び出す。

```
➜  SiCroF ✗ python3 SiCroF.py
Detecting OS type...
OS : Linux
>
SiCroF >> Fortran Interactive mode for Linux & OS X... 
Here, fortran script runs with  SiCroF-kernel.
You can debug your code with SiCroF-API
  
>
>
Initializing ...　
Please input fortran script *.f90 | or check manual by 'man'  
  
>>> Tutorial/RouteOptimization/RouteOpt1.f90
```

実行すると全ほ場の座標データが入った入力ファイルパスを聞かれるので、入力。
入力ファイルの形式は、

```
[全田圃数]
[田圃#1の緯度のgoogle map座標]　　[田圃#1の経度のgoogle map座標]　[田圃名（ローマ字）]
[田圃#2の緯度のgoogle map座標]　　[田圃#2の経度のgoogle map座標]　[田圃名（ローマ字）]
[田圃#3の緯度のgoogle map座標]　　[田圃#3の経度のgoogle map座標]　[田圃名（ローマ字）]
[田圃#4の緯度のgoogle map座標]　　[田圃#4の経度のgoogle map座標]　[田圃名（ローマ字）]
...
```
次に、入力ファイルのほ場のうち上から何筆まで指定するかを聞かれるので、1~[全田圃数]の間で値を入力。

計算が終わると、出力ファイルのパスを聞かれるので指定する（フルパス推奨、最後の/は不要）。

経路は出力ファイル内に RouteOpt_OptimalRoute.csv として出力されるので、google mymapなどで開く。

なお、以上の入出力をfortranスクリプトとして書くことも可能。

[2020/3/16追記]
Tutorial/RouteOptimization/RouteOptimization.pyにpythonAPIの使用例を追加しました。


```python
import src.PySiCroFClass.SiCroF

obj=src.PySiCroFClass.SiCroF.routeOpt()
# Project=[WriteYourProjectDirectoryPath] (without / in the last)
# In [WriteYourProjectDirectory], please set a file named "Addresslist.txt"
obj.getOptimizedRoute(Project="Tutorial/RouteOptimization")
```
僕のエラー解決手順

## はじめに
みなさんはエラーが出た際に、自己解決はできていますか？
僕が現場に入りたての頃は、「エラーが出てしまったんですけど、どうすればいいですか？」という質問を先輩によくしてしまい、先輩の方をよく困らせていました。
しかし正しいエラーの対処方法を見出してからは質問することはほぼなくなり、ほとんどのエラーを自己解決できるようになりました。
そこでこの記事では僕が考える正しいエラーが発生した時の僕なりの手順をまとめてました！

## エラーメッセージを翻訳する
まずはエラーメッセージをグーグル翻訳で日本語に翻訳してみましょう。
たいていの場合この段階でどの部分が原因でエラーが発生しているのかはある程度特定できます。
以前の僕はエラーがでたらすぐにエラーメッセージをググっしまっていたことが多かったです。
今だから思うのですがこれはあまり良くなかったです。
なぜかというと、あっさり解決方法が見つかることもありますが、中には適切ではない解決策が載っていることも多々あるからです。
その為、ググっても良いのですがむやみやたらと信じてしまうのはよくないです。
またググって解決するを繰り返していると癖がついてしまい、ググっても解決方法が見つからない時にどうすればいいかわからなくなってしまいます。
その為、翻訳してもどういうエラーか分からない場合にのみ、ググる。そして内容は参考程度にしておきましょう。

## 仮説を立てる
次に仮説を立てましょう。
ここで注意しなければならないのがあくまで仮説を立てるということです。
どういうことかというと仮説と予想は違うということ。
以前の僕はよく根拠のない予想を立ててしまっていました。
根拠のない予想を立てそれを検証したところでそれはギャンブルでしかありません。
僕は良くこの過ちを犯してしまい、問題解決にとてつもない時間をかけてしまっていました。
その為、仮説を立てる時は「〇〇だから〇〇と考える」というような根拠のある仮説をたてましょう。

## 検証する
仮説が立てられたらあとはその仮説を検証するだけです。
この方法はいろいろありますが、重要なのは確実にその仮説を検証するということです。
ここであいまいな検証をしてしまうと正しい結果は得られず無意味な検証を繰り返してしまうことへと繋がります。
そしてもう一つ意識してほしいのが求めている結果がえられなかったとしてもネガティブにならないことです。
ネガティブな気持ちになると集中力が切れてしまい次の検証に影響がでてしまうからです。
そもそもネガティブになってしまう原因は、検証に対しての答えを期待しすぎてしまうことにあると考えます。
その為、検証する際は、過度の期待はしないよう意識しましょう。

## 仮説と検証を繰り返す
あとは仮説と検証の繰り返しです。
上記の事をを正しく行なっていれば、間違いなく答えを導き出すことができます。

## わからなくなってしまったら一度離れる
上記は非常に集中力が必要な作業です。
その為少しでも気が抜けると分からなくなってしまうことが多々あります。
そんな時オススメなのが、いちど離れてしまうことです。
決して仕事をサボれと言っているわけではありません。
気分転換をしてみるということです。
僕がオススメする方法が、あまり頭を使わない作業に切り替えることです。
良い気分転換になりますし、また作業をしていると新たな仮説が生まれことがあります。
現に僕はこの方法で問題を解決したことが何度もあります。
何に切り替えるかはあなた次第ですが、僕のオススメはあまり頭の使わない作業です。

## 最悪の場合、誰かにきく
これは本当に最悪の場合です。
これは僕から言わせてみれば「諦める」という行為です。。
以前の僕は４番の途中か２番の手前で諦めてしまい、よく先輩に質問していました。
今はこれが良くなかったことだと気付けて本当によかっと思います。
もしこれを見ていただいている方で、以前の僕と同じようにすぐ人に聞いてしまっているという方は気を付けたほうがいいです。
なぜなら癖がついてしまい、エラーが発生した時に「誰かに聞く」という選択肢が自然と生まれてしまうからです。
また最悪誰かに聞けばいいやという気持ちがあると４番の途中で雑念が入り集中力を切らしてしまいます。
その為本当に切羽詰まった場合のみ誰かに聞くようにすべきだと考えます。

## さいごに
この記事では僕が普段から行なっているエラー解決の手順を書かせていただきました。
あくまで僕が考える手順となるので、参考程度に見ていただけるとありがたいです。
それではご視聴ありがとうございましたm(_ _)m
renderでビューを出す時の注意点

## 内容
先日、railsでウィザード形式でログイン機能を実装しました。
その中でエラーハンドリングを行いrenderでもう一度同じビューを表示させたところ
「AbstractController::DoubleRenderError in Users:: 〜」
が出ました。

## 解決策
どうやら「何度もおんなじビューを呼び出してますよー」というエラーのようです。
render ~~ and return
としてあげればrender地獄から抜けられました。
よかったです。
配列における計算と出力

## 問題
八百屋さんのシステムで以下の配列から名前と合計金額を出力するプログラムを描いてください

```ruby
fruits_price = [["banana", [200, 250, 220]], ["grape", [100, 120, 80]], ["watermelon", [1200, 1500]]]
```

## 解答
```ruby
fruits_price.each do |name, price|
  puts "#{name}は合計金額は#{price.sum}円です"
end
```
each文により配列から順に値を取り出してnameとpriceに入れます。
それを出力する際にprice.sumで値を全て合計してから出力をしています。
これにより出力結果が以下のようになります。

```:ターミナル
bananaの合計金額は670円です
grapeの合計金額は300円です
watermelonの合計金額は2700円です
```
【Chromebook】Spaceキーを常に半角にする方法

Chromebookを新規に購入した。
普段、自宅で使っているように、spaceキーで常に半角にする方法を探していたので、覚書として記録する。

１．設定を開く。
   ＃ランチャーからでもいいし、シェルフにある入力方法から、設定を開く方法でもいい。

２．言語と入力->入力方法を選択。

３．日本語入力の右横にあるマークをクリック。

４．日本語入力の設定という画面が出てくるはずなので、スペースの入力を「全角」から「半角」へと変更する。

これでspaceキーを押したときに、常に半角になっているはずだ。
【Xcode11対応】Prefix.pchの設定のやり方

##記事の背景
いつもプロジェクトを新規作成する際はいつも指示を出して追加していましたが、  
改めて調べた所、`Xcode6`から自動追加されないようになり、その頃とやり方が大きく異なるので最新のやり方についてまとめておきます。

##手順
❶プロジェクトファイルの直下に`「PrefixHeader.pch」`を追加する。
❷対象TARGETの`Bulid Settings`の`PrefixHeader`で上記ファイルのパスを指定する。


##プロジェクトファイルの直下に`「PrefixHeader.pch」`を追加する。

`Command+n`で新規ファイルを追加して`「Other」>「PCH FILE」`を選択。
![スクリーンショット 2020-03-01 14.34.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551622/d7959188-16fe-591e-4e4b-00ff01d6ae93.png)
名前は変更しても構いませんが本記事はデフォルトネームを取り扱いますのでご了承ください。

![スクリーンショット 2020-03-01 14.34.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551622/224f1588-8909-2092-a821-afe3b5779d57.png)
上記のようにプロジェクトファイル直下になれば問題ございません。  
(後にパスを指定する都合上こちらの方が都合が良かった)

##対象TARGETの`Bulid Settings`の`PrefixHeader`で上記ファイルのパスを指定する。
![スクリーンショット 2020-03-01 14.37.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551622/ed68c84d-d1bd-9753-219b-b572015a67ca.png)

上記`「Prefix Header」`を押下して`$(SRCROOT)/$(PROJECT)/PrefixHeader.pch`と設定する。
![スクリーンショット 2020-03-01 14.38.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551622/a40c5e2a-8bf7-544e-f43c-a7d11d5f1ae2.png)

これで`「PrefixHeader.pch」`を適用できておりますので、  
よく使うクラスなどは`#import "hogeViewController.h"`など書いてください。

###PrefixHeader.pch
```objective_c

#ifndef PrefixHeader_pch
#define PrefixHeader_pch

// importしたいクラスを記載する。
#import "HogeViewController.h"
// Include any system framework and library headers here that should be included in all compilation units.
// You will also need to set the Prefix Header build setting of one or more of your targets to reference this file.

#endif /* PrefixHeader_pch */

```
また以前記事書きましたが下記の色の定義の宣言はかなり便利なのでオススメです。活用してみてください。

```objc
#define RGB(r, g, b) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1]
#define RGBA(r, g, b, a)    [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:(a)]
```


##余談:`$(PROJECT)`など確認する方法
これは完全な脱線です。ただ他にはどんなコマンドがあるのだ？など疑問ある人だけ進めてください。  

❶TAGERT > BuildPhases > 「+」 > New Run Script Phase
❷RunScriptに`env > env.txt`を登録して`Build(Command+R)`する
❸プロジェクトフォルダに env.txt というファイルが生成されるので中身を確認する。

![スクリーンショット 2020-03-01 14.45.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551622/fa3d059d-ca9a-8d88-f8b7-e1c8215b5614.png)
![スクリーンショット 2020-03-01 14.46.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551622/6ad6f328-505c-61cd-fcf7-052465b907c1.png)

こんな感じで実行したプロジェクト内に格納されているかと。
これをテキストエディタにて開いて、希望のコマンド探してみてください。
![スクリーンショット 2020-03-01 14.46.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551622/366b7535-2e5e-8e84-74ca-2c509234ccef.png)
閏年は4年に1回？

初投稿です。
初回はプログラミングと関係ないことを書きます(笑)

今年はオリンピックイヤーですね。
オリンピックということは閏年でもあります。
ところで、閏年ですが4年に1回必ず来るものだと勘違いをしてはいませんか。
私も少し前まではそう信じていましたがそうではなかったのです。

### 閏年の真実
そんなに大袈裟なものではないですが…。

1. 基本的には4年に1度来る
2. しかし、100の倍数の年は閏年ではない
3. さらなる例外として、400の倍数の年は閏年である

つまり、厄介なのは100の倍数の年で、2000年は閏年であるが2100年は閏年でないということになります。
2000年と2100年はどちらがレア感があるのかは分かりませんが100の倍数の年なのに閏年である2000年に生きていられたことに感謝したいと思います。(2100年はもう生きてないと思うので…)
CustomCellに値を代入したときにFatal error: Unexpectedly found nil while implicitly unwrapping an Optional value: custom cell: file xxxというエラーが出たときの対処法

nibで作成したCustom cellに値を入れようとした時に次のエラーが出ました。

```
Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value: custom cell: file xxx
```

## 結論

- tableViewのregisterメソッドが間違っていた。

```:before
tableView.register(UserSearchCell.self, forCellReuseIdentifier: UserSearchCell.className)
```

```:after
tableView.register(UINib(nibName: UserSearchCell.className, bundle: nil), forCellReuseIdentifier: UserSearchCell.className)
```

cellをコードで実装している時は`before`が正しくて、cellをnibで作成した時は`after`でテーブルセルの作成に使用するクラスを登録しないといけないかと思われます。

## 参考
[register(_:forCellReuseIdentifier:) - UITableView | Apple Developer Documentation](https://developer.apple.com/documentation/uikit/uitableview/1614937-register)
曜日の取得

## 曜日の取得方と曜日による条件分岐
曜日によって表示が変わるプログラムがあったとします。
例)
金曜日なら　今日は華金だ！
他の曜日なら　今日は●曜日だ

上記のように曜日を取得して、取得した曜日によって条件分岐を行う方法はどのようなものでしょうか？

## Timeクラスを使用する方法
```ruby
day = Time.now
if day.friday?
  puts "今日は華金だ！"
else
  puts "今日は" + %w(日 月 火 水 木 金 土 )[day.wday] + "曜日だ"
end
```
日付に関する値を取得するTimeクラスがもともと存在します。
Time.nowで今日の日付情報を取得できます。
試しにTime.nowを出力すると

```ruby
day = Time.now
puts day
```
```:ターミナル
2020-03-01 14:25:39 +0900
```
上記のように日付情報を取得できます。この情報は自分のPCに依存します。

Time.nowに取得した値に対してwdayメソッドを使用することで曜日の値を取得できます。
曜日の値は0~6の数字で返され、0が日曜日、6が土曜日を表します。
これを利用して条件分岐を行なって行きます。
まず2行目のif文ではfriday?メソッドにより
今日が金曜日かを判断しています。
もし金曜日(値が5)であれば”今日は華金だ！”と出力され、筆者は夜の歓楽街へと消えることでしょう
それ以外の値であった場合5行目の%w(日..土)に対して[day.wday]により引数の中の何番目に当たる値を代入して表示するかの文で今日は●曜日だを出力しています。

このようにすることで曜日の取得と曜日による条件分岐を行うことだできます。


## 参考記事
[[Ruby] 本日の日付から曜日を日本語で取得する](https://qiita.com/kenji-nishie/items/3e44e3c208ec27b889f7)
Angularで使っているrxJsのOperatorを簡単にまとめてみた

現在使用しているrxJsのOperatorを簡潔にまとめていきます。

随時、加筆修正します。

現在、利用中のversionは以下です。

```p.json
    "@angular/core": "^8.2.9"
    "rxjs": "^6.5.1"
```

## forkJoin

### 概要

複数のObservableから値を受けとった後で処理を走らせたいときに使います。

### 詳細

1. subscribeされる　<br>
OBSERVER -> FORK JOIN
2. ObservableAとBから値が流れてくる <br>
A -> [0-a, 1-a, 2-a] -> FORK JOIN <br>
B -> [0-b, 1-b, 2-b] -> FORK JOIN <br>
3. AとBそれぞれがCompleteされて値がそろう <br>
FORKJOIN : [0-a, 1-a, 2-a], [0-b, 1-b, 2-b]
4. そろった値がまとめてobserverに送られる

```forkJoin.ts
forkJoin([
        this.requestService.getPersons(),
        this.requestService.getParams()
      ]).subscribe(result => {
        const personList: Array<Person> = result[0];
        const params: AppParams = result[1];
        this.setUp(personList, params);
      })
```

上記のようなコードを描くとsubscribeされた後で `this.requestService.getPersons()` と `this.requestService.getParams()` からforkJoinが値を受け取り続け、どちらもcompleteされて初めて `setUp` のメソッドが呼び出されます。

## flatMap

### 概要

あるObservableのレスポンスをもとに別のObservableで値を取得したい時に使います。
ネストをせずに済むので可読性を向上できます。

### 詳細

```flatMap.ts
this.queryParams.pipe(flatMap(param => {
     this.serviceId = param.sid;
     this.appId = param.appId;
     return forkJoin([this.getLayout(this.serviceId), this.getText(this.serviceId, this.appId)]);
})).pipe(flatMap(res => {
     this.layout = res[0];
     this.text = res[1];
     return this.appId ? this.service.get(this.appId) : null
})).subscribe(val => {
     ...
})
```

上記を日本語の手順で説明すると

1. Paramが届いたら `flatMap(param => {`
2. layoutとtextを取得する ` return forkJoin(this.getLayout(this.serviceId), this.getText(this.serviceId, this.appId));`
3. layoutとtextが取得できたら `flatMap(res => {`
4. サービスで情報を取りに行く`this.appId ? this.service.get(this.appId) : null`

となります。

ちなみにsubscribe()のなかでsubscribe()を呼ぶのはrxJsのアンチパターンなので絶対にしないようにしましょう。

> There's no "harm", but this is considered an antipattern in rxjs. And if the three calls are independent this is unnecessarily slow.

[Is it good way to call subscribe inside subscribe?](https://stackoverflow.com/questions/52317494/is-it-good-way-to-call-subscribe-inside-subscribe) より引用

### 補足

forkJoinのような生成系operatorと違って、flatMapのように流れてきたものに手を加えるoperatorは

```hosoku.ts
observable
 .pipe(operator(引数))
 .subscribe(x => ...
```

このようにpipeの中にoperatorを入れて使用します。
Node.js Expressフレームワークを使用する為の準備作業

#はじめに
本格的な開発をするにはフレームワークを活用します。
フレームワークを活用することで効率よく、開発することが出来るようになります。

今回は「Express」というフレームワークを採用しました。

#環境
OS:Windows 10 Pro 64bit
node.js:v12.16.1
npm:v6.13.4

#Express Generatorのインストール
Expressを使用するには、Express Generatorを使用するのが便利です。
まず、Express Generatorをインストールします。
コマンドプロンプトを立ち上げで、以下のコマンドでインストールします。

```Bash
npm install express-generator - g
```
上記コマンドはグローバルインストールと呼ばれるインストール方法になります。
Express Generatorはプログラム中で使用するものではありませんので、グルーバルな領域にインストールします。
ですので、コマンドを打つ場所（カレントフォルダ）はどこでも良いです。

#確認
以下のコマンドでインストールされたか確認出来ます。

```Bash
npm view express-generator version
```
今回は4.16.1がインストールされました。
![ex_var.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591423/fa7ce26d-1696-3724-4d26-d12c31e6e49f.jpeg)
空のデータが登録できないようにするために

##空のデータが登録できないようにするには
空のデータが登録できないようにするにはバリデーションを使います。
##バリデーション
バリデーションとはデータを登録する際、一定の制約をかけること
**空のデータが登録できないようにする**
**すでに登録されている文字列を登録できないようにする（メールアドレスの登録など）**
**文字数制限をかける（パスワードなど）**
などがあります。

```app/models/XXXXX.rb
class Post < ApplicationRecord
  validates :title, :comment, presence: true
end
```
上記のように記述すれば空白、同じ文字列を投稿をした際は、空のデータや、すでに登録がされているデータがある場合は登録ができないようになりました。
wordpressをはじめる。

wordpressをはじめる。

wordpressをはじめるにあたり調べると色々なはじめ方があるある！

その中から今回はawsのLightsailを使用しはじめました。

その前に今回の目標は、
①wordpressをインストールする
②wordpressの初期設定を行う
③テーマを設定する
④プラグインを追加する
⑤投稿を公開する
としました。

では、awsからLightsailに入り、インスタンスの作成。
選択肢の中にwordpressがあるのでチョイス！
その他設定をしスタート！

今後、テーマの設定や色々いじいじして行こうと思ってますので、その都度投稿できる様にして行こう。
RESTを簡単まとめ

<h4>はじめに</h4>

　現在、山本陽平さんの『Webを支える技術』を読んでいます。
今まで勉強した事の良い復習、また新しい知識をインプットする事ができてるので一部、アウトプットも兼ねてまとめようと思います。
　今回は第３章の「<strong>REST</strong>」についてです。この概念を以下3つの項目で簡単にまとめたいと思います。

1.そもそもRESTとは？
2.RESTを構成する「アーキテクチャスタイル」
3.RESTfulとは？

※注意
自分はまだ未熟なので、間違いや至らない点が多いです。間違い、曖昧等ありましたら是非教えてください！！


<h2>1.そもそも「REST」とは？</h2>

　一文でまとめと、<strong>”RESTはWebのアーキテクチャスタイル”</strong> です。

　日本語で言うと、「Webでの構造様式」といったところだと思います。Webサービスを作る際は、闇雲に作るのではなくこの「REST」に準拠します。そうする事によって、Webと言うシステムに調和させ、動作しなかったり問題を抱えるといった状況を避けることができます。
　つまり、「REST」はWebと言う大きな枠組み中で、問題なくサービスを設計する為に守る約束を指したものです。


　
<h2>2.RESTを構成する「アーキテクチャスタイル」</h2>

　先程,「REST」はWeb上でサービスを作成する時の約束であると記述しました。次に触れたいのは「REST」を構成する「アーキテクチャスタイル（＝お約束）」です。このお約束は一つではありません。
　具体的には__6つのお約束__があります。全ての詳細を説明するのは厳しいので簡易にまとめられたものを引用します。

><ul>
<li>クライアント/サーバー  : ユーザーインターフェースと処理を分離する</li>
<li>ステートレスサーバー  : サーバー側でアプリケーション状態を持たない</li>
<li>キャッシュ  : クライアントとサーバーの通信回数を減らす</li>
<li>統一インターファース  : インターフェースを固定する</li>
<li>階層化システム  : システムを階層に分離する</li>
<li>コードオンデマンド  : プログラムをクライアントにダウンロードして実行する</li>
引用：山本陽平 (2010) 『Webを支える技術』　株式会社技術評論社　p37
</ul>

　これらの複合アーキテクチャスタイルは「ULCODC＄SS」と言い、この別名が「REST」です。つまり、繰り返しになりますが、「REST」とはこららのお約束をまとめたものを指します。

<h2>3.RESTfulとは？</h2>

　今まで記述してきたことから察しはつくと思いますが、「RESTful」とは6つのお約束にしたがっていて「REST」らしい事を指します。ですが設計の問題上、これらのお約束を無視し妥協する場合もあります。まとめると「RESTful」とは、「REST]のお約束を守ることであり、Webにおける設計理念の理想的な状態を指す言葉です。



参考文献：　山本陽平 (2010) 『Webを支える技術』　株式会社技術評論社
【Swift】 配列要素の合計を求める拡張

## はじめに
数値計算を総称的に扱うためのNumeric Protocolみたいなのないの？
[→Swift5からあるらしいで。](https://developer.apple.com/documentation/swift/numeric)
それを知らなくて自分で考えてた話です。

<br>

- 当初似たようなことやってる人がいるだろうと思って探してみるも  
  見つけたものには、以下のような制約があった。
    - [初期値をプロトコルで要求](https://gist.github.com/kristopherjohnson/635e56dcc71842502fcd)
    - [初期値を引数で要求](https://stackoverflow.com/a/43985893)
- それの制約を取り払えないか？ というところからのスタート。

## A
 
### Swift5の標準に基づく実装と自前実装


##### Swift5の標準に基づく実装
まずは正しい（と思っている）答え

```Swift:standard
extension Sequence where Element:AdditiveArithmetic  {
    func sum() -> Element {
        return reduce(.zero, +)
    }
}
```
AdditiveArithmeticとは…
基本の数値型（Int、Doubleなど）で実装済みのプロトコル。（Swift5から）
`zero（初期値）と加減算オペレータが定義されている`

```swift:standard
protocol AdditiveArithmetic {
    static var zero: Self
    static func + (Self, Self) -> Self
    static func += (Self, Self)
    static func - (Self, Self) -> Self
    static func -= (Self, Self)
}
```

<br>

##### 標準実装があるのを知らなくて自分で定義したプロトコルと実装。
要らないんですが考えの過程を残すために載せておきます。

```swift:my_implementation
protocol Summable{
    init()
    static func +(lhs: Self, rhs: Self) -> Self
}

extension Int:Summable{}
extension Int64:Summable{}
extension String:Summable{}
// any more 

extension Sequence where Element:Summable  {
    func sum<T:Summable>() -> Element where Element==T {
        return reduce(T.init(), +)
    }
}

// use eg
print( [1,2,3].sum() )        // …6
print( ["1","2","3"].sum() )  // …"123"
```

##### 実装にあたり悩んだところ。
- protocolはclassとは異なる要領で総称型に対する処理を実現している。
 - class … `Class<T>`の要領で総称型（ジェネリクス）を定義して利用 (struct、関数も同様）
 - protocol … プロパティで総称型として扱いたい型情報を管理(associatedtype)
 - 扱いが異なる理由 … [なぜSwiftのプロトコルはジェネリクスをサポートしないのか](https://qiita.com/koher/items/b21879a31210f7408502)
 - 「`extension ExtProtocol where AssoociatedType:MyProtocl`の`where`は拡張対象を絞るだけであり、AssociateTypeを決定しているわけではない。protocolに対して汎用処理を実現したい場合、各関数に対してジェネリクス`<T>`を`T == AssociateType`だとして定義しなければ定まらない。」ことが最初理解できなかった。
- 合計値計算の基準となる初期値（数値であれば、**各型のゼロ**）をどのように定義するか。
 - `reduce`の第一引数に**型を指定た初期値**を与える必要がある。（異なる型同士は加算できないため）
 - 利用時の記述を楽にしたい。※  
 - `init()`で初期値が取得でき、楽ができた。



```swift:※利用時にこんな風に{}内の記述したくない
extension Double:Summable{  
     static var zero:Self { return Double(0)}
}
//protocol Summable{
//    static func +(lhs: Self, rhs: Self) -> Self
//    static var zero:Self{get}
//}
```
vscodeのコンソール文字化け回避

#状況
タイトル通りvscodeのコンソール文字化けしたため,その防止のメモ.
#対策
ググったら以下が出た
[Visual Studio Codeターミナル文字化け対策(shift-jis→utf-8)](https://www.mathkuro.com/?p=158)


記事の通り
`"terminal.integrated.shellArgs.windows": ["-NoExit","chcp","65001"],`
を
`settings.json`
に追加.

#結果
記事のをそのままコピペしたら,""が全角となっていて,エラーが出た.半角にして解決.

なお[コンソールや visual studio code などの文字化け](https://notes84.bitbucket.io/string-encoding/)に書いてある
`chcp 65001`を実行しても直る.
リダイレクト処理の仕方

##リダイレクト
リダイレクトとは受け取ったパスとは別のパスへ転送すること
アクションに処理を持たせて実行し、パスのビューを返すのではなく別のパスにユーザーをredirect_toメソッドで転送させることがでます。
##redirect_to メソッド
コントローラーで処理が終わった後に、別ページへリダイレクトさせることです。

```
redirect_to "リダイレクト先のパス"
```
【例】root_pathに飛ばしたい場合(仮にmodel名をPostとする)

```app/controllers/posts_controller.rb
def create
    Post.create(post_params)
    redirect_to root_path
  end
```
_pathを付けることにより、ルートパスを指定しました。
ルートパスに対応するアクションはindexなので投稿後(createはデータの投稿を行うリクエストに対応して動くアクション)はトップページへ遷移します。
もうひとつモデル(Comment)を作りCommentからPostにidをつけて飛ばしたい場合
【例】

```app/controllers/comments_controller.rb
def create
    comment = Comment.create(comment_params)
    redirect_to "/posts/#{comment.post.id}" 
  end
```
redirect_toの後にはルーティングのURLやPrefixを記述することでそのアクションを実行することができます。
ほかのコントローラ(今回はpostsコントローラ)のアクション(仮にshowアクションとします)を実行するにはidが必要です。
そのため、ストロングパラメーターを用いた上で変数commentに代入します。
リダイレクト先の指定には、アソシエーションを利用してcommentと結びつくツイートのidを記述しています。
普段のcreateだったらComment.create(comment_params)で済むのですがcomment.post.idでidを指定してるので、comment = Comment.create(comment_params)となります。
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[UIViewController _loadViewFromNibNamed:bundle:] loaded the "xxx" nib but the view outlet was not set.'というエラーがでたとき。

## 概要
イニシャライザでnibを呼び出す時に次のようなエラーが出た。

```
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[UIViewController _loadViewFromNibNamed:bundle:] loaded the "xxxViewController" nib but the view outlet was not set.'
```

```:init()
init() {
        super.init(nibName: UserSearchViewController.className, bundle: nil)
    }
```

loadViewで呼び出した時はこのエラーがでなかった。

```:loadView()
override func loadView() {
        guard let view = UINib(nibName: "UserSearchViewController", bundle: nil).instantiate(withOwner: self, options: nil).first as? UIView else { return }
        self.view = view
    }
```


## 結論
![貼り付けた画像_2020_03_01_13_57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276894/26d1b431-a445-a634-6fd1-8840e59b03cb.png)

- ①InspectorのFile`sOwnerにCustomClassをセットする。
- ②Placeholders>File`s OwnerからViewにOutletで接続する。(※画像を参考)

これでエラーがでなくなりました。

コードで実装していたときは、Ownerを指定したのに、init()の時はnibをロードするだけでOwnerを指定していたなかったのが原因かと思われます。


## 参考
https://qiita.com/maru_u/items/9b2f7dc0c4f5f3f5cac8
【RSpec】PATCHリクエストで躓いた変数の更新やパラメーターの付与

## 概要
* PATCHリクエストのテストで詰まった以下の２点についてのメモです。
  * ストロングパラメーターをpassするようにパラメーターを付与する方法
  * オブジェクトの更新をテストする方法

## 前提
* 詳しい話はわからずに解決した方法を書いているため、間違いやツッコミがありましたらコメントをいただけると助かります。

## ストロングパラメーターをpassするようにパラメーターを付与する方法
```ruby
it '名前が更新される' do
  user = create(:user, name: 'hoge')
  patch user_path(user, user: { name: 'new_hoge' }) # このように書くとストロングパラメーターに許可された形でパラメーターを送れる
  expect(user.name).to eq 'new_hoge'
end
```


しかし、これではuser.nameは`hoge`のままであるため、テストはfailしてしまいます。

原因は、`user`はあくまで変数であり、DBの方でuser.nameに変更があったとしても変数`user`には変更が反映されていないためです。

## オブジェクトの更新をテストする方法

先ほどのテストがfailしてしまう原因は
`user`はあくまで変数であり、DBの方でuser.nameに変更があったとしても
変数`user`には変更が反映されていないためです。


そのため、変数userに変更を反映する必要があります。
その時に使えたのが`reload`でした。
具体的には以下のように追記することでテストがpassすることができました :smiley: 

```ruby
it '名前が更新される' do
  user = create(:user, name: 'hoge')
  patch user_path(user, user: { name: 'new_hoge' })
  user.reload  # 追記
  expect(user.name).to eq 'new_hoge'
end
```

## 感想
PATCHリクエストを書くだけでも学ぶことが多いですね。
ストロングパラメーターの復習にもなって学びが多い挫折でした。
TerratermでESXiにログインするショートカットをつくる

WindowsでESXiに一発でSSH接続するショートカットを作りたかったので作成した。
※以下のドキュメントに記載してある通りの構文をショートカットの作成で指定するだけです。
https://ttssh2.osdn.jp/manual/4/ja/commandline/ttssh.html
※唯一注意するとすれば、チャレンジレスポンス認証でないとSSH接続できない点です。

```
"C:\Program Files (x86)\teraterm\ttermpro.exe" root@192.168.1.10:22 /ssh2 /auth=challenge /user=root /passwd=P@ssw0rd!
```
普通に入れる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257241/0bbcfacf-a55c-4663-d8fb-3862c0c3a09a.png)

こんな感じでできる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257241/ae31a3dd-ff85-42ee-1714-d2962c65aabe.png)

あとはESXi側でshhログインを許可していれば接続できます。
※セキュリティ上、パスワードべた書きだったりするのはよろしくないと思われるのであくまで検証環境用です。
pandas の SettingWithCopyWarning

#はじめに
pandasを使ってcsvファイルを操作するアプリをつくっていたら、
結果は思った通りに編集されるのだが、
SettingWithCopyWarningと警告された。

##SettingWithCopyWarning
参照渡し(っていうの?)であるがゆえの警告的なものっぽいっと思っています。
元のデータの一部を抽出→そのうち一部へ代入した場合、
「元のデータのその部分」を修正したかったのか、
「一部を変更した新しいデータ」を作りたかったのかどっちかわからないよ、という感じ？

お気軽にコメントにてご鞭撻下さい。

##解決
copy()で、参照ではなくコピーであることを明示したら、
SettingWithCopyWarningは解消されました。

##好きな果物をcsvファイルにまとめるアプリ

まず、
output_filesというディレクトリ(フォルダ)に
data.csvという名前のcsvファイルをつくる。

中身は
apple,8
orange,15
banana,4
apple,1
となっている。

```:data.csv
apple,8
orange,15
banana,4
apple,1
```

このcsvファイルを
apple,1を削除し、
apple,9に書き換え

```:data.csv
apple,9
orange,15
banana,4
```
と編集する事を目標とする。

```py:check_data.py
import pandas as pd

def check():
    df = pd.read_csv('output_files/data.csv', names=['fru_name', 'count'])
    #vcに最頻出(重複している)の果物を格納
    vc = df['fru_name'].value_counts().index[0]
    # freに出現回数を格納
    fre = df['fru_name'].value_counts().iat[0]

    if fre > 1:
        # 重複しているの果物の行を削除し、それを変数new_dataに格納
        new_data = df.drop_duplicates(subset='fru_name')

        # 重複しているの果物の元の数をdup_countに格納
        dup_count = int(new_data.loc[new_data['fru_name'] == vc, 'count'])
        # dup_countを+1する
        dup_count += 1
        new_data.loc[new_data['fru_name'] == vc, 'count'] = dup_count

        #data.csvに上書き
        new_data.to_csv('output_files/data.csv', index=False, header=False)

check()
```

```check_data.pyの実行結果:
SettingWithCopyWarning
```

csvファイルは目標の通り、

```:data.csv
apple,9
orange,15
banana,4
```
と編集されたが、
SettingWithCopyWarningが出た。

###改善

copy()で、参照ではなくコピーであることを明示する為、

```py:
new_data = df.drop_duplicates(subset='fru_name')
```
を

```py:
#copy()で、参照ではなくコピーであることを明示
new_data = df.drop_duplicates(subset='fru_name').copy()
```
に変更。

```py:check_data2.py
import pandas as pd

def check():
    df = pd.read_csv('output_files/data.csv', names=['fru_name', 'count'])
    #vcに最頻出(重複している)の果物を格納
    vc = df['fru_name'].value_counts().index[0]
    # freに出現回数を格納
    fre = df['fru_name'].value_counts().iat[0]

    if fre > 1:
        # 重複しているの果物の行を削除し、それを変数new_dataに格納
        new_data = df.drop_duplicates(subset='fru_name').copy()

        # 重複しているの果物の元の数をdup_countに格納
        dup_count = int(new_data.loc[new_data['fru_name'] == vc, 'count'])
        # dup_countを+1する
        dup_count += 1
        new_data.loc[new_data['fru_name'] == vc, 'count'] = dup_count

        #data.csvに上書き
        new_data.to_csv('output_files/data.csv', index=False, header=False)

check()
```

これで、
SettingWithCopyWarningが出ずに、
csvファイルは目標の通り、
と編集されるようになった。
Google Cloud RunでRubyを使ってFirestoreにアクセスする（サンプル付き）

# 背景

ちょっとした処理をGCEのf1-microインスタンスでdockerを使って定期実行していたのですが、なぜか昨年11月頃から動作が重くなり処理が完了できなくなりました。そもそもspec不足だろうとは思ったので、最近知ったCloud RunならRubyのまま移行できるのではないか、と考えました。

Cloud Runではボリュームに相当する機能が使えないので、ファイルに保存していたデータを別の方法で保存する必要が発生しました。試行錯誤の結果、今回はFirestoreに保存するのが良さそうという結論になったので、この記事を書いています。

# サンプル

https://github.com/skuroki/hello_google_run_with_firestore

Ruby2.6なのは、現時点ではRuby2.7でgrpcのgemがbundleできないからです。[あと数日で出来そうな気配はあります](https://github.com/grpc/grpc/issues/21514)。

# 要点

Cloud Runは、処理の内容が何であっても、HTTPリクエストを受け取って実行する仕組みです。なので、既存の処理を、リクエストが来たら実行するwebアプリケーションに書き換える必要があります。

Cloud Runは、同じプロジェクトであれば、設定を全く行わずに、Firestoreにアクセスできるようになっています。

# 動かしかた

１つ１つのプロセスは各サービスの基本的なものなので、公式ドキュメントやGoogleなどで調べられると思います。

## Firestoreのデータ

GCPの同じプロジェクトでFirebaseを動くようにして、Firestoreも動くようにして、以下のようにデータを入れます。

<img width="859" alt="Firestore" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17353/6e18353a-fad5-e7b1-a377-f6fc0c646841.png">

## コンテナのビルド

```
gcloud builds submit . --project=your-awesome-project --config=cloudbuild.yaml
```

プロジェクト名は置き換えましょう。

## サービスの設定

<img width="563" alt="新しいサービス_アカウントの作成_–_Cloud_Run_–_kokkai-iinkai_–_Google_Cloud_Platform.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17353/240aae20-2f1b-8fd4-b050-e1a9b7a79262.png">

<img width="562" alt="Cloud Run2" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17353/21172c24-47f9-47f7-c4b0-d5b4af9e5ffc.png">

サービスが設定されたら自動的に最初のデプロイが行われるので、すぐ実行できるようになります。

## 実行

<img width="909" alt="実行1" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17353/2eb99133-03e3-b8bc-5b34-fd8eb8db59f1.png">

<img width="558" alt="実行2" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17353/2ee96997-f352-48e3-bdbc-66468016479f.png">

<img width="672" alt="実行3" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17353/fc72e4a4-0987-b6b4-5db0-a0a198a8b763.png">


Firestoreのデータを引っ張ってこれていることがわかります。

ここまででCloud Runを動かす話は終わりです。ついでに開発時に手元で動作させる方法について書きます。

# 手元での動かしかた

## サービスアカウントの鍵を発行

<img width="544" alt="サービスアカウント" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17353/94e9102d-cdc9-0d58-619a-cfddd32c90d7.png">

発行時にJSONを手元にダウンロードして保存します。

## 鍵の配置

レポジトリの下に`data`ディレクトリを作って鍵ファイルを置いて、

```.env.sample
# Replace file name
GOOGLE_APPLICATION_CREDENTIALS=/data/your-awesome-project-deadbeef1234.json
```

鍵ファイルの名前に書き換えて、`.env`として保存します。この環境変数はFirestore用のgemが読み取ります。

## 起動

```
docker-compose up
```

で、 http://localhost:8080 にアクセスして、`{:foo=>"bar", :hoge=>"piyo"}`と表示されればOKです。

## TIPS

* `STDOUT.sync = true`を入れておかないと処理のログが出ないかも

### cronみたいな定期実行する方法

<img width="502" alt="Cloud Scheduler" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17353/7613fc28-dc39-55bd-df16-c23436c407d3.png">

こんな感じの設定でいける
【2020年度版】Struts2の入門系記事まとめ

# はじめに
業務系プロジェクトでは未だに現役で動いていることもあるStruts2さん。
2020年のこのご時世にまさか自分が触ることになろうとは…。

まったく触ったことがないのでHelloWorldをやってみた。
割と最近まとめてくれている優しい方がいたので触る分には困らなかった。
参考になった記事を紹介する。

## 自分のスペック
* Java経験が4年くらい
* Webシステム開発は1年くらい  
(SpringBootは分かる。新人の頃にSpringMVCも使っていたがよくわからない)
* ぶっちゃけサーブレットとJSPはあんまり分からない

APIの開発はできるけど、テンプレートを使うやり方がよく分かってない。

## 環境情報
* Windos10
* Eclipse : 2019-12(Pleiades All in One)
* XAMPP : XAMPP for Windows 7.3.11
* Java : 1.8.0_221
* Struts : 2.5.22(最新)

## 参考記事集
* [【超初心者向け】Struts2超入門 - 2018年版 - Qiita](https://qiita.com/tarosa0001/items/889faa2ab5853005f26b)
これ見れば終わり。
全部書いてくれている。2018年度版らしい。
違っていたのはバージョンくらいかな？
とりあえずこれ読んで触ってみれば、会社に行っても話が通じないレベルは脱せられそう。
記事ではallを使っているが、自分が構築したときは最小構成（min）のStrutsで起動できた。  

* [Apache Strutsプロジェクトへようこそ](https://struts.apache.org/index.html)
Strutsの公式ページ。
ドキュメントやチュートリアルがある（~~チュートリアルやってないけど~~）。
もちろんダウンロードもできる。

* [Struts2 を手動でwarファイルにしてデプロイするには - Qiita](https://qiita.com/misskabu/items/9066330ff4793b46fb3b)
eclipseでは実行できるけど、他の環境へのデプロイは分からないプログラマにならないために。
プロジェクト構成が違ったのか、記事のjarコマンドだけだと`classes`がデプロイできなかった。
ただ構成ツリーをサンプルで記載してくれているので合わせたらできた。

* [2014年度版 Eclipse + Struts2 による Java Web アプリ開発入門 | CYOKODOG](https://www.cyokodog.net/blog/first-struts2/)
流し読みしかしていないが、1番上の記事の方が参考にされていた。
サンプルページがあって参考になる。

## 作ってみたプロジェクトのソース
*  [aky100200/struts2-app: Struts2](https://github.com/aky100200/struts2-app)


## おわりに
SpringBootの方が簡単に作れるので、メインフレームワークとして使う気は今のところないがなんとなく触りは理解できた。
レガシーで情報がないことを覚悟していたが、概要をまとめてくれている記事があって本当に助かった。
なので自分も現在の最新状態で作れることを記事として残しておくことにした。
有用なリンクが他にあればぜひコメント等で教えていただけると幸いです。
ZoomでFaceRig使ってバーチャル参加する方法

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ごく一般的な会議風景 <a href="https://t.co/x4l8D7EbOa">pic.twitter.com/x4l8D7EbOa</a></p>&mdash; 伊藤周@オーナカ (@warapuri) <a href="https://twitter.com/warapuri/status/1233281390214430720?ref_src=twsrc%5Etfw">February 28, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

こんなことをできるようにします！

前置きはありません。単刀直入に「Zoomでバーチャルの顔で参加する」方法、というのを紹介します。Windowsのみの話です。Macの人、すみません。

# 1. FaceRigを買う＆インストール

![スクリーンショット 2020-03-01 11.37.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72960/bccebe68-5893-0b68-6e53-279c5c562511.png)

これは必須です。1,480円、安い。買いましょう
二次元がいいというのなら、「FaceRig Live2D Module」も同時に買いましょう。398円。
Steamから買うと良いでしょう。
https://store.steampowered.com/app/274920/FaceRig/

流れに任せてインストールします。

# 2. FaceRigVirtualCamDriver をインストールする

1でインストールしただけだと、Zoomからブロードキャスト接続できません。
以下の
![スクリーンショット 2020-03-01 11.35.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72960/3ac82c29-e575-a768-2601-c5e7e370b068.png)
[Steamインストールフォルダ]\steamapps\common\FaceRig\Bin\prerequisites\FaceVirtualCamDriver


FaceRigVirtualCamDriver_win10.exe

をダブルクリックして、インストールします。（まさかこのご時世でWindows10以外の人いないですよね）

これ、大事。（これを忘れていたので、最初Zoomから接続できなかったのでした）

# 3. FaceRig を立ち上げる

立ち上げるまではなんとか各自で頑張ってください。

で、右上のアイコンの「アドバンスUIに変更する」をクリックして、
![スクリーンショット_2020-03-01_11_41_43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72960/f88e0f77-181b-d2dc-446e-7e38555b6d79.png)

出てきたアドバンスUIの「ブロードキャストに切り替え」をクリックします。
![スクリーンショット_2020-03-01_11_41_58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72960/311f2cb4-355e-a7f5-ac41-227dd6b31afc.png)

こうすることで、Zoom側でもFaceRigのこの画像を取得できるようになります。

あとは適当に二次元美少女にしたい人はすればいいし、
![スクリーンショット_2020-03-01_11_42_37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72960/81517239-2177-2387-933b-478a95777b1a.png)

背景をZoom側で変えたい、という人はグリーンバックの背景にした方が良いかもしれない。
![スクリーンショット_2020-03-01_11_42_53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72960/1a682fbe-64ce-a7b1-f293-a49d88469a14.png)

FaceRig側の準備完了！
以下のZoom起動してもFaceRigは起動しっぱなしにしておきます。

# 4. ZoomでWebミーティングに参加

Zoomで普通に「ビデオあり」で参加します。

ビデオの左の「＾」をクリックして、「FaceRig Virtual Camera」にカメラを選択しなおします。
![スクリーンショット_2020-03-01_11_44_11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72960/dbe00cb1-913f-c307-b820-f3eb13f0a367.png)

すると、めでたくFaceRigの画面をZoomに取り込めるようになりました！
（↓は背景がZoomの方で設定されたものです）
![スクリーンショット_2020-03-01_11_45_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72960/f6cc1fef-cced-899d-9c11-ba8dbd822931.png)

というわけで皆さん、レッツZoomでバーチャル参加！
AWS Deep Learning AMI でJupyter Notebookを開く

#AWS Deep Learning AMI 
AWS Deep Learning AMI(DLAMI)は、AWS EC2サービスで機械学習に適したインスタンスをかんたんに作成できるというものです。
GPUを搭載しているほか、condaや各種フレームワークもはじめから入っており、ML/DLのセットアップが非常にやりやすくなっています。
同様のサービスに「SageMaker」もありますが、こちらのほうが割安だと思います。

# 1.インスタンスの作成
AWS EC2で「インスタンスの作成」をクリック
AMI検索窓で「Deep Learning AMI」を入力
Ubuntu系、Amazon Linux、Microsoft Windows Serverの3つがあります。
![2020-03-01_12h33_36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167339/2a633e41-75da-4b78-915e-b1b3b40a0880.png)
ここでは、「Deep Learning AMI (Ubuntu 16.04) Version 26.0」を選択します

ステップ2の「インスタンスタイプの選択」でも、複数のGPUインスタンスがありますが、ここでは安価な「p2.xlarge」を選択します。
![2020-03-01_12h39_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167339/beb9e4e9-f71c-2c9c-8ffb-7c54ee6b9107.png)
他は特に設定をしないので、「確認と作成」を押下して、インスタンスを作成します。
ちなみにこの構成では料金は、「1.542USD/時間」となっていました。

# 2.インスタンスの設定
後々、ローカルクライアント側からJupyter Notebookにアクセスできるよう、インスタンスの8888ポートを開けておきます。
作成したインスタンス>「説明」タブ>セキュリティグループのリンクをクリックし、セキュリティグループの詳細画面を開きます。
さらに「インバウンド」タブ>「編集」で「タイプ:カスタムTCPルール/ポート:8888」のルールを追加します。
![2020-03-01_12h44_58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167339/f09e4fb0-4993-9659-6f2b-17620689c7d1.png)

# 3.インスタンスへの接続
インスタンスを起動後、Teratermなどでインスタンスに接続します。
（ユーザー名は「ubuntu」です）
Deep Learning AMIを起動すると、下記の様に表示され、このインスタンスで起動可能なフレームワークとその起動コマンドの一覧が表示されています。
![2020-03-01_12h49_55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167339/db33a628-aeb0-0fa7-4948-51e3e2b16925.png)
赤枠にはTensorFlowの仮想環境の起動コマンドが記載されていますので、
TensorFlowを起動するには下記を入力すればOKです。

```
$ source activate tensorflow_p36
```

# 4.Jupyter Notebookの設定
Jupyter にはパスワードユーティリティがあるので、こちらを利用します。
後ほどブラウザからアクセスする際、パスワード認証がされるようになります。

```
$ jupyter notebook password
```
と入力し、パスワードを設定します。
![2020-03-01_12h54_44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167339/6f1fcbf5-b5ac-2d73-180a-d40664545bd1.png)



次にコンフィグファイルを設定します。

```
$ nano ~/.jupyter/jupyter_notebook_config.py
```
下記の行を加えておきます。

```
c.NotebookApp.ip = '*' #外部からのアクセスを許可する
c.NotebookApp.open_browser = False #自動でウィンドウを開かないようにする
c.NotebookApp.port = 8888 #ポート指定
```

さらに、自己署名 SSL 証明書を作成を作成しておきます。

```
$ cd ~
$ mkdir ssl
$ cd ssl
$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout mykey.key -out mycert.pem
```
# 5.Jupyter Notebookの起動
先に作成した証明書を利用しつつ、notebookを起動します。

```
$ jupyter notebook --certfile=~/ssl/mycert.pem --keyfile ~/ssl/mykey.key
```

![2020-03-01_13h03_35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167339/3cd7abcd-f27f-7dff-2c91-de06f47500c1.png)

クライアントPCのブラウザで、
https://[インスタンスのグローバルIPアドレス]:8888/
と入力すると、パスワードを求められた後、notebookを起動できます。
![2020-03-01_13h07_48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167339/789196f6-6d45-f758-9f3b-39caa82fbbaa.png)
Vuetifyでv-text-fieldの中の文字をセンタリングする方法

#なんの記事？
Vuetify の v-text-field の中の文字はデフォルトでは左寄せ。
それをセンタリングしたい時にどうするか。

[dispbarcode.com](https://dispbarcode.com/app/)を開発した際に実施した内容を記事化しました。

##方法
以下のCSSを作成しておき、それを v-text-field に適用する。

```
.centered-input input {
  text-align: center
}
```

#コード抜粋
```vue:index.vue
<!-- 抜粋です -->
        <v-row row justify-center align-center>
          <v-col xs12 class="d-flex justify-center">
              <v-text-field
                label="code"
                v-model="barcodeValue"
                class="centered-input"
                :hide-details="true"
                :change="changeWidth()"
                placeholder="input code"
              />
          </v-col>
        </v-row>
```

#表示例
「code」と「name」のところが v-text-field になっています。
「format」は v-select です。
<img width="482" alt="スクリーンショット 2020-03-01 13.08.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120785/9b3a14b3-f2c3-3262-ebb6-3e7ce1498081.png">



#わかっていない点
v-select の文言をセンタリングする方法がわかっていません。
v-text-field と同じ方法ではうまくいきませんでした。（左寄せのまま）

#参考
https://stackoverflow.com/questions/52742131/aligning-the-text-to-be-at-the-center-of-a-textfield-in-vuetify
ターミナルにて本番環境MySQLの確認

本番環境にてMySQLの中身をたびたび確認することがあったのでメモ

##MySQLの確認
本番環境ターミナルにて

```
mysqld -u root -p
```
###DB一覧
```
> show databases;
```

##DBを選択(成功すれば→Database changed)
```
> use データベース名;
```
#以降、DBを選択した状態で実行する

###DBのテーブルを確認
```
> show tables;
```

###テーブルの構造を確認
```
> describe テーブル名;
```

###テーブルの中身を確認
```
> select * from テーブル名;
```

###外部キー制約を無効にする
```
> set foreign_key_checks = 0;
```

###外部キー制約を有効にする
```
> set foreign_key_checks = 1;
```
Library not loaded: @rpath/Flutter.framework/Flutter

- 内容:  
Flutterでアプリを作成し、実機で確認をしようとした際に、
下記のエラーが発生したため、実機での確認ができませんでしたので、
情報共有させていただきます。  
※情報の判断はご自身の責任でお願い致します。

`dyld: Library not loaded: @rpath/Flutter.framework/Flutter`

- 環境:
Xcode 11.3
iPhoneX(iOS13.3.1)
iPhone5S(iOS10.3.2)

- 結果: 
[本家サイト](https://github.com/flutter/flutter/issues/49504)に追記がありました。特定の条件の場合、エラーが出てしまうようです。
   - signing identity profile 
   - iOS13.3.1  
ですと、ダメなようです。

iPhone5S(iOS10.3.2)では、実機で実行されることを確認致しました。

以上となります。🦔
DVWAでCSRF

## 前提
- kali linux環境がある
- DVWAのセットアップ済み（https://qiita.com/KPenguin/items/7e4f1c428c3dadf8591c ）

## 目標
- csrfでpassword奪取

## 手順概要
- 挙動の確認
- 模擬サイトを作る
- ユーザーに模擬サイトでpassword変更してもらう序でに盗む。

## 内容
### csrfとは
- cross-site request forgerieの略称
- 外部ドメインからのリクエストを制限していない場合、別サイトからの不正なリクエストを受けてします。
- 今回の場合はパスワード変更画面を模擬したサイト（フィッシングサイトの画面）でパスワード変更を行うと実際にパスワードが変更できてしまう。

### 前準備
- DVWAにログインする
    - 以下コードをkali上で実行しDVWAを立ち上げる。
    - http://localhost/DVWA-master/index.php
    - admin/passwordでログイン
- セキュリティレベルを下げる。
    - メニュー下にあるDVWA securityへアクセス
    - デフォルトがimpossibleなので、このままではハッキングできない。なのでlowに変更する

```shell:
# ファイルへのアクセス許可する
root@kali:~# service apache2 start
# DB_createできるようにする
root@kali:~# service mysql start 

```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584889/bb95d520-1602-b7b8-afa3-85da3ffb651e.png)

-- CSRFにアクセスする（左メニューにある）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584889/d1f516e2-ee7a-d356-bcd5-75768d7f180b.png)


### CSRF開始

- 挙動を確認する
    - 通常通りpassを変更してみる。[pw:test]
    - すると、以下のようなurlをリクエストすることでパスワードの変更が完了された。
    - 入力した値２つとchangeフラグの計３つを乗っければ実現できそう
http://localhost/DVWA-master/vulnerabilities/csrf/?password_new=test&password_conf=test&Change=Change#

- htmlを確認する
    - 下コードのようになっている。3つのinputをクエリに乗っけているみたい。

```html:
		<form action="#" method="GET">
			New password:<br />
			<input type="password" AUTOCOMPLETE="off" name="password_new"><br />
			Confirm new password:<br />
			<input type="password" AUTOCOMPLETE="off" name="password_conf"><br />
			<br />
			<input type="submit" value="Change" name="Change">

		</form>
```

- ダミーサイトを作る。
    - 上記html-form部分だけをコピーし、htmlファイルで保存。
    - form-actionをリクエストを投げたいurl（"http://localhost/DVWA-master/vulnerabilities/csrf/? "）に変更する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584889/69cc95ae-c035-597d-200b-dc03c6e626c6.png)


-  ダミーサイトでパスワードを変更してみる
    -  クエリを以下に変更してみる[pw:admin]。
    -  以下urlに飛んだので成功してそう
    -  http://localhost/DVWA-master/vulnerabilities/csrf/?password_new=admin&password_conf=admin&Change=Change

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584889/d8daf8d6-b531-88c7-a726-c34c4d9937c1.png)

- パスワードが変更されているか確認する
    - http://localhost/DVWA-master/login.php
    - admin/adminでログインすると成功する。
    - 後はダミーサイト側でchangeボタンclick時にinput情報を保存しておけば、自動でパスワード奪取できる

- 最後に
    - 今回、雑なダミーサイトだったが、見た目が同じだったら気づかないユーザーは多い。
    - リテラシーのあるユーザーはurlで判断するので、urlの偽造も最近は巧になっている。

おわり