OmniAICreator/Qiita-1.07M huggingface dataset:
Visual StudioでAzure FunctionsをAzureに発行しようとしたところ failed with HTTP status code Forbidden エラー

# はじめに
Visual Studio上からAzure Functionsを発行しようとしたところ、以下のエラーメッセージが表示され発行できませんでした。

`The attempt to publish the ZIP file through https://xxx.scm.azurewebsites.net/api/zipdeploy failed with HTTP status code Forbidden.`

# 状況
* Visual StudioでタイマートリガーのAzure Functionsプロジェクトを作成
* Azure Portal上でAzure Functions(関数アプリ)を作成、ここに開発用PC上のVisual Studio上から発行をしたかった(お遊びアプリ作成のためなのでCI/CDは考慮せず、Azure Functionsをサクッと試してみたかった)
* Azure Functions上で発行プロファイルを取得し、Visual Studio>発行からプロファイルをインポート
* ZipDeployをすると冒頭のエラーメッセージが表示され、発行に失敗した

# 原因と解決
Azure Functions作成時にアクセス制限でパブリックアクセスを許可していないためでした。
開発用PCからアクセスできるよう、関数アプリ>ネットワーク>アクセス制限から適切に設定することで解決しました。
BigQuery のナビゲーション関数を使用し、直近の過去データで穴埋めをする

## やりたいこと
BigQuery に GA4 のデータが蓄積されている状態で、以下のように user_id に null がある場合、同じ user_pseudo_id であれば、その直近の過去の user_id で置換をしたい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397664/59848acd-84c2-37f1-696f-8b47d8e2a5cc.png)




## 実現方法

FIRST_VALUE、または LAST_VALUE を使用して以下のクエリで実現できた。

<details><summary>上記のsampleテーブル作成用クエリ</summary><div>

```sql
WITH sample AS (
  SELECT
    null AS user_id
    , '123456789' AS user_pseudo_id
    , '2022-08-03 10:00:00' AS event_datetime
  UNION ALL
  SELECT
    null AS user_id
    , '123456789' AS user_pseudo_id
    , '2022-08-03 11:00:00' AS event_datetime
  UNION ALL
  SELECT
    'A' AS user_id
    , '123456789' AS user_pseudo_id
    , '2022-08-03 12:00:00' AS event_datetime
  UNION ALL
  SELECT
    null AS user_id
    , '123456789' AS user_pseudo_id
    , '2022-08-03 13:00:00' AS event_datetime
  UNION ALL
  SELECT
    null AS user_id
    , '123456789' AS user_pseudo_id
    , '2022-08-03 14:00:00' AS event_datetime
  UNION ALL
  SELECT
    'B' AS user_id
    , '123456789' AS user_pseudo_id
    , '2022-08-03 15:00:00' AS event_datetime
  UNION ALL
  SELECT
    null AS user_id
    , '123456789' AS user_pseudo_id
    , '2022-08-03 16:00:00' AS event_datetime
  UNION ALL
  SELECT
    null AS user_id
    , '123456789' AS user_pseudo_id
    , '2022-08-03 17:00:00' AS event_datetime
)

SELECT * FROM sample
```
</div></details>

```sql
SELECT
  user_id
  , FIRST_VALUE(user_id IGNORE NULLS)
    OVER (
      PARTITION BY user_pseudo_id
      ORDER BY event_datetime ASC
      ROWS BETWEEN 0 PRECEDING AND UNBOUNDED FOLLOWING
    ) AS most_recent_user_id_first_val
  , LAST_VALUE(user_id IGNORE NULLS)
    OVER (
      PARTITION BY user_pseudo_id
      ORDER BY event_datetime DESC
      ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
    ) AS most_recent_user_id_last_val
  , user_pseudo_id
  , event_datetime
FROM sample
ORDER BY event_datetime
```

| user_id | most_recent_user_id_first_val | most_recent_user_id_last_val | user_pseudo_id | event_datetime |
|:-----------|------------:|------------:|:------------:|:------------:|
| null       | A        |A        | 123456789         | 2023/05/01 10:00:00 |
| null     | A      |A        | 123456789       | 2023/05/01 11:00:00 |
| A       | A        |A        | 123456789         | 2023/05/01 12:00:00 |
| null         | B          |B        | 123456789           | 2023/05/01 13:00:00 |
| null         | B          |B        |  123456789           | 2023/05/01 14:00:00 |
| B       | B       |B        |  123456789       | 2023/05/01 15:00:00 |
| null         | null          |null        |  123456789           | 2023/05/01 16:00:00 |
| null         | null          |null        |  123456789           | 2023/05/01 17:00:00 |


## 参考
https://zenn.dev/justice_vsbr/articles/780235b4a4bd5d
「/etc/aliases」ファイル

●「/etc/aliases」ファイルではメールのエイリアス（別名）を設定することが出来ます。

「/etc/aliases」ファイルの書式。

アカウント名： 受け取りユーザ名[,受け取りユーザ名 ...]

別名
・/ファイルのパス　指定したファイルにメールのメッセージを追加
・|コマンド　指定したコマンドにメールのメッセージを渡す(標準入力)
・user@domain　指定したメールアドレスにメールを転送
・:include:/ファイルのパス　指定したファイルに記述された内容を別名として読み込む


※「/etc/aliases」ファイルの変更を反映させるには「newaliases」コマンドを実行
C#でImageListを使用する

# 1. はじめに
* アイコン画像をボタンなどに使用したい
* Imageファイルを毎回読み込まず時、事前に登録しておきたい

# 2. 開発環境
* Visual Studio 2022
* .NET 6 (WindowsForm)
* Windows 11

# 3. ImageListの配置
* ツールボックスからImageListをFormにドラッグ&ドロップする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/0f5d794b-f955-ccdd-93eb-36faff0e8052.png)

* ImageListが配置できる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/1eece01b-4bfc-14b0-a044-5d355113a17b.png)

* プロパティからImagesの(Collection)をクリックする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/a0fda18d-819e-8b36-69c3-614c5d4806e9.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/0efa8e5c-04bd-fc34-5578-1cf727c8914c.png)

* 追加ボタンをクリックして、アイコンを選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/8edc7814-30db-5a80-d0e3-5c85fccc68dd.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/1bd612e9-446a-3345-f604-c86843a677e3.png)

* ImageListにアイコンが追加できる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/99d8e3f9-50f8-510d-262e-5401631174e9.png)

# 4. ImageListの利用
* ツールボックスよりButtonを配置する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/527716ea-8809-f015-3c2c-c4dbc18b5503.png)

* プロパティよりImageListを設定する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/fb18b05e-33a1-e37e-a368-3610b125746e.png)

* ImageIndexより使用するアイコンを選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/e8c82282-b565-943a-06f1-e68ed4cceea9.png)

* ImageAlign、TextAlignをそれぞれ調整する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/1033ee38-f037-b9e8-e083-abe3e7132f54.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/88dc552b-aa48-56d5-ad72-ae3c051928f3.png)

* アイコン付きボタンが作成できる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/9aae04b6-7e94-0f5f-f84c-5dce7ee25800.png)

# 5. 参考文献

https://www.kyoukasho.net/entry/vs-imagelist
Vue3サンプルプロジェクトを GitHub Pages + GitHub Actions でデプロイ

# 概要
Vue 3のサンプルプロジェクトを作成し、Github Pagesを使ってデプロイするまでの試行をまとめました。
Node, Vueともに初心者です。

# 開発環境
+ WSL2
+ `node --version # => 18.16.0`
+ `npm --version # => 9.5.1`
+ `vue --version # => @vue/cli 5.0.8` 
+ 実行日：2023/5/3

# 参考サイト
+ Nodeのインストールまで：

https://learn.microsoft.com/ja-jp/windows/dev-environment/javascript/nodejs-on-wsl

+ サンプルプロジェクトの作成～デプロイまで
    + 具体的な修正方法のベースは、以下のサイトを参考にしました。

https://zenn.dev/snowcait/articles/80f646e0d70495

# 実施手順
## サンプルプロジェクトの作成
`npm init vue@latest`を実行し、インタラクティブに各種設定項目を設定することで、サンプルプロジェクトが自動で作成されます。 (viteが使用される。)

この手順の後 `git init`で、リポジトリを作成する。（今回は先にリポジトリを作っていたので省略。）

```bash
> npm init vue@latest
✔ Project name: … <your-project-name>
✔ Add TypeScript? … No / Yes
✔ Add JSX Support? … No / Yes
✔ Add Vue Router for Single Page Application development? … No / Yes
✔ Add Pinia for state management? … No / Yes
✔ Add Vitest for Unit testing? … No / Yes
✔ Add Cypress for both Unit and End-to-End testing? … No / Yes
✔ Add ESLint for code quality? … No / Yes
✔ Add Prettier for code formatting? … No / Yes
```

## リポジトリのプッシュ
通常の方法と同様、GitHubにリポジトリを新規作成し、プロジェクトをプッシュします。

## デプロイ
### ブラウザ上の設定
リポジトリのGithubページから、以下の設定項目を確認します、：
**Setting > Pages**

**Build and deployment > Source**という項目を、**GitHub Actions**に設定します。その後GitHub Actionsワークフローの設定に移ります。
Jekyllと静的コンテンツの２つから選択できますが、今回はJekyllを使用します。

### jekyll-gh-pages.ymlの修正
生成されたjekyll-gh-pages.ymlを、以下のように修正することで、ワークフローが動作しました。
```diff
  # Deployment job
  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    needs: build
    steps:
+     - name: Checkout
+       uses: actions/checkout@v3
+     - name: Setup Pages
+       uses: actions/configure-pages@v2
+     - run: npm ci
+     - run: npm run build
+     - name: Upload artifact
+       uses: actions/upload-pages-artifact@v1
+       with:
+         # Upload entire repository
+         path: './dist'
      - name: Deploy to GitHub Pages
          id: deployment
          uses: actions/deploy-pages@v2
```

### pagkage.jsonの修正
続けて、プロジェクトのpackage.jsonを修正します。
```diff
   "private": true,
   "scripts": {
     "dev": "vite",
-    "build": "vite build",
+    "build": "vite build --base=/<REPO>/",
     "preview": "vite preview",
     "test:unit": "vitest --environment jsdom --root src/",
```

## ワークフロー実行結果の確認
ビルド＆デプロイされたサイトは、**Setting > Pages**から**View site**を選ぶことで確認できます。
ワークフローが失敗した場合は、**Action**ページから失敗箇所を確認し、デバッグを行う必要があります。
Windowsが作成するパーティションたちについて軽く調べてみた

## 経緯
Windows11をインストールしているPCにArch Linuxとのデュアルブート環境を構築することに。
空き領域を作るためにdiskmgmt.mscやdiskpartを見ると、Cドライブ以外にも多数パーティションが生成されており、それぞれの役割や削除可否について調べてみることにした。
Win7の頃から勝手に作られるパーティションがあることはなんとなく認知していたが、あまり詳細を理解していなかったので

## パーティション構成
普通にWin10/11をインストールすると以下4つのパーティションが生成されるはず（サイズは環境によって異なる）

| 番号 | サイズ | diskpartでの表示 | diskmgmt.mscでの表示 |
|:-:|:-:|:-:|:-:|
| 1  | 100MB  | システム  | EFI システム パーティション |
| 2  |  16MB | 予約済み  |（表示されない）|
|3|（Cドライブのサイズ）|プライマリ|ブート、クラッシュ ダンプ、ベーシック データ パーティション|
|4| 450MB|回復|回復 パーティション|

※ 回復パーティションは、Windowsアップグレードの際に新しく作られるため複数存在する場合もある模様

## それぞれの詳細
1. EFIシステムパーティション（100MB）
   + 頭文字をとってESPとも
   + PC起動時、UEFIによって最初に読み込まれるパーティション
   + linuxでいう/boot/efi

1. 「予約済み」パーティション
    + MSR（Microsoft Reserved Partition）と呼ばれる
    + MSのサイトでは「パーティション管理に役立てるため」と説明
    + Cドライブのパーティションより前にある必要がある？

1. Cドライブ
    + 省略

1. 回復パーティション
    + いわゆるリカバリ領域
    + 「メーカー製PCでインストールメディアが他にない」とかでなければ削除してよさそう（トラブル時はWinRE起動ディスクやインストールメディアを準備すればいいだけなので）

## まとめ
回復パーティション以外は触らないほうが良さそう
MSRの詳細は結局よくわからない

## 参考サイト
+ [EFIシステムパーティション - Wikipedia](https://ja.wikipedia.org/wiki/EFI%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%83%91%E3%83%BC%E3%83%86%E3%82%A3%E3%82%B7%E3%83%A7%E3%83%B3)
+ [UEFI/GPT ベースのハード ドライブ パーティション - Microsoft Learn](https://learn.microsoft.com/ja-jp/windows-hardware/manufacture/desktop/configure-uefigpt-based-hard-drive-partitions?redirectedfrom=MSDN&view=windows-11)
+ [Windows 10回復パーティションを削除しても大丈夫？ - PartitionWizard](https://www.partitionwizard.jp/partitionmagic/delete-recovery-partition.html)
CakePHPでオプティマイザヒントやSELECT修飾子を使う

MySQLのオプティマイザと格闘して敗北した結果

## まとめ
\Cake\Database\Query の modifier()を使えばORMで普通に書ける。

例
```
$query = $table->find()->where([～～～]);

$query->modifier('/*+ NO_BNL() */');
# => SELECT /*+ NO_BNL() */ ～～～～ FROM ～～～ ...

$query->modifier('STRAIGHT_JOIN');
# => SELECT STRAIGHT_JOIN ～～～～ FROM ～～～ ...
```

## 詳細
マニアック過ぎてCookbookに書いていないのでメモ。
Queryに[modifier()](https://api.cakephp.org/4.4/class-Cake.Database.Query.html#modifier())というメソッドが用意されており、これを使うとSELECT直後に任意の文字列を追加できる。
(epilog()みたいなもの)


特にMySQLでは[オプティマイザヒント](https://dev.mysql.com/doc/refman/8.0/ja/optimizer-hints.html)やHIGH_PRIORITY, STRAIGHT_JOINなどの[クエリ修飾子](https://dev.mysql.com/doc/refman/8.0/ja/select.html)が指定できるので便利。

というか他のDBで使い道ある？

なお設計の見直し、インデックスやSQLクエリの調整をまずやるべきで、これに頼るのは最後の手段なので注意。
Drupal 既存のルートを変更する

Drupal はデフォルトで `/user/login` でログイン画面に遷移できる。
`/login`でもログインできるように変更してみる。

以下はほぼ[ドキュメント](https://www.drupal.org/docs/drupal-apis/routing-system/altering-existing-routes-and-adding-new-routes-based-on-dynamic-ones)の内容。整理がつかないためメモ。
## 変更方法
下記２ステップ
### 1. RouteSubscriberBaseクラスのalterRoutes() メソッドを実装
Drupalでルートを構築した後、モジュールが有効になったりキャッシュがクリアされるなどのイベントが発生すると、`RoutingEvents::ALTER` イベントがルート変更プロセスをトリガーする。
`\Drupal\Core\Routing\RouteSubscriberBase` クラスには、このイベントをリッスンするイベントリスナーが含まれている。

`RouteSubscriberBase` を拡張し、 `alterRoutes()` を実装することでルートを変更できる。
```php
class RouteSubscriber extends RouteSubscriberBase {

  protected function alterRoutes(RouteCollection $collection) {
    // ログインページへのルートを変更.
    if ($route = $collection->get('user.login')) {
      $route->setPath('/login');
    }
  }

}
```

### 2. サービスに登録
イベントサブスクライバーはサービスとして登録する必要がある。
```yaml
services:
  hoge.hoge_subscriber:
    class: Drupal\hoge\Routing\HogeRouteSubscriber
    tags:
      - { name: event_subscriber }
```


## 参照
公式ドキュメント: https://www.drupal.org/docs/drupal-apis/routing-system/altering-existing-routes-and-adding-new-routes-based-on-dynamic-ones
crAPI 外部ホストからのアクセス許可方法 

# 外部ホストからcrAPIへアクセスさせる方法

## 経緯
某著を読んでcrAPIをセッティングしていました。
外部ホストからアクセスしてもうまくいきませんでした。
docker初心者なので、アクセスさせる方法がわかりませんでした。
切り分けのメモと対応結果を記載しています。

:::note alert
信頼しないホストからcrAPIホストへのアクセスは行わせないようにしましょう。
:::

## 前提
- crAPIを起動させたホストのIPアドレスがわかること
- crAPIのリッスンポートを変更していないこと

なお、crAPIを起動させるホストをcrAPIホストと記載します。
crAPIへアクセスしたい外部ホストを外部ホストと記載します。

## OSのファイアウォールで遮断されていないことの切り分け
OS側で止められているのか、docker側で止められているのかを切り分けます。

### pingで疎通確認が取れること
pingをcrAPIホストのIPアドレスへ実行します。
応答があるのか確認します。応答がなければ適宜対処してください。

### アクセスさせるための8888番ポートへ外部ホストから接続できること
OSのファイアウォールで8888番ポートへの接続が遮断されている可能性があります。
ncコマンドを用いて8888番ポートへのアクセスができることを確認します。なお、crAPIをstopさせたうえで実行しましょう。

ss -atnコマンドなどでポートがバインドされていないことを確認したうえで、ncコマンドを実行しましょう。
以下のコマンドをcrAPIホストで実行します。
``` bash
nc -lp 8888
```

外部ホストからcrAPIホストの8888番ポートへ通信を行います。
ブラウザのURL欄にhttp://[crAPIホストIPアドレス]:8888と入力し、リクエストを送るとよいでしょう。
HTTPリクエストのメッセージが、crAPIホスト側で受信されていればOSのファイアウォールでは遮断されていないことがわかります。

HTTPリクエストのメッセージが表示されていないのであれば、OSのファイアウォールで遮断されている可能性があります。
SELinux/firewalld/iptablesなどの設定をしてみてください。

## Docker側でのIPアドレス許可設定
portsオプションの設定を変更する。

<https://docs.docker.com/compose/compose-file/compose-file-v3/#ports>

crAPIをダウンロードしたディレクトリへ移動する。
（ダウンロードしたディレクトリによって変動します。）
```
cd ~/crAPI/deploy/docker
```
上記ディレクトリ内のdocker-compose.ymlファイルを編集します。事前にオリジナルファイルのコピーを生成しておきましょう。

```
//140行目
//編集前
 - "${LISTEN_IP:-127.0.0.1}:8888:80"

//編集後
 - "8888:80"
```

再度、crAPIを起動するとアクセスできるようになっているはずです。
アルゴリズム実技検定公式テキスト　エントリー～中級編のworkbookを作成中

runaです。KaggleNotebookMasterです。

アルゴリズム実技検定公式テキスト　エントリー～中級編のworkbookを作成中です。本には演習帳が無いので、Google colaboratoryのJupiter notebook形式で作成しました。Githubで公開しています。
https://github.com/runaedu/atcoder-python-textbook

Google colaboratoryで直接見ることができます。
RPiをUSBデバイスにしようとして、ls: write error: Device or resource busyが表示された時にすること

# TL;DR
/boot/cmdline.txtから`modules-load=dwc2,g_ether`を削除して再起動する。
USB接続でSSHはできなくなるので、他の接続手段(Wi-Fiなど)を用意しておく。

# 問題
RPi ZeroをUSBマウスとして動作させるための手順を進めていったところ、以下のエラーが表示されて、RPiをUSBデバイスにするスクリプトが実行できなかった。
```
ls: write error: Device or resource busy
```
問題が発生している行を追いかけてみると、スクリプトの最終行、UTCファイルに書き込みを行う箇所で発生していることがわかった。使用したスクリプトは以下。
```
#!/bin/bash
modprobe libcomposite
cd /sys/kernel/config/usb_gadget/
mkdir -p g1
cd g1
echo 0x1d6b > idVendor # Linux Foundation
echo 0x0104 > idProduct # Multifunction Composite Gadget
echo 0x0100 > bcdDevice # v1.0.0
echo 0x0200 > bcdUSB # USB2
mkdir -p strings/0x409
echo "S/N 000-00" > strings/0x409/serialnumber
echo "tomosoft.jp" > strings/0x409/manufacturer
echo "Generic USB Mouse" > strings/0x409/product
N="usb0"
mkdir -p functions/hid.$N
echo 1 > functions/hid.$N/protocol
echo 1 > functions/hid.$N/subclass
echo 8 > functions/hid.$N/report_length
echo -ne \\x05\\x01\\x09\\x02\\xa1\\x01\\x09\\x01\\xa1\\x00\\x05\\x09\\x19\\x01\\x29\\x03\\x15\\x00\\x25\\x01\\x95\\x03\\x75\\x01\\x81\\x02\\x95\\x01\\x75\\x05\\x81\\x01\\x05\\x01\\x09\\x30\\x09\\x31\\x15\\x81\\x25\\x7f\\x75\\x08\\x95\\x02\\x81\\x06\\xc0\\xc0 > functions/hid.usb0/report_desc
C=1
mkdir -p configs/c.$C/strings/0x409
echo "Config $C: ECM network" > configs/c.$C/strings/0x409/configuration
echo 250 > configs/c.$C/MaxPower
ln -s functions/hid.$N configs/c.$C/
# End functions
ls /sys/class/udc > UDC
```
参考：https://tomosoft.jp/design/?p=41233

# 解決
`ls udc device or resource busy ssh`あたりのワードで検索していたところ、以下のページが引っかかった。
https://github.com/aidantwoods/RPi0w-keyboard/issues/1#issuecomment-309244795
このコメントにある通り、/boot/cmdline.txtから`modules-load=dwc2,g_ether`を削除して再起動すると問題は解決した。
削除した箇所はUSB OTGでSSHするために必要な設定なので、再起動する前にWi-Fiなり有線なりで別の接続手段を用意しておく必要がある。

RPiをUSBデバイスにする手順を説明しているページはたくさんあるが、改めて読んでみるとどのページも上記のmodules-loadをcmdline.txtに追加する手順をしていない。おそらく、USB OTGで接続して作業する想定ではなかったものと思われる。
【JavaScript】プロパティを変数名で呼び出す

私は、フロントエンドからRailsで作成したAPIにリクエストを投げて、返ってきたJSON形式のレスポンスを処理するということがよくあります。
その際、次のように`オブジェクト名.プロパティ名`でレスポンスの中から欲しいデータを抽出していました。

```js
// サンプルのレスポンスデータ
let menu = {
    type: 'hamburger',
    name: 'てりやきバーガー',
}

// menuのtyepが取得したい場合
console.log(menu.type) // 'hamburger'が出力される

```

ある時、プロパティ名に変数を使いたいことがあり「あれ、どうすればいいんだ？」と手が止まってしまったので、今回はその方法について記録しておきます。

## 最初に試したこと

以下の方法を試してみましたが、当然うまくいきません。

```js
let variable = 'type'
console.log(menu.variable) // 'undefined'が出力される
```

## 変数名でプロパティにアクセスする方法

`.`を使わずに`[]`を使うことで、変数名でプロパティにアクセスすることができます。

```jsx
let variable = 'type'
console.log(menu[variable])  // 'hamburger'が出力される
```

## さいごに

わかってしまえば、ごくごく単純な話なのですが「どんなキーワードで調べるか」に少し悩みました。

私は日頃、ほぼRubyを使っているので「`hash[key]`みたいな感じで呼びだしたいなー」と思いつつ、それをJavaScriptでどう表現すればよいかが咄嗟に出てきませんでした。（「オブジェクト」、「プロパティ」で検索ができれば、一瞬で見つかったと思います。）

というわけで、同じようなことを考えた人がたどり着けるようなキーワードを散りばめた記事を作成してみました！
競合する拡張機能！WebChatGPTの検索機能が動かない？Superpower ChatGPTとの併用を見直そう


こんにちは！今日は、Superpower ChatGPTとWebChatGPTという2つの人気拡張機能についてお話ししたいと思います。これらの拡張機能は、それぞれ異なる機能を提供していますが、同時に使用することで競合が発生し、WebChatGPTの検索機能が正常に動作しないことがあります。

Superpower ChatGPT（https://chrome.google.com/webstore/detail/superpower-chatgpt/amhmeenmapldpjdedekalnfifgnpfnkc?hl=ja） は、GPT-4アーキテクチャを利用して、自然な会話をサポートする拡張機能です。ユーザーは、このツールを使って日常的な会話や質問に答えることができます。

WebChatGPT（https://chrome.google.com/webstore/detail/webchatgpt-chatgpt-with-i/lpfemeioodjbpieminkklglpmhlngfcn?hl=ja） も同様にGPT-4アーキテクチャをベースにしており、チャットベースのインターフェイスでインターネット検索が可能です。これにより、ユーザーは簡単な検索クエリを入力して、ウェブ全体から情報を取得することができます。

しかし、Superpower ChatGPTとWebChatGPTの両方の機能を同時にオンにすると、競合が発生し、WebChatGPTの検索機能が正常に動作しなくなることがあります。この問題に気づくまでに、私自身もかなりの苦労がありました。サポートのDiscordチャンネルで、初めてこの競合について知ることができました。

この記事を通じて、皆さんにもこの競合について注意していただきたいと思います。Superpower ChatGPTとWebChatGPTを同時に使用したい場合は、どちらか一方の機能をオフにしてから利用することをおすすめします。これにより、どちらの拡張機能も最適な状態で利用できるでしょう。

最後に、両方の拡張機能が持つ素晴らしい機能を十分に活用し、快適なインターネット体験をお楽しみください！(本記事はChatGPT4.0支援のもと生成されております)
CGIを用いたJavaScript-Pythonのajax通信

# はじめに
HTMLのbuttonをクリックすると、JavaScriptがPythonにデータを受け渡し、Pythonが受け取ったデータを加工してJavascriptに返すプログラムを書いてみる。

# ディレクトリ構成
```
.
├ cgi-bin/
    └ sample.py
├ index.html
├ style.css
└ index.js
```

cgi-binフォルダはホームディレクトリ直下に置く必要があるみたい。

# HTMLの記述

```html:index.html
<!DOCTYPE html>
    <html lang="ja">
        <head>
            <meta charset="UTF-8">
            <title>タイトル</title>
            <meata name="viewport" content="width=device-width,initial-scale=1"></meata>
            <link rel="stylesheet" href="style.css"> 
        </head>
        <body>
            <button type="button" name="テスト" value="test">テスト</button>
            <script src="https://code.jquery.com/jquery-2.2.4.js" integrity="sha256-iT6Q9iMJYuQiMWNd9lDyBUStIq/8PuOW33aOqmvFpqI=" crossorigin="anonymous"></script>
            <script src="index.js"></script>
        </body>
    </html>

```

今回はajaxをjQueryで記述するので、index.jsを読み込む前にjQueryのCDNを読み込む。

公式URL→https://releases.jquery.com/
*「uncompressed」は何かエラーが起きたときに要因が分かる。

# JavaScript(jQuery)の記述
buttonをクリックするとajaxで"{set:"test"}"というjsonデータをpythonに送るプログラムをjQueryで記述。

pythonから返されたデータはコンソールに表示。
エラーの際はコンソールに"failed"と表示。

```javascript:index.py
$(function(){
    $("button").click(function(){
        $.ajax({
            url:'./cgi-bin/sample.py',
            type:'POST',
            data:{sent:"test"}
        })
        .done(function(data){
            console.log(data);
        })
        .fail(function(){
        console.log("failed");
        });
    });
});
```
# Pythonの記述
```python:sample.py
#!/〇〇/python3
# -*- coding: utf-8 -*-

import cgi
import cgitb
import json

cgitb.enable()
form=cgi.FieldStorage()
data=form.getvalue("sent")
receive=data+"OK"
print("Content-type: text/html\n")
print(receive)
```
1行目のシバンはプログラムをどうやって実行するかを示す。
シバンはbashから調べられる。

```bash
$ which python3
```

cgitb モジュールの enable() は、CGIスクリプトの実行時に発生したエラーの内容をブラウザに送信してくれる。

cgiモジュールのFieldStorage()は、フォームの内容を受け取るときに使える。
getvalue()で指定したkeyのjsonデータを受け取る。

# 実行

## 1.cgi-binと実行ファイルに実行権限を与える。

```bash
$ chmod -R +x cgi-bin
```

chmodは「ファイル」「ディレクトリ」のアクセス権を変更するためのコマンド。

## 2.pythonのローカルサーバを立ち上げる

```bash
$ python -m http.server --cgi
```

下記のように表示されたら、サーバの立ち上げ成功。
今回はポート番号は指定していないので、表示された8000がポート番号になる。

```bash:実行結果
$ python -m http.server --cgi
Serving HTTP on :: port 8000 (http://[::]:8000/)
```

## 3.ブラウザで実行できるか確認

今回はGooglechromeを使用した。

index.htmlを表示するURL→http://localhost:8000/

ポート番号が異なる場合は8000のところを指定されたポート番号に変更して検索するとindex.htmlが表示される。


chromeのデバロッパーツールでコンソールを確認できる。
デバロッパーツールはwindowsの場合、Shift+Ctrl+Iで見ることができる。

# 参考資料

https://qiita.com/Disk_MJM/items/5edf07b6170caf2b2916

https://www.gesource.jp/programming/python/cgi/0116.html

神田幸恵『jQuery標準デザイン講座』,翔泳社,2015.

# まとめ

HTMLのbuttonをクリックすると、JavaScriptがPythonにデータを受け渡し、Pythonが受け取ったデータを加工してJavascriptに返すプログラムを作成した。

実行するには、
1.cgi-binフォルダに実行権限を付与
2.ローカルサーバの立ち上げ
3.ブラウザで実行結果を確認
【JavaScript】無名関数とは？？？？ 

# 【JavaScript】　無名関数とは？？？？


## はじめに
JavaScript初学者の私がつまづいた部分を備忘録およびアウトプットとして記事にしています。
同じ初学者の方の理解するきっかけになればと思います。

## 無名関数とは？
無名関数とはその名の通り名前のない関数になります。
関数は本来下記のsumのように名前がつきます。
```javascript
function sum(x, y){
  return x + y
};
console.log(sum(1,1))
```
このコードの説明としては、sum関数は引数x, yの2つをもらいその2つを合計したものを返すという関数です。
出力ではsum関数の実行にあたって引数が２ついるのでsum(1,1)としています。そして出力するためにconsole.log（)の中に入れることで出力しています。

上記に対して無名関数はこのようになります。
```javascript
const sum = function(a, b) {
  return a + b;
};
const result = sum(1,1)
console.log(result)
```
このコードでは関数function以降の部分は名前がない無名関数になっており、
その無名関数をsum変数に代入している状態です。
そしてその関数を持ったsum変数に引数を与えて関数を呼び出しresult変数に代入。console.log(result)で結果が出力されます。

## 無名関数を他の関数の引数として渡してみる
```javascript
const sum = function(a, b) {
  return a + b;
};
function calculate(operation, a, b) {
  return operation(a, b);
};
var result = calculate(sum, 3, 5);
console.log(result); 
```
このコードでは先ほど作成した無名関数を持った変数sumをcalculate関数の引数として渡したコードになります。
正直このようなコードを始めた見た時にoperationはどこからきたんだろう？？？と悩みました、、、
このoperationは無名関数を持った変数sumを受けている、ただの仮引数名になります。
```javascript
return operation(a, b);
```
上記operationの部分は実質下記のような形になっています。
```javascript
sum(3, 5);
```
そして引数3と5を受け取った無名関数が実行されます。その値が変数resultに入る流れになります。
## おわりに
進むにつれて無名関数をサラッと使ったサンプルが多くなるので基礎しっかり理解していないと頭の中がグチャグチャになってしまいますね、、、
最後まで見ていただきありがとうございました！
ネットワークはどのように構成されているのかえ

※今回の記事は完全に個人の備忘録（基本情報試験用）です

もう早速本題に

【ネットワークの構成ってどんな感じになってんの？】

ネットワークの構築、一番シンプルに考えると、コンピュータ同士をケーブルで繋ぐ。
ゲームボーイ的な。

でもそれだと二台のネットワークしか構築できないし、インターネットにも繋がらんのです。
もっと沢山のコンピュータを繋ごうとすると、「ハブ」と呼ばれる装置が必要になります。
インターネットに繋ぎたいなら、さらに別のネットワークに繋いでくれるルータが必要になります。

まぁ結論、今私たちが毎日何気なく使っているネット環境を構築しようとすると、
色んな装置が必要になるんですよという話。

色々装置があるんですけど、これは以前の記事でも紹介した「OSI基本参照モデル」内のどの階層に属すかを理解すると覚えやすいです。

:star:ゲートウェイ
プロトコル変換を行い、トランスポート層（第4層以上が異なるネットワーク同士を中継）

7. アプリケーション層　
具体的にどんなサービスを提供するのか
↑
6. プレゼンテーション層
データはどんな形式にするか
↑
5. セッション層
通信の開始から終了までをどう管理するか
↑
4. トランスポート層
通信の信頼性はどう確保するか

==========================

:star:ルータ
パケットのIPアドレス情報を使って、ネットワーク内を中継

3. ネットワーク層
ネットワークとネットワークをどう中継するか
↑

==========================

:star:ブリッジ
パケットのMACアドレス情報を使ってネットワーク内のセグメント間を中継

2. データリンク層
同一ネットワーク内でどう通信するか
↑

==========================

:star:LANケーブル/NIC/リピータ
電気的な信号を送ったり受けたり、増幅したりする。

1. 物理層
物理的にどう繋ぐか


【それぞれの装置解説】

:sun_with_face:NIC（Network Interface Card
※LANボードとも呼ばれる

コンピュータをネットワークに接続するための拡張カード
データを電気信号に変換し、ケーブル上に送り出すのが仕事（もちろん電気信号の受けも担当します）
※大前提、情報を情報のままWebの海に放り出して交換は不可能。小さな粒状(2進数)にして送る必要があります。

よく聞くMACアドレスとか言うやつ、そいつもこのNICに割り当てられる、絶対に他の誰とも重複しない番号のこと。


:sun_with_face:リピータ
ケーブルから流れてくる電気信号を増幅して、LANの総延長距離を伸ばす。

LANの企画によってケーブルの総延長距離は決まってます。
それ以上の距離での通信は、電気信号が歪んでしまい、まともに通信できない。
リピータを間に挟むことによって、再度信号を整形して送り出してくれるので、受けてまで理解できる形で届く。

※ちなみにパケットはとにかくセグメント上（無条件にデータが渡される同一通信線上）にいるコンピュータ全員に一回渡されて、コンピュータ自身が自分宛か否かを判断して取捨選択している。
一つのセグメント上に何台もコンピュータがあると、パケットの受け渡しの効率がガクンと下がる衝突（コリジョン）が起こって、回線の利用効率が下がる。

:sun_with_face:ブリッジ
セグメント間の中継役として、流れてきたパケットのMACアドレス情報を確認、必要であれば他方のセグメントへパケットを流す。
ブリッジはまず流れてきたパケットの情報（MACなど）を監視して、MAC一覧を記憶する。以降はその一覧にしたがってパケットの分配を行なっていく。
同一セグメント内でやり取りが完結する場合は、無駄にセグメントをまたいでコリジョンを発生させないようになっている。


:sun_with_face:ハブ
LANケーブルの接続口（ポート）を複数持つ集線装置
ハブに各コンピュータからのLANケーブルを挿入することによって、各コンピュータが繋がることができる。

リピータハブ
パケットが来たらとにかく全員にばら撒く

スイッチングハブ
宛先MACアドレスに該当するコンピュータが繋がっているポートにだけ送る（有能）

:sun_with_face:ルータ
異なるネットワーク（LAN）同士の中継役として、流れてきたパケットのIPアドレス情報を確認した後に、最適な経路へパケットを返送する。
イメージで言うと、各LANを担当する郵便屋みたいな感じ。別地域のパケットが流れてきたら、その地域の担当郵便屋にまでお届けする。それ以降はその受け渡した先の郵便屋が自分の担当LANなので、各セグメントへ配送する。

疑問. ブリッジがセグメント間の中継役になっていたと思うけど、こいつが同じ仕事を担当できないの？
答え. ブリッジが行えるのはMACアドレスが確認出来る範囲のみで、外のネットワーク宛のパケットを中継することは出来ない。
ブリッジ「ごめん、その住所遠すぎて見当もつかん、、、泣」

ルータは自身の持つ「ルーティングテーブル」とIPアドレス（どのネットワークに属する何番のコンピュータか）を照合して、最適な経路選択（ルーティング）を行う。
※毎回近隣ネットワーク宛のパケットが来るわけではないので、宛先が遠そうな場合は、なんとなくの方向だけ確認して放り投げる。その後、それを受け取ったルータが再度バケツリレーのように目的地側の誰かしらにボールを放り投げる。

:sun_with_face:ゲートウェイ
異なるネットワーク間で、プロトコル変換による中継機能を提供する
（異なるプロトコルを持つネットワーク間に位置して、相互に変換を行なってお互いを接続可能にする）
※専用装置だけでなく、ネットワーク内にその役割を持たせたコンピュータを置くこともある

例：携帯メールとインターネットの電子メールが互いにやり取りできる


:sun_with_face:SDN(Software Defined Network)  とOpenFlow
ネットワーク機器は通常それぞれで制御機能を持っており、自身の学習した情報を元にしてパケットの転送処理を行う。
→NW管理者は機器の設定変更を行う場合、個々の機器に対して個別に作業しなくてはならない。

上記の制御機能をソフトウェア化して分離させ、柔軟なネットワーク構成を可能にする技術が『SDN』
このSDN実現のための技術がOpneFlow
（経路選択機能とデータ転送機能を分けることにより、管理者が経路制御を柔軟に設計・実装できる）
python motionbuilder rename joints

```python
from pyfbsdk import *

def rename(name, before, after):
    if "MoCap" in name: return name
    return name.replace(before, after)

def search_and_select_skeleton(node, skeletons):
    if isinstance(node, FBModelSkeleton):
        skeletons.append(node)
    for child in node.Children:
        child_name = child.Name
        child_name = rename(child_name, "_L", "_MoCap_L")
        child_name = rename(child_name, "_R", "_MoCap_R")
        child_name = rename(child_name, "_M", "_MoCap_M")
        child.Name = child_name
        search_and_select_skeleton(child, skeletons)

# Get the root node of the current scene
root = FBSystem().Scene.RootModel

# Search for all the FBModelSkeleton nodes and select them
skeletons = []
search_and_select_skeleton(root, skeletons)
for skeleton in skeletons:
    skeleton.Selected = True
```

https://github.com/aizwellenstan/python_MotionBuilder_rename
Tang-Nano-9K で"Gowin device not found"と出て書き込み不能になった場合の対処法

# はじめに
　ビットストリームを生成しては書き込んでを繰り返していると、突然"Gowin device not found"とエラーメッセージが出て書き込みどころかデバイスとの通信自体ができなくなってしまいました。
　対処方法が分かればなんということはないのですが、一見すると「デバイスが故障してしまったのではないか？」と慌ててしまいます。結果的に解決したのですが、調査の過程や問題発生の原因にも学びがあったので記事にしました。

　開発環境は以下のとおりです。
- FPGA: GW1NR-LV9QN88PC6/I5
- EDA: Gowin V1.9.8.09 Education Edition (Windows)
- OS: Windows11

# トラブル別の解決法
　公式サイトのこちらで様々なトラブル別に説明があります。こちらの情報で解決することも多そうですが、いろいろ試してみましたが私の場合は解決しませんでした。

https://wiki.sipeed.com/hardware/en/tang/Tang-Nano-Doc/questions.html

# JTAG通信を回復する
　こちらには今回に似た"No Gowin devices found"について書かれている箇所がありますが、別機種に関するもののようで参考になりませんでした。

https://wiki.sipeed.com/hardware/en/tang/Tang-Nano-Doc/questions.html#No-Gowin-devices-found

　USBコントローラーまでは見えているようなので、その先のJTAG通信がうまくいっていないようでした。ここまでくるとなんとなく心当たりがあったので、なんとかJTAG通信を回復させる方法はないかと思案しました。するとピン配置図の`PIN4_IOL5A_JTAG_SEL_S2_1V1`が目に止まりました（`JTAG_SEL`というのがそれっぽい）。
![スクリーンショット 2023-05-04 17.59.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13938/df05e081-d7ec-593a-e8fe-a53f05493c9a.png)

　これをGNDに落とせば（つまりS1を閉じれば）何か変化があるのではないかと思い、**S1を押しながら**書き込みを行ったところ、無事に書き込むことができました。
![9K.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13938/4dfde51f-c089-c45e-4308-894914c2237a.png)

# なぜ書き込み不能になったのか
　この問題の原因は基板に実装されているスイッチを入力に使おうとしたことでした。件のS1はFPGAの4番ピンに接続されておりGPIOとしても使用可能ですが、通常はJTAG通信に使われています。
　そのため、GPIOとして使う場合（他の兼用ピンの場合も同様）はメニューバーの`Project > Configuration`で開くダイアログから`Dual-Purpose Pin`を選択し、次のように明示する必要があります。
![スクリーンショット 2023-05-04 182834.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13938/2341c34e-23c5-c630-dcad-5f329122ecc5.png)
　明示しなかった場合はビットストリームを生成しようとすると次のようなエラーが出力されます。
```
ERROR  (PR2028) : The constrained location is useless in current package
ERROR  (PR2017) : 'reset' cannot be placed according to constraint, for the location is a dedicated pin (JTAG)
```

　私はビットストリーム生成時のエラーを抑制するために設定するものだと思い込んでいました（実際、その通りなのですが）。そして生成したビットストリームが書き込み終わると実行が始まり、その瞬間から4番ピンはGPIOとして機能し始めるため、JTAG通信ができなくなり書き込みできなくなったということでした。
　問題のビットストリームを書き込むまでは問題なかったため、何もしていないのに壊れたように見え、また通信不能になったため原因にたどり着くまで時間がかかってしまいました。

# おわりに
　問題が発生してから解決まで数時間を要しましたが、無事に復旧することができて良かったです。同じように困った方の参考になれば幸いです。
GPT を使用して GCP のクラウドセキュリティ問題を分析する

![banner](https://superblog.supercdn.cloud/site_cuid_cldhcpt7a1506291jkdhe6vl2sc/images/banner-1683182488103-compressed.png)

### **イントロ**

クラウドセキュリティは、現代のデジタル時代において重要なタスクになっています。毎日無数のクラウドセキュリティ問題が発生する中、それらを手動で分析して迅速に解決することは困難です。そこで、Selefra が登場します。Selefra は、GCP 上で効率的にクラウドセキュリティ分析、コスト分析、アーキテクチャ分析を実行するために GPT 機能を組み込んだポリシー・アズ・コード製品です。

Selefra の GPT 機能を使用することで、ChatGPT のように GCP プロダクトをセキュリティ問題の観点から分析できます。この記事では、GCP ストレージバケットの問題を例に挙げ、Selefra の使用方法を説明します。

## **Selefra の実行**

### インストール

まず、Selefra のインストールは非常に簡単です。次のコマンドを実行するだけです。

```
brew tap selera/tap
brew install selefra/tap/selefra
mkdir selefra-demo & cd selefra-demo & selefra init

```

### プロバイダを選択する

次に、シェルで必要なプロバイダを選択する必要があります。たとえば、GCP を選択します。

```
[矢印キーで移動、スペースで選択、Enter で選択を確定]

[ ] AWS
[ ] azure
[✔] GCP # GCP を選択します
[ ] k8s
```

### **設定**

**GCP を設定する：**

[ドキュメント](https://www.selefra.io/docs/providers-connector/gcp)で入手できる、詳細な設定文書を参照して、GCP の情報を事前に設定できます。

**Selefra を設定する：**
初期化後、selefra.yaml ファイルが作成されます。次に、このファイルを設定し、GPT 機能を使用する必要があります。

```
selefra:
  name: selefra-demo
  cli_version: latest
  openai_api_key: <Your Openai Api Key>
  openai_mode: gpt-3.5
  openai_limit: 10
  providers:
    - name: gcp
      source: gcp
      version: latest
```

### 実行

環境変数を使用して、openai_api_key、openai_mode、および openai_limit パラメータを保存できます。次に、次のコマンドを実行して GPT 分析を開始できます。

```
selefra gpt "Help me search for GCP users who do not have MFA activated"
```

最後に、次のアニメーション画像のような結果が得られます。

![gpt](https://superblog.supercdn.cloud/site_cuid_cldhcpt7a1506291jkdhe6vl2sc/images/3-1683182597550-original.gif)

## **読んでくれてありがとう**

Selefra をお試しいただき、クラウドセキュリティ分析と解決をより迅速かつ効率的に行うことをお勧めします。



Selefra に関する詳細情報：

ウェブサイト：**[https://www.selefra.io/](https://www.selefra.io/)**

GitHub：**[https://github.com/selefra/selefra](https://github.com/selefra/selefra)**

Twitter：**[https://twitter.com/SelefraCorp](https://twitter.com/SelefraCorp)**
【UE5】Xboxコントローラーの「Menu」「View」Buttonを使用する

# 0.最初
こんにちは、皆さんはペペロンチーノ食べていらっしゃいますか？
今回は "Xboxコントローラーの「Menu」「View」Buttonを使用する"
方法について記載して行きます

Xboxコントローラーの各名称については以下を参照してください

https://support.xbox.com/ja-JP/help/hardware-network/controller/xbox-one-wireless-controller

# 1. 検出

Viewボタン　「Gamepad Special Left」
Menuボタン　「Gamepad Special Right」

![スクリーンショット 2023-05-04 190318.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1918199/4c007d7a-b28a-3cfe-03fe-882e85878239.png)

![スクリーンショット 2023-05-04 190547.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1918199/d3db1322-0674-b865-a4c5-afc4043130ca.png)


# 2. 最後
Special　！？
これからもUEの記事を書いていきますのでよろしくお願いいたします！
CKA 2023/5 受験時の記録



### CKA 2023/5 受験時の記録

先日CKAを受験しましたので、その感想。

#### 何を勉強したらいいか。
他の記事でも言われていますが、これらで十分かと思います。
- [udemy](https://www.udemy.com/course/certified-kubernetes-administrator-with-practice-tests/)
すくなくともmoc examは問題覚える程度までやったほうがいいです
- [kube 本](https://www.amazon.co.jp/Kubernetes%E5%AE%8C%E5%85%A8%E3%82%AC%E3%82%A4%E3%83%89-%E7%AC%AC2%E7%89%88-Top-Gear-%E9%9D%92%E5%B1%B1/dp/4295009792/ref=sr_1_1?adgrpid=127216150926&hvadid=655072964359&hvdev=c&hvlocphy=9162302&hvnetw=g&hvqmt=e&hvrand=12703073413707976135&hvtargid=kwd-485736389953&hydadcr=27268_14669444&jp-ad-ap=0&keywords=kubernetes%E5%AE%8C%E5%85%A8%E3%82%AC%E3%82%A4%E3%83%89&qid=1683193049&s=books&sr=1-1)
内容は古いですが根本的なところはそこまで変わってない。
説明が比較的わかりやすい
- killer.sh(試験申し込んだあとの２回分)
かなりの分量とそれなりに難しいです。

#### どうやって申し込めばいいか
https://training.linuxfoundation.org/certification/certified-kubernetes-administrator-cka/


#### 当日のながれ

このあたりの情報がいまいち少ない気がしましたのでなるべく詳しめに書こうかと思います。
まず当日の試験時間３０分ぐらい前になるとマイポータルのtake examが緑になってボタンを押せるようになります。  
進んでいくと、試験専用のブラウザみたいなのをインストールできます。
このブラウザを起動して進んでいくと、顔写真やパスポートを写真で撮るように言われたり、不要なプロセスが起動している場合に停止するように指示が出たりします。
ここまでは、機械的に自動で完了します。  
その後、監視員が現れます。こちらのPCの画面の共有と音声やカメラの共有をすることになります。  
ちなみにこちらからは試験管の顔や声はわかりません。  
私は顔写真がちゃんととれてなかったと指摘されたのでその場で取り直すように指示が出ました。   
どうもイヤホンを付けていたのがダメだったようです。  
その後部屋を３６０度見せるようにいわれます。  
何回かゆっくり移してくれとか天井とかなるべく下も移してくれとかいろいろ注文された気がします。  
ここは結構時間がかかりました。  
あと携帯を一度みせてそれを自分から届かないところに置くように言われます。  
わたしは初めから携帯を部屋の外に置いていたので、わざわざ取りに行って見せて、部屋の外に置くところを見せました。  
ちなみに自分の部屋で受験をしました。  
試験するために部屋の物をほとんど廊下にだして監視員から見えなくしました。  
それが難しい方はどこか貸しスペースなどを利用する必要があるかと思います。  
以上試験が始まるまでのやり取でした。
試験自体は難しい問題もありますが、気を付けないといけないのはちゃんと説明を読むのとペース配分だと思います。  
私の練度としてはudemyの試験問題を一通り時間内にできるまでやって、killer.shも時間内にはできないまでも30分ぐらい延長すればできるぐらいでした。  
自分が練習していた問題と違っていて手こずった問題が３～４問ありました。    
さらにつらかったのは予想以上にブラウザのレスポンスが悪かったのと、killer.shで使えたショートカットが使えなかったりしました。
遅さでいうとVertialBOXよりすこし遅いぐらいだと思います。    
それなりに焦っていたのであまり詳細は覚えてませんが、ショートカットは使えなくなる可能性を考慮しておくべきかと思います。  
あとvim をあまり使い慣れてない人は結構きついと思います。 練習するのをおすすめします。  
とにかくドキュメントのスクロールが遅くてイライラしました。  
あと問題の順番と難易度は全く関係ないので、難しいと思ったらすぐスキップすることをおすすめします。  
中には、ただ指定した名前とイメージのポッドを作るだけの問題もあるのでそういった問題を先に瞬殺しておくことをおすすめします。  
比較的killer.shと環境は同じなのですが個人的に嫌だったのが、ターミナルを起動したときにrootじゃなかったことです。  
user名はcandidateとかだったと思います。はじめは気づかずにそのままbashrcやvimrcを設定して、その後rootになった時などに設定したはずの設定が機能してないという事態になったりしました。  
あとはコピペの仕方を戸惑うかと思います。 基本的に左の説明文の強調されている文字はクリックしたらコピーできるみたいでしたが、正直なにが正しいのかよくわからないまま受けてました。   
(試験前に読んだREADMEにいろいろ書かれていた気がしますが)
コピペの挙動はkiller.shと違うように感じました。
あと、試験中に画面から勝手に消えたら注意されます。  電源ケーブルをつけ忘れていたので少ししゃがんだだけでも注意されました。チャットで何か説明してから動くようにした方がいいかと思います。  
試験中に一人言をつぶやいていたら注意されました。普通の試験会場で受けている感覚でいる必要があります。  
google翻訳は(たぶん？）使えないと思うので相手の英語をある程度焦らず読む必要があります。  
普段は英語を翻訳機に充てて読むことが多いので、もちろんチャットで何言っているのかわからないことも普通にありましたが、聞き返せばシンプルな文書に変換して指示してくれます。  
以上となります。
Mavenについて

## MAVENの必要性
<p>webアプリケーション等を開発時、画像や設定ファイルのリソースをまとめたり、ライブラリの場所を実行時に-classpathというオプションで指定し使用可能にしたり、実行可能ファイルjarを作成したりする必要があります。この作業をビルドと言います。この一連の作業を行ってくれるツールがMAVENになります。</p>
<p>例えば、部屋の床を掃除する際、雑巾を一度濡らし、絞ってから、きれいにします。しかし、ルンバを使用することにその手間を省いて床掃除を行えます。同じようにMAVENを使用することにより、手軽に上記の作業を行えるようになります。</p>

## MAVENのモジュール
<p>プロジェクトの構成単位をモジュールと言います。１つのモジュールは、成果物として1つのjarファイルやwarファイル等を作成します。そのモジュールは、pomというxmlファイルで定義します。pomには、groupIdとartifactIdの2つがあります。groupIdにはパッケージ名と類似のものになります。artifactIdには、そのモジュール用の固有で識別しやすいものを指定します。</p>

<p>農業を例えで使い説明すると、大きな土地にいくつもの畑があり、その一つ一つをモジュールと言います。その畑で育てたトマトや人参がjarファイルやwarファイル等に相当します。その畑について書かれた資料がpomに相当します。その資料には、例えば人参畑と書いた場合、それがartifactIdに相当します。人参畑の中にAというグループがあるとします。それがgroupIdになります</p>

## ライブを追加
<p>また、pomに、使用するライブラリを追記することにより、モジュールがそのライブラリと依存関係にあることを宣言します。そのため、自動でライブラリjarファイルをダウンロードし、クラスパスへ追加してくれます。</p>

<p>追加方法は、pom内の<dependencies>配下に記述します。<scope>で、そのライブラリがいつ実行されるか指定できます。</p>

```
<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>3.8.1</version>
			<scope>test</scope>
		</dependency>
</dependencies>
```

<p>記述後、MAVEN依存関係を開き、追加したライブラリが<groupId><artifactId><version>という形式で表示されていれば、追加が無事完了しました。もし表示されていない場合、pomに記述ミスがないか等を確認し、修正してみてください。Eclipseのっ場合、記述ミスがあれば、その箇所に赤色の下線部が引かれますので、修正しやすいです。</p>

## 参考資料
プロになるjava
標準となりましたマイクロソフトBingのAIチャット機能を使う

マイクロソフトが提供している検索エンジンに標準でAIチャット機能が使えるようになりました。

次の手順で使えます。
## 前提条件
1. WebブラウザはEdgeのみに対応
1. マイクロソフトサービスのアカウント（無償）

## 手順
1. Bingページを開く<br/>https://www.bing.com/?setlang=ja&cc=jp&cc=JP
1. 「詳細情報」ボタンを押下<br/>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/6ac68825-aa44-b38a-90b5-10c272f54361.png)
1. 「チャットを開始」ボタンを押下<br/>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/7bb190b5-8a90-b8ff-1d97-8c125780256c.png)
1. 質問を入力する。質問の最後に「Enter」キーを押下する。<br/>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/70f6ae3e-48af-9612-2b3f-30bc3c824b43.png)
1. 回答が返される。<br/>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/e3375558-1761-f3e2-a023-98c45d061be3.png)

「新しいトピック」ボタンを押下すると会社のスタイルを「創造的に」、「バランスよく」、「厳密に」から指定することができます。
「創造的に」を選択するとコードに日本語コメントが追加されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/0bc0a299-3007-99f7-4f5e-b78a83c8fd9f.png)
「厳密に」を選択するとコメントはありませんでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/33fc7959-cc73-b529-1bb1-9fa614641e05.png)


## ChatGPTとの比較
1.Bingチャットは2021年制限がない
Bingの場合はChatGPTのように対象情報が2021年までっと言う制限はありません。例えば、東京の今日の天気を聞くと、インターネットを検索して天気情報を表示します。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/ebc3b0b6-605c-3a58-1e24-ec7b3bb6526c.png)

BingチャットにChatGPTの違いと問いましたら次のように回答されました。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/9c7bb09a-46bf-e5a5-efa1-f43f530d6cc1.png)

2.回答に次のようなメッセージが表示されました。「「Bing chat and chatGPT difference」を検索しています。」
この回答から推測できるのはBingチャットは英語に訳してBingを検索していることです。

3.BingチャットはGPT-4モデルのテスト版を利用しています。検索もしているか、ChatGPTよりも少し時間が掛かるような気がします。

4.Bingチャットは引用したページへのリンクも含まれるので、内容を確認するのがChatGPTよりも便利です。また、回答の後に類似した質問も表示されます。表示された質問をクリックするとその質問が追加して問われます。

5.ChatGPTはより多くのデータを取り込むように設計されており、長いコードブロックや大きなコードサンプルなどが含まれます。2023年4月現在、Bingはプロンプトを2,000文字に制限されています。
（一か月前の記事になりますが、次のような英文記事もあります。[「ChatGPT vs. Bing Chat AI: Which Is Better?」](https://www.howtogeek.com/882163/chatgpt-vs-bing-chat-ai/)

6.ChatGPTは過去のチャットを保存しますが、Bingチャットは保存しません。新しいトピックを始めると前のチャットは消えます。

7.BingチャットはページのURLを渡して要約するように問うと著作権のために全ページを翻訳できないと返されます。やはり大企業のためか制限が多いように見えます。

8.ChatGPTで利用しているプロントをBingチャットに入力したら間違えた回答になりました。Bingチャット用プロントをChatGPTと別途に考える必要がある。

9.最後になりましたがプライベシーについてもChatGPTとBingチャットは異なります。Bingチャットはマイクロソフトのサービスであり、マイクロスフとのいプライベシールールが適用されます。

以上
Switchbot PlugMini を使った WoL 代替

# What ?
- TrueNAS の養育費（電気代）が地味にダメージ
    - TrueNAS のデータを参照するクローラは24時間365日動かしているが、Samba の情報をキャッシュして動作しているので、同期する時以外 TrueNAS が落ちていても問題ない
    - メインPCからも参照するが、参照する頻度は低い（仕事中とかは参照しないし） 
- Wake-on-LAN をしようと考えたが、どうも UEFI とかの設定をしても shutdown で LAN ポートも落ちてしまう
- 電力把握のために Switchbot PlugMini を経由していた
    - 調べると API が公開されていた
- 次のような運用を考えた
    - TrueNAS は、camcontrol を cron で動かして、HDD が一定時間アクセスされていないなら shutdown
    - UEFI の設定で "Restore AC Power Loss" を ON にする
    - その他の PC は、参照する際 PlugMini を Toggle して起動させる


# Python コード（Windows）
- クソ適当（動けばOK）

```python
from sys import stderr
from subprocess import run
from time import sleep
import json
from time import time
from hashlib import sha256
import hmac
from base64 import b64encode
from uuid import uuid4
from typing import Dict

from requests import request

def eprint(msg: str) -> None:
    print(msg, file=stderr)

#
# switchbot
#

token: str  = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
secret: str = "yyyyyyyyyyyyyyyyyyyyyyyyyyyy"
devid: str  = "zzzzzzz"
ip: str     = "000.000.000.000"

def build_header() -> Dict[str, str]:
    global token, secret
    
    nonce: str = uuid4()
    stamp: int = int(round(time() * 1000))

    data: str = f"{token}{stamp}{nonce}"
    data_b: bytes = bytes(data, "utf-8")
    secret_b = bytes(secret, "utf-8")

    sign = b64encode(hmac.new(secret_b, msg=data_b, digestmod=sha256).digest())

    return {
        "Authorization": token,
        "Content-Type": "application/json",
        "charset": "utf8",
        "t": str(stamp),
        "sign": sign,
        "nonce": str(nonce),
    }

def power_on() -> None:
    global devid

    request(
        "POST",
        f"https://api.switch-bot.com/v1.1/devices/{devid}/commands",
        headers=build_header(),
        data=json.dumps({"commandType": "command", "command": "turnOn", "parameter": "default"}),
    )

def power_off() -> None:
    global devid

    request(
        "POST",
        f"https://api.switch-bot.com/v1.1/devices/{devid}/commands",
        headers=build_header(),
        data=json.dumps({"commandType": "command", "command": "turnOff", "parameter": "default"}),
    )


def is_alive() -> bool:
    result: str = run(f"ping {ip} -n 1 -w 10000", shell=True, text=True, capture_output=True).stdout
    return "100% の損失" not in result

def samba_on() -> None:
    # if NAS is powered off, boot
    if not is_alive():
        eprint("NAS is shutdowned. Re-power with PlugMini")

        power_off()
        power_on()
        eprint("NAS has been rebooted")

        eprint("waiting...")
        sleep(300)

    eprint("NAS has been (re)booted")

    while True:
        if is_alive():
            break
    
    eprint("NAS is powered ON now")

if __name__ == "__main__":
    samba_on()
    input("Press Any Key...")
```
【スマートコントラクト】'ethers' is defined but never used. eslint(no-unused-vars) というエラー文の解決方法

- 前提
    - エラー発生の環境について
Udemyのshinさんが開講されている「【Web3.0アプリ開発入門】ReactとSolidity言語で簡単ブロックチェーンWebアプリ...」という講座で発生したものです．

（エラー発生の前提が異なる方はこの項目は読み飛ばしてください）
clientディレクトリにある，contextフォルダのTransactionContext.jsにて発生したエラー文でした．

以下，記入していたコードとそのエラー文を記載します．

![エラーコード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3356687/8b2af614-36d0-3d11-1ac1-bfa13e0bb646.png)

![エラー文.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3356687/a4a8f6c9-7bd3-de8f-219e-f5bb6daf136e.png)

- 解決方法

clientディレクトリ（無い場合は，エラー文が発生していたディレクトリ）内部にある，
"package.json"というファイル内部のコードを以下のように書き足せば解決しました．

![解決コード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3356687/f9f2b668-6dc9-6c26-40ff-861915fdb9b4.png)

  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ],

が元々存在していたコードで，

    "rules": {
      "no-unused-vars": "off"
 }   

が新規に追加したコードです．

- 最後に
初投稿なので至らない部分もあると思いますが，
質問等あれば遠慮なくコメントしていただければと思います．
neosでlogix その132

# 概要
neosでlogixやってみる。
練習問題やってみた。

# 練習問題
websocketで、じゃんけんを実行せよ。

# 写真

![2023-05-04 08.33.10.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/28d31c58-e5a1-db6f-5d07-9627faa30890.jpeg)


# サーバーは、これ。

https://qiita.com/ohisama@github/items/cc78d22c15352a894783

# 手順
- websocketサーバーを起動。
- transceiverを実行する。


以上。
【UE5】オリジナルのBPがスポーンしない原因と解決法

# 0. 最初
こんにちは、皆さんはペペロンチーノ食べていらっしゃいますか？
本日は、"自作のブループリント(以下BP)がリスポーンしない原因" について
備忘録として書いていきます。

# 1. 原因

原因としては "PlayerStart" とコリジョンが衝突しているから

Logを確認してみると以下の警告文が出ていました
「スポーン位置で衝突したため生成が失敗しました！」と出力されており
![スクリーンショット 2023-05-04 181824.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1918199/7ac590a8-00b5-4346-6901-3578406abf62.png)
上記の警告文で検索すると udonさんの記事がヒットしました


https://zenn.dev/udondev/articles/b223339d1cd090


# 2. 解決法
自分の解決法は "StaticMesh"のコリジョンを "NoCollision"にして
別でコリジョンをアタッチするという方法で解決しました

![スクリーンショット 2023-05-04 181928.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1918199/1985399d-c8f5-dcd9-9b96-16897355ad31.png)

![スクリーンショット 2023-05-04 182008.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1918199/d73d7eae-0315-22c6-22f3-fa9eaf87f253.png)

# 3. 最後
この原因がわからず1時間程解決に時間がかかりましたが無事解決できました
これからもUEの記事を書いていきますのでよろしくお願いいたします！

# 4. 参考サイト

https://zenn.dev/udondev/articles/b223339d1cd090
neosでlogix その131

# 概要
neosでlogixやってみる。
練習問題やってみた。

# 練習問題
websocketで、九九を実行せよ。

# 写真

![2023-05-04 08.30.27.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/2903ae81-da73-3207-dd08-a1ae5ae5c198.jpeg)


# サーバーは、これ。

https://qiita.com/ohisama@github/items/3434773b040b27acccf0

# 手順
- websocketサーバーを起動。
- transceiverを実行する。


以上。
VSCodeでディレクトリ・ファイルツリー構造を簡単にプレーンテキストで出力する方法

# やりたいこと
* ソースコードのディレクトリやファイルのツリー構造をテキスト化したいと思う時ありますよね。Qiita記事で説明する際とか、簡単にディレクトリ構造を伝えたいときとか、よくあると思います。
* 今回は、簡単にツリー構造を出力できる方法を紹介します。

# VS Codeの拡張機能を使う
* `Ascii Tree Generator`という拡張機能があり、これですぐにテキスト化できます。
    * ASCIIは、アルファベット、数字、句読記号、および一部の特殊文字を含むコードで、英語圏でよく使われる文字コードです。ASCIIファイルを生成する、というのは、プレーンテキストのタイプで出力する、という意味と同じと考えて問題ないです。
* まず、拡張機能から「`Ascii Tree Generator`」と検索し、インストールします。
* ツリー構造で出力したいディレクトリを右クリック→`Generate ASCII Tree`をクリックします
* すると、新しいテキストファイルがエディタータブに表示され、指定したディレクトリ以下のツリー構造が出力されていることが分かります。
* こんな感じです。

```
.
├── docker
│   ├── docker-compose.yml
│   └── Dockerfile
└── web
    ├── mysite
    │   ├── mysite
    │   ├── polls
    │   ├── db.sqlite3
    │   └── manage.py
    └── requirements.txt
```

* ただし、 heavily-nested folders（深いネスト構造のフォルダ）は、表示が遅くなることがあるようです。
* デフォルトでは、`node_modules`と`.git`ファイルは無視される設定になっています。
* ちなみに、ブラウザ上で利用できるASCIIアートを使用して、ファイルやフォルダのツリーを生成するツールもあります。すぐに簡単に作成できるので、こちらも活用できそうですね。
    * [ASCII Tree Generator](https://ascii-tree-generator.com/)

# 参考記事
* [aprilandjan/vscode-ascii-tree-generator](https://github.com/aprilandjan/vscode-ascii-tree-generator)
* [Ascii Tree Generator](https://marketplace.visualstudio.com/items?itemName=aprilandjan.ascii-tree-generator)
CORS非対応でもWebAPIを呼び出せるCordovaプラグイン



CORS非対応でブラウザのJavascriptから呼び出しないWebAPIであっても、Cordovaからは呼び出せるようにプラグインを作成しました。
AndroidとiOSに対応させました。

# 種類

* httpaccess.doPostText：HTTP Post(JSON)で呼び出しStringを取得します。
* httpaccess.doGetText：HTTP Getで呼び出しStringを取得します。
* httpaccess.doPostBinary：HTTP Post(JSON)で呼び出しバイト配列を取得します。
* httpaccess.doPostBinary：HTTP Getで呼び出しバイト配列を取得します。

# 使い方

https://github.com/poruruba/cordova-plugin-httpaccess

```js
    let headers = {
        "x-api-key": "APIキーなど"
    };
    let timeout = 10000;

    let inputJson = {
        "username": "へのへの",
        "password": "もへじ"
    };
    let result = await httpaccess.doPostText("https://test.com/test-post", JSON.stringify(inputJson), headers, timeout );
    console.log(JSON.parse(result.result));

    let qs = {
        "username": "へのへの",
        "password": "もへじ"
    };
    const params = new URLSearchParams(qs);
    let result = await httpaccess.doGetText("https://test.com/test-get?" + params.toString(), headers, timeout );
    console.log(JSON.parse(result.result));

    let result = await httpaccess.doPostBinary("https://test.com/test-bin", JSON.stringify(inputJson), headers, timeout );
    console.log(result.result, result.mimeType);

    const params = new URLSearchParams(qs);
    let result = await httpaccess.doGetBinary("https://test.com/test.png?" + params.toString(), headers, timeout );
    console.log(result.result, result.mimeType);
```

以上
deviseでログイン後のリダイレクトを設定したらヘルパーメソッドのundefinedエラーが発生

<p>railsのdeviseライブラリを使った認証機能実装の練習をしていたところ、ヘルパーメソッド周りでどハマりしてしまい午前中を軽率に溶かしてしまったので、もし私と同じようなハマり方をしている方がいたら参考というか時短の助けにはなるかもと久々にQiitaに記録している次第です。</p>
<p>知っていればあまりに単純な見落としすぎるのですが、気づかないときは永遠にさまよい続けるものなので・・・。</p>
<p>初心者ゆえ、内容に大なり小なり事実誤認の可能性があることをご了承頂いた上で、お気づきの点などございましたらご教授いただけますと大変ありがたいです。</p>
<h2>deviseのログイン機能実装</h2>
<p>deviseの導入にあたっては定石通り、deviseをインストールしてビュワーやコントローラーを生成して行きました。</p>

gemファイルに以下を追加

```text
gem 'devise’
```

<p>gemを反映させるためにbundle install</p>

```text
bundle install
```

<p>deviseをインストール</p>

```text
rails g devise:install
```

<p>userモデルを生成</p>

```text
rails g devise user
```

<p>データベースをマイグレート</p>

```text
rails db:migrate
```

<p>viewファイルを生成</p>

```text
rails g devise:views users
```

<p>コントローラを生成</p>

```text
rails g devise:controllers users
```

<p>initializer/devise.rbファイルの247行目付近で以下のコメントアウトを有効化（ビューファイルの変更を反映させるため）</p>

```text
config.scoped_views = true
```

<p>その他もろもろ、細かな変更などしつつ、設定を反映させるために再度bundle installを実行し、rails sでサーバー立ち上げ。</p>

<p>ここまでが完了すると、views/users/sessions/new.html.erbがルーティングされている「/users/sign_in」にブラウザでアクセスすると以下のような画面を表示することができます。超おなじみの展開。</p>

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3073877/0a8351ac-2784-d3de-e253-40d7013ee4d9.png" />

<p>そして、ここからリダイレクト先を設定していきます。ログイン実行時後のリダイレクト先を指定するためには、application_controllerに以下のようなコードを書きます。</p>

```ruby:application_controller.rb
class ApplicationController < ActionController::Base

  def after_sign_in_path_for(resource)
    user_path(resource)
  end

end
```
<p>resourcesのヘルパーメソッドを使うことで、railsで定義されている７つのアクションに対してのURLの指定が、「_path」といったヘルパーメソッドを使用して行えるんですね。</p>

<p>「after_sign_in_path_for(resource)」は、deviseにてあらかじめ定義されているアクションで、ログイン後のリダイレクト先を指定することができるものとなっています。</p>

<h2>発生したエラー</h2>

<p>さて、ここまで設定したら問題なく動くはずと思っていたら、以下のようなエラーに見舞われました。</p>

![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f333037333837372f33313831343037612d633631352d653962332d313235662d3230643630633461656338642e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3073877/7f55bec8-dce2-5615-8117-1ad1c5674978.png)


<p>user_pathメソッドが未定義だ、と怒られているわけです。</p>

<p>formの設定を確認したり、コントローラを確認したり、gemファイルまで確認したりしたのですが、結局原因がわからず。しかし実はあまりにも初歩的なところに見落としがありました。</p>

<h2>ルーティングの設定</h2>

<p>私は絶対に見落としてはいけないポイントを見落としていたのですが、deviseを実行しただけでは、ルーティングは以下のような状態になっています。</p>

```ruby:routes.rb

Rails.application.routes.draw do

  devise_for :users

end

```

<p>お気づきかと思いますが、ヘルパーメソッドの根拠となるresourcesについて何も書かれていないのです。</p>

<p>書かれているに決まっていると何故か思い込んでいた私は、これに気づくまでに何時間もかかってしまったのでした、、、情けない、、、</p>

<p>解決策は言わずもがな、resourcesを書くだけ。</p>

```ruby:routes.rb

Rails.application.routes.draw do

  devise_for :users
  resources :users

end

```

<p>これだけでエラーは解消したのでした。</p>

<h2>deviseはresourcesを自動で設定しない</h2>

<p>こんなの当たり前なのかもしれないのですが、deviseがあまりにも便利なので、ついついresourcesの記述もあるような錯覚に陥っていました。</p>

<p>ヘルパーメソッドの根拠となるresourcesが定義されてない時は、こういうエラーが出るのだと知れたので、今後は一瞬で対応できるかと思います。</p>

<p>以上、もし万が一私と同じような詰み方をしている人がいたら、参考になるかも知れない駄文でした。</p>

ーーーーーー

追記：

ユーザー登録時のリダイレクト先変更には、また別の注意点あり

https://qiita.com/yuta-nos/items/fef68d3212091e948516