OmniAICreator/Qiita-1.07M huggingface dataset:
Django4とJWTでSPAの認証のサーバーサイドを作ろうとして失敗した話

# 1.初めに
　DjangoとReactでSPAを作るんだったら認証まわりどうなってるんだろうと思って調べてみたら先達の方々は自分で実装するよりも外部サービスを経由する方がセキュリティ的に安全と結論づけていました。その中でも特にメジャーな方法としてJWT(Json Web Token)を使ったやり方がより多くの情報が出回っているようでした。
　そこで、私も[こちらのサイト](https://medium.com/netscape/full-stack-django-quick-start-with-jwt-auth-and-react-redux-part-i-37853685ab57)を参考にして実装しようとしましたが、Django4のリリースに伴い、既存のやり方ではうまくいかないことが判明しましたので今回記事を執筆しようと考えました。

# 2.前提環境
- OS:Mac, Linux
- Python3.9
- virtualenv

# 3.Django4ではurl関数が削除されたらしい
　DjangoのバージョンにこだわらずDjango4を仮想環境に入れた上で[こちらのサイト](https://medium.com/netscape/full-stack-django-quick-start-with-jwt-auth-and-react-redux-part-i-37853685ab57)の説明に沿って初期設定を進めて行き、マイグレーションを実行しようとしました所、ターミナルでurlがねーよと怒られました。

　エラー文について調査をしましたところ、Django4ではdjango.conf.urlsのurl関数が削除されたらしいです。代わりに、urls.pyを下記のように

```config/urls.py
from django.urls import path
```

と記述し、urlpatterns = []内のurl関数を使用している箇所をすべてpath関数に変更したところマイグレーション、スーパーユーザー作成、サーバー起動のすべてのコマンドが正常に動きましたが、405エラーが返されてしまいました。本来だったら紹介しているサイト通りに構築を進めれば

![スクリーンショット 2022-12-06 22.29.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1167908/e8b25544-4222-69c4-f346-349a0ad81c9c.png)

こういう画面になるわけですが、405エラーが返される原因や対処法については私にはさっぱりでした。ここについては今後調べてみようと思います。でも、ここさえ解決できればDjango4とJWTで認証を構築する事も難しくはないと思います。少なくともサーバーサイドでのエラーはないというわけですから。

# 4.結論
######  構築時にDjango3を指定しましょう

Django3をサーバーサイドに指定すれば問題なく動きます。参考にしたサイトでは構築の流れとして

```terminal
$ mkdir backend/ && cd backend/
$ python3.6 -m venv env
$ source env/bin/activate
$ pip install coreapi django djangorestframework \ djangorestframework-simplejwt
$ pip freeze > requirements.txt
$ django-admin startproject config .
```

と説明していますが、このやり方ですと最新バージョンのDjango4が入ってしまいます。仮想環境に入るDjangoのバージョンを指定してやる必要がありますので、これらのコマンドの一部を下記のように修正します。

```terminal
$ mkdir backend/ && cd backend/
$ python3.6 -m venv env
$ source env/bin/activate
$ pip install coreapi django==3.1.14 djangorestframework pyyaml \ djangorestframework-simplejwt
$ pip freeze > requirements.txt
$ django-admin startproject config .
```

Djangoインストール時にこのようにDjango3のリリース済みのバージョンを3系で適当に指定しておきます。また、pyyamlのインストールもするようにコマンドを修正しました。pyyamlを追加しておかないとlocalhost:8000/apiにアクセスした際にpyyamlがねーよと怒られます。

![スクリーンショット 2022-12-06 22.29.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1167908/e8b25544-4222-69c4-f346-349a0ad81c9c.png)

localhost:8000/apiにアクセスし、右上のlog inをクリックしてスーパーユーザー作成時に設定したユーザー名とパスワードを入力し、ログインに成功するのを確認できたらOKです。

　以上です。あとは[こちらのサイト](https://medium.com/netscape/full-stack-django-quick-start-with-jwt-auth-and-react-redux-part-i-37853685ab57)の説明通りにconfig直下のsettings.pyやurls.pyを書き換えてやれば問題なく処理は動いてくれます。

　Django4でSPA実装する際の認証周り誰かやり方教えてくれないかなあ…。

## 参考URL
- [Full stack Django: Quick start with JWT auth and React/Redux (Part I)](https://medium.com/netscape/full-stack-django-quick-start-with-jwt-auth-and-react-redux-part-i-37853685ab57)(こちらを元にして構築しました)
- [【Django】cannot import name ‘url’ from ‘django.conf.urls’ エラーの原因と対処法](https://daeudaeu.com/django-import-url-error/)
COLMAP 複数のカメラパラメータ

「instantNeRFで遊ぶ Advent Calendar 2022」の10日目です。

今日は9日目に書いた画像ごとのカメラパラメータを解析するときに試したCOLMAPの手順を記します。

:::note
業務外の個人的な検討活動です。
間違っていても責任はとれません。
:::

#### COLMAPのgithub
https://github.com/colmap/colmap/issues/356
>　...すべてのカメラパラメータ/モデルの変更、複数画像間でのパラメータ共有は、Processing > Database Management ウィジェットで可能です。
（DeepLを使いました　https://www.deepl.com/translator）

tutorialを読んだりgoogle検索したり調べてみましたが、細かい手順を見つけることができませんでした。

#### colmap.bat
1. New projectでデータベースの作成と画像ファイルパスを設定
1. [Processing] > [Feature Extruction]
モデルはOPENCVを選択
ここでShared for all imagesを選択しなくても自動でパラメータが画像ごとに分かれなかったです。
追記　別の画像群だと分かれましたので、何か条件があるようです。
![10-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103446/0b3caf4f-d8c0-fe41-260e-381a39db1938.png)
1. [Processing] > [Database Management]
最初は全部の画像のcamera_idが同じでした。
![10-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103446/fd4d99e6-614f-0efa-73a7-05446ad9fb22.png)
image_idが2以降の行を選び、右上のSplit cameraを押し、出てきた窓のCamera_idを1にしてOKすると、camera_idが分かれて増えました。
![10-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103446/1efc5ee8-78ad-184b-6ebf-9102687a2bc5.png)
6つのimageにそれぞれcamera_idを割り当てました。
![10-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103446/8b5f2e88-9e24-b4ff-5db9-34c58e76d255.png)
ここでCamerasのタブに移るとcamera_id 1が分かれて6つになりました。
![10-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103446/d203da4f-8ded-aa50-8d86-70f0f5730df8.png)
1. [Processing] > [Feature Matching]
1. [Reconstruction] > [Reconstruction options]
BundleタブにあるRefine focal length, principal point, extra parametersにチェックを入れました。
![10-6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103446/b356f12f-bf68-f9ad-7fd8-4684bdb52554.png)
1. [Reconstruction] > [Start Reconstruction]
1. [Reconstruction] > [Bundle Adjustment]
1. [File] > [Export models as text]

#### cameras.txt
画像ごとにカメラパラメータが割り当てられていました。
![10-7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103446/912006c5-94d5-1b6f-8dd2-fe3e13230e1f.png)
得られたcameras.txtを使って、昨日のようにtransform.jsonのフレームごとにカメラパラメータを入力しました。

#### 参考
https://buaiso.blogspot.com/2018/11/colmap.html
代入演算子の返り値(C++)

c++でこういうコードを見たことありませんか？

```c++

vector<int> memo;

int func(int idx, int a){
    //省略

    return memo[idx] = a;
}
```

いや，何返してんねん？って思いませんか．
僕は思いました．

そこで，=などの代入演算子の返り値について調べてみました．

https://learn.microsoft.com/ja-jp/cpp/cpp/assignment-operators?view=msvc-170

>代入演算子は、代入後に、左のオペランドで指定されているオブジェクトの値を返します。

とあります．
例えば，

```c++
return a = b;
```

とあれば，左辺のaに格納された値が返されているようです！

いかがでしたか？代入演算子は，左のオペランドで指定されているオブジェクトを返すことが分かりました．
面白いと思ったら，高評価とチャンネル登録おねがいします！
NVIDIA Jetsonを色々いじってみる。

## はじめに

NVIDIA Jetsonをさわる機会があったのでセットアップのメモを残しておく

## スペックなど

[Box PC AG411B](https://www.avermedia.co.jp/professional/product-detail/AG411B)

## OSなど

Ubuntu 18.04 LTS

## VNCのセットアップ

本体にディスプレイ、キーボード、マウスを接続すれば、そのまま認識して使用できるが、リモートで使用したいのでＶＮＣサーバーをインストールする。
最初はTiger VNCをインストールしようとしていたが何故か画面が表示されなかったのでいろいろ調べた結果、[公式のドキュメント](https://developer.nvidia.com/embedded/learn/tutorials/vnc-setup)があることを発見。vino-serverを使えと言うことらしい。

```bash
$ mkdir -p ~/.config/autostart
$ cp /usr/share/applications/vino-server.desktop ~/.config/autostart/
$ cd /usr/lib/systemd/user/graphical-session.target.wants
$ sudo ln -s ../vino-server.service .
$ gsettings set org.gnome.Vino prompt-enabled false
$ gsettings set org.gnome.Vino require-encryption false
$ gsettings set org.gnome.Vino authentication-methods "['vnc']"
$ gsettings set org.gnome.Vino vnc-password $(echo -n '(パスワード)'|base64)
$ sudo reboot
```

手元のパソコンにはUltra VNCをインストールして接続を確認。

簡単ですが今回はここまで、
CharacterBPのSetSimulatePhysicsを使った時の床のすり抜けに対処する

CharacterベースのBPで作られた敵キャラを倒した際にラグドール化しようとしたら床をすり抜けてしまったのでその対処を記載しています。

コンポーネントはこんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38033/6d93e7f1-a8c9-585e-db85-72ff77cd92ae.png)

対処方法はMeshのコリジョンプリセットをデフォルトのCharacterMeshから別の設定にすればOKです。
原因としてはSetSimulatePhysicsを使った後のコリジョンが床に対して判定を持たないことが原因です。
私の場合はコリジョンプリセットをBlockAllに変更しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38033/640ccdcc-9d5c-148c-1db7-858f59edc629.png)

BPは以下のような感じで設定しています。
キャラがラグドール化した後にカプセルの判定が残ってしまうのでカプセルの判定を無しにしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38033/a78325e1-b754-2692-c978-59f99860a4ba.png)
何が違うの？～ping,traceroute編～

## **はじめに**

どうも！社会人1年目、普段から頭を沸かしながら仕事をしている山岡です。
（今回祝１回目の投稿になります！）

私は現在サーバエンジニアとして、頂いた案件を実際に機器に触れながら対応しています。

今回は、案件対応をする際によく使用しているコマンド「ping」と「traceroute」について記事を書いていこうと思います。


## **pingとtracerouteの違い**
「ping」と「traceroute」の違いを簡単に説明すると
**接続の可否を簡単に確認できる**コマンドか
**経路を詳細に表示する**コマンド、ということです。

（私は今までpingの存在しか知りませんでした。。）

実際にコマンドを使用した際の結果は以下の通りです。↓

～pingの場合～
![ping.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629112/b915f610-2a02-094b-df68-cb03afbc8dfe.png)
pingを打った場合、上図のように
接続の可否をYES/NOで簡単に確認することができます。
※上図は**接続ができている**場合の結果となります。

～tracerouteの場合～
![traceroute.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629112/dc10a92f-5d99-1987-30e8-c249d59c0d0c.png)
tracerouteを打った場合、上図のように
目的のホストまでの経路を順に表示しているため、
詳細な情報を得ることができます。

沢山の経路を知りたいときや、ネットワーク接続が正常ではない場合に、
どこに問題があるのかある程度確認することがtracerouteでは可能です。

このように、似たような意味を持ったコマンドでも
実際に打ち込んでみるとそれぞれで用途が違うことが
はっきりと理解できますね。

## **終わりに**
今回は、自分自身が実作業の際によく使用するコマンドについて
紹介しました。
今まで疎通確認をする際はpingしか使用してこなかったため、tracerouteの
存在を知ったときは "こんなに便利なものがあるのか！！" と感動しました。
また、自分が知っているコマンドはほんの一部しかないんだなと改めて実感しました。

これからも沢山の便利なコマンドに出会えると思うととても楽しみでなりません。
「こんなコマンドあるで～！」「これ便利でよく使用しとるよ～」などと
ありましたらご教授いただければ幸いです。

この記事が少しでもどなたかのお役に立てますように。

最後までご覧いただきありがとうございました。
Androidのラジオボタンも名前と値のペアで定義する方法

# え・・・Androidってラジオボタンも名前と値をペアで持っていないの？
[AndroidでHTMLの<SELECT>...<OPTION...>のように名前と値を対比してSpinnerを表示する](https://qiita.com/cozyk100/items/4d47a3bb89eda16030a9)で、HTMLのSELECTタグが名前と値を持てるのにAndroidのコンボボックス(spinner)が名前と値をペアで持てないという話を書きましたが、ラジボタンも同じです。
名前と値をペアで持てません。HTMLができているのに、なんでAndroidで標準でそんな機能がないんでしょう？

と、いうことでHTMLのラジオボタンと同じようなことを実現するにはどうするか？考えてみました。
# ラジオボタンの値を取得する
## 取り敢えず、ラジオボタンの名称でやってみる？
とりあえず、こんな画面を考えてみます。ボタンを押した時にラジオボタンのどっちが選択されているかを取得して、
ラジオ1だったら → 1
ラジオ2だったら → 2
をDBに更新するとか、HTTPでサーバに送るとか・・・そんなケースです。
<img width="50%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933408/572f3f91-72ba-999d-12b9-e86b54dd0055.png">
ラジオボタンのレイアウトのテキストが取得できますので、そのテキストで条件分岐を書くと、
```kotlin
binding.button.setOnClickListener {
    val id = binding.radioGroup.checkedRadioButtonId
    val radioTxt = findViewById<RadioButton>(id).text.toString()
    when (radioTxt) {
        "ラジオ1" -> binding.radioValue.text = "ラジオ1が選択されました"
        "ラジオ2" -> binding.radioValue.text = "ラジオ2が選択されました"
        else -> {}
    }
}
```
これは良くないです。レイアウトのデザインがモロ、コーディング中にかかれてしまっています。ボタンの名称が変わったら、コーディングも変えないといけません。

## Tagを使ってみる。
AndroidのViewにsetTag()、getTag()というメソッドがあります。viewにタグというオブジェクトを関連付けることができます。これで、ラジオボタンのそれぞれに値を関連付けて、それを取ってくるようにします。今、
ラジオ1 → "1"
ラジオ2 → "2"
を関連付けるとします。単純なStringであれば、コードで書かなくてもLayout xmlの中で定義できます。引数はObjectなのでString以外の独自のクラス、Enumとかを関連付けしたい場合はコードで書く必要があります。
```xml
    <RadioGroup
        （中略）
        <RadioButton
            android:id="@+id/radioButton"
          （中略）
            android:tag="1"
            android:text="ラジオ1" />

        <RadioButton
            android:id="@+id/radioButton2"
           （中略）
            android:tag="2"
            android:text="ラジオ2" />
    </RadioGroup>
```
コードはこのようになります。
```kotlonn
binding.button.setOnClickListener {
    val id = binding.radioGroup.checkedRadioButtonId
    val radioVal = findViewById<RadioButton>(id).getTag() as String
    binding.radioValue.text = "ラジオ${radioVal}が選択されました"
}
```
上のラジオボタンのテキストで条件分岐しているのと比べるとスッキリしていますし、ライアウトのデザインの変更がコードに影響しません。Tagについては公式のAndroid develpersを参照してください。
https://developer.android.com/reference/android/view/View#setTag(java.lang.Object)
https://developer.android.com/reference/android/view/View#getTag()

この例ではボタンのOnClickListenerを使ってボタンを押した契機でラジオボタンの値を取得していますが、ラジオボタンの選択を変更した時にすぐに値を取得することもできます。
RadioGroup#setOnCheckedChangeListenerを使います。この場合も同じ様にTagを使って、このようになります。
```kotlin
binding.radioGroup2.setOnCheckedChangeListener { radioGroup, i ->
    val id = radioGroup.checkedRadioButtonId
    val radioVal = findViewById<RadioButton>(id).getTag() as String
    binding.radioOnCheckValue.text = "ラジオ${radioVal}が選択されました"
}
```
# 最後に
完成版は[gitHub](https://github.com/cozyk100/AndroidStudioProjectsPublic/tree/main/RadioNameValueKotlin)に置きました
はじめてのGithub Actions〜Java,Maven編〜

# はじめに
本記事はMDC Advent Calendar 2022の6日目の記事です。

https://qiita.com/advent-calendar/2022/mdc

多くの情報が出ているネタではありますが、実体験記録と、少しでもやってみようと思える人を増やしたいので、記事として残しておきたいと思います。

# Github ActionsでCIしたい

手元でJavaソースをビルドするのも良いですが、何気なタイミングでGithub上のWebIDE上で、ちょろっとpom.xmlを修正したりする時にこれってビルドが通るのだろうか、、と心配になったことは無いでしょうか？

私はこれまでは壊れる可能性がある変更はローカルで変更、簡単なテスト、通ったらGithubへpushと普通にやってましたが、上記ができたら開発スピードアップするのでは？と考えてGithub Actionsもどんどん使う様になりました。

前提としては、SpringBootを使ったMavenプロジェクトになります。
よって、最新のソースコードで

```
mvn package
```
が成功しさえすれば良いということを目指します。

# やり方
基本的にはGithubの公式サイトのドキュメント通りにやればOKです。
以下を参考にしました。

https://docs.github.com/ja/actions/automating-builds-and-tests/building-and-testing-java-with-maven

# 実施記録
おしゃれにやる場合は、GithubActionのワークフロー実行ファイルをymlで手元で書いてpushする、、というやり方なのですが、
一旦初心者なので今回はGithubのサイト上から実施しました。

まず手頃なJavaプロジェクトを用意します。最近リリースされたSpringBoot3を使ったMavenプロジェクトで自分のGithubで管理されているソースコードを使いました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113217/0770db40-8e12-6eeb-3790-707838ab86f5.png)

Actionsタブを選択し、そこの上段にリンクのある、「set up a workflow yourself 」を押下します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113217/c66cd015-cc26-a101-721a-531d19ef1639.png)


そうすると、GithubActionsのビルド設定ファイルの入力画面になりますので、そこで直接記載、コミットすれば良いだけです。
相当楽ですね！

今回はGithub公式サイトでの記載を参考に以下のようにしました。ポイントは以下です。
- pushの度にビルドが行われるようにする
- SpringBootのライブラリが大量に使われるので、都度ダウンロードにならないようにキャッシュさせる
- 作られたJarファイルはアーティファクトとしてGithub上からダウンロードされるようにする

```main.yml

name: Java CI

on: [push]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3
      - name: Set up JDK 17
        uses: actions/setup-java@v3
        with:
          java-version: '17'
          distribution: 'adopt'
          cache: maven
      - name: Build with Maven
        run: mvn --batch-mode --update-snapshots verify
      - run: mkdir staging && cp target/*.jar staging
      - uses: actions/upload-artifact@v3
        with:
          name: Package
          path: staging
```

書けたら右上からStart CommitでOKです。

そうすると、Githubによって自動でファイルを検知、CIを動かしてくれます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113217/49800d76-9ff9-34fa-a697-8c30d1d7ba15.png)

無事成功しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113217/ff235a7f-3374-35e0-df51-5423342045eb.png)

アーティファクト（ビルドされたJarファイル）もここからダウンロードすることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113217/da8faf92-b6ba-47a2-2b98-8b876958e7d9.png)

簡単ですね！

# まとめ

Github Actions、簡単ですね。今回はビルドだけを試してみましたが、テストも拡充させていきたいですね。



使ったGithubリポジトリは以下です。ご参考です。
https://github.com/omix222/springboot30snapshottry
顔画像から表情を認識するモデルを動かしてみた！

事前学習済みモデルを使って表情認識をやってみようと思います。

# はじめに
人間の判断とそれほど相違ない結果になってそうでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952830/f808bf12-c933-55fe-b0a6-228f059bcbd7.png)


ソースコードはこちら↓
https://github.com/Kentea-Watanabe/Facial_Expression_Recognition/blob/main/Demo_Facial_Expression_Recognition.ipynb


# 使うもの
- Yolov5（顔の検出モデル）
- Multi-task EfficientNet-B2（表情認識モデル）


# Multi-task EfficientNet-B2とは？

Multi-taskとありますが、これは単一のモデルに複数のタスクを学習させることを言います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952830/76c0ca1c-3cff-7584-c36f-9e1753ccdb5b.png)



Multi-task EfficientNet-B2では、VGG Face2データセットで事前にトレーニングされたFace recognition CNNを用いて、性別・年齢・人種を分類するようにマルチタスク学習を行います。

〇トレーニングのデータセット
- 性別・年齢予測ではIMDB-WikiとAdienceデータセット
- 人種予測ではUTKFaceデータセット

〇モデル
学習した性別・年齢・人種は、同一人物であれば、画像間の変化は少ないのに対し、顔の表情は、同一人物であっても大きく異なります。

そのため、Face recognition CNNで抽出した特徴量をそのまま表情認識には使用できないと考え、表情認識のために、ネットワーク全体を表情認識データセットであるAffectNetを用いてFine Tuningしています。


# 実装のポイント解説

全体の実装は、[こちら](https://github.com/Kentea-Watanabe/Facial_Expression_Recognition/blob/main/Demo_Facial_Expression_Recognition.ipynb)にあります。


①Yolov5で顔の検出 
②検出された画像に対してMulti-task EfficientNet-B2を用いて表情認識

表情認識のラベルは以下
（※8クラス分類になってます。）
```python
idx_to_class = {
    0: '怒り',     # Anger
    1: '軽蔑',  # Contempt
    2: '嫌悪感',   # Disgust
    3: '恐れ',      # Fear
    4: '幸福', # Happiness
    5: '普通',   # Neutral
    6: '悲しみ',   # Sadness
    7: '驚き'   # Surprise
    }
```

```python
yolo_weight = "/content/face-emotion-recognition/yolov5_face_detection/weights/best.pt"
yolo_dir = "/content/face-emotion-recognition/yolov5_face_detection/yolov5"
d_model = torch.hub.load(yolo_dir, 'custom', path=yolo_weight, source='local')

# 画像の読み込み
img = cv2.imread(input_imgs[0])
# 顔検出_yolov5
pred_im = d_model(img)
# 画像のcrop
det_img = pred_im.crop(save=False)
  
# 1枚の画像に複数の顔が検出されるのでfor文を使用する
for idx in range(len(det_img)):
    # Yoloの推論結果から顔画像取得
    face_img = det_img[idx]["im"]
```

表情認識を行う
```python
MODEL_PATH = '/content/face-emotion-recognition/models/affectnet_emotions/enet_b2_8.pt'
DEVICE = 'cuda' if torch.cuda.is_available() else 'cpu'

model = torch.load(MODEL_PATH)
model=model.to(DEVICE)
model.eval()

img_transforms = transforms.Compose(
    [
        transforms.Resize((260,260)),
        transforms.ToTensor(),
        transforms.Normalize(
            mean=[0.485, 0.456, 0.406],
            std=[0.229, 0.224, 0.225]
            )
    ]
)

# 前処理
img_tensor = img_transforms(Image.fromarray(face_img))
img_tensor.unsqueeze_(0)

# モデル推論
scores = model(img_tensor.to(DEVICE))

# 予測結果
scores=scores[0].data.cpu().numpy()

# 表情認識結果
text = idx_to_class[np.argmax(scores)]
print("感情: ", text)
```
たったこれだけで表情認識できるなんてすごいですね。

# まとめ
これを使って合コン中に相手の表情を取得してやろうと思います!(^^)!

他の事前学習済みモデルを使用すると年齢や性別についても予測できるみたいです。

[論文](https://arxiv.org/abs/2103.17107)には、Multi-task EfficientNet-B2は、モバイルアプリやエッジデバイスで動作するように軽量かつ高精度で認識することを目的に構築されたそうなのでIoT端末でもリアルタイムに動作するかも検証してみようと思います。
価値があるかどうかわからないソフトウェアを遅く提供する方法

この記事は[ NTTコムウェア Advent Calendar 2022 ](https://qiita.com/advent-calendar/2022/nttcomware)14日目の記事です。

# 背景
- スクラムマスタ―として、いくつかのエンタープライズ企業でアジャイルなプロダクト開発をサポートしたり、勉強会などで他のチームの話を聞いていると、組織的な制約や文化などが障壁となり、「価値があるものを早く提供する」理想的な組織像にはなかなか近づけないなと感じます。
- むしろ、あえてそうしているんじゃないかとすら思えるほど、価値があるかどうかわからないものを長い時間かけて検討・開発していることが多くある気がします。（個人の主観です）
- そこで、アジャイル開発としてはアンチパターンと呼ばれるものを、「価値があるかどうかわからないものを遅く提供する」ためのベストプラクティスとしてまとめてみたら面白いんじゃないかと思い、今回の記事を書きました。


# 3つのプラクティス
私の考える最も重要なベストプラクティスは以下です

[1. 詳細な”要件”を全て決めて、全て設計するまでは開発は一切しないようにしましょう。](#1詳細な要件を決めて全て設計するまでは開発は一切しないようにしましょう)
[2. 多くの承認プロセスを設けましょう](#2多くの承認プロセスを設けましょう)
[3. チームを機能別にたくさん分割しましょう](#)


# 1.詳細な要件を決めて全て設計するまでは開発は一切しないようにしましょう

- スケルトンベースのものは作れるからといって開発を始めてしまうと、ショボいものしか提供できないのでやめましょう。たくさんの機能をずーっと長い時間作り続けている方が作っているものの価値があるかどうかもわからないまま過ごせます。
- 入念に検討と計画を行い、特に手戻りは”絶対に"起こさないように気をつけることで、多くの時間を検討に費やすことができるため、開発の着手を遅らせ、結果としてリリースを遅らせることができます。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2323569/e6d55fdb-c2ae-ad10-8431-42a806eebdcd.png)

# 2.多くの承認プロセスを設けましょう
- 開発着手前に「顧客へのヒアリング活動承認」、「スコープ&チーム活動承認」、「設計着手判断」、「設計承認」、「開発着手承認」などできるだけあらゆる活動に対して上位者の承認を得るようにしましょう。そうすることで承認のための準備・調整に時間を割くことができ、価値を生み出す一次ニーズへの対応稼働をなくすことができます。
- できるだけ承認者を複数用意した合議制にし、スケジュールはそれぞれ別の会議で埋めておくことが望ましいです。そうすれば承認会議をはるか先に設定できるので、開発着手等の承認後の活動をさらに遅らせることができます。
 ![スクリーンショット 2022-12-10 午後5.11.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2323569/41a60998-5c77-e4ee-dea9-ba922fde65f7.png)


# 3.チームを機能別にたくさん分割しましょう
- 1つの小さなプロダクトをリリースするまで、できるだけ多くのチームが関わるようにしましょう。そして、各チームが複数のプロダクト開発を兼務する状態にすることで、リリースまでの時間を長くすることができます。
- さらに、各チームがいまなにをやっているのか、余力があるのかどうかをできるだけ不透明にしておくとボトルネック特定ができなくなるので、より効果的です。
 ![スクリーンショット 2022-12-10 午後4.58.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2323569/37eb742f-4d91-f316-743e-14c9cf12a4a3.png)

 
# さいごに
- 私は、「価値があるものを早く提供する」理想像を実現したいので、今回まとめた"ベストプラクティス"はひとつも採用したくはないです。
- ただ、いざ改善していこうとすると組織構造上の問題や文化などすぐにはどうにもならない制約がつきまというまくいかず挫折しそうになります。
- いまは、少しずつやれるところから変えていくしかないと割り切って、試行錯誤しながら理想像の実現に向けて改善を進めています。
- 何を達成したいのか次第ではありますが、今回まとめた"ベストプラクティス"に対する"アンチパターン"を踏みまくってもらい、少しでも素早く市場に価値を届けられるようなチーム・組織が増えることを祈ります。
Google Earth EngineでDEMデータを使ってみた

## はじめに
この記事では、Google Earth EngineでDEMデータを使ってみたいと思います。DEM（Digital Elevation Model）は、数値標高モデルと呼ばれており、簡単にいうと土地の標高を表すデータです。今回は、DEMデータを使って日本がどうなっているのか可視化していきたいと思います。

DEMについての簡単な説明は、こちらの記事をご確認ください。

https://www.gsi.go.jp/KIDS/KIDS16.html

## Google Earth EngineでDEMデータを使ってみた
今回はこちらのデータを使って、試していきたいと思います。

https://developers.google.com/earth-engine/datasets/catalog/CGIAR_SRTM90_V4

こちらのデータを使って、日本の標高を可視化するスクリプトが以下です。

```js
// データの読み込み
var image = ee.Image('CGIAR/SRTM90_V4');
// マップの中心は名古屋市
Map.setCenter(136.9059794183006,35.18392745436158, 7);
// マップの表示
Map.addLayer(image, {min: 0, max: 4000}, 'SRTM');
```

スクリプト自体はめちゃくちゃ簡単です。地図の中心を名古屋市とし、標高は0~4000mの範囲で表示されるようにしました。結果は以下の画像のようになりました。

![スクリーンショット 2022-12-06 22.30.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581736/7f0e0c1f-4053-2824-7539-515428c3c9a1.png)

標高が高い場所ほど色が白くなり、標高が低い場所は黒くなるようになっています。伊豆半島の左上あたりに一点白くなっている場所があると思いますが、そこは富士山です。北アルプス、中央アルプス、南アルプスも一際高いことが見てわかります。これに対して、関東地方は真っ黒になっています。如何に関東平野が広く低地が広がっているかが、一眼で見ることができます。

今回使った90mメッシュになっているので、地図をズームしてみること尾根線や谷線が結構鮮明にみることができます。今回は、富士山や南アルプスの辺りをズームしてみました。右側の白い点のような場所が富士山で、画面中央のモジャモジャしている箇所が中央アルプスです。

![スクリーンショット 2022-12-06 22.37.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581736/40d9eda8-33d1-9cc1-027d-08e437a393d5.png)


## さいごに
今回は、簡単ではありますがGoogle Earth EngineとDEMデータを使って、日本の標高がどうなっているか見てみました。今後はこちらを応用した記事も書いていきます！
ろう者のエンジニアとして働くということ②

### 現在

そしてWEB業界に就職して、WEBエンジニアとして働くことになりましたが、ここでもまた色々な困ったことが起こりました。

その頃はチャットがメインになりつつあったので、聴覚障害者として働く上で困ったことはあまりありませんでした。
でも、周りの人たちの考え方で色々と変なことがあって、それに困りました。

例えば、

１：聴こえない人に仕事を任せて大丈夫なのか？と言われる

２：お客さんとのやり取りでも、「この人は聴こえないから私が代わりに話を聞きます」と言われて割り込まれる

３：仕事を横取りされ、私自身が作ったものを「私がやりました」と嘘をつかれる

４：何かを作っても、「聴こえないのにこんなのできるわけがない、他の人に手伝ってもらったのだろう」と言われる

など、色々なことがありました。
そのたびに色々と困って、でも、何も言えませんでした。

でも、友達に相談したら、「それはあなたも悪い。あなたがはっきりと、自分で堂々としてそれはおかしいです、それは違います！と言わないから、みんなもなめてしまうんじゃないか」と言われました。

その時は、相談したのになんでそんなこと言うの？と思って、悔しかったのですが、でも、そういえば私はいつもいつも聴こえる人からそういうことをされても、「私が聞こえないから仕方がないのかな」と思って黙って我慢してきていたな、と思いました。

そして、そこから、私は聴こえなくても、恥ずかしくない！と思うようになりました。

そして、周りの人たちから変なことをされたら、「やめてください！」とはっきり言うように頑張りました。

その結果、周りの人も最初はビックリしたり笑ったりしていたのですが、私がずっとはっきりと「やめてください」と言うようになったら、だんだんやめてくれました。

そして、私は、聴こえない自分に自信を持っていれば大丈夫なんだ、と気づきました。

今は、周りの人たちに、自分は聴こえないということ、聴こえなくて困ることや助けてほしいことは何かをはっきりと言うようにしています。
そして助けてもらいながら仕事をしています。

### ろう者としての目覚め
これは、人によっていろいろな考え方があると思いますが、私の場合、周りにいるろう者は常に自分をきちんと持っていて、聞こえないということをはっきりと示すことができる人が多いです。
それまで、私は難聴として生きてきたのですが、難聴者だと、なんだかずっと聴こえに縛られているような気がしたのと、もう一つ、自分が聴こえないことを恥ずかしいと思う気持ちがある気がしたので、これからは私は聞こえない人として強く生きていこう！と思うようになりました。
それで、自分のことをろう者と名乗っています。


## 思ったこと

聴こえないと、バカにされたり、何もできないと思われたりして、色々と問題が起こります。
でもそれは、私が聞こえないからではない。
周りの人が勝手に思い込んだり、誤解したりしているだけ。

そして、私自身も、聴こえる人に対しておどおどしていたから、なめられていたんだと思います。

聴こえないと、それだけで、聴こえない人は仕事ができないと思われたり、お客さんと話すことを任せて何かあったらどうしようと思われたり、信頼してもらうのが難しいです。
でもそれだと、エンジニアとして勉強もできないし、成長することもできません。

周りから信用してもらうためには、自分が、聞こえなくても堂々として、自分に自信を持つことが大事だと思います。
そして、間違っていることに対しては、はっきりとやめてくださいと言ったり、私は聴こえないので、困った時は助けてくださいと言ったりすることも大事だと思います。

## 聴こえる人たちへ言いたいこと

聴こえないエンジニアもたくさんいます。
デフエンジニアの会は、50人ぐらいいます。
皆、聴こえなくても頑張っています。なので、聴こえないだけでバカにしたりするのはやめてください。
それよりも、聴こえないということを理解して、一緒に働くことを大事にしてほしいと思います。
よろしくお願いいたします。
for文を使って演習（拡張for文、二重ループ）

# 問題
拡張for文で以下の配列の要素を全て出力してください。
{"まぐろ", "いくら", "うに", "さば", "いか", "ほたて"}

```java
public static void main(String[] args) {
    String sushi[] = {"まぐろ", "いくら", "うに", "さば", "いか", "ほたて"};

    for( String stomach : sushi) {
    System.out.println(stomach);
    }
}
//演算結果
//まぐろ
//いくら
//うに
//さば
//いか
//ほたて

```

# 問題
底辺の値を受け取り 斜辺が右向きの三角形を出力してください。
 
```java
public static void main(String[] args) {  
    triangle(5);
}  
 public static void triangle(int bottom) {
   	for (int i = 0; i < bottom; i++) {
       	for (int j = 0; j <= i; j++) {
   			System.out.print("〇");
   		}
   		System.out.println(" ");
   	}
}

//演算結果
//〇 
//〇〇 
//〇〇〇 
//〇〇〇〇 
//〇〇〇〇〇 

```
【SwiftUI】@AppStorageってまじ便利

# はじめに
iOS14から使用できる@AppStorageがまじで便利なので知らない人には知ってほしい！

# @AppStorageとは？
SwiftUIの@AppStorageは、アプリの設定や状態を永続化するためのプロパティラッパーです。これを使用することで、アプリを終了したり再起動したりしても、その設定や状態を保存したままにすることができます。使用するには、プロパティを@AppStorageプロパティラッパーでラップし、そこに対してアプリ内での設定や状態を保存したい値を代入するだけです。

ChatGPTに書かせてみました笑
たぶんあってますね笑

# 実装
### 基本的な使い方
これだけで値がUserDefaultsに保存されます。
値を変えた時点でUserDefaultsに保存されます。
```swift
@AppStorage("fontSize") var fontSize: Int = 15
```

### AppGroupで使う
このようにすることでAppExtensionでもUserDefaultsを共有することができます。
```swift
@AppStorage("fontSize", store: UserDefaults(suiteName: "com.taishin-miyamoto")) var fontSize: Int = 15
```

# おわり
便利ですが、まだ対応していない型があるのでこれからに期待です。
個人的にはDictionary型に対応して欲しいです。
ORANGE-4 でロータリーエンコーダを読み取る

[ORANGE-4](http://www.picosoft.co.jp/ORANGE-4/index.html) でロータリーエンコーダを読み取ってみた。
今回は、ロータリーエンコーダとして [Pmod ENC](https://digilent.com/shop/pmod-enc-rotary-encoder/) モジュールを用いた。

# ロータリーエンコーダ

(今回扱う)ロータリーエンコーダは、軸を回転させるとA,Bの2本の信号がタイミングをずらして切り替わり、回転していることと回転の方向がわかるものである。
例えば、オシロスコープ FNIRSI-1013D の CH1 に Pmod ENC モジュールの出力Aを、CH2 に出力Bを接続し、軸を上から見て時計回りに回転させると、例えば以下の波形が得られた。
![Pmod ENC の出力例(時計回り)](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/a3455795-2444-c5ca-f8e2-2311632edd44.png)
また、軸を上から見て反時計回りに回転させると、例えば以下の波形が得られた。
![Pmod ENC の出力例 (反時計回り)](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/5cee906a-ca58-7c84-2448-edb5e94b74a7.png)

Pmod ENC では、A,Bが両方HIGHの状態で安定し、軸を次の安定する場所まで回すとA,Bがそれぞれ2回ずつ (合計4回) 変化して再び両方HIGHになる。

# 実装

ロータリーエンコーダの操作により2進LEDの点灯位置が変化するプログラムを作成することにした。

今回は、信号の変化のうち、「BがLOWのときのAの立ち上がりまたは立ち下がり」に注目して検出を行う。
BがHIGHのときは待機し、BがLOWのときにAが変化したらそれに応じて点灯位置を切り替える。
すなわち、以下のような状態遷移となる。
![状態遷移図](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/be9b189b-4572-9faa-26b6-46457158aee1.png)

以下が作成したプログラムである。
[MikeAssembler](https://mikecat.github.io/mike_assembler/) でアセンブルできる。
また、先頭の `target orange4` を削除すれば ORANGE-4 IDE でもアセンブルできる。

:::note
ちなみに、MikeAssembler では最初に `org` を使わない場合アドレスは0から始まるが、ORANGE-4 IDE (Ver 1.02) では後に書いた `org` のアドレスから最初に書いたプログラムが配置されるようであった。
:::

```
target orange4

	; PORT1 : A
	; PORT2 : B

	org 0x00

	; LEDの表示を初期化する
	ldyi 0
	scall 1
	abyz
	; PORT1とPORT2をデジタル入力に設定する
	ldi 2
	ldyi 1
	ioctrl
	ldyi 2
	ioctrl
	; B がLOWでない間、待機する
	ldyi 2
b_high:
	in
	cpi 0
	jmpf b_high
	; B が LOWになった
	ldyi 1
	in
	cpi 0
	jmpf a_high
	; A の LOW→HIGH の変化を待つ
a_low:
	; B をチェックし、HIGHであれば終了
	ldyi 2
	in
	cpi 0
	jmpf b_high
	; A をチェックし、HIGHになっていなければ待機継続
	ldyi 1
	in
	cpi 1
	jmpf a_low
	; LEDの位置を1個左へ
	abyz
	scall 2
	addyi 1
	cpyi 7
	jmpf led_inc_no_wrap
	ldyi 0
led_inc_no_wrap:
	scall 1
	abyz
	jmpf a_high

	org 0x80

	; A の HIGH→LOW の変化を待つ
a_high:
	; B をチェックし、HIGHであれば終了
	ldyi 2
	in
	cpi 0
	jmpf b_high
	; A をチェックし、LOWになっていなければ待機継続
	ldyi 1
	in
	cpi 0
	jmpf a_high
	; LEDの位置を1個右へ
	abyz
	scall 2
	addyi 0xf
	jmpf led_dec_no_wrap
	ldyi 6
led_dec_no_wrap:
	scall 1
	abyz
	jmpf a_low
```

以下が、このプログラムの ORANGE-4 のモニタ用の表現である。

```
E00:A0E1282A1F70A2F7
E10:0A2F72C0F13A1F72
E20:C0F80A2F72C0F13A
E30:1F72C1F252E2B1D7
E40:F45A0E12F80
E80:A2F72C0F13A1F72C
E90:0F802E2BFF9EA6E1
EA0:2F25
```

Pmod ENC と ORANGE-4 を以下のように接続して実行する。

|Pmod ENC|ORANGE-4|
|---|---|
|A|PORT1 (ピン番号6)|
|B|PORT2 (ピン番号7)|
|BTN|-|
|SWT|-|
|GND|GND (ピン番号4)|
|VCC|3.3V (ピン番号1)|

:::note warn
ORANGE-4 の入出力ポートは、デフォルトでは出力モードになっているようである。
Pmod ENC では抵抗が入っているので最初から接続してよいが、その他のモジュールなどを用いる場合はプログラムを実行して入力モードに切り替えてから接続したほうがよい可能性がある。
:::

:::note alert
ORANGE-4では、5Vトレラントの入出力ポートはPORT2のみのようであるため、VCCを5Vに接続してはいけない。
:::

# 実行結果

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

ロータリーエンコーダの操作に合わせて2進LEDの点灯位置が変化している。
【Azure】App Serviceのnginxの設定を初期化しない方法

## 問題
App Serviceで作成したWebアプリのnginxの設定ファイルが、仮想ネットワーク統合やデプロイなどする度に初期化されてしまいます。その都度、設定ファイルを変更するのは面倒ですが、ドキュメントにその対策方法が記載されていたため、忘備録として記事にさせていただきます。

## 解決方法
App Serviceのスタートアップコマンドから、nginxの設定ファイルをコピーして、nginxを再起動します。
ドキュメントに記載されているコマンドはすでに、`/home/site/wwwroot/`にコピーしている想定ですので、下記コマンドを実行しておきます。

````
cp /etc/nginx/sites-available/default /home/site/wwwroot/default
````

そして、ドキュメントに記載されてあるコマンドを入力して設定します。
これでnginxの設定を永続化することが可能です。

## ドキュメント
https://learn.microsoft.com/ja-jp/azure/app-service/tutorial-php-mysql-app#5---change-site-root
競プロ典型90問 022 - Cubic Cake（★2）をJavaで解いてみた！

こんにちは、[Kuni](https://qiita.com/kuniengineer)です。現在Javaを学習中で、Atcoderでコーディング力を高めているところです。
今回は[競プロ典型90問 022 - Cubic Cake（★2）](https://atcoder.jp/contests/typical90/tasks/typical90_v)の実装にチャレンジしてみました。

# ACのプログラム
```java:Main.java
import java.util.*;
 
public class Main {
    public static void main(String[] args) throws Exception {
        // Your code here!
        Scanner sc = new Scanner(System.in);
        long A = sc.nextLong();
        long B = sc.nextLong();
        long C = sc.nextLong();
        
        long gcd_abc = gcd(A,gcd(B,C));
        long count = A / gcd_abc - 1 + B / gcd_abc - 1 + C / gcd_abc - 1;
        
        System.out.println(count);
    }
    
    private static long gcd(long a, long b) {
		// ユークリッド互除法にて最大公倍数を算出
		return b == 0 ? a : gcd(b, a%b);
	}
}
```

# 　プログラムの方針
　今回はA,B,Cとして幅、奥行き、高さを与えられ、それを最低何回の面の切断で立方体にすることができるかを求めるというものでした。
　ここでn×n×nの立方体が作れる場合としては、A,B,Cがそれぞれnで割り切れることが必要です。ここで出来る限り少ない回数で立方体を作る場合には出来る限り大きく切ったほうが良いということになります。つまり複数のnの候補の中でも最も大きい、A,B,Cの最大公約数となるnを探せば良い事になります。
　そこで最大公約数を返すgcd関数を作成しました。gcd関数の内部では、最大公約数を求める方法であるユークリッドの互除法を行っています。
　そして最大公約数が求まった後は、切断の回数を計算します。ここである長さaをある長さbで分ける時の計算方法は(a/b)-1であることから、A,B,Cそれぞれにおいてこちらを計算します。そしてその結果を全て足すと解が求まります。
　
　参考になれば嬉しいです！！
TerraformでEC2のauthorized_keysをUserDataとcloud-initで設定する

TerraformにてUserDataにcloud-initを設定する方法でSSH公開鍵を `authorized_keys` に設定する方法を記載します。


`variables` に公開鍵を `list(string)` で受けるように設定し、`tfvars` にもリスト形式で設定しておきます。


```variable.tf
variable "ssh_authorized_keys" {
  type = list(string)
}
```

```tfvars
ssh_authorized_keys = [
  "ssh-rsa xxxxx",
  "ssh-rsa yyyyy",
]
```


後は[yamlencode](https://developer.hashicorp.com/terraform/language/functions/yamlencode)関数で受ければOKです。

```ec2.tf
resource "aws_instance" "instance" {
# 省略

  user_data = <<EOF
Content-Type: multipart/mixed; boundary="==BOUNDARY=="
MIME-Version:  1.0

--==BOUNDARY==
Content-Type: text/cloud-config; charset="us-ascii"
MIME-Version:  1.0
#cloud-config
${yamlencode({ "ssh_authorized_keys" : var.ssh_authorized_keys })}

EOF
}
```

# 参考

https://cloudinit.readthedocs.io/en/latest/topics/modules.html#authorized-keys
AWS IoTの基礎

自分用メモ

---

# Device Software
- デバイスと接続・操作

## AWS IoT Device SDK
- アプリケーション向け
- アプリからAWS IoT Coreを利用できるようになる

### AWS SDKとAWS IoT Device SDKの違い
- AWS SDKが高機能
- AWS IoT Device SDKは最小限

## Amazon FreeRTOS
- マイコン向け
- OTAアップデートをサポート

## AWS IoT Greengrass
- LinuxOS向け
- デバイス上でAWSサービスを利用できるサービス
    - tar.gzやDockerコンテナ、aptでデバイスにインストールする

### AWS IoT Greengrass Core
- デバイスにインストールするアプリケーション
- クラウドと接続が切れても動作可能
- デバイス間の通信を実現

#### コアデバイス
- Coreを実行するエッジデバイス
- IoTのモノ
- Greengrass Group内に1つ存在する

#### クライアントデバイス
- コアデバイスと接続するローカルIoTデバイス

#### Greengrass Componets
- コアデバイス上で実行されるソフトウェア
- LambdaやDockerなど

### AWS IoT Greengrass Service
- AWS IoT Greengrassのクラウド側のサービス


### Greengrass Lambda
- Core上で動くLambda
- Lambdaで組み込みソフトウェア開発を簡素化


### デバイスシャドウ
- Greengrass Core上で動き、IoT Coreのデバイスシャドウと同期する

# Control Services
- デバイスの通信・管理・保護

## AWS IoT Core
- IoTデバイスを通信できるようにするサービス
    - 大量のデバイスをAWSにつなげられる
- データ収集とデバイス制御を担う

### レジストリ
- デバイス毎に静的な属性（レジストリ）と動的な状態（デバイスシャドウ）を管理

#### モノのタイプ
- 属性やモノの親にあたる
- 1つのデバイスに指定できるモノのタイプは1つかつ変更不可
- モノのタイプの名前変更不可

#### モノのグループ
- デバイスをグループ化して管理する
- モノのグループの名前変更不可
- 1デバイスに指定できるグループは10個まで
    - 同階層のグループに所属はできない
- モノのグループの親は1つまで設定可能かつ変更不可
    - 階層は7階層まで
    - 子グループは最大100個
- グループにアタッチできるIoTポリシーは最大2つ

## AWS IoT Device Management
- 増加するデバイスの導入、整理、監視、リモート管理するサービス
- デバイス管理を担う

## AWS IoT Device Defender
- IoTセキュリティサービス

# Analytics Services
- IoTデータから価値を抽出

## AWS IoT SiteWise
- データ収集

## AWS IoT Events
- 監視してイベント発生時にトリガーするサービス

# 感想
- いろいろあってイマイチそれぞれの使いどころが分かっていない……
CATのここが好き

# 概要
CATフリープランをテスト管理に使ってみました。実は筆者はCATよりQaseの方が好きです！
いきなりの浮気ですが、CATには
1. dashboardがフリープランで付いている
2. ワークスペースの容量が 5GB と広い
3. Excelっぽい使い勝手
という特徴もあって、特にExcelっぽいのは、とかくスプシやExcel形式のテストケースが忌み嫌われがちですが、ツールですから、馴染んだ道具を選ぶというのもアリです。
# お気に入り、その1：外部参照
CATはアカウント使ってのログインを必須としますが、dashboardや集計・分析画面については、外部参照という機能を使って、プロジェクトチーム内で共有することも可能です。画面のURLが発行されますので、見るだけですが共有ができます。見るだけでは足りない時は、CATに招待すればいいです。
![cat001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939617/bcbb8f68-5e31-4ba0-37fa-75ed17fe51aa.png)
# お気に入り、その2：ヘッダテンプレート設置
Qaseのテストケースが、「Action」「Input Data」「Expected Result」という基本的ヘッダで構成されていて、Excelの限界まで列が増殖したテストケースを見てきた経験からシンプルさはとても魅力的に感じました。CATのデフォルト列設定は、あまり好きじゃないので、Qaseっぽいヘッダテンプレートを定義して利用しています。
![cat002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939617/73977244-e7ae-8121-c348-248cc384abec.png)
使いにくいと思ったら、好きなようにカスタマイズすればいいのです。
# お気に入り、その3：テストケース編集作業がExcelっぽい
編集作業中のセルのコピペが、まるでExcelです。複数セル選択して、同じものを全部にコピペできたり、Excelの操作に馴染んでいる方には、ほとんど違和感なく使えると思います。
![cat004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939617/38d756fb-8bad-2527-fa2b-24c2b6610acc.png)
# お気に入り、その4：複数行のテスト結果、一括入力
自動テストのテスト結果のように、件数が多い場合には、複数行選択して、テスト結果ボタンから記録ができる点、楽です。
![cat003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939617/e49a8814-4c8e-e3ce-fd0c-7262a0e7c1cc.png)
# お気に入り、その5：種別の管理
課題管理機能には、テスト実行中のバグ登録から入る場合が多いですが、テスト前のレビューでも、CATが使えます。この場合、デフォルトの「不具合」「要望」「問い合わせ」「サブタスク」に加えて「レビュー観点アプローチ」という種別を定義して課題管理で使います。
![cat005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939617/84a597fa-b29c-058e-0a27-5e5b76dc12ce.png)
セミナーで入手した情報は、どんどんツールで使いまくりましょう。
# お気に入り、その6：テストケース修正履歴
特にマニュアルテストのテストケースは、テスト開始から終了まで、修正されないことはあまり無くて、ケース修正をしながらテスト実施ということも多いのですが、修正箇所の記録が残るため、記録されたタイムスタンプから修正し忘れをある程度防げます。
![cat007.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939617/a7f65687-a919-6344-10b9-811c81654e1b.png)
# お気に入り、その7：Excelからテストケースのインポート
GIHOZで生成したテストケース、または、Pictmasterで生成したpairwiseテストケースなど、一旦、Excelで整形した後、テストケースとしてCATに取り込んで利用した方が簡単な場合もあります。
![cat006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939617/9e7cf3e3-8c89-c3c3-2fc1-f6fcc1b7b69d.png)
# 総括
道具は使いようで、工夫して使えばツールの恩恵を受けることができます。
フリープランのテスト管理ツールで、ここまでできます。
使わない手は無いですね。
Javaで何か作ってみる(2022/12/6 Day47)

## 今日やった事
- オブジェクト指向の動画教材を見た。（**J2-02_コンストラクタ** の途中まで見た。）
## 参考にしたもの
- [Spring 入門 ～ SpringBoot 2 を使ってお問い合わせアプリとToDoアプリを作る ～](https://www.udemy.com/course/java_spring_beginner/)  
- [【超初心者も必見】Javaプログラミングの「オブジェクト指向」が絶対理解できる講座【プロ講師が丁寧解説】](https://www.udemy.com/course/uz-java-obj/)  
## 所感
- 現場でC#をやっていた時に、オブジェクト指向をやっていたが、直近はPHPでC#ほど意識しなくても支障がなかったので、
思い出しながらやっている。
## 明日の予定
- 引き続き、動画教材を進めていく。
Javaで何か作ってみる(2022/12/5 Day46)

## 今日やった事
- オブジェクト指向の動画教材を見た。（**J2-01_オブジェクト指向とは** の途中まで見た。）
## 参考にしたもの
- [Spring 入門 ～ SpringBoot 2 を使ってお問い合わせアプリとToDoアプリを作る ～](https://www.udemy.com/course/java_spring_beginner/)  
- [【超初心者も必見】Javaプログラミングの「オブジェクト指向」が絶対理解できる講座【プロ講師が丁寧解説】](https://www.udemy.com/course/uz-java-obj/)  
## 所感
- Springの動画教材を見ていて、オブジェクト指向について若干怪しかったので、  
オブジェクト指向の動画を進める事にした。
## 明日の予定
- 引き続き、動画教材を進めていく。
FPGAプログラミング大全Xilinx編第2版 TD4 #6

FPGAに再入門しようと思いたち[FPGAプログラミング大全Xilinx編第2版](https://www.amazon.co.jp/FPGA%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E5%A4%A7%E5%85%A8-Xilinx%E7%B7%A8-%E7%AC%AC2%E7%89%88-%E5%B0%8F%E6%9E%97-%E5%84%AA/dp/4798063266/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=1S5G3UKPB55O9&keywords=FPGA%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E5%A4%A7%E5%85%A8Xilinx%E7%B7%A8%E7%AC%AC2%E7%89%88&qid=1669893715&qu=eyJxc2MiOiIwLjc2IiwicXNhIjoiMC4wMCIsInFzcCI6IjAuMDAifQ%3D%3D&sprefix=fpga%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E5%A4%A7%E5%85%A8xilinx%E7%B7%A8%E7%AC%AC2%E7%89%88%2Caps%2C151&sr=8-1)を頭からやっていく6日目

時期的にも良いので一人Advent Calendarで25日続ける

FPGAプログラミング大全ではCPUを作る方に行かないので今日からは[CPUの作り方](https://www.amazon.co.jp/CPU%E3%81%AE%E5%89%B5%E3%82%8A%E3%81%8B%E3%81%9F-%E6%B8%A1%E6%B3%A2-%E9%83%81-ebook/dp/B08639XM13/ref=sr_1_1?adgrpid=56066879911&gclid=Cj0KCQiA7bucBhCeARIsAIOwr-9UTCHVPClOIgYn0LaaqYmR4g2MWF40orC-R0t2tmpx87cU-Wj1ko0aAljrEALw_wcB&hvadid=618673188431&hvdev=c&hvlocphy=1009300&hvnetw=g&hvqmt=e&hvrand=12178006679013735266&hvtargid=kwd-335340839695&hydadcr=15818_13600556&jp-ad-ap=0&keywords=cpu%E3%81%AE%E4%BD%9C%E3%82%8A%E6%96%B9&qid=1670330101&sr=8-1)と合わせてやっていくことにする

### 25日終了時の目標
4004等の実CPUの実装

### 目次
| # | タイトル |
|:-:|:-:|
|   01|  [ツール導入](https://qiita.com/Gazyu/items/8f3797abf4ddc88ecacd) |
|  02 |  [実機テスト下準備](https://qiita.com/Gazyu/items/b59e0a1e023005bc02d5) |
|  03 |  [実機テスト](https://qiita.com/Gazyu/items/23ec4da6c241d95bfa8e) |
|04|[クロック利用](https://qiita.com/Gazyu/items/a653fe87023323f308de)|
|05|[シミュレーション検証](https://qiita.com/Gazyu/items/508370018465c164120b)|
|06|TD4|
|07|未定|


### 環境
【実装ボード】 [Digilent Artix-7 35T Arty FPGA 評価キット](https://japan.xilinx.com/products/boards-and-kits/arty.html#resources)
【OS】 Windows10
【IDE】 Vivado 2022.2

### 今日のゴール
TD4の命令セットをまとめる

### TD4の仕様
CPUの作り方に載っているTD4を実装できるように仕様をまとめる

#### 大枠
- 4bit CPU
- 演算用レジスタは2つ、それぞれ4bitずつ
- フラグはキャリーのみ
  - 加算でキャリーが発生した時に1になるのみ
- 入出力が4bit

#### 命令フォーマット
|bit7|bit7|bit6|bit5|bit4|bit3|bit2|bit1|bit0|
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|

上位4bitをオペコード、下位4bitをイミディエイトデータにする

#### 命令セット
|命令|意味|オペコード|
|:-:|:-:|:-:|
|ADD A, Im|AレジスタにImを加算|0000|
|ADD B, Im|BレジスタにImを加算|0101|
|MOV A, Im|AレジスタにImを入れる|0011|
|MOV B, Im|BレジスタにImを入れる|0111|
|MOV A, B|AレジスタにBのデータを入れる|0001|
|MOV B, A|BレジスタにAのデータを入れる|0100|
|JMP Im|Imアドレスにジャンプ(絶対アドレスのみサポート)|1111|
|INC Im|キャリーフラグがない場合のみImアドレスにジャンプ（必ず加算命令の直後のみ実行）|1110|
|IN A|入力ポートからAレジスタに転送|0010|
|IN B|入力ポートからBレジスタに転送|0110|
|OUT B|Bレジスタのデータを出力ポートに転送|1001|
|OUT Im|データをそのまま出力ポートに転送|1011|

今日はここまで
ChatGPTのエンターキー問題を解決するChrome拡張を書いたよ

ChatGPT、使っていますか？
めちゃくちゃ便利ですよね。

ですが、日本語入力中に変換を確定させるために押す Enter と、本当に送信したい時に押すEnterの区別がつかないようなんですね。

なので、文字変換の際のEnterではChatGPTに話しかけないようにするChrome拡張を作成しました。

https://greasyfork.org/ja/scripts/456119-chatgpt-enter-fix

インストールにはTampermonkeyが必要です。

なんだそりゃ？という方は以下をご参照ください。

[Tampermonkeyの使い方 | SYMMETRICソフトウェア開発ブログ](https://www.symmetric.co.jp/blog/archives/920)

それでは快適なChatGPTライフを！
SpeechRecognitionで遊んでみたよ

詠唱したら魔法打てないかな、なんて思っていたので、Pythonの音声認識モジュールであるSpeechRecognitionで遊んでみました。誰かナノマシンつくってくれないかな。
[Python - SpeechRecognition](https://pypi.org/project/SpeechRecognition/)
## SpeechRecognitionのインストール
```:cmd
pip install SpeechRecognition
```
みんな大好きpipコマンドです。
## wavファイルで入力して文字列に変換
コードはこんな感じ。
```python:test.py
import speech_recognition as sr

r = sr.Recognizer()

with sr.AudioFile("./aftereat.wav") as source:
    audio = r.record(source)

text = r.recognize_google(audio, language = 'ja-JP')

print(text)
```
ファイルは.wav拡張子じゃないと通らないので気をつける。
拡張子を無理やり変えてもだめです。ちゃんとコンバート、コンバート。
あとちゃんとパスを指定しましょう。

音声ファイルはこちらからお借りしました。
[Booth - Afterifk Kawaii Voice β](https://booth.pm/ja/items/3724228)

Let's 実行
```:cmd
python test.py
ごちそうさま
```
きゃーコマンドプロンプトちゃんkawaiiデス！
彼女と結婚できる日もそう遠くないでしょう。
## リアルタイム入力で字幕付け
リアルタイム入力での文字起こしでは、SpeechRecognitionのほかに、PyAudioというモジュールが必要になってきます。こちらもpipコマンドでインストールしておきましょう。
```:cmd
pip install pyaudio
```
ではコードはこんな感じ。
```python:test.py
import speech_recognition as sr
import pyaudio, time

SAMPLERATE = 44100

def callback(in_data, frame_count, time_info, status):
    global sprec 

    try:
        audiodata = sr.AudioData(in_data,SAMPLERATE,2)
        sprec_text = sprec.recognize_google(audiodata, language='ja-JP')
        print(sprec_text)
    except sr.UnknownValueError:
        pass
    except sr.RequestError as e:
        pass
    finally:
        return (None, pyaudio.paContinue)
    
def main():
    global sprec 
    sprec = sr.Recognizer()
    audio = pyaudio.PyAudio() 
    stream = audio.open(
        format = pyaudio.paInt16,
        rate = SAMPLERATE,
        channels = 1, 
        input_device_index = 1,
        input = True, 
        frames_per_buffer = SAMPLERATE*2,
        stream_callback=callback
    )
    
    stream.start_stream()
    while stream.is_active():
        time.sleep(0.1)
    
    stream.stop_stream()
    stream.close()
    audio.terminate()

if __name__ == '__main__':
    main()
```
実行結果は以下の通り
```:cmd
python test.py
おはよう
フェリシアです
おねむ です
あめんぼあおいよ あいうえお
ニセコ
```
私は「おはよう ふぇりしあです おねむです あめんぼあおいよあいうえお すごい」とマイクに向かって入力したので結構精度高いみたいです。というかふぇりの名前がカタカナで出力されたのですが、これはreconize_google()が優秀だったのかな？
ユーザビリティ備忘録

世の中にあるいろんなWEBアプリを使ったり、時には作ったりしてきた中で、こういう工夫がユーザビリティにつながるのでは？と思ったポイントを備忘録的にまとめます。
テーブル行は交互に色を付けたほうが見やすいとかそういうのです。
（要件がどうとか諸説あると思いますが気にせず書いていきます。備忘録なので）


### ・有名どころの画面レイアウトを~~パクる~~参考にする
ユーザーの目は肥えてるので、彼らが慣れ親しんでいるWEBサイトやアプリの素晴らしい画面を基準に画面を操作する。
というのを前提に、独自の視点で画面を作らないようにする。
自分が作ろうとしているものの競合になりそうな（またはそれに近いジャンルの）WEBサイトの中でビュー数が多そうなものを見てみて、どうして見やすいのかを分析する作業が大事かな。


### ・ユーザーのIQは2であることを意識する
要は画面を見るときに、ユーザーに推測させてはいけない（頭を使わせてはいけない）。
頭からっぽでも操作できるように、小手先のテクニックをちりばめて誘導させまくるというマインドが重要。
↑の「有名どころの画面レイアウト」はエンドユーザーのことをバカだと思って作っているから成功しているんだと思う。

僕は重度のAmazonユーザーでよく利用しているんですが、たまにAmazonプライムビデオのリンクってどこだ…？ってなるときがある。
ヘッダーに「Prime Video」って出てるんだけどアホなので見逃す。こういうユーザーもいるんだと思って画面は作ったほうがよさげ。
（Amazonは何も悪くないです）


### ・テーブル行は交互に色を付ける
ついでにテーブル罫線はなるべく使わず、ヘッダー明細とかもできるだけ色分けで表現する。
（罫線がついてるとヘッダー固定のスクロール機能つけるときに厄介）
```css
table tbody tr:nth-child(odd) td {
	background: red;
}
```


### ・入力フォームにはプレースホルダーをつける
すぐ横にラベルがついてるからわかるでしょは通じないというマインドを持っていたほうがいい気がする。
（人間はいざ入力しようとフォームに意識を向けるとラベルが視界から消える生き物なので）
ついでに入力中でもプレースホルダーが消えないようなCSSを実装するとなおいいかも
```html
<input type="text" placeholder="名前">
```
※逆にプレースホルダーがあるからといってラベルなしのフォームは用意すべきでない。
※**人間は空のフォームに注目が行きやすい生き物なので、プレースホルダーがあると逆に入力済みと誤認するリスクがある。** ので一概には言えない気もする。。。
参考：

https://u-site.jp/alertbox/form-design-placeholders


### ・TABキーの移動を常に意識してフォームを配置する
TABキーで移動する場合につながりのある移動を行えるようにフォームを置く。（単純なのだと姓→名とか）
人間の視界の動き方（Zの字）とtabindexの挙動は同じなので、これを意識しておけばレイアウト設計は割とスムーズに行く気がする。


随時追加していきます。
DOM操作、WINDOWオブジェクトのみでの英単語システム作成方法

<h1>本記事はDOM操作、WINDOWオブジェクトによるランダム英単語作成システムの作成方法に関して紹介しています。</h1>

<p>まず、クリックしたらランダムな単語テストを表示する機能を作成します。</p>
<p>htmlでテスト作成ボタンを作ります。</p>


```html
<button id="buttonid">作成</button>
```
<p>そしたら、DOM操作を使ってバタンのidを取得します。</p>

```js
let button = document.getElementById('buttonid');
```
<p>ボタンのidはgetElementByIdで取得します。</p>
<p>次にaddEventListenerでクリックされた時の処理を作成します。</p>
<p>この前にhtml内にテーブルを作成する素地を作っておきます。</p>

```html
<p>Transelate English to Japanese.</p>
            <table id = "testTable" border="1" width="500">
                <tr>
                    <th>word</th>
                    <th>answer</th>
                </tr>
            </table>
```
<p>問題となる単語を格納する配列を作成します。</p>


```js
wordList=['word1','word2','word3'];
```
<p>ランダムな数を作成する関数を作成します。</p>


```js
var randoms = [];
var min = 1, max = wordList.length-3; 
for(i = min; i <= max; i++){
  while(true){
    var tmp = intRandom(min, max);
    if(!randoms.includes(tmp)){
      randoms.push(tmp);
      break;
    }
  }
} 
function intRandom(min, max){
  return Math.floor( Math.random() * (max - min + 1)) + min;
}

```

<p>そしたら、いよいよランダムテスト作成システムを作っていきます</p>


```js
button.addEventListener('click',function(e){
    alert('test creating start.');
    for(let i=0;i<11;i++){
        let tbl = document.getElementById("testTable");
        let row = document.createElement("tr");
        let cellText = '';
        for (let j=0; j<2; j++){
            let cell = document.createElement('td');
            if(j===0){
                cellText  = document.createTextNode(wordList[randoms[i]]);
            }else{
                 cellText = document.createTextNode('　　　　　　　　　　　　　　　　');
            }
            cell.appendChild(cellText);
            row.appendChild(cell);
        }
                tbl.appendChild(row);
    }
},false);
```

<p>最後に作成した英単語テストを印刷する機能を作成します。</p>

```html
<button id="buttonid2">印刷</button>
```
<p>印刷はWindowオブジェクトのwindow.print()を使います。</p>

```js
let print_button = document.getElementById('buttonid2');
print_button.addEventListener('click',function(e){

  window.print();
});
```

<p>style.visiblyを使うとよりいい感じに作れると思います！</p>

<p>実際に作成したコードの一部を改変して記載しているのでコピペして使用した場合バグが発生する可能性があります。予めご了承ください。</p>

<a href="https://tiger3046.github.io/testCreater_GUIver/html/index.html">こちらが実際に作成したシステムです。</a>
GASでタイムゾーンを設定する方法を調べてみた

## はじめに
Google Apps Scriptで、日付操作ライブラリである`Day.js`を使っていたときに、現在時刻を取得しようとしたら日本時間ではない時間が取得されてしまいました。関数の方にタイムゾーンを設定しても上手くいかず少し迷ってしまったので、今回はGASでタイムゾーンを設定する方法をまとめようと思います。

## GASでタイムゾーンを設定する方法を調べてみた
### 事前に
今回は時間を取得するために`Day.js`というライブラリを使います。ライブラリの追加する方法は、GASのエディタを開き、ライブラリから以下のコードを貼り付けて検索、追加してください。

- コード：`1ShsRhHc8tgPy5wGOzUvgEhOedJUQD53m-gd8lG2MOgs-dXC_aCZn9lFB`
- [参考資料](https://gas.excelspeedup.com/dayjs/)

追加されると、以下のように表示されます。
![スクリーンショット 2022-12-06 14.03.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581736/468e7a19-4369-4d30-979c-1f85d7df9460.png)

### 本題
さて、本題に移ります。以下のスクリプトを動かしてみたところ、違うタイムゾーンの結果が返ってきました。
```js
const getTime = () => console.log(dayjs.dayjs().toDate());
// Tue Dec 06 2022 00:08:04 GMT-0500 (Eastern Standard Time)
```

関数の方をいじってみましたが上手くいかず、調べてみたところ`プロジェクトの設定`から変更できることがわかりました。GASのエディタの左サイドバーにある歯車マークをクリックすると、タイムゾーンを設定する箇所が出てきます。そこから、自分が使いたいタイムゾーンに設定してください。

![スクリーンショット 2022-12-06 14.14.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581736/0fda25da-1b33-9d3c-6fd5-a6793e8046b2.png)

ちなみに`プロジェクトの設定`以外からタイムゾーンを変更することも可能です。GASにはプロジェクトのマニュフェストファイルである`appsscript.json`があり、そこからタイムゾーンを設定することも可能です。

以下のようなファイルになっているため、`timezone`の箇所を自分が使いたいタイムゾーンに書き換えることで変更可能です　(今回は`Day.js`ライブラリを追加しているため、ライブラリが追加されています）

```json:appsscript.json
{
  "timeZone": "America/New_York",
  "dependencies": {
    "libraries": [
      {
        "userSymbol": "dayjs",
        "version": "1",
        "libraryId": "1ShsRhHc8tgPy5wGOzUvgEhOedJUQD53m-gd8lG2MOgs-dXC_aCZn9lFB"
      }
    ]
  },
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8"
}
```

## さいごに
今回は、簡単ではありますがGASでタイムゾーンを設定する方法についてまとめてみました。
バックエンドエンジニアが React Redux をメンテナンスするためにやっていること

# バックエンドエンジニアが React Redux をメンテナンスするためにやっていること
こんにちは CLB です。
今回は、所属企業のアドベントカレンダーとして記事を投稿します。

この記事はチームスピリット Advent Calendar 2022の6日目の記事です。

https://adventar.org/calendars/7905

# ストーリー
私たちの企業では、画面を担当するフロントエンド(以下FE)と業務ロジックを担当するバックエンド(BE)が一緒のチームで機能を追加・実装しています。

FEとBEは利用する技術が異なるため、通常はそれぞれの担当領域のタスクを実施しておりますが、
実装のタスク量やスケジュールの関係でFEがチームの人数以上に必要な場合が時として発生します。
(その逆のパターンも当然あります。)

そんな時にBEもFEのタスクを助ける必要があります。
今回は自分がFEのタスクをできるようにするために行ったキャッチアップの方法を紹介します。

なお注意点ですが、
- あくまで個人の見解です。また、当方初心者なのでReactに関する記述については誤りもあるかもしれません。
- 私の企業では React Redux を利用しているので、前提として React Redux の記事となります。

それでは行きましょう。

## React Developer Tools を利用して、どのファイルを変更すれば良いのかを知る
フロントエンドのタスクを最初に行うにあたり、最初に思ったことは

**どのファイルを変更すればよいかわからない**

ということです。
最初の段階では、画面に表示された単純なテキストですら
どのファイルを変更すれば良いかわかりませんでした。

このようなときに非常に役に立つツールがChrome の React Developer Tools です。


https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi/related

このツールでReactのページを表示し、開発者コンソールから `components` タブを開きます。
すると画面上に表示しているコンポーネント(ファイル)がハイライト表示されるので、
どのコンポーネント(ファイル)を変更すれば良いのかがわかるようになります。


![スクリーンショット 2022-12-06 19.18.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360434/baafa7a4-9178-c9ab-280e-e24356484f1c.png)

これを駆使して最初は画面の単純な修正などを行っていきました。


## Reactのjsxファイルを理解する
React Developer Tools を利用してどのファイルを変更すれば良いのかを知ることができれば、
理解ができると思うのですが、jsxファイルとは(私の理解では) html を返す関数のことです。

https://create-react-app.dev で作成した初期状態の jsx ファイルは以下のように `return` で
htmlを返却しているようになっております。 

```jsx
import logo from './logo.svg';
import './App.css';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        ”中略”
      </header>
    </div>
  );
}

export default App;
```

この `return` は html であるため、中身を変更すればメッセージや表示内容を変更することができますが、
より深い内容を知りたかったので次に React チュートリアルを行うことにしました。

https://ja.reactjs.org/tutorial/tutorial.html

このチュートリアルを行うことで、基礎的な React の操作を行うことができるようになりました。


## React-Redux を学習する
ここまで行うと、表示のロジックなどやや複雑なことは理解できるようになりますが、
まだデータの保存やAPIの実行などの不明点が多かったので、さらに理解を深めるため、
現在は以下の記事を読んで勉強しています。

https://reffect.co.jp/react/react-redux-for-beginner

この記事の内容を理解しつつ、コードを写していくことで
よりFEの業務を担当することができるようになってきております。

## これから
上記を行うことによって簡単なものであればFEタスクを一部担当することができようになりましたが、より複雑なタスクを行うために以下のような学習を模索しています。
- テストの書き方
- 他のReactライブラリの理解を深めること(usememoやeffectなどなど・・・)

来年あたりにはフルスタックを名乗れるように頑張りたいと思います！
脅威インテリジェンス とは

## 勉強前イメージ

インテリジェンスはわからんけど
なんかセキュリティ系のことってだけはわかる。。。。

## 調査

### 脅威インテリジェンス とは

英語で Threat Intelligence と言われており
脅威に関する情報で攻撃者の意図や設備に関する情報を整理・分析して意思決定に使われるように集計したものを指します。
脅威インテリジェンスの中には攻撃の識別方法や影響、防御のアドバイスなどもあり、これらを活用することで
そもそも検知すらできなかった高度なサイバー攻撃などを検知・防御できる可能性が高まります。

### 脅威インテリジェンスのタイプ

脅威インテリジェンスはほとんどが以下の3つのタイプのどれかに当てはまります。

- 戦略的インテリジェンス

組織の上層部が使用することを想定したもので、
事業戦略を立てたりサイバー攻撃の情勢を知るために使われます。

- 運用的インテリジェンス

主にマネージャー層が使用することを想定して
トレンドを知ったりパッチマネジメントなどのサイクルを回すために使われたりします。

- 戦術的インテリジェンス

担当者が使用することを想定して
サイバー攻撃のトレンドや脅威のハンティングなど現場で使用するために使われます。

## 勉強後イメージ

セキュリティを防御するためのトレンドみたいなのがあるってイメージかな

## 参考

- [脅威インテリジェンス（Threat intelligence）](https://www.sompocybersecurity.com/column/glossary/threat-intelligence-definition)
- [脅威インテリジェンスとは？その種類や重要性などについて解説](https://www.lrm.jp/security_magazine/threat_intelligence/)
【Linux】ログインシェルの変更方法

## 現在のログインシェルの確認

変更前のログインシェルを確認するには以下のコマンドを実行します。  

```terminal
$ grep $USER /etc/passwd
sample:x:1000:1000:,,,:/home/sample:/bin/bash
```

上の場合にはログインシェルは`/bin/bash`です。  

## 変更方法

ログインシェルを変更するには次のコマンドを実行します。  

```terminal
chsh -s シェル
```

`/bin/sh`をログインシェルにする場合には以下のようにします。  

```terminal
$ chsh -s "$(which sh)"
Password: 
```

また利用できるシェルの一覧を確認するには次のコマンドを使用します。  

```terminal
$ cat /etc/shells
# /etc/shells: valid login shells
/bin/sh
/bin/bash
/bin/rbash
/bin/dash
```

`sudo`を使用して以下のように実行しても同様の結果となります。  

```terminal
sudo chsh -s "$(which sh)" sample
```

```terminal
$ grep $USER /etc/passwd
sample:x:1000:1000:,,,:/home/sample:/bin/sh
```