OmniAICreator/Qiita-1.07M huggingface dataset:
【UiPath】謎のハッカー風操作をしてみる＃4（データアップロード）

# はじめに

この投稿は、RPAツール「UiPath」での 実装例 について記事です。

UiPathのコミュニティ「UiPath Friends」が企画する「UiPathブログ発信チャレンジ2021サマー」の 30日目の投稿でもあります。

企画の内容は [**こちら**](https://note.com/shumpei_w/n/n651cbdbec4e8) 。カレンダーのURLは [**こちら**](http://u0u1.net/sUwZ) です。

https://twitter.com/ShumpeiWatanabe/status/1405168150736359427


# 謎のハッカー風操作

前回に引き続き、よく映画で見る「ハッカーがやってそうな操作」をUiPathでしてみます。

それっぽく見えれば良いので、操作に意味はありません。

シリーズになっています。前回までの投稿はこちら。

https://qiita.com/miya_gis/items/a304d6d4600d63e98314

https://qiita.com/miya_gis/items/e78b03923954ff4920f1

https://qiita.com/miya_gis/items/0676d0c48201e2aee78f

操作のイメージは以下のような感じです。

<iframe width="560" height="315" src="https://www.youtube.com/embed/EeYmih4uDho?start=10" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

# 謎のデータアップロード

前回の投稿で「データのダウンロード」を作ったので、今回はそのデータを「アップロード」しているように見せます。

ローカルフォルダにある画像を、大量にアップしているように見せるため、途中で進捗状況を見せます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/16f68133-516e-f988-cfe5-4f4556ad7c0d.png)

作成したフローはこちらです。
![e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/6cb80120-9e3e-bd7f-ed87-9fcda7d80f61.png)

実際に動かすと、以下のようになります。

![uianime8.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/65a29869-155c-9b47-f23d-f65e321be178.gif)

# 終わりに

いかがでしたでしょうか？
あまり役に立ちそうにないですが、UiPathではこんな 遊び方／見せ方もできます。

この記事が参考（？）になったら、LGTM をお願いします。
最後までご覧いただき、ありがとうございました。
【DRF（Django REST framework）】serializerのフィールドにmany=True指定時のrequired=Trueのバリデーションが想定と異なる

## 環境
- djangorestframework：2.4.0

## 問題のコード
- 下記のようなシリアライザーを定義した
- デフォルトで`required=True`のはずなので、tagを`NULL`で渡したときにバリデーションエラーになると考えた

```python
class MediaSerializer(serializers.Serializer):
    tag = TagSerializer(many=True)
```

- こんな感じのJSON

```json
{
  "tag": null
}
```

- しかし、結果はバリデーションエラーにならず処理が進んでしまった
- `required=True`を定義しても結果は同じ
- 動作検証をしたところ、バリデーションエラーになるのは`tag`キーがない場合のみ

|パターン|バリデーション|
|:--|:--|
|`tag`キーがない|NG（バリデーションエラー）|
|`tag`がNULL|OK|
|`tag`が空データ|OK|


- DRF公式サイトを読んでも、それらしき記事は見つからず
- 代わりにstag overflowに[こんな記事](https://stackoverflow.com/questions/30479563/djangorestframework-not-validating-required-true)があった


## 対策
- tagのバリデーション関数を用意して、NULL or 空データをチェックする
- DRFのバージョンが古いから発生するのかな。。。

```python
class MediaSerializer(serializers.Serializer):
    tag = TagSerializer(many=True)

    def validate_tag(self, attrs, source):
        if not attrs.get(source):
            raise serializers.ValidationError("NULL or 空データだよ")
        return attrs
```
【UiPath】祝日を判定する

# はじめに

この投稿は、RPAツール「UiPath」の 実装例 の記事です。
良くある実装ですので、参考程度に。

UiPathのコミュニティ「UiPath Friends」が企画する「UiPathブログ発信チャレンジ2021サマー」の 30日目の投稿でもあります。

企画の内容は [**こちら**](https://note.com/shumpei_w/n/n651cbdbec4e8) 。カレンダーのURLは [**こちら**](http://u0u1.net/sUwZ) です。

https://twitter.com/ShumpeiWatanabe/status/1405168150736359427


# 祝日をどうやって判定するか

ざっくり言えば、以下の2択だと思います。

```
- 1）ネット上にある「祝日リストAPI」を使用して判定
- 2）自分で「祝日リスト」を管理して判定
```

「1」の場合、APIの情報が古かったり、特別休暇日を設定出来ないなどの課題があります。そのため大抵の場合は「2」の方法に落ち着きます。

また、「Orchestratorの非稼働日設定があるから、それで祝日を管理しよう」という案も出ますが、止めたほうが良さそうです。
この機能は「Orchestrator上のジョブの非稼働日」を定義するためで、用途が違います。「非稼働日制限を適用」をオフにすれば制限は受けませんが、それだと「非稼働日」の機能ではなくなってしまいます。

※ 「祝日＝非稼働日」とするなら、利用できるかも知れません。
※ DataServiceに祝日リストを入れるという形でも良いかも知れません。
※ Googleカレンダーの「日本の休日」を使用するのもありかも知れません。

と、色々考えていくと、Excelで祝日を管理するというのが、その「簡単さ・確実さ」で考えると「妥当」かと思います。


# Excelシートの祝日リストで判定する

一番オーソドックスなのがこの方法だと思います。リスト管理して、データテーブルで読み込んで、判定します。
シートはこんな感じだと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/728756e0-0536-9660-fde5-dbe8070a2db7.png)

会社や組織によって、創立記念日などを祝日扱いにする日があれば、上記に行を追加します。

読み込む xaml ワークフロー側は以下のようなものです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/96fd3437-473d-5182-a0e6-b7af51b5b4c8.png)

このワークフローを呼び出せば、祝日かを判定できます。

問題点として「呼び出すたびにエクセルシートを再読込してしまう」のがちょっと残念です。なので「読み込み」は1回で済むようにしたワークフローを以下で公開しています。

https://marketplace.uipath.com/listings/1424

どうやっているかというと、アプリケーションリソース領域にデータテーブルを格納し、2回目以降の呼び出しでは、シートは読まずにメモリからデータテーブルを取得しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/0d315814-5afb-fe55-6978-db2248e02e27.png)

この「アプリケーションリソース」を使用した実装は、乱用するとメモリの衝突に繋がり、また可読性の低下につながるので、推奨はできませんが、使用方法をピンポイントに絞った仕様であれば使っても良いと思います。「推奨はできないが自己責任で」というスタンスだと思います。


# 終わりに

いかがでしたでしょうか？実装の参考になれば幸いです。
この記事が参考になったら、 LGTMをお願いします。閲覧ありがとうございました。
Pythonで辞書を使ってエクセルに書き込む

# はじめに
openpyxlでエクセルにリスト（２次元配列）の書き込みを行う場合において，辞書で書き込みをするとオシャレになります．

```python:excel.py
import openpyxl

wb = openpyxl.Workbook()
ws = wb.worksheets[0]

# ここに書き込んでいきます

wb.save('sample.xlsx')
```

# リストでの書き込み
リストを使ってエクセルに書き込みます

```python:list_excel.py
def write_list(ws, row, col, list_data):
    for y, list_value in enumerate(list_data):
        for x, value in enumerate(list_value):
            ws.cell(row=row+x, column=col+y, value=value)

list_data = [['nature', 1, 2, 3], ['prime', 2, 3, 5], ['Even', 2, 4, 6]]

write_list(ws, 1, 1, list_data)

#[('nature', 'prime', 'Even'),
# (1, 2, 2),
# (2, 3, 4),
# (3, 5, 6)]
```

# 辞書での書き込み
辞書を使ってエクセルに書き込みます

```python:dict_excel.py
def write_dict(ws, row, col, dict_data):
    for y, (key, list_value) in enumerate(dict_data.items()):
        ws.cell(row=row, column=col+y, value=key)
        for x, value in enumerate(list_value):
            ws.cell(row=row+1+x, column=col+y, value=value)


dict_data = {'nature': [1, 2, 3], 'prime': [2, 3, 5], 'Even': [2, 4, 6]}

write_dict(ws, 1, 1, dict_data)

#[('nature', 'prime', 'Even'),
# (1, 2, 2),
# (2, 3, 4),
# (3, 5, 6)]
```

# 最後に
良きpythonライフを

# 参考
- 投稿者：https://github.com/Hayate-Leo/python-tool
- https://note.nkmk.me/python-openpyxl-usage/
BoxFitでcoverやfitWidthを指定しているのに両サイドにスペースができる場合の対処法

# 結論
widthを設定しましょう

```dart
Column(children: [
  Expanded(
    child: SizedBox(
      child: Image.network(
        'path',
        fit: BoxFit.cover,
      ),
    ),
  ),
  Expanded(
    child: SizedBox(
      width: MediaQuery.of(context).size.width, // この一行を追加
      child: Image.network(
        'path',
        fit: BoxFit.cover,
      ),
    ),
  ),
]);

```
おめでとうございます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589461/cdbde791-199e-bb29-4f41-1bf94fec5235.png" width=400>
サーバー仮想化とESXi <忠誠心が強い太郎くん>

Aカンパニーで働く太郎さんはこんな悩みを抱えていました。
「僕の会社はサーバが8台あるけど、どのサーバもリソースを30%も使っていない。もう少し効率良くできないのかな。。。」
太郎さんは会社への忠誠が強かったので会社のために調べてみた。
するとあるキーワードを見つけた。それは、**サーバ仮想化**だ。
「もしやこれは！」と思い調べていくと太郎さんはニヤリとした。
サーバ仮想化が太郎さんの悩みの解決策であったからだ。
サーバ仮想化とは言葉通り、物理的には存在しない仮想上のサーバを実在するサーバとして扱う技術だ。

#サーバ仮想化とは
詳しく見ていこう。
物理的に8台のサーバがある会社のサーバを2台に減らすこともできる。
まず、2台のサーバの上に**仮想化ソフト**を置く。
そうするとこの仮想化ソフトの上に**仮想化マシン**を立てることができる。
この仮想化マシンが元々物理的に存在していた8台のサーバだ。
つまり、2台のサーバの上で動く8台の仮想化マシンが仮想化サーバだ。
そして何よりも太郎君を惹きつけたのが仮想化サーバのメリットだ。

#サーバ仮想化のメリット
まず、仮想化サーバは**リソースの効率化**ができる。
仮想サーバのリソースには物理サーバのリソースを割り当てる。そのため、20しかリソースを使わない仮想サーバには30を割り当て、50リソースを使う仮想サーバには60のリソースを割り当てるなどリソースの割り当てが自由自在だ。
他にも、物理的なサーバが減るということはサーバの維持管理費や必要な敷地面積も減るだろう。

#サーバ仮想化のネットワーク構成
「サーバ仮想化！なんて素敵なんだろう」と思った太郎君であったが、1つ疑問に思ったことがあった。
それは、**ネットワーク構成はどうすればいいんだろう？**ということだった。
太郎君の疑問に答えよう。
まず、仮想マシンは仮想上のNICを持つ。**vmNIC**と呼ばれる。
仮想マシンはこのvmNICを本物のNICだと思い機能する。
しかし、仮想上のNICではネットワークに出ることはできない。しかし、大丈夫。仮想マシンのvmNICは仮想化ソフトの**vスイッチ**に繋がる。
そしてそのvスイッチが物理的なサーバのNICに繋がるため仮想マシンもネットワークに出れるのだ。
太郎君は一安心してもっと深く調べていくとESXiというサーバ仮想化でNo.1のシェアを誇る仮想化ソフトを発見した。

#ESXi
ESXiの魅力を**「vCenter Server」****「vMotion」****「HA」**という3つのキーワードで紹介しよう。

##vCenter Server
vCenter Serverは仮想マシンを一元管理するための仕組みだ。**ESXiの司令塔**とも言える。
vCenter Serverがリソースの効率化を実施したり、後述するvMotionを行ったりする。

##vMotion
「片方の物理サーバをメンテナンスしたい」
こんなことがあったとする。この時、片方の物理サーバの上で動いていた仮想マシンはどうなるのか。一回止めなきゃいけないのか。でも、一回止めるだけで社内に大きな影響が出るだろう。こんな時にvMotionを行えば仮想マシンを停止することなくもう片方のサーバに移動できる。**計画的に仮想マシンの移動を行う**のがvMotionだ。

##HA
HAはvMotionと似ている。vMotionは計画的な仮想マシンの移動だった一方、HAは**非計画的な仮想マシンの移動**だ。
片方のサーバに障害が発生して電源が落ちてしまった。「やばい、そのサーバの上でたくさんの仮想マシンが動いている。急いでもう片方の物理サーバで仮想マシンを動かさなきゃ。」
HAを使えばこんな心配は不要だ。HAでは片方の物理サーバが落ちたら、自動的に動いているもう片方の物理サーバに仮想マシンを移動させてくれる機能だ。なんともありがたい。

#最後に
ESXiは他にも便利な機能がたくさんあるが紹介しきれないのでここら辺にしとこう。
太郎君も仮想化サーバのメリットを実感し、「ESXiを利用してみることを社長に提案してみよう！」と意気込んでいる。
いい社員だ。
Before starting UiPath:プロセス名は大事

## 皆もすなるQiitaといふものを、儂もしてみむとてするなり。

と言う訳で、こん＊＊は！はなっち！です。

★★★この記事はUiPathブログ発信チャレンジ2021サマー、7/30の記事です。★★★

今回は、ちょっとしたシリーズです。UiPathを使うに当たって、UiPathの機能ではなく、コンピュータ言語を使う上での基礎知識を展開していこうと思います。

#プロセス名は大事

UiPathで、ロボットの名前を「プロセス名」として認識します。

プロセス名：命名に使用できる文字コードは、UiPathのソフトウェア要件を満たすOSに準拠したものになります。
　　　　①：ダメ
　　　　┤：ダメ
　　　　﨑：使える
　　　　∑：ダメ
　　　　Σ：使える
　　　　★使えない文字は、入力した時にエラーが出ます

新たにプロセスを起こすと、
　　　　１．プロジェクトフォルダとして、フォルダが作成されます。
　　　　２．そのフォルダの中に、最低限必要なファイル(project.jsonなど)が生成されます。
　　　　３．プロセスプロジェクト名は、project.json中に展開されます。
　　　　４．このプロセスプロジェクト名は、PUBLISH時のプロセス名になります。

「空のプロセス」を作ってから試しにロボットを作っていき、ある程度実装のメドが立ったらちゃんとした名前にしていくケースもあるかと思います。
その際には、以下のことに注意ください。
　　　　１）「空のプロセス」フォルダを、「正しいプロセス名」に改名してください
　　　　２）その中にあるproject.json中の"name"を、「正しいプロセス名」に書き換えてください。
　　　　　　その際、「①」のように使えない文字も使えてしまいますが、PUBLISHした時に認識されない文字になってしまいます。
　　　　３）保存の際には、UTF-8コードであることを確認してください。
　　　　４）「正しいプロセス名」のロボットをStuidoで開いて、PUBLISHした時のログ上の名前が「正しいプロセス名」になっていることを確認ください。

【追加情報】
調査の結果、UiPathのソフトウェア要件を満たすOSに準拠した、使用できる文字カテゴリは、以下の通りです。
　　　　Ll（字、小文字）
　　　　Lu（字、大文字）
　　　　Lt（字、タイトル文字）
　　　　Lo（字、その他）
　　　　Lm（字、修飾）
　　　　Mn（結合文字、幅なし）
　　　　Nd（数、10進数字）
　　　　Pc（句読点、接続）

使用とする文字が、どのカテゴリに含まれているかを調べるには、
　　　　https://www.compart.com/en/unicode
で調べられます。このサイトにアクセスして、調べる文字を入力し、その結果のCategoryをご覧ください。
★例えば「①」は、Category:Other Number (No)となり、情報に存在しないので、使えない文字である事が分かります。

##おわりに
いかがでした？

通常のロボットの作り方では、プロセス名を入力する際にチェックしてくれるのですが、project.jsonファイルの中身を書き換えることでプロセス名を変えることができます。
その際に、UiPathのプロセス名で使えない文字を使用して設定し、思っているプロセス名と実際のプロセス名が違うって事が発生してきます。名前は重要です。
因みに、はなっち！は「はなっち」ではなく、「！」を付けた「はなっち！」が正しい名前です。

是非UiPathでのロボ開発の一助になればと思っています。

ありがとうございました！
Power BI : The Definitive Guide to DAX (英文本)を読む理由

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/7b309222-1aa9-7184-97da-83407c00c272.png)

---
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/7d56bfa0-c51f-34d4-b750-0d7ccf7054ab.png)
1

---
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/6bdc7fe3-c19c-6582-1498-ce1899f22758.png)
2

---
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/1c0ea08e-51c1-1272-e59e-7434988bf315.png)
3

---
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/d77a9e63-922e-4026-7f47-1921c3927d17.png)
4

---
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/3e135bfe-3547-9fac-b83f-9e23f621e42a.png)
5

---
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/31e1fec0-94e5-0da6-0fb6-f472e3fc784a.png)
6

---
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/e8b85012-1d91-e063-0ce0-5453fc48621b.png)
7

---
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/e5d2aae3-3958-ae6b-9c22-77b99273c8e0.png)
8

---
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/cb64b832-8073-b385-6c36-74987ddddde3.png)
9

---
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/1b723514-ce4b-33cc-2576-7cf26307163a.png)
10

---
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/f783a6ef-85cc-71d0-233c-ae9252a87428.png)
11

---
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/950e68cf-9e8b-0156-9504-c78fab7f59fe.png)
12

---
Laravelでinput,select,checkboxの値を取得する方法


### input 
- view

```html
<input name="name" value="hoge">
```

- controller

```php
public function namae(Request $request)
{
    $name = $request->input('name');

    echo $name;
}
//出力結果　
//hoge

```

###select
- view

```html
<select name="age">
    <option value="20" selected>20歳</option>
    <option value="30">30歳</option>
</select>
```

- controller

```php
public function nenrei(Request $request)
{
    $age = $request->age;

    echo $age;
}
//出力結果
//20

```

###checkbox

- view

```html
<input type="checkbox" name="color[]" value="red"　checked>
<input type="checkbox" name="color[]" value="yellow" checked>
<input type="checkbox" name="color[]" value="green">
```
name属性にカッコをつけてあげます。カッコつけないと値が1つしか入りません。


- controller

```php
public function iro(Request $request)
{
    $colors = $request->input('color');

//このとき$colorsは配列になっています。
    foreach($colors as $color){
        echo $color."\n";
    }
}
//出力結果
//red
//yellow
vuexで管理しているデータをCookieに保存して簡単には消えないようにする

※この記事は5分で書きました && 読めます

筆者、Nuxtでグローバルなstate管理にvuexを用いていました。
ログイン情報やユーザー情報をvuexに保存していたのですが、vuexは標準でリロードすると消えてしまうので
なんとかブラウザに残したいところでした。
<br>

リサーチしてみると、

・サーバーサイドでセッションを持ってクライアントからリクエストを送りそれを参照する
・（外部プラグイン、モジュールを追加するなどして）vuexのデータを保持する

のふたつに分けられるようで後者の場合
・セッションストレージ
・local storage
・Cookie
が選択肢としてありました。

## 「サーバーサイドでセッションを持ってクライアントからリクエストを送りそれを参照する」について

筆者のケースですが、プロダクトの開発初期でサーバーサイドをプロジェクト分けて開発するのが面倒だったのでNuxt内でフルスタックで開発しています。
どちらにせよBFF（SSR）は持つ予定だったので、一時的にフロントで持つべきでない処理も全て書いています。
つまり、のちのちサーバーサイドは移行する予定で書いています。移行タイミングはかなり不明確です。

設計的にセッションをフロントとバックでどちらで持たせるべきかなど悩んでいましたが、上記事情とフロントでログイン状態を扱うほうが良さそうな気がしたことから一旦この選択肢は捨てました。

## vuexのデータを保持する
調べると[vuex-persistedstate](https://github.com/robinvdvleuten/vuex-persistedstate)を導入する記事が多く目にあたると思います。
英語で「vuex cookie」など検索してもこれが上位に出てきます。

永続化はしたくなくセッションではユーザー体験悪いので、
Cookieだなと決断しまして[vuex-persistedstate](https://github.com/robinvdvleuten/vuex-persistedstate)をyarn add、nuxt.config.jsのmodulesへの追加と[公式サンプルのCookie x Universalの例](https://github.com/robinvdvleuten/vuex-persistedstate#using-cookies-universal-client--server-side)を参考にしてplugins/persistedState.jsを追加します。
pathsのところはvuexのstateに

```hoge.js
export const state () => ({
  hoge: '',
  hogehoge: '',
});
```

など書いていればstore.hogehogeなどでアクセスできると思うので配列に突っ込みます。
keyは'hage'など指定してあげます。Cookieで保存したりsetItemでアクセスする際に用いられるkeyです。

そうすると自分の環境ではうまくいったように感じたのですがしばらくたって確かめてみるとgettersでアクセスできなくなっていました。
調べるとこの記事がありました。
https://noumisoblog.com/vuex-persistedstate-nuxt/#toc4
これで解決できる方もいるかもしれませんが、バリデーション後にaxiosを発火してvuexに保存している自分のケースでは解決できませんでした。

## 結論
[js-cookie](https://github.com/js-cookie/js-cookie)を使いましょう。vuexの記述にgetやsetなどをよしなに追加するだけです。
上で挙げた[公式サンプルのCookie x Universalの例](https://github.com/robinvdvleuten/vuex-persistedstate#using-cookies-universal-client--server-side)を見るとわかりますがクライアントだけでcookieを扱う分には特に[vuex-persistedstate](https://github.com/robinvdvleuten/vuex-persistedstate)を使う理由も無いのかと。

これで落ち着いてクッキーを食べられますね。
余談ですが5分で書きましたは嘘でした。
Git・Githubについて

##Gitとは
プログラムのソースコードなどの変更履歴を記録・追跡をするための分散型バージョン管理システムである。
###できること3選
####①ファイルのバージョン管理
任意のタイミングでファイルの状態を記録できる。
>ファイルはひとつだけどメタ情報としていつ・誰が・どんな変更をしたのかが保存されている。
ファイルは常に最新でありながら変更の記録を確認することができる。

####②以前の状態に戻せる
変更の記録を使って前のバージョンにすぐに戻すことができる。
####③チームでスムーズに開発できる。
思わぬ上書きを防止できる。
>複数人の共同編集は事故りやすい。
誰かが気が付かずに修正を上書きしてしまうことがあるため。

##Gitの基本的操作の流れ
![Gitの操作の流れ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797153/ed82aa47-183a-1979-7e36-28d29be83f22.png)

##ローカルの基本操作①初期化
![ローカルの基本操作・初期化.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797153/c5a947b3-9548-1c1d-1751-c7efba4a93a4.png)
ローカルにGitの変更を記録するファイルを作成する。
$ git init
##ローカルの基本操作④
![ローカルの基本操作②.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797153/7d24b6b3-b8c2-3f6d-f0da-c9f1f190b07c.png)

ワークツリーとは
お手元の作業環境のこと
ステージとは
コミットするためのファイルの事前置き場
リポジトリとは
変更履歴を記録する場所
add
commit

$ git add .
$ git commit -m
##ローカル基本操作（状況確認）
![ローカルの基本操作③.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797153/e9fdb510-9d03-167b-e545-63a7e1fca3d9.png)
何のファイルを変更したか確認できるようになっている。
diff 変更内容をチェック
status 変更ファイルをチェック
![git状態確認コマンド.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797153/ecf8be7c-b506-d120-c08c-7b8efbdca93c.png)

##ローカルの基本操作④履歴の確認
$ git log　コマンド
![git変更記録の確認.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797153/d5078d35-4d86-87cd-1929-8be3a48c91c4.png)
#ローカルの基本操作⑤元に戻す
![ローカルの基本操作⑤元に戻す.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797153/c22f242b-e43c-01de-1d8a-b2ae13070939.png)
$ git restore <ファイル名>
ワークツリーの変更を取り消す

$ git restore -staged <ファイル名>
ステージにあげた変更をワークツリーに戻す
![git元に戻す.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797153/1796b2bf-c073-ed59-de2d-e3aaf6e0b926.png)
Savings Plans とは

## 勉強前イメージ

リザーブドインスタンス的なやつ？

## 調査

### Savings Plans とは

1年または、3年契約期間中、特定1時間あたりの使用量を契約することで、
その使用量に対して割引を受けられる料金体系です。

例えば、1時間20ドル使用する契約を購入した場合、以下の費用で使用することができます。
20ドルまでの使用量 → 大幅な割引が適応される
20ドル以上の使用量 → オンデマンドの費用

割引率はEC2インスタンスでは最大72%、Fargatreでは最大52%、
lambdaでは最大17%の割引を受けることができます。

### Savings Plans のタイプ

- Compute Savings Plans

柔軟性があり、最大66%削減できるプランです。
インスタンスファミリーやタイプ、リージョンやOSに関わらずEC2インスタンスに適応されます。
EC2インスタンスだけでなく、Fargateやlambdaにも適応されます。
EC2からFargatehの移行へ関しても割引対象となります。

例としてCompute Savings Plansでの購入の画面になります。
期間と時間単位のコミット、支払いオプションを選択します。

![1Cost Management - Google Chrome 2021-07-28 17.18..png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/89712faf-f1be-a4f0-a78d-631f33850cfd.png)


- EC2 Instance Savings Plans

特定のリージョン内の特定のインスタンスファミリーに適応されます。
最大の72%の割引が適応され、OSやサイズに関わらず自動でコストが削減されます。
リージョン間の移動やインスタンスファミリーの変更は対象外ですが、
リージョンとインスタンスファミリーさえ決まっていればお得なプランになります。
こちらはEC2のみで、Fargateとlambdaに関しては対象外になります。

以下が例としてEC2 Instance Savings Plansでの購入画面になります。
Compute Savings Plansとは違い、リージョンとインスタンスファミリーの選択肢が増えました。

![2Cost Management - Google Chrome 2021-07-28 17.22.4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/db2f57e7-427c-8acf-74ae-05273fac6f4c.png)


### リザーブドインスタンスとの違い

Savings Plans と リザーブドインスタンスとの違い

- Savings Plans → `一定のリソースを一定時間使用する事` で、購入した分の割引を受けることができる。
- リザーブドインスタンス → `特定のインスタンス・インスタンスファミリーを使用する事` で、購入した分の割引を受けることができる。

例えばSavings Plansで10ドルの契約をしていたとして、実際のEC2は20ドル毎時しようしていたとすると
Savings Plans では割引を受けることができないが、
リザーブドインスタンス では、指定のインスタンスを使用していれば割引を受けることができます。

## 勉強後イメージ

`一定の処理量を使用することで` 割引を受けることができる のが Savings Plansってことか。
ただ、lambdaとかforgateとかも使用してるなら色々使えて良いかもしれない。


## 参考

- [柔軟に低価格でAmazon EC2を使用できる Savings Plansとは](https://www.acrovision.jp/service/aws/?p=990)
- [AWSのリザーブドインスタンスとは？適用のされ方や注意点について解説](https://www.yume-tec.co.jp/column/awsengineer/4473)
テストコードに関するポエム

# 前置き
新卒で、小さな小さな自社パッケージソフト開発の会社に入社。
その後転職してSES企業に入社し、客先常駐エンジニアに転身してもうすぐ３年になります。
３年間の間、複数の案件を渡り歩き、ふとテストコードに関するポエムを書きたくなりました。

そもそもテストコードとは、テストコードを書くべきかとか、テストコードを書く意義、そもそもTDDという手法があってな...といったところは世の中でさまざまに語られているので、ここで私が今更論ずることも無いですが、私個人としてはテストコードは絶対に書くべきだと思っています。  
ただ、テストコードを書くと言っても以下まで実践しないとテストコードの効果を最大限発揮できないだろうと考えています。  

1. テストコードを書く
2. テストコードを共有する（Git,SVNにコミットする）
3. テストコードをCI/CDの仕組みに乗せてコミット時やリリース時に逐次自動実行させる

そもそもこの辺りも、世の中のスタンダード的には常識過ぎて何を今更といったところだと思いますが、私が３年間の間に見てきた現場ではそうではありませんでした。
これが今回このポエムを書きたくなったきっかけです。  

# これまで経験した現場のテストコードに対するスタンス

これまで経験してきた現場のテストコードに対するスタンスは以下のような状況でした。

## 1
- そもそもテストコードを書くという土台、文化がない。

## 2
- 単体テストを通すためだけにテストコードを書く（単体テストを通す=カバレッジを100%にする）。
- でもテストコードはソースコード管理ツールにコミットしない。
- CI/CDの仕組みは無いのでテスト自動実行をしない。
- 要は使い捨て。
- WF開発で、単体テストフェーズ以降では使用しない。
- よって、製品コードもテストコードでテストする前提で実装しない。インターフェースなどを使用して依存性を排除したりはしない。
    - コード内で`DateTime.Now`が書かれていたりした
    - Microsoft.Fakes が使えたのでこの辺はMock化してテストした
 
## 3
- テストコードを書いて実行させることを単体テストとしてよい。
- ルールにはしていない。テストコードを書くかは開発者の任意。ただし、テストコードはコミットしてはいけない=共有しない。
- テストプロジェクト自体はあるんだけど…なんで？
- Repository は インターフェースで抽象化されているが、Service クラスは Controller の中で new している…なんで？
    - 自分の担当分はテストコードを書きました。外部サービス、DBにも依存したままでしたが。
    - Controller、Service のメソッドを１つずつテストコードで動作確認するような形で作業を進めました。  

## 4
- テストコードを書いて Git にもコミットして共有する。
- 単体テスト=テストコードの実行。
- だけどCIが無いためローカルで開発者が逐次手動実行するだけ。

大まかに以上のような感じでした。
要するに、前述の**テストコードを書いてCI/CDに乗せて自動実行させるところまでできている現場は１つも無かった**のです。

|#| テストコードを書く | 共有する | CI/CDで自動実行する |
|---|---|---|---|---|
|1|☓ | NA | NA | SVN、GitHub |
|2|○ | NA | NA | GitLab |
|3|○ | ○ | NA | GitLab |

そもそも前のステップを踏んでいないと、次のステップは実行できないですね。

3のパターンに関しては非常にもったいないなと感じてしました。
MVCのWebアプリケーションだったのですが、各レイヤー感の依存性は排除されていてテストコードも書きやすく、ソースコード管理は GitLab を使用していたので、CI/CDの仕組みに乗せるのはやろうと思えば出来たはず…

そう感じていたのであれば、CI/CD出来るよう提案したら？という声が聞こえてきそうですが、
規模が大きい案件で私のような末端の１開発者が声を上げられるような状況では無かったのです…
お察しください。

# 自社開発のときはどうしていたか

当時、自社開発企業在籍時はソースコード管理に Microsoft の Team Foundation Server を 利用していました。  
利用していくうちにまずは自動ビルド、その次にテストコードを書けば自動ビルドしたあとにテストも自動実行できるっぽいぞ、こりゃすごい！と段階的に気づきながらいまでいうCI/CD環境を構築してました。  
※当時はCI/CDという単語は世の中的にもまだ聞いたことがなく、TFSのドキュメントだと「ALM（アプリケーション・ライフサイクル・マネジメント」と書かれていたのを記憶しています。

自動ビルド・テスト自動実行は１日１回実行していました。
自動ビルド導入後は、これまで手動で配置していたテスト、リリース用アプリの配置も自動化して効率化アップ。
レガシーなシステムだったのでテストコードもコアロジックの部分だけなんとか実行できるようにしていただけだったのですが、それでも大規模な回収があるときはデグレを何度も発見してくれて、効果は絶大でした。

この辺り、自社開発だったのでこうしたパイプライン構築なんかは自分の裁量である程度やれていたのは自由度は高くて良かったなあ…と懐かしんでしまいます。

# 今後

前述の自社開発でのテストコードに関する成功体験があったので、テストコードを書く文化ではない現場、CI/CDの無い現場を見るとモヤモヤしてしまう気持ちが強いのかもしれません。  
経験年数的にはそろそろこういった部分も提案できるようなレベルのエンジニアになっていかないとなあ…と感じております。
Storybookを運用する上でのマインドセット

# はじめに

Storybookは、WebフロントエンドのUIコンポーネントカタログを作成する強力なツールです。しかし、どんなツールであっても、これを運用し、継続的にメンテナンスしていくのには作業コストが発生します。

Storybookの運用に関わる人は、このツールから得られる恩恵と、得られないものを適切に認識しておく必要があるでしょう。

この記事では、Storybookの具体的な書き方ではなく、その前提となるマインドセットについて、私見を述べていきます。もちろんここで書かれることはコミュニティの公式見解などではなく、あくまで私個人の一意見として受け取っていただけると幸いです。

なお、ここではあくまでStorybookを前提に話を進めますが、マインドセットとしては、flutterのmonarch運用などにも通ずるものがあるかもしれません。

# Storybookがもたらす恩恵

Storybook公式には次のコピーが掲げられています。

> Storybook is an open source tool for building UI components and pages in isolation. It streamlines UI development, testing, and documentation.
> https://storybook.js.org/

拙訳：StorybookはUIコンポーネントおよびページを分離して構築することで、UI開発、テスト、およびドキュメンテーションを合理化するオープンソースツールです。

ここから、Storybookの目的には3つの要素があることがわかります。

1. UI開発時のプレビュー用途
1. UIのテスト用途
1. UIのドキュメンテーション

これらは既に目的でもありますが、さらに大きな目的への手段でもあると言えるでしょう。

1. なぜプレビューするのか？→UI開発の高速化
1. なぜテストするのか？→アプリケーションの品質向上（バグ低減）
1. なぜドキュメンテーションするのか？→コミュニケーションコストの低減

以上の恩恵を、「インタラクティブなUIコンポーネントカタログ」という形で実現しているのが、Storybookの利点であり価値です。これらのメリットがあるということを、まずは認識しましょう。

## とはいえ、メンテナンスは大変

上記のメリットをすべて享受することができるのがStorybookの強みではありますが、実際にはどこにフォーカスするのかを決めておいたほうが、メンバーがStorybookをメンテナンスするモチベーションにつながると思われます。

たとえば、UIの実装に当たって、ローカルでのサーバ立ち上げと実際の画面上での実装に慣れているメンバーからすれば、1のメリットはさほど大きく映らないでしょう。

ドキュメンテーションに関しては、「誰向けのドキュメントなのか」ということを意識する必要がありそうです。たとえば、デザイナーとのコミュニケーションにコンポーネント名という共通言語を使用する目的であれば、有効に働きそうです。
API仕様書のようにStorybookを作ることももちろん可能ですが、これはデザインシステムを作る際には便利であるものの、手元で参照できるアプリケーションコードがあるのであれば、TypeScriptの型情報を見る方が早かったりするでしょう。

# Storybookが提供しないもの

Storybookを利用するメリットがわかったところで、この優秀なツールが提供しないものについても認識しておきましょう。

## 最終的な品質担保にはならない

Storybookは、あくまで「所与のパラメータに対して任意のUIコンポーネントがどのようなレンダリング結果を返すか」を確認する道具です。

ですから、これによってアプリケーションの振る舞いや、外の世界（≒バックエンド）とのやり取り結果を測ることはできません。

やはり、アプリケーションとしての品質を担保するには、別途E2Eテストが必要となるでしょう。テストとしてのStorybookは、すなわちUIの静的な単体テストであると捉えましょう。

## デリバリーされるものではない＝ユーザ体験の直接的な向上には寄与しない

当たり前の話ですが、Storybookはあくまで開発補助ツールです。最終成果物ではありません。

ユーザへの価値提供を第一とするWebサービスにおいては、体験そのものにはつながらない、あくまで補助的な役割を果たすのみであると認識しましょう。

## プラグインについて

Storybookにはさまざまなプラグインが用意されいますが、これらを導入する際は、メンテナンスコストや得意なこと・苦手なことについて意識するようにしましょう。

たとえば、[Storyshot](https://storybook.js.org/docs/react/workflows/snapshot-testing)とJestを組み合わせれば、Storybookによるレンダリング結果を用いてスナップショットテストを実行できるでしょう。しかし、ドキュメンテーションとしての役割を重視するのであれば、余計な差分がスナップショットファイルの中に含まれてしまう可能性が大きくなります。

[controls](https://storybook.js.org/docs/react/essentials/controls)くらいは当たり前に入れてもいいんじゃないか、という向きもあるかもしれません。しかしこれにしたって、「宣言的UIに与えるパラメータをインタラクティブにすること」がどれだけ効果を発揮するかを考えたほうが良いはずです。Storybookのファイル作成手続きが面倒になると、次第にメンテナンスされなくなる可能性が高まっていきます。十分に気をつけましょう。

# おわりに

Storybookは、メリットも多いですが、メンテナンスが大変なツールです。あなたたちの組織が、Storybookがもたらすどのメリットを欲して導入しているのかが定まれば、自然に書き方も定まっていくでしょう。

私の意見ですが、大切なのはルールを決めすぎないこと、PRに含まれているすべてのコンポーネントに対して精密なStorybookを作成することを求めないことかもしれません。

Storybookを書くのは楽しいですし、きれいに表現できると気持ちいいですが、運用担当者はしっかりとメリット・デメリットを認識した上で導入・運用していきましょう。最後までお読みくださりありがとうございました。
給付金を活用してプログラミングスクールに通ったらお得なのでは？

プログラミングスクールに通うのは、いい悪いいろいろな意見があると思いますが、給付金を活用してお得にプログラミングを学ぶのはとてもいいのではないかと考えています。

https://careerhub.jp/benefits-programming-schools/

この記事を参考に書いていきます。

#プログラミングスクールの給付金は？
プログラミングスクールで使える給付金は以下の4つです。

- 一般教育訓練給付金
- 特定一般教育訓練給付金
- 専門実践教育訓練給付金
- 自立支援教育訓練給付金
- 第四次産業革命スキル習得講座

#給付金がもらえるプログラミングスクール
- Aidemy
- AI ジョブカレ
- KENスクール
- キカガク
- TechAcademy
- DMM WEBCAMP COMMIT
- ヒューマンアカデミー

実際にこのプログラミングスクールに通った人いたら話を伺いたいので、コメントください。

参考記事
https://careerhub.jp/ai-aidemy/
https://careerhub.jp/kikagaku-review/
https://careerhub.jp/dmm-webcamp-commit-benefit/
https://careerhub.jp/techacademy-benefits/
2021/07/28開催 Connpassイベントランキング

# 申込数TOP5

|順位|イベント名|グループ|申込数|定員|
|:---:|:---|:---|:---:|:---:|
|:one:|[Cookpad Lounge #7 世界最大級のモノリスcookpad_allどうする会議](https://cookpad.connpass.com/event/219934/)|[クックパッド株式会社](https://cookpad.connpass.com/)|312|999|
|:two:|[人類よ！これがアジャイルテスティングだ！QAテックリードが語るアジャイルQAの実践とは何か？](https://mabl-japan.connpass.com/event/218199/)|[mabl Japan](https://mabl-japan.connpass.com/)|309|500|
|:three:|[[MLS3]第１回機械学習システムセキュリティ勉強会](https://mlxse.connpass.com/event/219132/)|[機械学習工学研究会（MLSE）](https://mlxse.connpass.com/)|271|350|
|:four:|[ZOZO Tech Meetup〜マイクロサービス化に取り組む、16年目のZOZOTOWN〜](https://zozotech-inc.connpass.com/event/217488/)|[株式会社ZOZOテクノロジーズ](https://zozotech-inc.connpass.com/)|232||
|:five:|[コンテナ共創センター勉強会 #4](https://5cm.connpass.com/event/215224/)|[コンテナ共創センター勉強会](https://5cm.connpass.com/)|186|250|
【JavaScript / jQuery / 非同期処理】「$(async function() {...})」と書いて良いのは jQuery 3.3系 以降っぽい

# 前段

`$(function() {...})`内で、ある非同期処理を await で待機する処理を書こうとしてハマった話です。

# 結論

`$(async function() {...})`と書いて良いのは jQuery 3.3系以降のようです。  
それ以前のバージョンの jQuery を使用しているなら 
 `document.addEventListener('DOMContentLoaded', async function() {...}` 
 で代替するしかなさそうです。

# 内容

await を記述するために`$(async function() {...}`と書いたのですが、実行させるとそもそもこの関数自体が実行されなくなってしまいました。

もちろん、以下のように await を直接書いてしまうと`Uncaught SyntaxError: await is only valid in async functions and the top level bodies of modules`のエラーが発生します。

```js
function resolveAfter2Seconds() {
    return new Promise(resolve => {
      setTimeout(() => {
        resolve('resolved');
      }, 2000);
    });
  }

$(function() {
    const result = await resolveAfter2Seconds();
    console.log(result);
});
```
調べると、`$(async function() {...}`を認識してくれるのは jQuery 3.3系以降のようでした。  
Google Hosted Libraries で1つずつ確認しました。（3.3.0 はCDNに存在しなかったようなので未調査）

|バージョン  |結果  |
|---|---|
|1.X系  |☓  |
|2.X系  |☓  |
|3.2.0  |☓  |
|3.3.1  |○  |
|3.4.0  |○  |

※~~jQuery 3.X 系のバージョンアップ情報を探しても正確な情報は見つけられなかったのですが、~~
実際に src のバージョンを書き換えて１つずつ実行してみた結果が前述の表になります。

※@ko1nksm さんより情報頂きました。ありがとうございます
https://qiita.com/shimamura_io/items/57e18f11d3cc0faaefce#comment-80979316e737ee64bef8
FormControlのcdkDragが上手くいかない

自分の思考整理用

##起こったこと
フォームをドラッグ＆ドロップした時に、見た目では交換されているが中身のデータが移動出来ていない。

##原因
moveItemInArrayを利用してevent.container.dataを交換していた。
event.container.dataではFormGroupオブジェクトのcontrolsプロパティのみが交換され、
valueプロパティは交換されない。


##FormGroupオブジェクトの中身
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464003/ecb46522-39b4-dfa6-a8c2-450199f990d6.png)

###controls
データがコントロールのオブジェクトとして格納されている。

###value
データが配列、キーバリューで格納されている。



##問題のあったdrop()コード
controlsプロパティのみが交換されている。

```
drop(event: CdkDragDrop<string[]>) {
    if (event.previousContainer === event.container) {
      moveItemInArray(event.container.data, 
                      event.previousIndex, 
                      event.currentIndex);
    } else {
      transferArrayItem(event.previousContainer.data,
                        event.container.data,
                        event.previousIndex,
                        event.currentIndex);
    }
  }
```

###moveItemInArrayについて解決

**moveItemInArrayは何をしてくれるか** :
→同一の配列内でのアイテム交換

FormGroupオブジェクトのvalueについても交換処理を書く。

```
moveItemInArray(this.myForm.get('items')['controls'], 
                event.previousIndex, 
                event.currentIndex);
moveItemInArray(this.myForm.get('items').value, 
                event.previousIndex,  
                event.currentIndex);
```


動作を見る限り
```event.container.data``` = ```this.myForm.get('items')['controls']```
とcontainerのデータはcontrolsに紐づいているみたい。

###transferArrayItem

**moveItemInArrayは何をしてくれるか** :
→配列間でのアイテム交換

moveItemInArrayと同様にやればいい気がするけど、
別の配列との交換のため、宛先のオブジェクトと元のオブジェクトを指定しなければならない。
交換したいオブジェクトの階層が複雑で直接指定するのが難しい。

**解決案**
dropに引数を持たせる。ただ、交換先のグループの場所どうやって知るか。
eventからなんとか引っ張れないか。
個人情報を抜かれる危険性を認識したのでApacheの設定を見直した

## 概要

アクセス履歴を見たところ次のような履歴を見つけた

```
GET /composer.json
GET /.git/.env
GET /.git/config
GET /.idea/workspace.xml
GET /.settings/org.eclipse.core.resources.prefs
GET /nbproject/private/private.xml
GET /administrator/phpmyadmin/index.php
POST /vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php
```

Git、IntelliJ、NetBeans、Eclipseのファイルを開こうとしたり、phpMyAdminの管理画面を探したり、PHPUnitの脆弱性から何か悪い事をしようと考えているのは明らか。基本的にはドキュメントルートとプロジェクトのルートは別のため/.gitや/vendorにアクセスされる事はないが、一部ドキュメントルートとプロジェクトルートが同じプロジェクトがあったので見直した。

## 作業内容

### 各ディレクトリに.htaccessを設置

* .git
* .idea
* .settings
* nbproject
* vendor

内容はアクセス禁止

```.htaccess
AllowOverride none
Require all denied
```


### httpd.confとドキュメントルートの.htaccessに記述

アクセスされたくないディレクトリやファイルへのアクセスは404リダイレクトするよう追記
※phpMyAdminを使うURLの時はvendorをアクセスできるようにしておかないと使えません

```.htaccess
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /

  # ドットから始まるディレクトリとファイルへのアクセス禁止
  RedirectMatch 404 /\..*$

  # vendorとnbproject(netBeans)へのアクセス禁止
  RedirectMatch 404 /(vendor|nbproject)/

  # .iml(IntelliJ)ファイルへのアクセス禁止
  RedirectMatch 404 .*\.iml

  # composer関連へのアクセス禁止
  RedirectMatch 404 composer\.(phar|json|lock)

</IfModule>
```


### 個人的なテスト用のディレクトリに.htaccessを設置

ローカルアドレスで私のパソコンからのみとした

```.htaccess
Order Allow,Deny
Allow from 127.0.0.1
Allow from 192.168.0.11
```

### 残作業

悪意のあるURLで接続を試みてきたら、数週間IPアドレスをバンする

追記:[PHP 不正なURLで接続してきたIPアドレスを.htaccessにDeny fromに書き込む](https://qiita.com/Yamine1San/items/0ccc8bb7faac47594cd2)
Rails6でjQueryを使おうとしたらハマった

<h3> Rails6.0.3にjQueryを入れようとしたらハマった話 </h3>

by @tatsuhiko-nakayama様

https://qiita.com/tatsuhiko-nakayama/items/b2f0c77e794ca8c9bd74

こちらの記事で

<pre>
yarn add jquery
</pre>

```javascript:config/webpack/environment.js
const { environment } = require('@rails/webpacker')
// 以下追記
const webpack = require('webpack')
environment.plugins.prepend('Provide',
    new webpack.ProvidePlugin({
        $: 'jquery/src/jquery',
        jQuery: 'jquery/src/jquery'
    })
)
// ここまで
module.exports = environment
```

```javascript:config/javascript/packs/application.js
//中略

require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
// 追記
require('jquery')

//中略
```

をやったのだが下のエラー発生


<pre>
ERROR in ./app/javascript/packs/application.js
 Module build failed (from ./node_modules/babel-loader/lib/index.js):
 Error: Cannot find module './node_modules/@rails/webpacker/package/babel/preset.js' from '/myapp'
</pre>

webpackのインストールが失敗？
いや、node_modulesとbabelって書いてあるからそこが不足しているのか…
など色々試行錯誤したが、
結局アンインストールして入れ直しで解決

<pre>
# webpacker：installで追加されたpackage.jsonから無効なbabelpresetを削除
yarn remove @rails/webpacker
yarn remove webpack webpack-cli webpack-dev-server
rm -fr node_modules
rm -fr public/packs
bundle exec rails webpacker:install
Railsアプリの階層にある.browserlistrcを手動で削除する
yarn add node-releases
yarn add electron-to-chromium
bundle exec rails webpacker:compile
# おわり
</pre>

<h3>備考</h3>
Rails6のwebpackerは壊れやすいようです。
npmも同じく壊れやすいらしいので色々インストールしてる間に、コンフリクトしたのかなと分析。
解決まで時間がかかり焦ってしまったが、明けない夜はないように明けないエラーもないのかなと。

参考

https://github.com/rails/webpacker/issues/2723
医療情報技師試験勉強2

#診療情報の利用方法

##　一次利用

その患者さんに直接関係する
　・診療そのものへの利用
　・本人や家族への説明
　・スタッフ間の情報共有、カルテ閲覧
　・術前カンファレンス
　・診療情報提供書
　・会計、診療報酬請求に関すること



## 二次利用

患者さん自身に直接は関係ない
　・病院の経営
　・行政への届出（がん登録など）
　・公衆衛生（感染症など）
　・研究、教育
　・症例報告

#データの標準化
## MID-NET
MID-NET®は、国の事業で構築されたデータベースシステムで、国内のいくつかの医療機関が保有する電子カルテやレセプト（保険診療の請求明細書）等の電子診療情報をデータベース化して、それらを解析するためのシステム。
これまでの医薬品の安全対策は、副作用が疑われるとして医療現場から報告される情報などに基づいて行われてきました。しかし、医療関係者が副作用を疑わなければ報告されない、報告された副作用の発生頻度を計算することが難しいといった課題がありました。
そこで、医療関係者からの報告に依存せずに、データベース化した電子診療情報を用いて、副作用を直接把握したり評価すること等を目指して、MID-NET®の構築が進められてきました。
　MID-NET®を利活用することによって、医薬品の安全対策のさらなる質の向上が期待されます。
## NCD
外科系臨床学会が連携して設定。
## JーDREAMS
糖尿病患者のデータを集める。
## JROAD
日本循環器学会が行っている循環器診療の実態調査。
## MCRDS
臨床症例データ登録システム用ソフトウェア
##ICDー１０
WHOから公表
国際統一基準として疾病・障害・死因を分類するもの
具体的には人口動態調査での死因統計や患者調査での疾病分類、DPC等における疾病分類に用いられる。
##DPCコード
入院期間中に最も医療資源を集中した傷病名と手術や処置などの診療行為の組み合わせによって患者を分類する

##ICDーDA
歯科および口腔疾患の疾患分類

##Kコード/Jコード
基本診療料ではない
手術・処置コード

##JJ１０１７
放射線領域のコード
３２桁のコード
主部と副部からなる
主部には種別・手技・部位・左右。および姿勢。撮影体位が含まれる
副部には詳細指示、詳細体位、特殊指示など

##JLAC１０
臨床検査コード
分析物・識別コード・材料コード・測定方法コード・結果識別コードの１７桁

##医薬品コード
https://www.data-index.co.jp/knowledge/detail1-1.html

JANコードは医療品以外もある

##SSーMIX
厚生労働省電子的診療情報交換推進情報
医療機関同士の情報交換を標準化

##LONIC
臨床検査や生理検査の表現することが可能なデータベース
米国発
【Node.js】NVM(Node Version Manager)インストール

> 私は日本就職を目指して、勉強している韓国人大学生です。
> もし、内容の中で間違った表現や言葉などがあれば、書き込みをしてください。

> 本コンテンツはmacOSを基準とします。

#NVMというのは？
- [NVMのレポジトリ](https://github.com/nvm-sh/nvm)（公式ドキュメント）
- Node.jsのバージョン管理アプリ
- 様々なプロジェクトを行う時、簡単にNode.jsのバージョンを管理できる
    - デフォルトバージョンの設定
    - インストールされたバージョンのリスト確認
    - etc…

#NVMインストール
1. インストール 

    ```bash
    $ sudo curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash
    ```

2. `~/.bash_profile`にスクリプトを追加（`zsh`シェルを使っていると、`~/.zshrc`に追加）

    ```vim
    export NVM_DIR="$HOME/.nvm"
    [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm
    ```

    ```bash
    $ source ~/.bashrc
    ```

3. インストール結果を確認

    ```bash
    $ nvm ls
    ```

    ```bash
    ->       system
    node -> stable (-> N/A) (default)
    iojs -> N/A (default)
    ```

#Node.jsインストール
1. インストール 

    ```bash
    $ nvm install 14.17.3
    ```

2. インストール結果を確認

    ```bash
    $ nvm ls
    ```

    ```bash
    ->     v14.17.3
             system
    default -> 14.17.3 (-> v14.17.3)
    node -> stable (-> v14.17.3) (default)
    stable -> 14.17 (-> v14.17.3) (default)
    iojs -> N/A (default)
    lts/* -> lts/fermium (-> v14.17.3)
    lts/argon -> v4.9.1 (-> N/A)
    lts/boron -> v6.17.1 (-> N/A)
    lts/carbon -> v8.17.0 (-> N/A)
    lts/dubnium -> v10.24.1 (-> N/A)
    lts/erbium -> v12.22.3 (-> N/A)
    lts/fermium -> v14.17.3
    ```

3. Node.jsのバージョンを確認

    ```bash
    $ node -v
    ```

    ```bash
    v14.17.3
    ```

#他のバージョンのNode.jsインストール・バージョン変更
1. インストール 

    ```bash
    $ nvm install 10.15.1
    ```

2. インストール結果を確認

    ```bash
    $ nvm ls
    ```

    ```bash
    ->     v10.15.1
           v14.17.3
             system
    default -> 10.15.1 (-> v10.15.1)
    node -> stable (-> v14.17.3) (default)
    stable -> 14.17 (-> v14.17.3) (default)
    iojs -> N/A (default)
    lts/* -> lts/fermium (-> v14.17.3)
    lts/argon -> v4.9.1 (-> N/A)
    lts/boron -> v6.17.1 (-> N/A)
    lts/carbon -> v8.17.0 (-> N/A)
    lts/dubnium -> v10.24.1 (-> N/A)
    lts/erbium -> v12.22.3 (-> N/A)
    lts/fermium -> v14.17.3
    ```

3. Node.jsのバージョンを確認

    ```bash
    $ node -v
    ```

    ```bash
    v10.15.1
    ```

4. Node.jsのバージョンを変更

    ```bash
    $ nvm use 14.17.3
    $ node -v
    ```

    ```bash
    v14.17.3
    ```

# 他ののNVMコマンド
- 最新バージョンをインストール

    ```bash
    $ nvm install --lts
    ```

    ```bash
    Installing latest LTS version.
    v14.17.3 is already installed.
    Now using node v14.17.3 (npm v6.14.13)
    ```

- 現在使っているバージョンを確認

    ```bash
    $ nvm current
    ```

    ```bash
    v14.17.3
    ```

- 特定バージョンのアンインストール

    ```bash
    $ nvm uninstall <version>
    $ nvm uninstall v10
    ```

    ```bash
    Uninstalled node v10.15.1
    ```
JSONをふんわりとしか理解していない人へ

# はじめに
私自身、普段開発を行っている中でJSON形式のデータをよく扱うのですが、その構造や概要についてふんわりとした理解しか無かったので、自己学習も兼ねてまとめてみました。

# JSONとは
JSONとは「JavaScript Object Notation」の略で、「JavaScriptのオブジェクトの書き方を元にしたデータ定義方法」のことです。名前にはJavaScriptと入っていますが、現在ではJavaScriptに限らず、 各種プログラム言語で利用できます。RubyやPythonなど、 現在は多数の言語で利用可能になっています。そのため、これらの言語をまたいで、 あるいはネットワークを通して、データを交換できます。

主にサーバーとWebアプリケーション間でデータを送信する時に使用されます。


# JSONの書き方
JSONは {} の中にキーと値をコロンで区切って記述します。キーは必ずダブルクォーテーションで囲む必要があり、シングルクォーテーションだとエラーになります。

`キー`：キーは常に引用符で囲まれた文字列です。
`値`：値には、文字列、数値、ブール式、配列、またはオブジェクトを指定できます。
`キーと値のペア`：キーと値のペアは特定の構文に従い、キーの後にコロンが続き、その後に値が続きます。キーと値のペアはコンマで区切られます。

    {
     “key1” : “value1”,
     “key2” : “value2”,
     “key3” : “value3”
    }

# 使える値の種類

文字列：通常は単語を形成するいくつかのプレーンテキスト文字

```
{“name” : “suzuki”}
```
数値：整数

```
{“id”, 1}
```
ブール値： TrueまたはFalse

```
{“a” : true, “b” : false}
```
配列：値の連想配列

```
{
    "id": 1,
    "name": "suzuki",
    "result": [
        87,
        83,
        71,
        59,
        91
    ]
}
```

オブジェクト：キーと値のペアの連想配列

```
{
    "id": 1,
    "name": "suzuki",
    "attribute": {
        "gender": "male",
        "phone_number": "xxxxxxxxxxx",
        "birth": "1998/01/01"
    }
}
```


# 実際に使ってみる
## JSON文字列 → オブジェクトへの変換
JSON形式の文字列であるjson_strをJSON.parseに渡してオブジェクトに変換している。
### JavaScriptコード
```
var json_str = '{"id":1, "name":"tanaka", "attribute":{"gender":"male", "phone_number":"xxxxxxxxxxx", "birth":"1991/01/01"}}';
var obj = JSON.parse(json_str)
console.log(obj.name)
console.log(obj.attribute.birth)
```
### 結果
```
tanaka
1991/01/01
```

## オブジェクト → JSON文字列への変換
オブジェクトであるobjを二行目でJSON.stringifyへ渡して、JSONの文字列へ変換している。

### JavaScriptコード
```　javascript:
var obj = {"id":1, "name":"tanaka", "attribute":{"gender":"male", "phone_number":"xxxxxxxxxxx", "birth":"1991/01/01"}}
var json_str = JSON.stringify(obj)
console.log(json_str)
console.log(typeof json_str)
```
### 結果
```
{
	"id": 1,
	"name": "tanaka",
	"attribute": {
		"gender": "male",
		"phone_number": "xxxxxxxxxxx",
		"birth": "1991/01/01"
	}
}
```


# 便利ツール
## JSONきれい
ごちゃついているJSON型のデータを放り込むだけでスッキリさせてくれます。

![スクリーンショット 2021-07-30 0.35.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/997177/478cb7a9-edd2-f188-48d7-0e6968186d0a.png)

https://tools.m-bsys.com/development_tooles/json-beautifier.php
サーバーIPのブラックリスト確認とSorbs.netでの解除申請方法

### 実行環境
メールサーバ: Postfix
IMAP/POP3サーバ: Dovecot
CentOS Linux release 8.3.2011

### 経緯
弊社では迷惑メール防止目的で、DNSにSPF、DKIM、Dmarcの3レコードを入れているが、そのためにサーバーIPアドレスが何らかのブラックリストに入ると、途端にメールが届かなくなったりする。

### 症状
今回、サーバー内に新規に立てたホストで構築していたところ、Gメールのアドレス宛に送受信テストをすると、
SPF判定が `NEUTRAL` となっていた。（キャプチャはGメールのメールソースの画面）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565397/b262b673-20aa-7015-fa69-fb7feba2b41d.png)

### 原因
問題のIPアドレスを[ブラックリストチェックツール](#ブラックリストチェックサイト)で調べると、 `Sorbs.net` というブラックリストに登録がされていた。
### 対応
解除申請を行うわけだが、これが最悪に面倒だった。半分愚痴になるので先に方法を言うと、
1. 「Register」からアカウント登録
2. 「Login」ボタンをクリック
3. 「DELIST AN IP ADDRESS」ボタンをクリック
4. 下記のような画面になるので、「Get Help/ Support」ボタンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565397/affb2c29-006b-7e68-5043-bcde2979f7c4.png)
5. 「Getting Help for ～」と記載された問い合わせ申請フォームになるので、内容は英語で①どこの誰か②どういう状況で③どのIPを外してほしいかを伝え、「Open Ticket」をクリックします（早く対応して欲しければ英語で書いてこいと文面にもあります）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565397/701bf8b8-4753-e377-fb16-0d817f69da4a.png)
6. リクエスト処理中にエラーが起きましたといって、下記のエラー画面になることを確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565397/af2c7436-e0da-58a0-aa26-c97aeaadc44e.png)
7. 「An Error Occurred Processing Your Request」と書かれたその下にエラー報告をしてくれとメールアドレスが書いてあるので、そのアドレス宛にこのIPをブラックリストを解除して欲しいと英文でメールを送る。
8. 半日ほどで `payments@support.sorbs.net` から返信メールが2通ほど届くかと思います。一通は注意事項が大半なので、最終的にもう一通の `Subject: [sorbs.net #] 送信したメール件名` の件名で来るメールで本文に delisted と書かれていることを確認すればOKかと思います
9. 再度ブラックリストのチェックサイトに行き、チェックがないことを確認。
10.  そのまま再度Gメールで送受信テストをしてすべてPASSになっていれば完了です
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565397/cdf13777-5083-5a12-3b40-7117a2ffc0c8.png)


##### 注意点
- 以上の流れですが、1点だけ注意があって最後にメールで問い合わせをするまでのすべての実施結果 （上記で書いた番号でいえば1～6までの手順）はエラー画面 になります。（DBには登録されているぽいので、どうもわざとのようです。）
- 結果的に問い合わせ先のメールアドレスが知りたいだけなので、最初から直接 `support@sorbs.net` にメールしてリストから外すよう言ってみるのもありなのかもしれません。

##### 送信メール例
```
Subject: Regarding our IP in black-listing (問い合わせたいIPアドレス)

Dear person in charge,

Hi. I`m a staff of 会社名 that Japanese company, owner of 
the website and IP 問い合わせたいIPアドレス.
We will email you for an error occurred in the blacklist remove 
application form on your site.
In short, we have now getting in troubled with our client mail sending 
are failed to sent off for we found it listed on your blacklist.
So, please quickly remove our IP from your blacklist for these things 
are fully managed within us.
Thanks.
```


### 参照
###### ブラックリストチェックサイト
https://www.dnsbl.info/dnsbl-database-check.php
https://www.blacklistalert.org
###### 過去に解決された方のページ
https://onoredekaiketsu.com/request-delete-blacklist-to-sorbs/
【C#】ユニットテストでMockを作るとUnsupported expression:～Non-overridable membersとなった際の対策法。

# はじめに
ASP.NET Core C# + NUnitで開発をしていた際にユニットテストで詰まった部分について備忘録として残しておきます。
ユニットテストでアプリ側のクラスを生成し、コンストラクタ引数をモックで作成してテストをした際に「System.NotSupportedException : Unsupported expression:～Non-overridable members (here: ～～) may not be used in setup」というエラーが出てしまいました。
![unittest.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538249/3f34a818-a9c8-1ee0-9a29-901dfc0cc821.png)

今回はその解決方法を2つほど記載していこうと思います。

## サンプルコード
アプリ側が以下のコードになっている場合を考えてみましょう。
利用しているのはASP.NET Core コンソールアプリです（簡略化のためProgram.csのMain関数は省略しています）。
appSettings.jsonファイルから「Test1」キーの値を引っ張ってきてその値が9999だったら0を返却し、そうでない場合は1を返却するというプログラムです。

```csharp:program.cs
public class TestClass : ConsoleAppBase
{
    private readonly TestConfig _testConfig;

    public TestClass(IOptions<TestConfig> options)
    {
        _testConfig = options.Value;
    }

    [Command("test")]
    public void Test1()
    {
        Console.WriteLine(WriteNumber());
    }

    public int WriteNumber()
    {
        if(_testConfig.Test1 == 9999)
        {
            return 0;
        }
        else
        {
            return 1;
        }
    }
} 
```

```csharp:TestConfig.cs
namespace ConsoleApp2
{
    public class TestConfig
    {
        public int Test1 { get; set; }
    }
}
```

テストコードは以下のように作成してみました。

```csharp:UnitTest1.cs
[Test]
public void WriteNumberMethodTest()
{
    var testConfigMock = new Mock<IOptions<TestConfig>>();
    testConfigMock.Setup(o => o.Value.Test1).Returns(9999);
    var target = new TestClass(testConfigMock.Object);
    // appSettings.jsonのTest1キーが9999時は0が返却される
    Assert.AreEqual(0, target.WriteNumber());

    testConfigMock.Setup(o => o.Value.Test1).Returns(9998);
    var target2 = new TestClass(testConfigMock.Object);
    // appSettings.jsonのTest1キーが9999以外の時は1が返却される
    Assert.AreEqual(1, target.WriteNumber());
}
```
コンソールアプリ自体は正常に動作しますがユニットテストでは最初に記載した通りエラーが出てしまいます。

## エラーの原因
色々と調べていると世界には同じ内容で詰まっている方がいるものです。

https://github.com/moq/moq4/issues/961

Moq開発メンバーが回答してくれていますが、どうやらMoqはvirtualを付ける必要があるようです。
（インターフェースを対象とすればオーバーライドの心配はしなくても大丈夫です。）

そこで元のコードを見ると、確かに・・・Test1はvirtualになっていないですね・・・

## virtual修飾子を付けてみる

そこでvirtual修飾子を付けてみましょう。

```csharp:TestConfig.cs
namespace ConsoleApp2
{
    public class TestConfig
    {
        public virtual int Test1 { get; set; }
    }
}
```

テストを実行～～～
しっかりテストが通ったのが確認できましたね！
![unittest2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538249/b0963151-8637-a651-9bb7-7d27a73168ae.png)

## もう1つの解決方法
こちらは公式ではないですが、stackoverflowで以下のような回答がありました。

https://stackoverflow.com/questions/40876507/net-core-unit-testing-mock-ioptionst

Options.Createについて調べてみたら単純に自身のインスタンスをOptions<T>の型で返すようです。

https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.options.options.create?view=dotnet-plat-ext-5.0

こちらだとMoqを使用していないので先ほどのようにvirtualを付ける必要もないので良さげです。
どちらが良いのかは・・・ちょっと分かりませんが好みという感じなんですかね？？

# おわりに
記事を書きながらMoqやOptionsについて調べているといかに自分が雰囲気でそれらを使っていたかが分かります。
なかなか実務の時間にじっくり深堀りする余裕がないので仕方ないといえば仕方ないのですがその分しっかり自学でカバーしていきたいです。
Progateで作ったWebアプリをDjangoで作ってみる2！ Part4 -ログアウト機能編-

# 目標物の確認

ProgateのNode.jsコースで作ったブログアプリと同じものをDjangoで作ってみます。

Djangoでのアプリ開発の一連の流れを整理するために記していきます。

**完成イメージ**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/471633/147877a6-1b3a-25e2-7956-720596125802.png)

#ログアウト機能の実装

ログアウトボタンをクリックすることによってurl→viewの順にコードが実行されていき、viewの中でログアウトをするための処理を行います。その上でログインページにリダイレクトさせます。

ログアウト用のviewを作ります。**logout()**を使うことによってログアウトさせます（☆1）。

```python:blogapp/blog/views.py
from django.shortcuts import render, redirect
from django.views.generic import TemplateView
from django.contrib.auth.models import User
from django.db import IntegrityError
from django.contrib.auth import authenticate, login, logout # ☆1

class BlogTop(TemplateView):...

def signupview(request):...

def loginview(request):...

def logoutview(request): # ☆1
    logout(request)
    return redirect('blog:login')
```

続いて、**urls.py**ファイルにコードを書きます（☆2）。

```python:blogapp/blog/urls.py
from django.urls import path
from .views import BlogTop, signupview, loginview, logoutview # ☆2

app_name = 'blog'

urlpatterns = [
    path('', BlogTop.as_view(), name='top'),
    path('signup/', signupview, name='signup'),
    path('login/', loginview, name='login'),
    path('logout/', logoutview, name='logout'), # ☆2

]
```

これでログアウト機能は作成完了です！
私的「人工知能」研究宣言

# はじめに
子供の頃、初めて「人工知能」という言葉に接したときのイメージを思い出してみる。

- すごく複雑な機械。「コンピュータ」か。
- 人間と「会話」（時に創発的な情報交換）ができる。
- たぶん「自分が何か」を理解している。
- でも生物とは異なり自己増殖はしない。あくまでも機械。

一方で、現在分かっている自然法則によれば、人間も機械も原子の集まり（物質）でできていると説明される。一般的に「機械」は、自然法則を巧みに利用して使用者が望む機能を実現する仕掛け（道具）として捉えられるが、機械自身が「自分が何か」を理解して動作しているわけではない、とみられる。

同じ「物質」なのに、「自分が何か」を理解して行動している（ようにみえる）人間と、一般的な「機械」との作りの違いはどこにあるのか？
逆に、「自分が何か」を理解して行動する機械、つまり私のイメージにある「人工知能」を作成することは可能なのか？

私自身の長年の興味であり、また多くの人が持っているであろう疑問の解明に、後半生をかけて取り組んでみたい。


# 私的「人工知能」の定義
人工的に作られた「無機物」又はそれらの組合せであって、「主観」を持って動作（行動）するもの

### 「主観」とは
そのものが持つ「**感覚**」と「**行為**」により、「**自己**」と「**外界**」を「認識」することで形成される世界観

「主観」を説明するには、「自己」と「外界」、および自己が持つ「感覚」と「行為」をセットで説明する必要がある。

- 自己が外界から部分的な情報を得る（インプット）機能を「感覚」と呼ぶ。
- 自己が外界に対して何らかの働きかけをする（アウトプット）機能を「行為」と呼ぶ。
- 「主観」を持っておこなわれる一連の「行為」すなわち「動作」は、「行動」と呼んでもよかろう。

### 「無機物」であること
今や再生医療などに見るように、「人工的」に生体の一部を作り出すことは可能になってきている。何らかの「種」（幹細胞..など）を「培養」することにより仮に「主観を持って行動するもの」が作り出されたとして、それを「人工知能」と呼ぶか、と言ったら否であろう。artificialというニュアンスからも外れる。**ここで言う「無機物」とは、「生体でないもの」を指す**。

### 「自己」と「外界」を「認識」すること
例えば昨今の掃除ロボットや自動運転車は、3Dセンサー等での空間スキャンにより内部的に地図を構成して動作していることから、一見「主観」を持って行動していると言えなくもない。しかしながら、掃除ロボットや自動運転車に**「自分が何か」を理解する仕組み**があるかといえば、否であろう。場合によっては、掃除ロボットの設計において「自己認識機能」という命名の部分機能を持つことは考えられるが、掃除ロボットが「何であるか」については設計者があらかじめ定義して実装しているはずであり、「自己認識機能」において掃除ロボット自体が「自分が何であるか」を初めて気付くというものではないであろう[^1]。

「自己」を「認識」することとはつまり、**持っている「感覚」能力と「行為」能力を使って、創造主（設計者等）が先天的に与えることなくその「行動原理」を見い出す（導き出す）こと**[^2]、と言えるかもしれない。そして、**「自己」を「認識」することは同時に、「外界」に対する「自己」の立場も「認識」することになる**ように思われる。「自己」と「外界」の「認識」は、これらを統合した世界観を「自己」の中に形成することになるはずである。

[^1]: 「掃除ロボット」という役割を決めて作っているはずの機械に、そんな回りくどい設計はしないはずである。
[^2]: これは「主観」を「客観」的に説明しようとしている。
CakePHP4 フォーム値をセッション管理する

Every Qiita #24
のんびり独学初学者投稿 24日目
今回は・・・
cakePHP4のフォーム値をセッション管理した時の備忘録です。

###controllerでセッションを準備する

cakephpではSessioオブジェクトを使って書き込みや読み込みを行います。`$this->getRequest()->getSession()`でセッションにアクセスすることができます。
公式ドキュメントではセッションを独自でカスタマイズする方法が載っていますので、近々実装して投稿しようと思います。

```php:AppController.php
public function initialize(): void
{
  $session = $this->session = $this->getRequest()->getSession();
  $this->set(compact("session"));
}
```
viewでセッションにアクセスするたびに記述するのが面倒なので、AppControllerのinitializeアクションに変数をセットしておきます。

###セッションを管理する
`$this->session->read()`：セッションの読み込み
`$this->session->write()`：　セッションの書き込み
`$this->session->destroy()`：セッションの削除
`$this->session->check()`：指定のセッションデータが存在しているか確認
基本的に上記のメソッドを使っていきます。
今回は,
前回実装した複数検索で検索内容を保持するためにセッション管理を行なっていきます。

```php5:任意Controller.php
foreach($session_array as $key => $val){
    if(!empty($val)){
        $this->session->write($key,$val);
    }elseif($this->session->check($key)){
        $this->session->delete($key);
    }
}
```
$session_arrayにはセッションに入れたい値と任意のキーを連想配列で格納してあります。

- 値があればセッションに格納します
- 値がない場合、前回検索時にデータがあるかを確認し、あれば削除します。（直前の検索内容に更新）

###viewに表示する

最後にセッションがあればvalueに設置し完了です。

```php:view/任意.php
<?= $this->Form->control('gym_id',["label" => false,"empty"=>"ジムを選択","value"=> $session->read('gym') ?? '']);?>
```

- formControlの引数にvalueを設定するとhtmlのvalueに変換できます。
- セッションには検索した値のみ格納しているので検索していない箇所はnullで帰ってきます。readメソッドでnullでなければ検索した内容が初期値として設置されます。
ノーコード開発で Acty-G3 から SORACOM Unified Endpoint へ通信してみる

# はじめに

IoT デバイス特価キャンペーン で特別価格になっていた Acty-G3 を~~手が滑って~~購入してとりあえず気軽に使ってみたい、ということで MIT App Inventor で Acty-G3 のアプリを開発し、SORACOM Unified Endpoint へつなげてみる。

# MIT App Inventor 実装

以下のサイトを参考に、 Unified Endpoint へ POST リクエストする処理をブロックで実装

[Using Web APIs with JSON](http://ai2.appinventor.mit.edu/reference/other/json-web-apis.html)
[Unified Endpoint を利用して Funnel と Harvest にデータを送信する](https://users.soracom.io/ja-jp/docs/unified-endpoint/funnel-and-harvest/)
[Post and json and RequestHeaders](https://community.appinventor.mit.edu/t/post-and-json-and-requestheaders/3517/7)

Designer
![002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49240/ad57221b-800d-32ab-2a59-1024a059c73c.png)

Blocks
![001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49240/ec4b0b37-8f22-006f-043c-741a58983aaf.png)

# 動作確認

Acty-G3 を PC に USB 接続して、 VYSOR でリモート接続して確認

[Acty-G3でリモートデスクトップを使う](https://blog.covia.co.jp/entry/2020/09/10/133226)

Unified Endpoint にはつながってるけど、 Beam/Funnel/Harvest を OFF にしてたので 400 が返ってきたorz
![003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49240/5915b6ca-4dfb-5405-be55-75c9644cad9d.png)

IFTTT Webhooks を SORACOM Beam に 設定してた SIM グループがあったので切り替えたら 200 ｷﾀ━━━━(ﾟ∀ﾟ)━━━━!!
![004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49240/0aadcc94-4738-5f50-dc1c-2bc37b748e04.png)

※POSTメッセージの確認忘れてたので、あとで Harvest ON の状態も確認しますorz

# おわりに

1時間半くらいごにょごにょしてたらできた。
次はセンサーデータの送信を試してみたい。