OmniAICreator/Qiita-1.07M huggingface dataset:
エンジニアにとって資格は取得すべき？不要？

![24903871_m.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23130/21632082-186f-17b3-8dd7-f4416c3b540d.jpeg)

エンジニア資格は、取得した方が良いのか、取る必要が無いのか。
資格と言っても、IPA情報処理試験やJava言語の資格やAWSの資格等沢山ありますが、いづれも無いとプログラミングが出来ないとかAWS構築が出来ないというものではありません。
医師や弁護士とは違います。

ウイキペディアには、
資格（しかく、英: certification）とは、ある行為を行うために必要もしくは相応しいとされる地位や立場や、組織内での地位、または仕事として任務に就くために必要な条件のことである

条件ではないので、地位とか立場的な位置づけでしょうか？

# 何故あるの？
昔は、エンジニア資格によって、その人のステータスを示す度合いが強かったと思います。

理由としては、ネット上に沢山の情報がある今とは違い、書籍や資格のための勉強をしないとそれなりの知識をつける事が出来ませんでした。
そのため、転職する場面にあたって資格取得を重視される側面がありました。それは、面談で全てのスキルをチェックできるはずが無く、面接官側からすると、同じレジメで資格取得の数の違いだけであれば、資格取得の数の多い方を採用するからです。
SESや開発受託の会社では、営業面でも有用です。発注先から見たら、資格取得者数が多い会社の方が発注する時の安心材料になるからです。

そういう理由もあり、給与アップの条件として資格取得が折り込まれてる企業もありました。僕の新卒入社時の会社はそうでした。

# 資格とりましたか？
その流れもあって、僕も資格を沢山取得しました。
・第2種情報処理
・第1種情報処理
・ネットワークスペシャリト
・データベーススペシャリト
・プロダクションエンジニア
※今は呼び名が違うと思います。
お金がもらえるので、その他色々と取りましたｗ。

# 今後はどうか？
ベンチャー系の企業では、資格という物はあまり意味のない状態になってます。
実際、ベンチャーのエンジニアで、資格を保有している人をあまり見た事が無いです。
ベンチャーでは、学歴は意味がありません。即戦力の実力社会です。
世の中が学歴社会から実力社会に変わってきた影響もあると思います。
しかし、これによって世の中に、**エセエンジニア**が沢山います！
プログラムをコーディングできて、データベースの設定もできて、Linuxの設定もある程度できる。
これは、業務をこなしていけば、ある程度はできる様になるかもしれません。
しかし、設定できても設計できない、理解出来てないエンジニアが沢山います。極論AWSコンソールの使い方だけをしってるいる様エンジニアもいます。

ネットワークの基本は理解できるのでしょうか？
DeafultG/Wについて、本当に理解できてるのでしょうか？
データベースの正規化については、理解できるのでしょうか？
要件定義は、大枠で理解でもても、手法論、方法論は知っていますか？
プログラムが何故動くのか理解できてますか？
2進数と16進数が分かりますか？
サーバー、ネットワークの見積もり手法が分かりますか？

これらの事は、専門分野で特に力を入れて勉強しないと、業務をするだけでは、出会う事はありません。

情報システムに関わる全般的な基礎を学べるのがIPAの情報処理試験だと思います。

最終的には資格に受かる必要は無いです。
勉強する事が大事なのです（勉強したら資格は取ってみたくなりますが。。）

是非、エンジニアの皆様、情報処理試験を勉強してみて下さい。

AWS，Java，Python,OracleやMicorSoftの資格等とても良いと思います。
でもプログラミングとかシステムの基礎を学ぶには、IPAの情報処理試験が良いと思います。
ド・モルガンの法則をphpにて

# ド・モルガンの法則？

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">今の数学の先生はド・モルガンの法則教えるときに「これプログラミングでめっちゃ役立つので覚えておいてくださいね！」って強く言えるのいいなぁ</p>&mdash; Hardcore Engineer (@mpyw) <a href="https://twitter.com/mpyw/status/1593069390584778752?ref_src=twsrc%5Etfw">November 17, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">復習してね♥ <a href="https://t.co/wSzEyN4RU1">https://t.co/wSzEyN4RU1</a></p>&mdash; Hardcore Engineer (@mpyw) <a href="https://twitter.com/mpyw/status/1593071336750223360?ref_src=twsrc%5Etfw">November 17, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

ということで勉強させて頂いた。

# 結論

否定の否定は、肯定である。
というだけのこと。

https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1325294138


# デートで例える

```
「彼はごはんをごちそうしてくれなかったわけではなかった。」
```

と

```
「彼はご飯をごちそうしてくれた」
```

が同じ意味を持つ。
どっちがわかりやすいか一目瞭然ですね。


# phpで解説

りんごを7個以上持っているというプログラムを作る

```
if(!($ringo < 7)){}
```

```
if($ringo <= 7){}
```

上記2つとも同じ動きをするが、否定形「！」が無い方がわかりやすいですよね。

# まとめ

否定の否定はわかりづらいので、肯定を使っていきましょう。
教えて頂きありがとうございました。


# 以下参考




ある集合が別の集合と等しくなるという法則だ。 
これには2つあって、一つは「AかつB」でないは、「Aでない」または「Bでない」と等しい。 
もう一つは「AまたはB」でないは、「Aでない」かつ「Bでない」に等しい。 
これをド・モルガンの法則と呼ぶ。
否定の否定の～ってなった時こそ、ドモルガンチャンス！！



はぁ？意味わからん。



ということで
https://webgroove.work/de-morgan-law-php/

を参考にした

ド・モルガンの法則 をJavaScriptで表すと下記のような感じ。

!(P || Q) == !P && !Q
!(P && Q) == !P || !Q
1
2
!(P || Q) == !P && !Q
!(P && Q) == !P || !Q
さて、これを使ってさっきのを加工すると。

if (!(word != null && word !="")) { //以下略
1
if (!(word != null && word !="")) { //以下略
否定で括って && を || にする。

if (!( !(word == null || word == "") )) { //以下略
1
if (!( !(word == null || word == "") )) { //以下略
で、否定の否定って肯定だから、! が二つで打ち消しあう。

if (word == null || word == "") { //以下略
1
if (word == null || word == "") { //以下略






https://nzigen.com/ysawa/de-morgan-s-laws/
論理式を書くときは、なるべく否定が少なくなるように常に心がける。
これが、鉄則になります。


https://blog.shimabox.net/2017/03/30/de_morgans_laws/


最初のコード


for ($i = 0; ! ($i > $limit || $i >= count($list)); $i++) {
}
ド・モルガンの法則


for ($i = 0; ! ($i > $limit) && ! ($i >= count($list)); $i++) {
}
否定の部分を反転

for ($i = 0; $i <= $limit && $i < count($list); $i++) {
}
Google Open Source(Go)ではDeprecated(非推奨)なコードがわかりやすく表示される

netパッケージのソースコードを読んでいると、ファイル内で使われている[syscallパッケージの記述に打ち消し線が引かれていた](https://cs.opensource.google/go/go/+/refs/tags/go1.19.3:src/net/dial.go;l=609;bpv=0;bpt=1)。

![スクリーンショット 2022-11-19 15.26.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261575/0ab12f7b-1ac2-b249-e11f-56e0bc4d080f.png)

他にも、この画像でいうと`Cancel`にも打ち消し線が引かれている。
まあ、なんとなくどういうときに打ち消し線が引かれるのか予想はできるが、軽く調べてみた。

---

どういうときに打ち消し線が引かれるかというと、そのパッケージやメソッド、型や変数が**deprecated**(非推奨)のとき。

Goでは、`Deprecated:`という修飾を含んだコメントを記述することで、対象が非推奨であることを伝えることができる[^1]。もちろん、この記述は開発者による目視のときのサポートだけではない。静的解析ツールの`staticcheck`には、この記述がある関数や型などを呼び出していると警告してくれる機能がある[^2]。

この規則を利用して、Go本体、標準・準標準パッケージのソースコードが管理されている`Google Open Source`内では、そういった非推奨になっているコードの記述が一瞬で分かる様になっているという仕組み。便利。

GitHubで管理されているソースコードは、こういったことは上記で説明したような`Lint`を実行してみないとわかりにくい。GitHubにもこういった痒い所に手が届く機能があると良いな。

[^1]: https://github.com/golang/go/wiki/Deprecated
[^2]: https://github.com/dominikh/go-tools/tree/master/cmd/staticcheck
Whitebox-toolsでGISデータプロセッシング

## Whitebox-toolsとは

- Rust製のGISデータ処理系ツールセット
    - [https://github.com/jblindsay/whitebox-tools](https://github.com/jblindsay/whitebox-tools)
    - MITライセンス

## Whitebox-toolsの環境構築

環境構築といっても、ビルド済みバイナリが配布されているので、それを使う手順だけ紹介。

- ドキュメント
    - [https://whiteboxgeo.com/manual/wbt_book/intro.html](https://whiteboxgeo.com/manual/wbt_book/intro.html)
- バイナリのダウンロード
    - [https://www.whiteboxgeo.com/download-direct/](https://www.whiteboxgeo.com/download-direct/)
- ダウンロードして展開したフォルダで、下記コマンドが通ればOK
    ```shell
    cd WBT
    ./whitebox_tools --version
    # WhiteboxTools v2.2.0 by Dr. John B. Lindsay (c) 2017-2023
    ```

:::note
ソースコードからのビルドを少し試したが、依存関係をすぐ解決できなかった
:::

## Whitebox-toolsを使ってみる

ドキュメントを見る限り多くの処理を実行できますが、今回は[ClipRasterToPoylgon](https://whiteboxgeo.com/manual/wbt_book/available_tools/gis_analysis_overlay_tools.html#ClipRasterToPolygon)を使って、いらすとやさんの日本地図を手書きのポリゴンデータでクリップしてみます。

![Screen Shot 2022-11-19 at 15.36.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73197/6dc04476-c154-def3-443e-84b518ae78ce.png)

日本地図は`raster.tif`、ポリゴンは`polygon.shp`とし、WBTフォルダに配置されているとします。ここで、Whitebox-toolsで共通のお作法のようですが、入力データの投影法は統一されている必要があることに留意してください。

```
入力のベクターデータはシェープファイル形式である必要がある模様
```

```shell
cd WBT
./whitebox_tools -r=ClipRasterToPolygon -i=raster.tif --polygons=polygon.shp -o=clipped.tif --maintain_dimensions
# --maintain_dimensionsは、ドキュメントや名前からわかりづらいですが、CRSを維持するためのオプションです
```

実行するとclipped.tif`が出力されます。QGISで表示してみます。

![Screen Shot 2022-11-19 at 15.41.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73197/4ed8100b-de89-3449-fcb8-4bcca337ca60.png)

ラスターをポリゴンで切り抜くことができました。
Whitebox-toolsには、たくさんのプロセッシングツールが含まれているので、便利そうです。Rustで書かれているのもモダンで良いですね。
Amazon RDSでinsufficient-capacityになって詰まった件

## insufficient-capacityとの遭遇
最近、DBインスタンスタイプのdb.r3系統が廃止されると聞いて、検証環境で移行の動作確認していたところDBインスタンスが一つ落ちていることに気づく。

ワイ「は？insufficient-capacity？」

これが生産性ゼロの一週間を生むのであった。

## insufficient-capacityとは
結論「AZ（アベイラビリティゾーン）のオンデマンドキャパシティが足りない場合に発生するステータス」のよう。
capacityとはオンデマンドキャパシティのことを指すっぽい。

ワイ「マジかよ。対策立てようないやん。」

というのもEC2インスタンスはオンデマンドキャパシティを予約できるが、ぷらんnAmazon RDSはできない。

そしてこの現象が発生する最大の要因はRDSを停止させることにある。
顧客要望によっては、運用時間を減らすことがコスト削減につながるため、夜間や非営業時間はサーバを動かさない等の対応を行う場合がある。
ましてや検証環境なんかは本番環境と違って使用頻度も少ないので、高確率でそうなることが多い。
停止させることによるリスクについては参考記事に載せている「[RDSを本番環境で停止運用しないほうが良い理由について](https://blog.serverworks.co.jp/tech/2019/06/26/stopdbinstance/)」が参考になる。
PS: 本当に助かりました。ありがとうございます。

余談だが、AZ内のオンデマンドキャパシティは時間経過とともに変化するので、落ちた場合は再起動で直る。
ただ今回の場合、aurora-mysqlでマルチAZ 2系運用の中の一つがやられたため、awscliでの再起動、停止、開始コマンドも効かない状態であった。

## insufficient-capacityの対応
さてさて原因が分かったのでリカバリ対応をするわけだが、前述も申し上げた通りawscliからの再起動、停止。開始コマンドも効かない状態だったので、インスタンスを削除するしか方法が無い。
とはいえ、DBインスタンスを削除するなぞ話しても通るものでもなく。

ワイ「DBインスタンスの削除新規で対応できます！」
上司「削除するにもリスクあるよね？」
ワイ「で…でも…公式にもそう書いてあるわけですし…」
上司「削除するにもお客さんが納得できる、もしくは許可を得ることが大事だよね？」
ワイ「…そうですね」

ワイ、お客さんの説得が最高に苦手なんですが…。

まあワイが言い訳を考えるのに3日間かけた話はさておき、ワイが入っているプロジェクトはCloudFormationでRDSの設定値を管理していたので、可能あればそれで対応したいと考えたわけです。

結論、以下の手順で実施（バックアップは必ずしてネ☆）。

1. 落ちたDBインスタンスを削除したテンプレートを用意し取り込む。
2. 落ちたDBインスタンスが削除されたことを確認する。
3. 落ちたDBインスタンスを復元したテンプレートを用意し取り込む。
4. 落ちたDBインスタンスが「利用可能」ステータスになっていることを確認する。

もし4で起動できなくても再度1からやり直せばOK（多分）。
無事これで復旧完了。DBインスタンスタイプも変更し、全てが丸く収まったってわけですね。
魔の調査（2日間）+言い訳（3日間）期間が終わったわけです。

## 結論
- insufficient-capacityはAZ内のオンデマンドキャパシティが不足したことで発生する。
- insufficient-capacityにならないように停止期間を設けないように提案を頑張る。
- insufficient-capacityになると再起動できる場合は再起動するが、再起動、停止、起動ができない場合は削除しか対応方法が無い。
- CloudFormationで対応する場合は、テンプレートの中から落ちたDBインスタンスを消して取り込み、削除する前のテンプレートを流しなおすと立ち上がる。

これで何とかしてくれよ、兄弟。

## 参考記事
- [RDSを本番環境で停止運用しないほうが良い理由について](https://blog.serverworks.co.jp/tech/2019/06/26/stopdbinstance/)
- [Troubleshoot instance launch issues](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/troubleshooting-launch.html#troubleshooting-launch-capacity)
【プログラミング初学者】Linux OS（オペレーティングシステム）

# OSの仕組み

マザーボード、CPU、メモリーのようなハードウェアとの橋渡しをするソフトウェアのこと
ここで記述するのは、Mac、Windowsなどがある中でLinuxについて書く。

#### Linuxのメリット
- 開発環境を整えるのが便利
- テキスト処理に早い
- 無料

#### Linuxのデメリット
- Windows,Mac,などのメジャーな製品の場合動かないことが多い
- Linuxディストリビューションが多くてわからない(後述)
- クローズドソースなアプリが使えない
- 使用したことのない人にとっては敷居が高い
- MicrosoftOfficeなどが利用できない

#### ディストリビューションとは
基本的にカーネルと他の役割を担っているソフトウェアを一緒くたにした形態のこと。Linuxの種類と言ってもいいかもしれない。
ちなみにディストリビューションで代表的なものがRHEL(Red Had Enterprise Linux)のクローンであるのがCentOSである。

#### UNIXとLinuxの違い
UNIXもOSで最も古いOS。UNIXを真似て作られたものをUNIX系と言われ、その一つにLinuxがある。なのでUNIXに影響を受けている、という点ではあるが似て非なるものである。
Windowsコマンドプロンプトからsayコマンドもどき（合成音声）を実行する方法

# 1. はじめに
今回は、自分自身への備忘録を兼ねて、Windowsコマンドプロンプト（cmdコマンドプロンプトを想定）からsayコマンドもどきを実行する方法を、お伝えしたいと思います

- 参考文献：[Windowsでもsayコマンドを](https://nacookan.hatenadiary.org/entry/20081221/1229802781)
- 参考文献：[VBSでOneCoreの音声を使用する](https://qiita.com/7shi/items/7781516d6746e29c03b4)
- 参考文献：[Windowsバッチで，手軽に日本語テキストを自動読み上げ（Text To Speech）する方法　…WSHでSAPIやSpeech.SpVoiceを使う音声合成の手順とサンプルコード](https://language-and-engineering.hatenablog.jp/entry/20150202/JapaneseTextToSpeechProgramming#EnglishTextToSpeechByWSH)
- 参考文献：[Windows 10は好きな文章を合成音声で簡単に喋らせることができる](https://ascii.jp/elem/000/004/055/4055975/)
- 参考文献：[拡張子「.js」のファイルをダブルクリックしても「ファイルを開けません」って出る](http://www.oshiete-kun.net/archives/2009/03/js.html)

# 2. この記事を読んでできること
- Windowsコマンドプロンプトからsayコマンドもどきを実行できるようになる

# 3. 注意事項
- 特になし

# 4. 必要なもの
- Windows OS PC（Windows11を想定）
- テキストエディタ

# 5. say.jsスクリプトファイルの作成
- say.jsファイルを作成し、作業ディレクトリ内にファイル保存する

```plaintext:say.js
var args = [];
for(var i = 0; i < WScript.Arguments.length; i++)
  args.push(WScript.Arguments.Item(i));

var sapi = new ActiveXObject('SAPI.SpVoice');
sapi.Speak(args.join(' '));

```

# 6. Windowsコマンドプロンプトから実行
- Windowsコマンドプロンプトを起動する（cmdコマンドプロンプトを想定）
- say.jsファイルを保存した作業ディレクトリに移動する
- sayコマンドもどきを実行する

```plaintext:say.js
// 作業ディレクトリに移動
> cd xxxxxxxx

// syaコマンドもどきを実行
> wscript say.js こんにちは、世界

```

---

# 7. おわりに
いかがでしたでしょうか？Windowsコマンドプロンプトからsayコマンドもどき（合成音声）を実行することができたのではないかと思います
今回の記事が、みなさまの学習の参考になれば幸いです

2022/11/19 TAKAHIRO NISHIZONO
【HTML, JS】csvファイルの中身をtableに表示する

## はじめに
かんたんなWebサイトに更新履歴を表示する際，htmlファイルに直に更新履歴を追記するという方法もあるが，更新履歴を追記するためだけにhtmlファイルを開くのはナンセンスだと思った．  
そこで，更新履歴はcsvファイルに記述し，jsを使って表示する，という方法を思いついたので，そのやり方と注意点をまとめる．
## 最初に実装したもの (良くない例)
```html:index.html
<table id="displayCsv"></table>

<script>
function getCsv(){
  const req=new XMLHttpRequest()
  req.addEventListener("load", (event)=>{
    const res=event.target.responseText

    var line=res.split("\n")
    var str=[]
    var insert=""
    for(let i=0; i<line.length; i++){
      str=line[i].split(",")
      insert='<tr><td>'+str[0]+'</td><td>'+str[1]+'</td></tr>'
      document.getElementById("displayCsv").innerHTML+=insert
    }
  })
  req.open("GET", "input.csv", true)
  req.send()
}
//実行
getCsv()
</script>
```

### 実行結果
```text:input.csv
2022.11.1,hogehoge
2022.11.10,fugafuga
```
```html:index.html
<table id="displayCsv">
  <tbody>
    <tr>
      <td>2022.11.1</td>
      <td>hogehoge</td>
    </tr>
  </tbody>
  <tbody>
    <tr>
      <td>2022.11.10</td>
      <td>fugafuga</td>
    </tr>
  </tbody>
</table>
```

### 問題点
- loop毎にinnnerHTMLに加算する方法では，行ごとにtbody要素が生成されてしまう．(加算するごとにDOMノードが生成される為？)
- 新しい履歴をcsvファイルの末尾に追記している為，この方法では最新の更新履歴が一番下に表示されてしまう．

## 再び実装
```html:index.html
<table>
  <tbody id="displayCsv"></tbody>
</table>

<script>
function getCsv(){
  const req=new XMLHttpRequest()
  req.addEventListener("load", (event)=>{
    const res=event.target.responseText

    var line=res.split("\n")
    var str=[]
    var insert=""
    for(let i=0; i<line.length; i++){
      str=line[i].split(",")
      insert='<tr><td>'+str[0]+'</td><td>'+str[1]+'</td></tr>'
      document.getElementById("displayCsv").insertAdjacentHTML("afterbegin", insert)
    }
  })
  req.open("GET", "input.csv", true)
  req.send()
}
//実行
getCsv()
</script>
```

### 実行結果
```text:input.csv
2022.11.1,hogehoge
2022.11.10,fugafuga
```
```html:index.html
<table>
  <tbody id="displayCsv">
    <tr>
      <td>2022.11.10</td>
      <td>fugafuga</td>
    </tr>
    <tr>
      <td>2022.11.1</td>
      <td>hogehoge</td>
    </tr>
  </tbody>
</table>
```

### どう直したのか
- `id`を`table`要素ではなく`tbody`要素に付加した．
→ 行ごとに`tbody`要素が生成されるのを防げる．
(`insert=...`を`insert+=...`に変え，`innnerHTML+=insert`をloopの外に出したうえで`innnerHTML=insert`に変えることでも解決するが，この方法では2つめの問題点を解決できない．)
- `innnerHTML`ではなく`insertAdjacentHTML()`を使用した．
→ これにより最新の更新履歴がいちばん上に表示されるようになる．

## 参考文献
- Element.innerHTML - Web API | MDN
https://developer.mozilla.org/ja/docs/Web/API/Element/innerHTML
- element.insertAdjacentHTML - Web API - MDN Web Docs
https://developer.mozilla.org/ja/docs/Web/API/Element/insertAdjacentHTML
- JavaScriptでCSVをHTML表示
https://qiita.com/hiroyuki-n/items/5786c8fc84eb85944681
実機ビルドエラー(DeviceSupportに対応iOSサポートファイルがない時)

ipadへ実機ビルドの際に、つまずいた点を以下に記録。


実機ビルド先のios機器のバージョンが、xcodeでサポートしていなくてはならない。されていない時は実機ビルドの際に以下のエラーを吐く。
``”Could not locate device support files.”``

解決策は以下の通り
1\. xcodeへiosサポートファイルをDL。

以下のURLへアクセスし、リモートリポジトリをクローン OR zipファイルでわかりやすいところにダウンロードする。
https://github.com/iGhibli/iOS-DeviceSupport/tree/master/DeviceSupport

2\. DLしたサポートファイルをxcode内のSupportFile内に置く。

ターミナルでSupportFile内に置きたいファイルのディレクトリまでアクセス。
```zsh:zsh
cd Desktop/SupportFile/15.6
//相対パス
```

次にXcodeのDeviceSupportにファイルを置く

```ターミナル:zsh
mv 15.6 /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/
```

以上でXcodeが実機ビルド先のiosバージョンに対応することになる。

>ちなみに絶対パスの記法は`/PATH/PATH...`のように、最初は／から始まる。
>相対パスは`PATH/PATH`のようにPATH名から始まる。




。
Teratermを卒業してsshクライアントでEC2に接続するまで

# はじめに
今までTeratermでEC2にssh接続を行っていました。sshクライアントをセットアップすることによりTeratermを卒業するためのメモです。卒業したいわけではないのですが、Teratermを利用できない環境で試行錯誤したので備忘録です。

# sshクライアントのインストール
PowerShellコンソールで下記のように実施します。これによってWindowsコンポーネントとしてOpenSSHというsshクライアントが利用できるようになります。
```powershell:Install the OpenSSH Client
# Check the OpenSSH Component
Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH*'

# Install the OpenSSH Client
Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0
```

下記が参考資料です。

https://learn.microsoft.com/en-us/windows-server/administration/openssh/openssh_install_firstuse?tabs=powershell


# EC2への接続
EC2は接続の際に作成したキー(pem)ファイルを利用して接続し、```ec2-user```で接続します。

```powershell:ssh 接続 
ssh -i "AWSKEY.pem" ec2-user@HOSTNAME
```
```AWSKEY.pem```はキーファイルです。```HOSTNAME```はEC2のホスト名で、IPアドレスでもOKです。

## ファイルの転送

```powershell:scp ファイル転送
#ローカルのカレントディレクトリのgomi.txtファイルをリモートのホームディレクトリへ転送します。
scp -i "AWSKEY.pem" gomi.txt ec2-user@HOSTNAME:~
#リモートのホームディレクトリのgomi.txtファイルをローカルのカレントディレクトリへ転送します。
scp -i "AWSKEY.pem" ec2-user@HOSTNAME:~/gomi.txt .
```

# おわりに
無事にssh接続できて良かったです。しかし昔からお世話になっているTeratermはGUIでのファイル転送やマクロなど機能が豊富なので、まだまだお世話になります！

https://ttssh2.osdn.jp/

# 参考文献

https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/connect-linux-inst-ssh.html

https://qiita.com/sayama0402/items/c5c2795968ced798150a
地理空間情報を支える理論の紹介

# はじめに

本記事では、地理空間情報を支える理論を紹介する。

# 可視化理論

可視化理論は、地理学者のジャック・ベルタンが地図上に情報を表現する方法を発表したことに端を発する学問である。

https://ja.wikipedia.org/wiki/%E3%82%B8%E3%83%A3%E3%83%83%E3%82%AF%E3%83%BB%E3%83%99%E3%83%AB%E3%82%BF%E3%83%B3

可視化理論では、可視化するデータの分類、効果的な可視化方法などを研究する。

# 空間論理演算

空間論理演算（Spacial Logic）とは、空間内の情報を処理する演算のことである。

空間論理演算では、空間内の一定の領域を専有するエンティティ同士の関係性を分類し、その分類ごとに演算方法を定義している。

実際のエンティティには、丸や矩形などの様々な形がありうる。

```plantuml
rectangle "　　　　　"

("　　　")
```

しかし、空間論理では閉局面で覆われていれば同じものとして扱われる。すなわち、エンティティの形に依存せずに処理を一般化できるのである。

空間論理には様々な種類がある。最も有名なものがDE-9IMである。
これは、2つのエンティティの関係を以下の9つに分類して処理する方式である。

> ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114392/cf27eba4-dfeb-a09a-0ab7-9607fe587a91.png)
> 
> [DE-9IM - Wikipedia](https://en.wikipedia.org/wiki/DE-9IM)

aとbという2つのエンティティの領域の内側（Interia）、境界（Boundary）、外側（Exterior）の3つが互いにどのような関係にあるかを表現する演算である。

DE-9IMでは、2つのエンティティの包含関係にだけ着目し、その領域の大きさなどには言及しない。

# 時相論理演算

時相論理演算（Temporal Logic）とは、時間軸上の情報を処理する演算のことである。

> ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114392/ceded37b-4940-ec04-b200-331ff444d202.png)
>
> [Allen's interval algebra - Wikipedia](https://en.wikipedia.org/wiki/Allen%27s_interval_algebra)
C言語学習者のPythonスクレイピング入門 

# はじめに
<!-- 発端や概要を記載 -->
C言語を学習しているPython初心者の私がスクレイピングに手を出したぞぉ～っている話ですっ！
私は今大学生なので、弊学のシラバスでもスクレイピングしていこうかなと思います。（禁止されていないことは確認済み）。

#### スクレイピングとは
スクレイピングとは何か っていうのは、この記事にたどり着いた人なら知ってるんじゃないかなと思うので、説明は割愛です。Webサイト情報から自分に必要な情報だけを抽出することをスクレイピングって言うらしいですけど。Python以外にGoogleAppsScript（GAS）でもやっている人いるみたいです。スクレイピングを定期実行したい、頻繁にデータを更新したいとかならGASの方が便利かも。

#### 経緯
筆者は「Kadai-Board」という香川大学の学生向けのWebアプリを作っているのですが、それで、LMS（Moodle）と教務システム（住友系SIerのSCSK製DreamCumpus）の2つのサイトそれぞれの授業に関するデータが必要になりました。それで、スクレイピングして、シラバスデータを頂戴しようか という感じで始めました。（詳しいことはまた別の機会に）


# 目次
<!-- タイトルとアンカー名を編集 -->
1. [Python環境構築](#Chapter0)
1. [文法](#Chapter1)
1. [pip や conda](#Chapter2)
1. [Python文法](#Chapter3)
1. [スクレイピングをする前に](#Chapter4)
1. [よく利用されるライブラリ](#Chapter5)
1. [参考文献](#reference)


<a id="#Chapter0"></a>
# Python環境構築
ググってください。
ポチポチするだけです。
Windowsの人はインストーラのPATHを通すチェックボックスに印を入れ忘れないようにする 的な注意点があった気がする。詳しくは忘れちゃった ガハハ。

#### バージョン
Python2.xの2系とPython3.x系の3系があるみたいだけど、業務で使うとかで無い限り3系で良いいんじゃないんですかね。2系は2020年にサポート終了してるみたいだし。
#### 環境の種類
python.orgの「Python」で良いと思います。
Anacondaとかもけっこう使われてるみたいだけど

<a id="#Chapter1"></a>
# 文法
とほほ さんのPython入門でも見てください。
https://www.tohoho-web.com/python/index.html

変数の型はC言語みたいにint hoge = 1;って書くのも出来るけど、Pythonでは hoge = 1 だけでもOK。（個人的には明示的に書くのが好き）
for文とかが便利になってます。

なんか投げやりで すいまそん。

<a id="#Chapter2"></a>
# pip
C言語学習者がまず戸惑うのがpip install <パッケージ名>ってやつだと思います。
Anaconda環境だとconda install らしいです。

C言語では#include <stdio.h> って感じでヘッダーファイルをincludeしてライブラリを取り込みますが、
Pythonではimport /*パッケージ名*/で読み込みます。

Pythonはライブラリの開発が盛んで標準ライブラリ以外の外部ライブラリを利用することが多くあります。
https://utakataworks.com/pip-and-conda-install/#index_id1

<a id="#Chapter3"></a>
# スクレイピングの手順 と ライブラリ
#### 手順
1. WebサイトのHTMLを取得
2. HTMLを解析（必要な部分を取り出していく）
#### ライブラリ

- Requests
  - 軽量。
  - 静的なサイト（JSとかを利用して描画していない）に適する
    - どっかの企業の商品ページとか？
- Selenium 
  - 動的なサイトにも対応
    - ログインが必要なサイト
    - クリックやスクロールしないと必要なデータが表示されないサイト
  - スクレイピング以外に、操作の自動化にも使われる （というより、メインの役割は自動化）
- Beautiful Soup
  - これはとりあえずインストールしておこう。
  - HTML解析に使う


<a id="#Chapter4"></a>
# Requests
詳しくはコチラへ（外部サイトです）
- [requestsライブラリのメソッド一覧](https://web-kiwami.com/requests.html)
- [Python, Requestsの使い方](https://note.nkmk.me/python-requests-usage/)

<a id="#Chapter5"></a>
# Selenium
詳しくはコチラへ（外部サイトです）
- [図解！PythonでSeleniumを使ったスクレイピングを徹底解説！(インストール・使い方・Chrome)](https://ai-inter1.com/python-selenium/)

<a id="#Chapter6"></a>
# Beautiful Soup
詳しくはコチラへ（外部サイトです）
- [図解！Python BeautifulSoupの使い方を徹底解説！(select、find、find_all、インストール、スクレイピングなど)](https://ai-inter1.com/beautifulsoup_1/)

<a id="#Chapter7"></a>
# 謝罪
この記事の著者は、ここまで書いて満足して、逃亡してしまいました。続きを読みたい人は筆者に向かって肉声をベースバンド伝送してください。（どこかのコピペ）
SLP-KBIT（香川大学プログラミング研究会）のアドベントカレンダーの %d 日目の記事なんですが、大学の名、サークルの名を汚すような記事になってしまいました。 最後の方なんてタダのリンク集になっちゃってる笑。この場を借りて、一応、謝罪させてください。


<a id="#reference"></a>
# 参考文献
- [Qiita C言語系プログラマのためのPython入門 @shiracamus](https://qiita.com/shiracamus/items/fd35c685e9679323471f)
- [AI-interのPython3入門](https://ai-inter1.com/python-basic/)
クイックスタート: Salesforce アプリケーションの構築  ＞Trailblazer アプリケーションを作成する

[
Trailblazer アプリケーションを作成する](https://trailhead.salesforce.com/ja/content/learn/projects/quickstart-devzone-app/devzone-app-1)

エラーメッセージの内容が理解でしがたい

お約束の何もしないで確認ボタンを押す

**Could not find the 'Waypoint__c' object.**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/34b9bfaa-f8dd-ca31-3967-c132d4dfd2a5.png)
6.saveまで


**Could not find a Lightning App with the App Name 'Trailblazer'.**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/8f3821fb-bfb4-092f-3d77-9d8050fab409.png)

タブをつくった
**Could not find a Lightning App with the App Name 'Trailblazer'.**


変わらんなぁ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/0b3664b4-7ab3-4e6c-36fa-f0f4934e222d.png)


作ったカスタムオブジェクトのタブを入れずに確認したら、合格だ何で？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/845f5b51-a5f3-dc88-ffe2-257f5a053710.png)

このエラーは何故？

[An error message appears and I cannot proceed to next step.](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000LGpQzSAL)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/336206c2-b56e-02c5-efa8-a66009141f66.png)
エンジニアリングとビジネスの関係性に関する一考察

# はじめに

エンジニアリングとビジネスの関係性とエンジニアのビジネスへの関わり方について考える。

# エンジニアリングとビジネスとは何か

まず、エンジニアリングとビジネスの定義を確認する。

## エンジニアリングとは

エンジニアリングとはなにか。辞書を引いてみると、工学とある。

> 〘名〙 (engineering) 工学。工学技術。
> 
> [エンジニアリング | 精選版 日本国語大辞典 | コトバンク](https://kotobank.jp/word/%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%83%AA%E3%83%B3%E3%82%B0-447672)

では、工学とはなにか。さらに辞書を引くと「XXを目的として、YYを用いて、ZZする学問」とある。

> こう‐がく【工学】
〘名〙 工業に役立てることを目的として、自然科学的手法を用いて、新製品、新製法、または新技術を研究する学問。
>
> [工学 | 精選版 日本国語大辞典 | コトバンク](https://kotobank.jp/word/%E5%B7%A5%E5%AD%A6-61583)

つまり、工学は目的と手法が限定されている学問である。

## ビジネスとは

一方、ビジネスとは何者なのか。辞書を引いてみると、仕事、事業とある。

> 〘名〙 (business) 仕事。職業。事務。また、事業。商売。
> 
> [ビジネス | 精選版 日本国語大辞典 | コトバンク](https://kotobank.jp/word/%E3%83%93%E3%82%B8%E3%83%8D%E3%82%B9-609899)

では、事業とはなにか。さらに辞書を引くと「一定の目的で同種の行為を行う経済活動」とある。

> 〘名〙
① しごと。わざ。じごう。
② 一定の目的で同種の行為を継続的にまたは繰り返して行なう経済活動。
>
> [事業 | 精選版 日本国語大辞典 | コトバンク](https://kotobank.jp/word/%E4%BA%8B%E6%A5%AD-503337)

つまり、ビジネスは目的は一定しているが手法はとはない活動なのである。

# エンジニアリングとビジネスとの比較

目的、手法、活動の観点でエンジニアリングとビジネスを比較すると次のようになる。

|項目|エンジニアリング|ビジネス|
|----|----|----|
|目的|工業に役立てること|一定の何か|
|手法|自然科学的手法|問わない|
|活動|学問的活動|経済活動|

ビジネスは工業に比べると目的と手法の自由度が高い。

実務上の状況を考えるとイメージしやすい。
利益率向上という経営目標に対して、エンジニアリングでは製造コスト削減や製品機能の追加などの技術的に解決できる方法で利益率を改善しようとする。
一方で、ビジネスではアウトソーシング、オフショア、人件費削減など様々な方法で利益率を改善しようとする。ビジネスでは手法に制限がないのでどのような方法も取れる。

# エンジニアリングとビジネスの境界

どこからどこまでがエンジニアリングか。ビジネスとの境界はあるのだろうか。

では、経営工学はエンジニアリングだろうか。
経営工学もまたエンジニアリングと言ってよいだろう。マクロ経済、ミクロ経済や金融工学といった学問と同様にお金に関する数学的な問題の一種である。

たとえば、マネジメントはエンジニアリングだろうか。
マネジメントの半分は、エンジニアリングと言えるだろう。マネジメントに含まれるスケジュール管理やリソース管理は数学的で自然科学的な問題であり、チーム管理やリーダーシップは心理学的あるいは社会科学あるいは人文科学的な問題である。社会科学や人文科学は自然科学とは異なり人間やその社会活動を対象としており、エンジニアリングが手段とする自然科学とは異なる。したがって、半分はエンジニアリングでもう半分は非エンジニアリングと言えるだろう。

では、経営戦略や経営者のビジョンはエンジニアリングであろうか。
経営戦略や経営者のビジョンはビジネスだろう。経営工学や数学と言ったお金に関する定量的評価に支えられているので、一見してエンジニアリングのように見える。しかし、その本質は、経営者の目指す目的である「一定の何か」を体現している標語に過ぎない。標語は自然科学的な手法で導き出されるものではないため、エンジニアリングとは言えないだろう。指標は従業員を含めたステークホルダーに訴えかけるために作られる、いわば社会科学的な手法である。

これらの例から次のことがわかる。

* 目的と手法に着目してエンジニアリングかビジネスかを峻別することはできそうである。
* 一定の目的を持つビジネスを自然科学的な手法を実現するエンジニアリングが支えている。ただし、手法には、社会科学的・人文科学的な非エンジニアリング的なものもある。

# エンジニアのビジネスへの関わり方について

ここまでの分析を踏まえて、エンジニアのビジネスへの関わり方のポイントを以下の2つにまとめた。

* 第一に、ビジネスの「一定の目的」を達成するための自然科学的な手法、すなわちエンジニアリングを実践すること、が肝要である。エンジニアリングはなにがしかの形でビジネスの目的に役立つものでなければならない。
* 第二に、社会科学的・人文科学的な非エンジニアリング要素の有用性を認め、学び、実践すること、が肝要である。ビジネスを支える要素はエンジニアリングだけではない。

ビジネスとエンジニアリングは切っても切り離せない関係にあるので、まぁ好き嫌いに限らず、はばひろいしやで上手に付き合っていくしかない。
UWP URLで指定した画像をダウンロードする

# 実現したい内容

URLで指定した画像(HTMLを走査して得たjpegのURLなど)をダウンロードし、`SoftwareBitmap`に格納する。

# 対処

`HttpClient`の`GetAsync()`で画像データを取得し、streamに書き込んだものを、`BitmapDecoder`を介して`SoftwareBitmap`として生成する。

:::note
HttpClientには以下の2つがあって、少々ややこしい。本稿は上の例。
- Windows.Web.Http ; UWP向け
- System.Net.Http ; .NET向け
:::

- url: 画像のURL

```C#:using Windows.Web.Http;
var uri = new Uri(url);
InMemoryRandomAccessStream ras = new InMemoryRandomAccessStream();
var client = new HttpClient();

try
{
    var result = await client.GetAsync(uri);
    result.EnsureSuccessStatusCode();
    await ((HttpStreamContent)result.Content).WriteToStreamAsync(ras);
}
catch (Exception ex)
{
    Debug.WriteLine(String.Format("GetAsync err: {0}", ex.Message));
}

var decoder = await BitmapDecoder.CreateAsync(ras);
SoftwareBitmap sb = await decoder.GetSoftwareBitmapAsync(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied);
```
emotionを使用してreact-three-fiberのCanvasを全画面表示にする(メモ)

# はじめに
react-three-fiberのCanvasで作成した画面はデフォルトだと全画面描画されません。
下の図のようにcanvasの領域が固定化されてしまいます。
今回はこれを、emotionを使って全画面化する方法を紹介します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2962731/63862365-28b8-fd18-ef5a-3201ada0b82c.png)

## emotion適用前のコード
Starsだけの単純なコードです。
```typescript: index.ts
import type { NextPage } from "next";
import React from "react";
import { Canvas } from "@react-three/fiber";
import { Stars } from "@react-three/drei";

const SampleStarts: NextPage = () => {
  return (
  <Canvas>
    <Stars></Stars>
  </Canvas>
  );
};

export default SampleStarts;

```

# emotionとは？
CSS in JSのフレームワークです。
詳しくはこちら。
https://emotion.sh/docs/introduction

# さっそく使ってみる
## 事前準備
@emotion/reactをインストールします。
```
npm i @emotion/react
```
tsconfigの設定変更とbabelの設定ファイルを作成します。
※.babelrcはpackage.jsonと同じ階層に置いてください。
```text:tsconfig.json
  "compilerOptions": {
　　・・・（略）
    "types": ["@emotion/react/types/css-prop"],　←追加
  }
```
```json:.bablerc
{
    "presets": [
      [
        "next/babel",
        {
          "preset-react": {
            "runtime": "automatic",
            "importSource": "@emotion/react"
          }
        }
      ]
    ],
    "plugins": ["@emotion/babel-plugin"]
  }
```

index.tsを以下のように書き換えます。
スタイルはオブジェクトスタイルでも、ストリングスタイルでもどちらでも構いません。
ポイントはCanvas要素をdivでラップしてあげているところです。



```typescript: index.ts
import type { NextPage } from "next";
import React from "react";
import { Canvas } from "@react-three/fiber";
import { Stars } from "@react-three/drei";
import { css } from '@emotion/react'

const theme = css({
  width: '100vw',
  height: '100vh',
  backgroundColor: 'black'
});

const Home: NextPage = () => {
  return (
    <div css={theme}>
      <Canvas >
        <Stars></Stars>
      </Canvas>
    </div>
  );
};

export default Home;

```

# 確認
無事全画面にCanvas要素が描画されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2962731/708dd67f-8f8c-5505-324a-f95d610edbeb.png)
DDDがわからない～上司と部下～

# 厳しい縦社会であるべき
システムの中では縦社会は厳しくいくべきです。部長は次長に、次長は課長に、課長は係長、主任、平社員、順で指示と報告をするようにしましょう。

# 上司の心得
上司は、何を指示するべきか？何を報告されるか？を理解しておく必要があります。しかし、部下がどんな方法でやるかはあんまり気にする必要はありません。


# 部下の心得
部下は、何を指示されるか。何を報告するか。を明確にしておく必要があります。上司が何のために指示を出しているか？何のために報告をするのか？を意識する必要はありません。


# 命令系統を壊してはいけない
基本的に指示と報告は同じグループ内で行いましょう。部下が上司に指示を出したり、別のグループに指示を出してはいけません。主任が平社員に指示をだしたら、その平社員が急に部長に指示を出したら驚いてしまいます。こういった驚きはシステムにおいて混乱をきたすのでやめた方がいいです。
【Laravel】三項演算子を使用したクラス属性の追加方法

条件によってクラス属性を追加し複数設定したい場合あったのですが、実装につまったので備忘録にしたいと思います。

```php
<div class="col-sm-7">
    {{ Form::select('content', ['hoge', 'hogehoge'], old('content'), ['class' => 'form-control ' . (is_null($hoge) && empty($hogehoge) ? 'form-color' : '')]) }}
</div>
```

## 解説
デフォルトのclass属性にはform-controlというクラス名が設定されている。
そこに三項演算子の結果がtrueならば、form-colorというクラス名を追加している。

三項演算子の結果は、「**文字列連結**」しているところがミソなのではないかと考えている。
この実装が初めは思いつかず苦労しました。。。
文字列連結は基礎中の基礎ではありますが、すぐにはこの実装が思いつきませんでした。。。

文字列連結した結果は以下の状態になる
```php
'class' => 'form-control form-color'
```

また、文字列連結する際は、デフォルトのクラス名の後に半角スペースを入れる必要があります。
上記から分かるようにclassを複数設定する時には半角スペースを入れていますよね。

```php
'form-control '
```
【Twilio】Voice（通話機能）を調べてみた

**Twilio**の**Voice**について調べてみた


# Voiceとは
**Twilio**が提供する**通話**関連の機能
**Voice API**を使うとこで、**通話の発信**をアプリに実装することができる

## Voice APIとは
通話の**発信・受信**をAPIで実装することができる
`PHP` `Node` `Python`など様々な言語でサンプルコードが用意されている
**インタラクティブ音声応答**（IVR）システムを構築することも可能

#### **インタラクティブ音声応答（IVR）**
>IVR（Interactive Voice Response）とは、音声認識やキーパッドの入力により、機械と人間との対話を可能にする技術です。

https://cognigy.tdse.jp/glossary/ivr/

## 高度な機能
通話関連で**複雑な処理**を実装したい場合にも対応している
* 例
    * SIPによる通話の発着信
    * 着信転送
    * 自然言語理解エンジンの適用


# 調べてみた感想
通話の『発信・受信』以外も多くの機能があることが分かった
楽しそうな機能が多いので、まずはハンズオンをやってみたいと思う

# 参考
https://www.twilio.com/ja/docs/voice
Listの編集距離（Java）


編集距離のList版。
Java17で簡単な動作確認しましたが、Java8でも動くと思います。

# 動機
集合（Set）での類似度（Jaccard係数、Dice係数、Simpson係数、など）のような感じで、順番を考慮した類似度を使用したかったため。


# ソースコード

```java
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class EditDistance<T> {
	Map<Integer, Map<Integer, Integer>> memo;
	
	public EditDistance() {
		memo = new HashMap<Integer, Map<Integer, Integer>>();
	}
	
	public int distance(List<T> list1, List<T> list2) {
		if (list1.isEmpty()) return list2.size();
		if (list2.isEmpty()) return list1.size();
		
		// このフェーズでは一致している場合
		if (list1.get(0).equals(list2.get(0)))
			return distance(list1.subList(1, list1.size())
					, list2.subList(1, list2.size()));
		
		// 以下は一致していない場合
		int diff = -1;
		//メモで探す
		if (memo.containsKey(list1.hashCode()))
			if (memo.get(list1.hashCode()).containsKey(list2.hashCode())) {
				diff = memo.get(list1.hashCode()).get(list2.hashCode());
				System.out.println("get from memo " + diff);
			}
		
		//メモにない場合
		if (diff == -1) {
			int l1 = distance(list1, list2.subList(1, list2.size()));
			int l2 = distance(list1.subList(1, list1.size()), list2);
			int l3 = distance(list1.subList(1, list1.size())
					, list2.subList(1, list2.size()));
			
			// l1とl2とl3のうち最小の値を求め、+1する
            // （+1は、このフェーズでは一致していないため）
			diff = Math.min(l1, Math.min(l2, l3)) + 1;
			
			// メモする
			Map<Integer, Integer> m = new HashMap<Integer, Integer>();
			m.put(list2.hashCode(), diff);
			memo.put(list1.hashCode(), m);
		}
		
		return diff;
	}

	public void clearMemo() {
		memo.clear();
	}
	
	public void printMemo() {
		System.out.println("print memo");
		memo.entrySet().forEach(System.out::println);
	}
```

# 簡単な動作確認
```java
	public static void main(String[] args) {
		EditDistance<String> test = new EditDistance<>();
		
		//一致するリスト
		// 0になることを期待
		List<String> list1 = Arrays.asList("test1", "test2", "test3");
		List<String> list2 = Arrays.asList("test1", "test2", "test3");
		
		System.out.println("--- ---");
		System.out.println("dist : " + test.distance(list1, list2));
		System.out.println("---");
		test.printMemo();
		test.clearMemo();
		test.printMemo();
		
		// 一致しないリスト
		// 操作1: list1の先頭のtest2を削除
		// 操作2: list1の２つ目の要素にtest2を追加
		// 操作3: list1の最後にtest4を追加
		// でlist1とlist2は一致するはずなので3が返るを期待
		list1 = Arrays.asList("test2", "test1", "test3", "test4");
		list2 = Arrays.asList("test1", "test2", "test3");
		System.out.println("--- ---");
		System.out.println("dist : " + test.distance(list1, list2));
		System.out.println("---");
		test.printMemo();
		test.clearMemo();
		test.printMemo();
	}
}
```

動いているっぽい。。

```console
--- ---
dist : 0
---
print memo
print memo
--- ---
get from memo 2
get from memo 2
dist : 3
---
print memo
110251521={110251520=1}
958565345={2105574015=3}
-766918686={-766918718=2}
2105574047={-766918718=2}
print memo
```
ネットワークについて学びなおす1

[前回の記事](https://qiita.com/yasaigaoisi/items/44ad2567d4ef2c948fbd)

# WEBブラウザでURLを解析する
WEBブラウザでは、ユーザが入力したURLで何をどうしたいのか解析し、それをWEBサーバに送ってもらうようにプロトコルスタックに依頼する、までを行います。
## URLについて
よく目にしているURLの先頭には、httpと書かれていると思います。これは、httpプロトコルというものを使ってWEBサーバにアクセスするという意味で、他にもいろいろなプロトコルがあります。なので、先頭がhttp以外のURLも存在し、それぞれのプロトコルに応じたサーバにアクセスすることができます。そういった意味では、WEBブラウザというのは、いろいろなサーバにアクセスすることができるプラットフォームのようなものと考えることができます。
## URLの解析（HTTPプロトコルの場合）
URLの先頭のプロトコルについて先ほど述べましたが、それ以降にはプロトコルへの具体的なリクエストが含まれています。
このリクエストを解析することがWEBブラウザの最初の役割になります。httpプロトコルの場合、URLは以下のように構成されます。
http: + // + webサーバ名 + / + ディレクトリ名 + / ... / + ファイル名
これによって、WEBブラウザは、httpプロトコルを用いて、指定したwebサーバに存在する、指定したパス（ディレクトリ/.../ファイル名）のファイルにアクセスするという要求であることを解析します。

:::note info
WEBサーバの設定次第では、ファイル名は省略できる
:::

## HTTPメソッド
URLの解析によって、何をどうするかというリクエストのうち、「何を」の部分がわかりました。
「どうするか」の部分にあたるのが、HTTPメソッドになります。代表的なメソッドにGETメソッドとPOSTメソッドがあります。
### GETメソッド
これは、普段私たちがブラウザでサイトを閲覧するときにリクエストとして送っているメソッドです。URLの解析でアクセスするファイルを読み出す処理を要求します。
### POSTメソッド
ユーザがサイトの入力欄で入力した内容をリクエストを送る時に、リクエストに含めるメソッドです。
### どうやってリクエストからHTTPメソッドを判断するのか
ここで、普段URLを入力するときに、GETメソッドなんて明示してないからどうやって解析するんだろう、と思ったかもしれません。HTTPリクエストをどう判断するかというと、リクエストの送り方で判断します。
URLを入力すること自体がGETメソッドとして判断されるということなのです。

## リクエストメッセージ作成
ここまでで、入力したURLによって何をどうしたいのかがわかりました。
これを用いて、あらかじめ書き方の決まったリクエストメッセージを作成します。

## 次回
次回は、作成したリクエストメッセージをOSに依頼する処理を追っていきたいと思います。
Windowsバッチファイルで現在日時を出力する方法

# 1. はじめに
今回は、自分自身への備忘録を兼ねて、Windowsバッチファイルで現在日時を出力する方法を、お伝えしたいと思います

- 参考文献：[IF文で現在と指定の日時を比較・分岐してコマンドを実行するバッチファイル](https://qwerty.work/blog/2017/10/if-date-time-command-batchfile.php)

# 2. この記事を読んでできること
- Windowsバッチファイルで現在日時を出力できるようになる

# 3. 注意事項
- %date%の書式がyyyy/mm/ddであること、詳しくは参考文献を参照

- 参考文献：[Windowsのバッチで date を加工して使うのはやめよう！](https://qiita.com/UFOnian/items/7355d5e6ee332f843909)

# 4. 必要なもの
- Windows OS PC（Windows11を想定）
- テキストエディタ

# 5. 現在日時出力バッチファイル
- .batファイルを作成し、実行する

```bat:timestamp.bat
@echo off
cd /d %~dp0
setlocal enabledelayedexpansion

rem 現在日時を取得
set YYYY=%Date:~0,4%
set MM=%Date:~5,2%
set DD=%Date:~8,2%

set HH=%Time:~0,2%
set HH=%HH: =0%

set MIN=%Time:~3,2%
set MIN=%MIN: =0%

set SS=%Time:~6,2%
set SS=%SS: =0%

set TIMESTAMP=%YYYY%%MM%%DD%%HH%%MIN%%SS%

rem 現在日時を出力
echo %TIMESTAMP%

endlocal
pause
exit /b
```

---

# 6. おわりに
いかがでしたでしょうか？Windowsバッチファイルで現在日時を出力することができたのではないかと思います
今回の記事が、みなさまの学習の参考になれば幸いです

2022/11/19 TAKAHIRO NISHIZONO

---
【Unity】Photon Fusion の TickTimer に関する処理を UniRx で簡潔に実装できる拡張メソッド

# 概要

Photon Fusion の TickTimer を便利に扱える拡張メソッドを作りました。
完了時にメッセージを飛ばしたり、秒刻みのカウントダウンを実装したりするのに役立ちます。

# 使用例

``` Enterキーを押したらゲーム開始のカウントダウンを始める.cs
private void Update()
{
    if (Input.GetKeyDown(KeyCode.Return))
    {
        RpcReady(TickTimer.CreateFromSeconds(Runner, 5f));
    }
}

public Subject<Unit> OnGameStarted { get; private set; } = new Subject<Unit>();
public Subject<int> OnCountDowned { get; private set; } = new Subject<int>();

[Rpc(RpcSources.StateAuthority, RpcTargets.All)]
private void RpcReady(TickTimer tickTimer)
{
    tickTimer.OnCountDowned(Runner).Subscribe(OnCountDowned).AddTo(this);
    tickTimer.OnCompleted(Runner).Subscribe(OnGameStarted).AddTo(this);
}
```

# コード

お手持ちの PhotonFusionEx クラスに下記の関数を追加してご利用ください。

``` PhotonFusionEx.cs
using Fusion;
using System;
using System.Linq;
using UniRx;
using UnityEngine;

namespace Extensions
{
    using Fusion;
    using System;
    using UniRx;
    using UnityEngine;

    namespace Extensions
    {
        public static class PhotonFusionEx
        {
            /// <summary>
            /// Runner.Tick と tick との時間差
            /// </summary>
            public static float ElapsedTime(this NetworkRunner runner, int tick) => (runner.Tick - tick) * runner.DeltaTime;


            /// <summary>
            /// TickTimer が完了した時に実行
            /// </summary>
            public static IObservable<Unit> OnCompleted(this TickTimer tickTimer, NetworkRunner runner)
                => Observable.EveryUpdate().First(_ => tickTimer.Expired(runner)).Select(_ => Unit.Default);

            /// <summary>
            /// TickTimer が有効の間、常に実行
            /// </summary>
            public static IObservable<Unit> OnUpdated(this TickTimer tickTimer, NetworkRunner runner)
                => Observable.EveryUpdate().TakeWhile(_ => !tickTimer.Expired(runner)).Select(_ => Unit.Default);

            /// <summary>
            /// TickTimer の RemainingTime が更新された時に実行
            /// </summary>
            public static IObservable<float> OnRunnerUpdated(this TickTimer tickTimer, NetworkRunner runner)
                => Observable.EveryUpdate()
                    .TakeWhile(_ => !tickTimer.Expired(runner))
                    .Select(_ => tickTimer.RemainingTime(runner).Value)
                    .DistinctUntilChanged();

            /// <summary>
            /// TickTimer の RemainingTime の整数部分が更新された時に実行
            /// </summary>
            public static IObservable<int> OnCountDowned(this TickTimer tickTimer, NetworkRunner runner, int minCount = 1, int maxCount = int.MaxValue)
                => Observable.EveryUpdate()
                    .TakeWhile(_ => !tickTimer.Expired(runner))
                    .Select(_ => Mathf.CeilToInt(tickTimer.RemainingTime(runner).Value))
                    .DistinctUntilChanged()
                    .Where(count => count >= minCount && count <= maxCount);
        }
    }
}
```
JetpackComposeのLazyColumnでClipToPaddingのような余白のあるリストを設定する方法

JetpackComposeでリストの表示などは簡単にできますが、今までのリストのように上に余白を作りたいと思いました。

簡単に設定ができました。

# 設定方法

```list.kt
LazyColumn (contentPadding = PaddingValues(top = 16.dp)){
    items(100) { index ->
        Text(text = "Item: $index")
    }
}
```

`PaddingValues`
こちらをLazyColumnに設定するとできます。
`PaddingValues`は`start` `top` `end` `bottom`
それぞれ設定ができます。

![Videotogif (2).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/d2fba24b-1492-b327-7cd8-61e6737edd5b.gif)


以上です！
NTPサーバの作成【サーバ構築】

# 参考サイト

https://www.isoroot.jp/blog/2844/

https://genchan.net/it/server/18479/


# 環境
OS：CentOs8 stream
IPアドレス：192.168.160.10/24


# 手順
今回、CentOsの構築手順は省略する。
全体的に、そこまで長くない。

## Chronyのインストール
以下のコマンドでインストールする。
```
sudo yum -y install chrony
```

## 設定ファイルの変更

インストールしたら、設定ファイルを変更する。
```
sudo vi /etc/chrony.conf
```

```
sudo vi /etc/chrony.conf
------------------------------------------------------------
以下をコメントアウト
 #pool 2.centos.pool.ntp.org iburst
 pool ntp.nict.jp iburst
 pool jp.pool.ntp.org iburst

 # Allow NTP client access from local network.
 # allow 192.168.0.0/24(アクセスを許可するネットワークアドレス)
 # Serve time even if not synchronized to a time source.
local stratum 10
```


- `allow アドレスのセグメント` アクセスを許可するセグメント帯を指定する。
- `local stratum 10` 上位NTPサーバーを参照していなくても、時刻同期を行えるようにする
- `pool ntp.nict.jp iburst` パブリックの、ntpサーバ群を参照するようにする。 
    - 独立行政法人情報通信研究機構(NICT)　の公開NTPサーバー


# NTPサーバの再起動
以下のコマンドで、NTPサーバの再起動と、自動起動の設定を行う。
```
sudo systemctl restart chronyd
sudo systemctl enable chronyd
```

# 動作確認
以下のコマンドで、_NTPのサービスが起動しているかを確認する。
```
sudo systemctl status chronyd
```
Activeとなっている事を確認する。

また、以下のコマンドを実行する。
```
sudo timedatectl
```
そして、
- 表示されている時刻が現在の時刻と正しいか、
- NTP service: active と表示されており、ntpのサービスが動いているか
- System clock synchronized: no で、他のntpサーバに同期していないか 
を確認する。

以上

## 注意（コンプラ的な）
公開用のpublicサーバは、数台の指定なら問題ないが、何十台、何百台と指定するのは、接続先のNTPサーバに負荷がかかるので、マナー違反となる。
そのため、今回のように自前でNTPサーバを作成し、後から作るサーバはその自前のサーバを参照する事で、元の公開用ntpサーバの負荷を減らす。
Swift #0

# ライブラリ
## 標準ライブラリ
基本的な機能を提供するライブラリ。文字列、数値、配列などのデータ型を提供。
標準ライブラリは言語の1機能として使用可能であり、import文を書いてインポートする必要がない。


## コアライブラリ
高機能なものを集めたライブラリ。非同期処理や通信、ファイル操作などが出来る。
- Foundation
　　基本機能を扱える。キャッシュやタイマー、並列処理、通知センターなど。
- libdispatch
　　マルチコアハードウェア上の並列処理を抽象化する
- XCTest
　ユニットテストのためのライブラリ
JavaScriptを始めてみます

今回、JavaScriptを始めて、その勉強していく過程をQiitaに書いていこうと思います。

私はシステムエンジニアで若干開発に携わったことがあります。現在は開発には携われず運用保守です。

新入社員研修でJavaに触れましたが、だいぶ忘れています。

最もたくさん書いた言語はVBAです。
業務の中で手でやるには大変な作業や繰り返す行う作業について、VBAで自動化することをたまに行っています。お客様に納品するレベルではなく、自分で自分のために作るといったものになります。

あとは、OracleとTeradataのSQLに仕事で少し触れたことがあります。

C#、JavaScriptについては、本当に一瞬だけ仕事でやりましたが、ほとんど理解していないレベルです。

こんな私がJavaScriptを勉強してみて、どう成長していくか、その記録として記事を書いていきます。
「ちゃんと勉強は続いているのか？」といった監視でも良し、「私もここでつまづいたので参考になる！」でも良し。

何かのお役に立てれば幸いです。

では早速始めていきたいと思いますが、JavaScriptはブラウザ上で動くということで、Javaのようにファイルをダウンロードしてきて開発環境を整えるといったことが不要です。
もちろん、エディタなどがあった方が良いらしいのですが、私は面倒くさがりなので、とりあえずメモ帳で簡単なコードを書いて、必要なファイルを用意します。

```html

<!DOCTYPE html>
<html lang="ja">
  <head>
    <title>タイトル</title>
    <script>alert('初めてのJavaScriptです！');</script>
  </head>
  <body>
  </body>
</html>

```

上記のソースコードをメモ帳に書き、拡張子をhtmlにして保存します。

その後、そのhtmlファイルをChromeなどのブラウザで起動すると、「初めてのJavaScriptです！」というポップアップが表示されます。

scriptタブで挟まれている部分がJavaScriptによる記述になります。

htmlファイルとJavaScriptファイルをそれぞれ用意して、htmlファイルがJavaScriptファイルを呼んで実行する方法もあったのですが、私はうまくいきませんでしたので、今回は上記のhtml内にJavaScriptを記載する方法にしました。

今回の記事を作成するにあたって、以下を参考にいたしました。ありがとうございます。

【参考文献】

https://masa-enjoy.com/%E3%80%90javascript%E5%85%A5%E9%96%80%E3%80%91javascript%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9%E3%81%A8%E5%AE%9F%E8%A1%8C%E6%96%B9%E6%B3%95

https://qiita.com/shizuma/items/8616bbe3ebe8ab0b6ca1
AxiosでAPIを叩いたら設定は正しいのに401エラーが発生する

# はじめに

AxiosでPOSTリクエストをする際にかなり時間がかかってしまったのでまとめていきます。
内容は正しいのになぜだろうと、原因がわからないときに確認してみてください

# 問題

以下の関数でRedmineにPOSTリクエストを送りました

```tsx:Popup.tsx

  const fetchData = async () => {
    const data = JSON.stringify({
      issue: {
        project_id: "100",
        tracker_id: "4",
        subject: 新規チケット作成",
        description: "APIで作成しました",
        status_id: "1",
        priority_id: "4",
        custom_fields: [{ id: 105, name: "Job No", value: "12345" }],
      },
    });
    try {
      const res = await axios.post(
        "https://redmine-sample/issues.json",
        {
          headers: {
            "X-Redmine-API-Key": "12345",
            "Content-Type": "application/json",
          },
          data,
        }
      );
      return res.data;
    } catch (e) {
      console.log(e);
    }
  };

  const onClick = () => {
    const res = fetchData();
    console.log(res);
  };

```

しかしこのAxiosを叩くとなぜか`401 Unauthorized`というエラーが返ってきます
何故エラーになっているのかがエラーレスポンスからわからないので苦戦しました

# 解決方法

まずはPostmanから実際に動いているリクエストを`<>`ボタンからコード出力して`node.js`の`axios`コードとして出力し、確かめてみました

そうすると問題なくAxiosがリクエストを送ることができました

動いたAxiosと動かないAxiosを比べたところ`Axios`のURL以下の`Header`と`Body`を渡す引数の順番に問題がありました

問題となっているコードは`header`, `data`の順に対してPostmanのコードは`data`, `header`になっていました。
よくよく考えたら間違えいているのですが気づけずにいました

順序を変えることで問題なく動きました

```tsx:Popup.tsx

  const fetchData = async () => {
    const data = JSON.stringify({
      issue: {
        project_id: "100",
        tracker_id: "4",
        subject: "新規チケット作成",
        description: "APIで作成しました",
        status_id: "1",
        priority_id: "4",
        custom_fields: [{ id: 105, name: "Job No", value: "12345" }],
      },
    });
    try {
      const res = await axios.post(
        "https://redmine-sample/issues.json",
        data,
        {
          headers: {
            "X-Redmine-API-Key": "12345",
            "Content-Type": "application/json",
          },
        }
      );
      return res.data;
    } catch (e) {
      console.log(e);
    }
  };
```

# おわりに

実際の原因は単純だったのですが、API側が悪いのではないか、POSTしている情報がたりないのではないかなど色々深追いしてしまって時間がかかってしまいました

普段当たり前のようにやっていることだったのでここでエラーになっているとは思いませんでした
デバックをするのは大切です
jupyter labのショートカット一覧の確認方法

# 結論

1. "Settings" -> "Advanced Settings Editor" を選択
2. "Keyboard Shortcuts" を選択
3. ショートカットの一覧が確認できる

### 補足
- ^(ハット）は Ctrlキーのこと
- ⇧はShiftキーのこと
- 例えば、^S　は　Ctrlキー+S
- [日本語でショートカットが分かりやすくまとめられているサイト]( https://pystyle.info/jupyterlab-keyboard-shortcuts/)
#11 messages.propertiesの値をコントローラに渡す

# #11 messages.propertiesの値をコントローラに渡す
前回の記事ではmessages.propertiesに記述した内容を各画面に直接入力してましたが、今回はコントローラに渡してから各画面で値を表示します。

# 前提条件
この記事はSpringの最低限の知識が必要になります。
また、なるべく分かりやすく書くつもりですが、この記事の目的は自分の勉強のアウトプットであるため、所々説明は省略します。

# 前回まで
前回の記事

https://qiita.com/Jackoguro/items/b71597bfeb79a90e7b7c

前々回の記事

https://qiita.com/Jackoguro/items/db35aa456341a484254b

# 構築環境
1. 各バージョン
Spring Boot ver 2.7.5

2. 依存関係
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884987/67356b8d-2039-81cd-c1a0-bf6e6259e02e.png)

# 成果物
前回と変化無し

# 今回行うこと
## 1. サービス処理にmessages.propertiesの値を渡す

```java:UserService.java
package com.example.service;

import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Service;

@Service
public class UserService {
	
	/* messages.propertiesの値を取得するためにMessageSourceを使用する */
	@Autowired
	private MessageSource messagesource;
	
	/* 性別のMapを生成する */
	public Map<String, Integer> getGenderMap() {
		Map<String, Integer> genderMap = new LinkedHashMap<>();
        /* getMessageを使用することでmessages.propertiesの内容を取得 */
		String male = messagesource.getMessage("user.signup.Male", null, Locale.JAPAN);
		String female = messagesource.getMessage("user.signup.FeMale", null, Locale.JAPAN);
		genderMap.put(male, 1);
		genderMap.put(female, 2);
		return genderMap;
	}
}
```
:::note
getMessageメソッドの引数
- キー名(第1引数)：messages.propertiesのキー名を記述します。
- 埋め込みパラメーター(第2引数)：メッセージに入れるパラメーターを指定します。
- ロケール(第3引数)：国(地域)を指定します。
:::

# 最後に
コントローラー、画面レイアウトは変更しなくともこれで変更は完了です。

~~ラジオボタンがどちらか片方しか押せないはずなのに両方押せてします事象が発生中~~
→name属性がないことことが原因と判明
paiza.ioでelixir その82

# 概要
paiza.ioでelixirやってみた。
練習問題やってみた。

# 練習問題
ローパスフィルターを実装せよ。

# サンプルコード

```

defmodule Main do
    def vin(v) do
        v
		|> Enum.with_index()
		|> Enum.map(fn {x, t} ->
            (0.6 * :math.sin(t / 8000 * 2 * :math.pi * 220) + 0.5) * :math.sin(t / 8000 * 2 * :math.pi * 2000);
        end)
    end
	def lpf(v) do
	    samplerate = 8000 
	    freq = 300
	    q = 1.0
	    omega = 2.0 * :math.pi * freq / samplerate
	    alpha = :math.sin(omega) / (2.0 * q)
	    a0 = 1.0 + alpha
	    a1 = -2.0 * :math.cos(omega)
	    a2 = 1.0 - alpha
	    b0 = (1.0 - :math.cos(omega)) / 2.0
	    b1 = 1.0 - :math.cos(omega)
	    b2 = (1.0 - :math.cos(omega)) / 2.0
	    in1 = 0
	    in2 = 0
	    out1 = 0
	    out2 = 0
	    v
	    |> Enum.map(fn x -> 
		    v = b0 / a0 * x + b1 / a0 * in1 + b2 / a0 * in2 - a1 / a0 * out1 - a2 / a0 * out2
		    in2 = in1
		    in1 = x
		    out2 = out1
		    out1 = v
        end)
	end
	def main do
        IO.puts """
<html><head></head><body>
<canvas id="canvas" width="300" height="300"></canvas>
<script type="text/javascript">
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
function draw(data, n) {
	var hcenter = n * 100 + 50;
	ctx.strokeStyle = "#f0f";
	ctx.lineWidth = 2;
	ctx.moveTo(0, hcenter);
	for (var i = 1; i < canvas.width; i++) 
	{
		ctx.lineTo(i, data[i] * 30 + hcenter);
	}
	ctx.stroke();
}
var src = [
"""
		List.duplicate(0, 300)
		|> vin
		|> Enum.map(fn x -> 
            IO.puts(x)
            IO.puts ","
        end)
IO.puts """

];
var dst = [
"""
        List.duplicate(0, 300)
		|> vin
        |> lpf
		|> Enum.map(fn x -> 
            IO.puts(x * 9)
            IO.puts ","
        end)
IO.puts """

];
draw(src, 0);
draw(dst, 1);
</script></body></html>
"""
	end
end
Main.main




```

# 実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/f9aa6b7f-c655-36ed-1217-82cf5b4499dd.png)



# 成果物

https://paiza.io/projects/L4-Bpsq-oHAyDBI9zMxDMA


以上。
PostmanでPOSTしたときヘッダーと送るデータが正しいのに401エラーになる

# はじめに

外部のAPIを試しに叩こうと思いPostmanを利用したのですが、うまくいかずデバックの方法について知ることができたので記事にまとめていきたいと思います。

他の人はAPIを叩けるのに自分は叩けないなどの状況があればデバックを参考にしてみてください

# 問題

Postmanを利用してPOSTのリクエストを送りました

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/0ae4f9ca-276b-ec64-e3fb-12bafc8a2f53.png)

しかしなぜか`401エラー`が発生してしまいます。

一方、先輩は以下のリクエストで問題なく行えていました
ヘッダーやボディーなどの項目は全く同じでした

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/efe61370-884c-de72-6ea5-aa45e16921ab.png)

なぜか私の環境だと送れなかったので、調査を進めました

# 解決方法

まずはデバック方法について説明していきます。
今回は先輩が実際に送って200OKが返ってきているのでその違いを確認すれば良さそうです

まずはPostmanのCurlコマンドで2つのリクエストを比較してみます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/4fd8673a-74e2-a372-74f7-52d126ae2e92.png)

私のバージョンでは`<>`マークをクリックすることでコード出力ができました

まずは動いているほう

```
curl --location --request POST 'http://localhost:3000/v1/auth/sign_in' \
--form 'email="test2202181@gmail.com"' \
--form 'password="password"'
```

次に動いていないほう

```
curl --location --request POST 'http://localhost:3000/v1/auth/sign_in  ' \
--form 'email="test2202181@gmail.com"' \
--form 'password="password"'
```

よくみるとアクセスしているURLにスペースが2つ空いていることがわかりました

このスペースをなくしたところ問題なく動きました


# さいごに

Postmanのデバック方法について今回の問題を通して知ることができました
同じような状況が発生したらコードから確認するを試してみてください
docker build時のapt-get updateでGPG errorが出る場合の対処 

今までビルドがうまくいっていたDockerfileで久々にdocker buildを行なうとなぜかエラーが出る場合がありますよね。今回はapt get update でGPG Errorが出た場合の対処方法を解説します（と言っても一瞬で完了）

まずDockerfileは前半部分の例を一部切り取って下記に掲載します。
```dockerfile
FROM nvidia/cuda:11.2.0-cudnn8-devel-ubuntu18.04
LABEL Hogehoge <hogehoge@hogehoge.com>
ENV API_ROOT /home
ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get clean
RUN apt-get update
RUN apt-get install -y  --fix-missing \
    build-essential \
    wget \
    bzip2 \
    git \
    gcc \
    g++ \
    cmake \
    pkg-config \
    checkinstall \
    libssl-dev \
    libreadline-gplv2-dev \
```

過去にビルドしたときはうまくいっていたのに今回はなぜかapt-get updateでこのようなエラーがでます。

```bash
W: GPG error: https://developer.download.nvidia.cn/compute/cuda/repos/ubuntu1804/x86_64  InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY A4B469963BF863CC
```

このようなときはBase imageの最新版をpullしなおせばエラーが解決します。

```bash
$ docker pull nvidia/cuda:11.2.0-cudnn8-devel-ubuntu18.04
```

過去にdocker pullしていたBase imageの中に適切なpublic keyがないためこのようにして最新版のBase imageに更新する必要があります。