OmniAICreator/Qiita-1.07M huggingface dataset:
Unity 2021.2からProject Windowでもコピー・カット・ペーストができるようになった

Unity 2021.1までは、Project Windowにおいては、「Ctrl/Cmd+D」による複製（Duplicate）しかできませんでした。

Unity 2021.2からは、Project Windowにおいて、

* コピー : 「Ctrl/Cmd+C」
* カット : 「Ctrl/Cmd+X」
* ペースト : 「Ctrl/Cmd+V」

ができるようになりました。

次のGIFはProject Windowにおいて、コピー&ペーストを行う様子を録画したものです。

![copy_and_paste.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4125/abb65408-ee1d-fd1c-80c6-b5992076a495.gif)

次のGIFはProject Windowにおいて、カット&ペーストを行う様子を録画したものです。

![cut_and_paste.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4125/38c83fa1-1cf9-4224-3fb8-5d04e48854ae.gif)

Unity 2021.2はまだLTSになっていないので、これから使うという人も多いのではないでしょうか。

直近のUnityは、Editor機能において細かい改善が多数なされています。昔からUnityを使っている人には「これ、不便だったんんだよ−」という点が改善されたり、「ここ、こんなに便利になっていたのかー」という改善も多いと思います。ぜひ、新しいUnityにアップデートして、これらの改善を体験し、開発生活の質を向上させてみてください。


---

関連記事・動画

* Unity for Pro 「[Unity 2020 LTS / Unity 2021.1におけるUnity Editorの小さな機能改善集](https://forpro.unity3d.jp/unity_pro_tips/2021/09/24/2509/)」
* Unity Learning Materials 「[Unityをもっと使いやすく！Unityカイゼン委員会！](https://learning.unity3d.jp/7690/)」
* Unity Learning Materials 「[Unity 2021 アップデートまとめ](https://learning.unity3d.jp/7552/)」
QiitaでLGTMする方法

[う　え　き　ぷ　に　き　あ　く　ん　笑 Advent Calendar 2021](https://adventar.org/calendars/6939 "うえきです")　2日目です
アドカレ出オチで本当にごめんなさい

##教えます　えっへん
↓このボタンを押しましょう
![LGTMb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389480/7ab4e191-468e-cd35-49b3-e7102ea9d4e2.png)
↓このように、チェックマークがついたらLGTMをしたということになります。
![LGTMa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389480/1af89992-ad47-b535-9773-023834af23cf.png)
試しに、早速この記事で試してみましょう！（しなくていいです）
LGTMは記事やコメントに対してすることができます。

記事に対するLGTMのボタンの位置は、
・パソコンの場合
　記事の左
<img width="1200" alt="スクショpc" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389480/943fb557-a919-2f56-5438-912ccf73c2d8.png">

・スマホの場合
　画面下部
<img width="400" alt="スクショsp" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389480/fb0cfb21-2406-0adb-9d4c-6d42c68dea24.png">
に常時表示されます。
※自分の記事でスクリーンショットを撮っているため、LGTMボタンが灰色になっています。このとき、ボタンを押すことはできません

また、コメントに対するLGTMのボタンの位置はどちらの環境でもコメントの下に配置されています。
・パソコン
<img width="800" alt="コメントpc" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389480/8f3721e7-a4f1-4c50-954d-95bb959b43b4.png">

・スマホ
<img width="400" alt="コメントsp" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389480/fc91fb1c-7594-6bf2-dcd5-703c5d90d40a.png">
※画像はイメージです

##最後に
この記事、[Qiitaの利用規約](https://qiita.com/terms "Qiitaの利用規約")に反していないよね...？と少しだけ心配しています。
Qiitaに投稿する記事は、エンジニアに関する知識を記録・共有するような内容でないといけないのですが、Qiitaの使い方はエンジニアに関する知識に該当するはず...

明日はうえきさんの記事です！楽しみですね！
SHARPのCOCORO AIR対応家電を、Node.jsから操作する話


この記事は記事は[道メン（身内向け）アドベントカレンダー](https://adventar.org/calendars/6306)の2日目の記事です。
## はじめに
Qiitaの記事投稿は100万年ぶりです。なずなです。
ある程度いろいろなプログラムを書けるようになってきたので、そろそろアウトプットが必要な頃合いでしょうということで投稿します。

空気清浄機が欲しかったので買いました。
購入したのはシャープの加湿空気清浄機 [KI-LS40-W](https://jp.sharp/kuusei/products/kils40/)です。

![130567.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306146/ccbb7a95-de7b-468c-c336-2a5082ce3a6d.jpeg)

特徴は気化式の加湿機能を備えている点と、COCORO AIRに対応にしており、外部から操作が可能な点です。
...今、「__外部から操作が可能__」と言いました。
つまり、APIが存在してるということです。
botから制御ができたら、さらに便利になるのではないでしょうか？
ということで早速調べたのですが、公式に提供されているものはなく、実際にスマートフォン等の端末のCOCORO AIRアプリの通信を覗き見て解析する必要がある、ということがわかりました。

調べた結果ヒットした記事はこれだけ。
シャープの加湿空気清浄機をアプリ外から操作する(https://rcmdnk.com/blog/2021/03/03/computer-iot-raspberrypi/)

記事にあったのは私の触ったことが無いPythonのサンプルコードでした。
「じゃあPythonを勉強しよう」でもよかったのですが、いろんな都合でNode.jsばかり触っているのと時間があまり取れないので「じゃあNode.js版も作ろう」ということに。

## プロキシを利用していろいろ取得
mitmproxyを利用して通信を覗き見する部分は完全に同一であるためスキップします。
ちなみにWSLでmitmproxy導入して見てやろうと思ったらポートフォワーディング関係で沼った話もありますが、それは別の機会に。素直にWindows版使うのがいいかもしれません。

## コード
コードはこちら([Github](https://github.com/na2na-p/COCORO_AIR_Node.js))
`npm install`して、state_sample.jsonやら.env_sampleやらのファイル名から末尾の`_sample`を消していい感じにします。
先に挙げたページを見ると、何を取得すればいいのかわかるかと思います。

### 流れ
JSESSIONIDの取得(`get_JSESSIONID`)→コマンドをシャープのサーバーへ送信(`sendCommand`)
`sendCommand`の引数として、JSESSIONIDと操作用のコードを渡しています。
非同期処理周りなにもわからないのでGithubCopilotの力を借りています。

サンプルコードでは、毎回JSESSIONIDを取得しているので、あまりスマートなやり方ではないです。有効期限切れるまで保持して切れたら更新する、とか前回使用したJSESSIONIDを再利用してみて、エラーが返ったら再取得して再試行するとかがいい気がします。公式のアプリは後者のやり方をしてたはず。

## 応用例
私はIFTTTとDiscordBotと組み合わせて、毎朝おやすみモードから自動運転モードに切り替えるような使い方をしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306146/3d56dcff-3adc-4500-a222-9f9aec43f943.png)


## 最後に
あんまり内容が濃いものではなかった気もしますが、ここまで。ありがとうございました。
最後、関係ないんですがおすすめのReact入門の記事や書籍あれば教えてほしいです。
Ansibleのtemplateモジュールで複数ファイルを対象にする

## はじめに
Ansibleのtemplateモジュールでとあるディレクトリ配下に存在する条件に一致する複数のj2ファイルをターゲットのサーバに末尾の".j2"を取り除いたファイル名で展開したいという場面がありました。
templateモジュールでのループの方法や正規表現の記載方法など備忘録的な意味も込めて記事を作成。

## 条件
ディレクトリ構成は下記の通りです。

```
roles
  └── test
        ├── tasks
        │     └── main.yml
        │
        ├── templates
        │     └── test
        │           └──2021
        │                ├── test1.conf.j2
        │                ├── test2.conf.j2
        │                ├── test3.conf.j2
        │                └── sample.conf.j2
        │
        ├── vars
        |     └── main.yml
        │
```
今回はtemplates/test/2021/配下のファイル名に"test"がつくj2ファイルのみをtemplateモジュールで/tmp/test/配下に展開します。
展開する際のファイル名は".j2"を取り除いたものとします。
（test1.conf.j2であればtest1.conf）
また、srcに指定するtemplates配下のパス（test/2021/）は変数`src_path`として定義されていることとします。

```yaml:vars/main.yml
---
src_path: test/2021/
```

## templateモジュールで複数ファイルを対象にループ
templateモジュールで複数ファイルをループしたい場合は`with_fileglob`を使用すればできます。
with_fileglobはワイルドカードを使用してファイルを指定できるため、特定の条件に一致するファイルのみをループしたい場合にも使えます。
Playbookは下記の通りです。

### Playbook
```yaml:tasks/main.yml
---
- name: Set test vars
  include_vars: ../vars/main.yml

- name: template test
  template:
    src: "{{ item }}"
    dest: "/tmp/test/{{ item | regex_replace('.j2$','') }}"
  with_fileglob:
    - "../templates/{{ src_path }}test*.j2"

```
このPlaybookを実行したところ問題点がありました・・・。

### 問題点
with_fileglobはフルパスが戻り値となるため、上記のPlaybookのように末尾の".j2"を取り除くだけでは不完全でした。

### 解決策
解決策としてregex_replaceに末尾の"j2"をだけでなく余計なパスを取り除き、ファイル名のみを抽出する正規表現を記述します。
destには下記を記載しました。

```
dest: "/tmp/test/{{ item | regex_replace('^.*test/2021/(.*).j2$','\\1') }}"
```

正規表現については[こちら](https://murashun.jp/article/programming/regular-expression.html)を参考にしてください。

destを上記に修正しPlaybookを実行したところ上手くいきました。

## regex_replaceで変数を使用
destのregex_replace内にtest/2021/を直打ちする場合は上記で大丈夫なのですが、今回は変数src_pathを使用してマッチさせる必要がありました。
変数を使用したい場合は変数部分を下記のように`+変数+`の形で記載します。

```
dest: "/tmp/test/{{ item | regex_replace('^.*' + src_path + '(.*).j2$','\\1') }}"
```
最初はitemのように単純にsampla_pathと記載したり、{{　}}でくくったみたりしたのですがうまく行かず、意外とここに苦戦しました・・・。

## 最後に
とても単純な処理内容ですが、正規表現やregex_replace内で変数を使ってマッチさせる際の記述方法などとても勉強になりました。
Vue Devtoolsを使ってVue.js × VSCodeでデバッグができるようにする

## やりたいこと
- Vue.jsのコードをデバッグしたい
    - ブラウザから入力 => ソースコード上で処理の流れを追いたい

## どうすればできそうか
- Vue Devtoolsという拡張機能を使えば、Chrome等のブラウザを使ってデバッグできそう
- 全体的な方針は以下の記事を参考にすれば良さそう
    - https://jp.vuejs.org/v2/cookbook/debugging-in-vscode.html

## やったこと・手順
- Chromeの拡張機能で`Vue.js devtools`をインストールし、設定変更
    - ブラウザから拡張機能を[インストール](https://marketplace.visualstudio.com/items?itemName=msjsdiag.debugger-for-chrome)する
    - ブラウザの拡張機能の設定で、「ファイルの URL へのアクセスを許可する」をONにする
- VSCode側で設定を行う
    - `vue.config.js` に[設定を追加する](https://jp.vuejs.org/v2/cookbook/debugging-in-vscode.html#%E3%83%96%E3%83%A9%E3%82%A6%E3%82%B6%E3%81%A7%E3%82%BD%E3%83%BC%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E8%A1%A8%E7%A4%BA%E3%81%99%E3%82%8B)
    - ` launch.json`に[設定を追加する](https://jp.vuejs.org/v2/cookbook/debugging-in-vscode.html#VS-Code-%E3%81%8B%E3%82%89%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E8%B5%B7%E5%8B%95%E3%81%99%E3%82%8B)

```js:vue.config.js
// Vue CLI 3 を使っている場合、vue.config.js 内の devtool プロパティを設定もしくは更新してください:
module.exports = {
  configureWebpack: {
    devtool: 'source-map'
  }
}
```
```json:launch.json
{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "chrome",
      "request": "launch",
      "name": "vuejs: chrome",
      "url": "http://localhost:8080",
      "webRoot": "${workspaceFolder}/src",
      "breakOnLoad": true,
      "sourceMapPathOverrides": {
        "webpack:///src/*": "${webRoot}/*"
      }
    },
    {
      "type": "firefox",
      "request": "launch",
      "name": "vuejs: firefox",
      "url": "http://localhost:8080",
      "webRoot": "${workspaceFolder}/src",
      "pathMappings": [{ "url": "webpack:///src/", "path": "${webRoot}/" }]
    }
  ]
}
```
- ブレイクポイントを設定する
- VSCodeからアプリケーションを[起動させる](https://jp.vuejs.org/v2/cookbook/debugging-in-vscode.html#VS-Code-%E3%81%8B%E3%82%89%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E8%B5%B7%E5%8B%95%E3%81%99%E3%82%8B)

=> 無事ブレイクポイントにデバッガが止まった！

## つまった箇所
- 拡張機能をONにしたけどデバッグできない
    - エラー。VSCode側（ソースコード側）で、ライブラリのインストールが必要なのか？
    - 原因は、前述した「vue.config.js に設定を追加する」をやっていなかったため。手順を見直して解決。

> Download the Vue Devtools extension for a better development experience:https://github.com/vuejs/vue-devtools`

## 参考サイト
- https://jp.vuejs.org/v2/cookbook/debugging-in-vscode.html
- https://jp.vuejs.org/v2/cookbook/debugging-in-vscode.html
Next2D NoCode Toolで絵を描く

# 描画ツール
本日は、描画ツールを紹介したいと思います。
Tool Areaに雛形として、`矩形`、`楕円`、`角丸矩形`を準備してます。
![スクリーンショット 2021-12-01 23.06.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80502/c1905f4d-41d1-bc04-6e63-2039ed47d137.png)
ツールを選択後、Screen Area上で描画範囲をマウスで選択する事で追加できます。
![スクリーンショット 2021-12-02 11.38.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80502/a90d4337-34b9-2f43-70ad-d42f4983474c.png)


# 塗りツール
色設定もTool Areaに設置されてます。
画像の上から、`塗りの色`、`線の色`、`線の幅`となっています。
線の幅が0の時は線の描画は行われず、塗りだけが実行されます。
![スクリーンショット 2021-12-01 23.09.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80502/4297170b-640e-0712-6287-b628237a5a04.png)
Screen AreaにShapeを追加した後、Controller Areaから以下の色設定変更が可能です。
- 色変更
- 画像の塗り(繰り返し)
- 線形グラデーション
- 円形グラデーション
![スクリーンショット 2021-12-01 23.03.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80502/98292ca5-58f1-1ef7-2484-2f0dba376224.png)

# ペンツール
`ペンツール`はマウスで自由に線を描く事ができます。
![スクリーンショット 2021-12-01 23.07.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80502/a8d094bf-de60-2db4-ab3a-8b623d964852.png)

塗りツールの線の幅とカラー設定すると、Screen Areaに直接線を描く事ができます。
![スクリーンショット 2021-12-02 11.04.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80502/b43e02b6-8324-9a51-5804-b7d5a61bb920.png)
![スクリーンショット 2021-12-02 11.06.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80502/b926ed60-79d6-f68f-3c7f-b780390ad18b.png)



# 変形ツール
Tool AreaのShape変形ツールからShapeのパスのカスタマイズが可能です。
![スクリーンショット 2021-12-01 23.21.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80502/ffa2c26f-c759-e915-bcda-1a278e231cde.png)

四角のポインターがパスのxy座標で、円のポインターがカーブのxy座標になっています。
Shapeの外側もしくは内側をダブルクリックすると新しいパスのポインターが追加されます。
四角のポインターをダブルクリックすると円のポインターが追加され、Deleteボタンで削除する事ができます。
![スクリーンショット 2021-12-02 10.59.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80502/9bcd1221-c461-d4d2-29f5-8d66adbebde2.png)

# 中抜き
中抜きを行いたい場合は新たに雛形などでShapeを追加し、右クリックで表示されるモーダルメニューの`Integrating paths`でShapeを結合させる事ができます。
![スクリーンショット 2021-12-01 23.31.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80502/c1fc4cdb-83c7-960c-b847-3c1be47c0124.png)

## 動作サンプル動画
(僕自身、絵が描けないので下手なサンプル動画となり、すみません。。。)
<iframe width="560" height="315" src="https://www.youtube.com/embed/mg_DyFBXSAs" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

Shape機能は、まだまだ機能が不足していると思いますので、これから順次機能を拡張できればと思っています。
もし、この記事を見て、どんな絵が描けるか試してたい方はこちらから動作確認が可能です。
[NoCode Tool](https://tool.next2d.app)

明日はテキストツールを紹介できればと思います。
Moleculeテスト環境用のDockerゴールデンイメージを作成する

Ansible Moleculeでテストを実行する時にテスト対象になるDockerイメージの作成方法について解説します。

今回はGitHub Actionsを用いてGitHubコンテナレジストリへDockerイメージを登録するまでになります。

## なぜテスト環境用のDockerイメージを作成、登録するのか？


* CIの実行時間を短縮するため
* コードの記述量を減らしメンテナンスしやすくする

これらの理由が考えられます。

### CIの実行時間を短くする

Moleculeの機能から言えばMolecule実行時にDockerfileからテスト環境用のコンテナを作成する事は可能です。しかし毎回イメージをビルド、コンテナを起動しているとCIの実行時間が長くなってしまいます。

### コードの記述量を減らしメンテナンスしやすくする

テスト環境用のDockerfileを一箇所で管理する事によりメンテナンスコストが減らせます。例えば**Ansible Role / Playbookでリポジトリがそれぞれ分かれていてなおかつそれぞれのリポジトリでDcokerfileが管理されている場合Dockerfileに変更が生じると全てのリポジトリに対して修正を行う必要が出てきます**。これは相当悪手なので絶対に避けます。


## ゴールデンイメージの仕様

ゴールデンイメージの設計図となるDockerfileには以下を含めます

* イメージのアップデート処理
* Ansibleを実行するユーザーの作成
* Ansible実行ユーザーへroot権限の付与

### sshdはインストールしない？

Ansibleは標準でDockerコンテナへの実行をサポートしています。そのためsshdはインストールしません。

* [How to build your inventory — Ansible Documentation](https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html#non-ssh-connection-types)

### イメージのビルドの頻度は？

毎日が理想だと思います。減るものでもないのでcron等で自動化しておくと良いでしょう。

## Dockerfileのサンプル例

```dockerfile:Dockerfile
FROM centos:8

# Install requirements
RUN dnf clean all \
  && dnf update -y \
  && dnf install -y sudo

# Create `ansible` user with sudo permissions
ENV ANSIBLE_USER=ansible SUDO_GROUP=wheel
RUN set -xe \
  && groupadd -r ${ANSIBLE_USER} \
  && useradd -m -g ${ANSIBLE_USER} ${ANSIBLE_USER} \
  && usermod -aG ${SUDO_GROUP} ${ANSIBLE_USER} \
  && sed -i "/^%${SUDO_GROUP}/s/ALL\$/NOPASSWD:ALL/g" /etc/sudoers
```

## GitHub Actoinsのサンプルファイル

```yaml:.github/workflows/build.yml
---
name: build
on: [deployment, push]

jobs:
  github-container-registory:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        base-image: [centos7, centos7jp, centos8]
    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v1

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1

      - name: Login to GitHub container resigtory
        uses: docker/login-action@v1
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.CR_PAT}}

      - name: Build and push
        uses: docker/build-push-action@v2
        with:
          file: ${{ matrix.base-image }}/Dockerfile
          push: true
          tags: ghcr.io/org/repo/${{ matrix.base-image }}:latest
```

## 参考サイト

* [コンテナレジストリの利用 - GitHub Docs](https://docs.github.com/ja/packages/working-with-a-github-packages-registry/working-with-the-container-registry)

### 今回の記事のサンプルになるGitHubリポジトリ

* [docker-images-mamono210/ansible-test_centos at 225a8dab63650ce42cc11ec50fb4d8e43ebf43f4](https://github.com/docker-images-mamono210/ansible-test_centos/tree/225a8dab63650ce42cc11ec50fb4d8e43ebf43f4)
[Unity] Visual Effect GraphのSDFとParticle Stripを使ってみた

初めてVisual Effect Graphを触ったので、作ったものの紹介や感想を書いていきます。
今回VFXの説明は省きます（まだそんなに詳しくない）のでVFXについて知りたい方は別途調べてみてください！

　環境
・Unity2020.3.20f1
・Visual Effect Graph　10.6.0
・Universal RP　10.6.0

#作ったもの
早速ですが制作したものがこちら
![VFX.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1594638/df782e7d-2aac-135e-1c88-f6132ec6d779.gif)![Videotogif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1594638/58492447-2027-71a1-bf0b-29c0aef39a9b.gif)



外側から画面奥にかけてパーティクルが動いています。
カラフルな線に包まれているようなエフェクトです。周りの白いパーティクルもランダムに生成されています。

もう一つは球体の周りを這うようなエフェクトです。

それでは制作過程の紹介に入ります！

#　　Particle Strip
最初はカラフルな線のほうから！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1594638/09e56ec3-02be-ba57-df50-a3064264d991.png)
Particle Stripについて軽く説明すると、パーティクルの軌跡を描画できるものです！


Particle Stripの説明はUnityJapanのこちらの動画がとても分かりやすいです！
https://youtu.be/gdb9zvHh3r0

今回作りたかったのは奥に向かって流れるカラフルな線だったので、カラーの設定以外には特別な処理はありません。

Update Particle Stripの中身をいじればぐにゃぐにゃにすることもできます！
今回は触りだけやってみましたが、いろいろと遊べそうな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1594638/5e883822-21bb-34e9-e039-8959f77b67b0.png)



そして、制作中につまづいたところの話
###TriggerEventRateがない
最初にTriggerEventRateを使おうと思ったときでした、検索しても出てきません！！
![スクリーンショット (368).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1594638/edebc977-8063-8203-45f9-64469d292d54.png)
なんでないんだ？？？？？と調べてみると、どうやらデフォルトでは使えないようになっているようです。

PreferencesのVisualEffects内の Experimental Operators/Blocks にチェックを入れると使えるようになります！まだ実験的実装ということでしょうか…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1594638/b0fa9134-e3da-5b7a-51af-117b91e2b3f9.png)

#　SDF
次は球体のほうです！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1594638/6d66e8ab-a02f-729b-9902-0c9a1d0fadf9.png)

SDFを使うと、メッシュの表面にパーティクルを這わせたり、メッシュ表面に向かってパーティクルを飛ばすなどができます！

今回の作品だとわかりづらいと思うのでStanfordBunnyに協力してもらいました。
それがこちら
![Videotogif (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1594638/7c1f4ab0-33a9-77ef-cf2e-0e40eb78087e.gif)

パーティクルがメッシュの表面に生成されて、よく見るウサギさんが現れました！！
このようにSDFを使うといろんな形を表現できます！

ちなみに、メッシュ表面にパーティクルを生成するだけならPoint Cacheでも表現できます！
メッシュから一定距離を保ちながら移動できるのがSDFのいいところだと思います。

##注意！
製作途中で気が付いたのですが、メッシュをSDFにベイクするためのSDF Bake ToolがUnityにあるのですが最新バージョンでしか使えないそうです。
具体的には2021.2以上で使うことができるようです…

今回は2020.3.20を使っていたので、ベイクできない!!　
なのでウサギさんと球体は別プロジェクトを作りそこでベイクしたものを持ってきました。
（ほかのやり方もあるみたいですが、Unity内でできる2021.2以上のバージョンのほうが楽そうです）

#まとめ
初めてVisual Effect Graphを試してみましたが、きれいな見た目を簡単に作れるのでとても楽しいです！
新機能も追加されていくそうなので、またいじくってみようと思います。
AtCoder ABC182 D Wandering 解

## 問題

https://atcoder.jp/contests/abc182/tasks/abc182_d

## 考察

当然ながら愚直な全探索は $O(N^2)$ かかるので不可能。

任意回操作後のロボの位置は、事前に`A[]`の累積和`cs[]`を計算しておくことで、dp によって$O(N)$で計算できる。だから、(i-1)回目の操作終了後の位置を所与として、次の i 回目の合計 i 個の操作 $(+A_1,...,+A_i)$ を行う過程における位置 $p_i$ の最大値を高速に(遅くとも$O(\log N)$ で) 計算できれば良い。

この $p_i$ は、(i-1)回目の操作終了後の位置 $dp_{i-1}$ に、i 回目の操作における移動の最大幅を足すことで求められる。後者は、i 個の移動$(+A_1,...,+A_i)$ を順に行っていく際の累積和の最大値だから、$p_i = dp_{i-1}+\min_{k \le i} cs_k$ と計算できる。この右辺第二項(`pmax[i]`と呼ぶことにする)は、明らかに位置情報`dp[]`とは無関係に、累積和`cs[]`に対する漸化式として動的に$O(N)$で計算できる。

`cs[]`や`pmax[]`を事前に計算しておくことにより、全体の計算量は$O(N)$に収まる。

## 実装
以上の考察を素直に実装するだけ。

```cpp
int main() {
    // read input
    auto n = in<ll>();
    auto a = vin<ll>(n);

    // cumulative sum
    vector<ll> cs(n, 0);
    cs[0]              = a[0];
    rep(i, 1, n) cs[i] = cs[i - 1] + a[i];

    // path max
    vector<ll> pmax(n, 0);
    pmax[0]              = max(0, a[0]);
    rep(i, 1, n) pmax[i] = max(pmax[i - 1], cs[i]);

    // calc by dp
    ll ans = max(0, a[0]);
    vector<ll> dp(n, 0);
    dp[0] = a[0];
    rep(i, 1, n) {
        chmax(ans, dp[i - 1] + pmax[i]);
        dp[i] = dp[i - 1] + cs[i];
    }
    // show
    print(ans);
}
```
.NETでの暗号化について

#.NETでの暗号化について

Microsoftでは以下のように暗号化を推奨している

https://docs.microsoft.com/ja-jp/dotnet/standard/security/cryptography-model?redirectedfrom=MSDN

暗号化時のキーとベクタの生成は以下が参考になる（上記ページの続きにある）

https://docs.microsoft.com/ja-jp/dotnet/standard/security/generating-keys-for-encryption-and-decryption


実際の参考になるコードは以下の記事が参考になった
https://qiita.com/tera1707/items/a0dc441a7a432433d84d

暗号化時のbyte桁数は規定値では16の倍数になる
以下のURLのサンプルコード参照
https://atmarkit.itmedia.co.jp/ait/articles/1709/06/news020.html
実際には0～15文字をEncoding.UTF8.GetBytes(string)した時には16バイトになる
そこから16～31文字は32バイト、32～47文字は48バイト...という感じになる
【UE4】エディタ上で移動を確認できるスライダーを用意する【C++】

#概要
例えば指定距離進むアクタがあったとします
基本はゲームをプレイしてどのような動きにするか確認する必要があります。
もしくは動きをマップ上で確認した上で計算してパラメータを入力するなどですが、マッパーの負担になります。
確認用パラメータを用意することは可能ですが、パラメータが設定された状態で動かしたりすると大変です。
そこでちょっとしたテクニックを使って安全なデバッグパラメータを作成してみます。

#仕様
矢印の方向に指定距離動くというアクタを作成します。
移動する足場、プレスする天井など、用途は様々かと思います。

#実装
`UObject`にはいくつか編集用の関数が用意されています。
少しだけ紹介してみます。

```C++
// 移動やプロパティの変更など幅広く呼ばれる関数
void OnConstruction(const FTransform& Transform);
// プロパティ編集前に呼ばれる関数
void PreEditChange(FEditPropertyChain& PropertyAboutToChange);
// プロパティ編集後に呼ばれる関数
void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent);
// 移動後に呼ばれる関数(bFinisheedはドラッグ移動などで移動完了後にtrueになる)
void PostEditMove(bool bFinished);
// Undo前に呼ばれる関数
void PreEditUndo();
// Undo後に呼ばれる関数
void PostEditUndo()
// 複製前に呼ばれる関数
void PreDuplicate(FObjectDuplicationParameters& DupParams);
// 複製後に呼ばれ鵜関数(PIEはPlay In Editorで、エディタ上でプレイする場合も内部で複製処理をしているためそのこと)
PostDuplicate(bool bDuplicateForPIE);
```

正直`OnConstruction`以外はあんまり頻出ではないですね。
Undo系は怖いのでなかなか手が出せません。アセット使用者が変にUndoしないように祈りましょう。
Duplicate系は`OnConstruction`などでコンポーネントを生成している系は複製時に複製元のコンポーネントが参照されてしまう上に
コンポーネントまで複製されてしまうので、それをどうにかするという手があります。
個人的には`OnConstruction`でコンポーネント全部取得して`UActorComponent::IsDefaultSubobject`関数で判定し、
非デフォルトなコンポーネントは削除しちゃうのが楽です(これで一本記事書けるなぁ。)
一番大事なことですが`OnConstruction`関数を除いた他のすべての関数は、
`BeginPlay`**などと同様に親クラスの関数(**`Super::*`**)を呼ぶ必要があります！**
もし挙動がおかしいなどあったらここが原因なことがよくあったので使用する場合は必ず確認しましょう。
(ないといけないものって知識がないとわからないのでハマりやすい罠です。)

今回は`OnConstruction`と`PostEditChangeProperty`を使用します。
`PostEditChangeProperty`の引数の`PropertyAboutToChange`には`ChangeType`というパラメータがあり、
`EPropertyChangeType::ValueSet`で値が確定した時を判別できます。
これを使用してデバッグ用パラメータを初期化しちゃいます。
また、ベースとなる位置を取得したいので`OnConstruction`で位置を取得します。
配置するときに最初だけ先に`PostEditMove`より先に`PostEditChangeProperty`が来てしまうので、
順序の速い`OnConstruction`で値をとっておきます。
(`PostEditMove`は移動中は重くて行えないような処理を移動完了時に行う時ぐらいしか使い道はないです…自分は過去に一回だけ使いました)
ベースとなる位置の変数(`baseLocation_`)はレベル開きなおしても値を保持するように`UPROPERTY()`をつけておきましょう。
`moveDistance_`は移動距離として公開、`debugRate_`は0~1でクランプして公開してあります。

```C++
void AArrowMoveBox::OnConstruction(const FTransform& Transform)
{
	Super::OnConstruction(Transform);
	
	baseLocation_ = GetActorLocation();
}

#if WITH_EDITOR
void AArrowMoveBox::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
{
	Super::PostEditChangeProperty(PropertyChangedEvent);

	if (PropertyChangedEvent.ChangeType == EPropertyChangeType::ValueSet)
	{
		debugRate_ = 0.f;
	}

	SetRateLocation(debugRate_);
}
#endif

void AArrowMoveBox::SetRateLocation(float rate)
{
	const FVector direction = arrow_->GetForwardVector();
	const FVector location = FMath::Lerp(baseLocation_, baseLocation_ + direction * moveDistance_, rate);
	SetActorLocation(location);
}
```

これを実行してみると以下のようになります。

![ArrowMoveBox00.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530664/4af1d32e-7e73-c126-4d43-21bd39febc71.gif)

`debugRate_`のスライダーを離すと0に戻っています。
これでエディタ上で安全に移動の確認ができました。
ただし、レベル上の変更としてDirtyになってしまうので複数人でレベルを操作するときは気を付ける必要があります。

#まとめ
- `PostEditChangeProperty`を用いて移動確認用デバッグパラメータを作る
- `PostEditChangeProperty`などの関数は親クラスの関数(`Super::*`)を呼ぶ必要がある

以上、快適なアンリアルライフを送りましょう。
pythonでpgrepして多重起動を防止する（走り書き）

# ※この記事は個人的なメモです

pythonの多重起動を防止するのに，ファイルの存在でチェックしたり（例外で落ちてファイルが残る），ファイルのロックを使ったり（他プログラムからファイル自体を消されたり），専用のライブラリを導入したり（わざわざ？）等いろいろありますが，bashで多重起動をしないようにする方法をそのまま利用してしまえば早いし応用性が高い（perlでも似たようなことができる）．

# コード

```Python:main_code.py
import os

def main():
    # main codes here.

if __name__ == "__main__":
    pid = os.getpid()
    scriptname = os.path.basename(__file__)
    oldest_pid = int(os.popen(f"pgrep -fo {scriptname}").read())

    if pid == oldest_pid:
        main()
    else:
        print("other process already running.")
```

# 結局やってること
bashで言う下記のコードを実行してます．

```bash:main_code.sh
#!/bin/bash

main(){
  # main codes here.
}

pid=$$
scriptname=`basename $0`
oldest_pid=`pgrep -fo $scriptname`

if [ $pid == $oldest_pid ]; then
  main
else
  echo "other process already running."
fi
```

# 注意点
スクリプト名が一緒だと別のファイルでも実行制限に引っ掛かります（笑）

# 参考サイト
- https://docs.python.org/ja/3/library/os.html
- https://docs.python.org/ja/3/library/subprocess.html
- https://www.mk-mode.com/blog/2016/02/21/linux-bash-check-double-start/
ルームのコライダーレイヤーについて

※この記事は、[VCI Advent Calendar 2021][1] の2日目の記事です。

バーチャルキャストルームのコライダーレイヤーを分かりやすく説明してみます！

以下のバーチャルキャスト公式wiki文章と自分の経験を参考しています。

https://virtualcast.jp/wiki/vci/component/unitycomponent/collider

:::note warn
バーチャルキャストバージョン2.1.4aまでの資料です、バーチャルキャストのアップデートで仕様変更する可能性があります、その場合はバーチャルキャスト最新の公式資料を参考してください。
:::

# コライダーレイヤーとは

バーチャルキャストルーム環境で高さと壁の概念があります、そのためにバーチャルキャストの背景やアイテム（VCI）に壁と足場を設定できるコライダーレイヤー機能が追加された。

# コライダーレイヤーの設定方法

Collider が付いている GameObject の Layer を VCI に対応するもの（赤い部分）に設定する
![コライダーレイヤー設定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542363/8052fb83-0d39-3921-6aaa-7d90d47e8ad5.png)

# コライダーレイヤーの早見表

公式 wiki が以下の画像があるけど
![公式wikiの画像](https://virtualcast.jp/wiki/_media/vci/component/unitycomponent/image_ph_2.png?w=400&tok=914fac)

よく見たら以下の早見表にまとめることができます

![IMG2@4x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542363/68578f5b-9220-ccca-d3fc-a68358fc7a06.png)


# 最後まで読んだあなたに

コライダーレイヤーサンプルVCIの限定公開URLです、ありがとうございました！

https://seedonline.jp/products/e925331cff12f2022b682f3ef60854b2228c0d511e7a633a446019965db5378e

[1]:https://qiita.com/advent-calendar/2021/vci
laravel8 Storageファサードのドライバのふるまい

# 目的

- `Storage::get()`の振る舞いについて若干詰まったので簡単にまとめておく

# Storageファサードの振る舞い

- そもそもStorageファサードは`disc()`メソッドや.envで指定しない限り`config/filesystems.php`の`'default'`で指定されたドライバを参照しにいく。
    - ここで言うドライバとはローカルとかS3とかの記憶する「場所」の話である。
    - 完全にデフォルトの場合下記のように記載されてlaravelプロダクトのローカルを参照するようになっている。

        ```config/filesystems.php
        /*
        |--------------------------------------------------------------------------
        | Default Filesystem Disk
        |--------------------------------------------------------------------------
        |
        | Here you may specify the default filesystem disk that should be used
        | by the framework. The "local" disk, as well as a variety of cloud
        | based disks are available to your application. Just store away!
        |
        */
    
        'default' => env('FILESYSTEM_DRIVER', 'local'),
        ```

    - 下記の様に.envに記載されている　場合、ドライバはs3が指定されている。

        ```.env
        FILESYSTEM_DRIVER=s3
        ```

    - この場合Storageファサードを使った処理は`disk()`メソッドで指定しない限りs3を参照して実行される。
- なので「殆どのファイルはs3に上げたいけど、ローカルでzipファイルに固めてダウンロードしたい」などのケースでzipをダウンロードする場合下記のように記載する。
    - `Storage::download()`を用いる場合（あくまでダウンロード処理の例のみ記載、コチラだけを記載してもzipで固めてダウンロードしてくれない）

        ```php
        Storage::disk('local')->download('ファイルパス', 'ファイル名', 'ヘッダー');
        ```

    - `response()`を用いる場合

        ```php
        response()->download('ファイルパス', 'ファイル名', 'ヘッダー');
        // ダウンロード後のファイルを削除してほしい場合、deleteFileAfterSend(true)を呼ぶ
        response()->download('ファイルパス', 'ファイル名', 'ヘッダー')->deleteFileAfterSend(true);
        ```

# 参考文献

- [https://readouble.com/laravel/5.8/ja/filesystem.html#storage](https://readouble.com/laravel/5.8/ja/filesystem.html#storage) ディスクインスタンス取得部分
- [https://stackoverflow.com/questions/44769693/laravel-file-not-found-at-path-but-it-does-exist](https://stackoverflow.com/questions/44769693/laravel-file-not-found-at-path-but-it-does-exist)
- [https://laravel.com/api/10.x/Illuminate/Filesystem/FilesystemManager.html]()
Firestoreでサーバーのタイムスタンプを設定する時はフィールド名をtimestampにする

# 起きたこと
Firestoreのドキュメント追加処理を下記の様に書きました。

※`"firebase": "^9.5.0"`
※`users`はコレクションの名前です。
※省略部分で分からない事があれば聞いてください。

```tsx
import { doc, setDoc, serverTimestamp } from "firebase/firestore";
// 省略
const userDocRef = doc(firestore, "users", "userId");
await setDoc(userDocRef, {
    ...userDocData,
    updatedAt: serverTimestamp(),
});
```
すると、こんなエラーが出ました。

```
Unhandled Rejection (FirebaseError): Function setDoc() called with invalid data Unsupported field value: a function (found in field updatedAt in document users/xxx...)
```

# 解決方法

フィールド名を`timestamp`にする。

```tsx
import { doc, setDoc, serverTimestamp } from "firebase/firestore";
// 省略
const userDocRef = doc(firestore, "users", "userId");
await setDoc(userDocRef, {
    ...userDocData,
    timestamp: serverTimestamp(),
});
```

以上、経験が浅く迷ってしまったため書き留めました。公式に素直に従うのは大事ですね。

# 参考

[Firestore入門ガイド](https://cloud.google.com/firestore/docs/manage-data/add-data#server_timestamp)
画像処理やめとけフローチャート

# はじめに

こちらは鈴鹿高専 Advent Calendar 2021の2日目の記事です。

https://qiita.com/advent-calendar/2021/snct


# 画像処理ってなんだ
画像処理というのは読んで字の如く、画像を処理する話です。
コンピュータは画像を「この1画素は赤が〜だけあって緑が〜あって青が〜だけある！」のように扱っています。
この画像処理は難しく見え、初学者にはなかなか考えるのが大変です。
よって、この記事では初学者の方も簡単に目的の達成をできるようにフローチャート作成してみました！
# フローチャート
![task-cv.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604861/09e59c71-6eeb-e898-143c-be1065d313da.jpeg)

# 解説
## 画像処理じゃなくてもできる？
画像処理はとても不安定です。光加減や背景ですべてが狂います。
もしあなたが求めている目的を別の方法でできるならその別な方法で行ったほうがいい結果になる可能性は高いです。
この別な方法の例を挙げると点群データを使うなどがあります(もちろんタスク次第ですが)。
## 光加減が変化する？
上でも述べたとおりに画像処理は光加減が変化するとその画像自体の情報が大きく変化し、求めている結果が得られないことがよくあります。
例として画像の中の赤色だけを抜き出したいというタスクを考えてみましょう。
このタスクの場合、赤色の閾値を設定することによって求めている結果を得られます。
光加減が変化すると同じ赤色と言ってもコンピュータ的には違うものとして認識されるため、最初に設定したままの閾値だと変化後の環境では求めている結果が得られなくなるのです。
## 検出したいのは透明？
人間の目と脳はものすごい性能を持っており、透明なペットボトルを一瞬で「ペットボトル」と認識できます。
しかし、コンピュータとカメラでは透明なものを認識するのはとても困難を極めます。
なんと最近の研究で認識することは可能になってきましたが、しかしそれでも計算量がとても多くリアルタイムに使うには難しいです。
## CPU力が不安？
画像はその画像の縦*横*その画素の情報を保持しています。画像処理するときはこの大量の情報を処理するため、計算機能の処理性能が画像処理の速さに直結します。
# 画像処理の落とし穴
それでも画像処理をしたいんだ！という人がよく落ちる穴を箇条書き。

* 解像度が足りない
* 新技術に飛びついてコードにバグがあることに気づかない/求めてる環境に対応していないことに気づかない
* 前処理不足/忘れ
* 背景による認識阻害
* カメラの個体差/設定不足
* 自分の思い込み/ドキュメントを読み込んでない


# まとめ
とはいえ画像処理はとても奥深く、楽しい世界です。尻込みせずにどんどん沼に足を滑らせていきましょう！
リアルタイムに防災情報を配信をするために

これは[地震情報アプリ界隈 Advent Calendar 2021](https://adventar.org/calendars/6729)の2日目の記事です。

私が提供している、気象庁の[防災情報の再配信APIサービス（個人向け）](https://dmdata.jp)について記載します。

## 概要
気象庁から発表された防災情報などのデータは、[一般財団法人 気象業務支援センター](http://www.jmbsc.or.jp)を通じて民間気象会社や報道各社(ここでは二次配信者という)などに配信されます。

二次配信者又は気象庁HPなどを経由し、ごく普通の人に情報が渡ります。

しかし、まれに生データでもいいから1秒でも早く受け取りたい逝般人がいます。
今回はその酔狂な人が使うサービスが、リアルタイムにデータ配信を行うための工夫などを紹介します。

### サービスを作った経緯

二次配信者やその再配信者など、気象庁と受け取りての間が入れば入るほどデータの受け渡しの遅延が大きくなります。
また、気象庁HPでもPULL型として防災情報XMLを配信していますが、データキャッシュなどでどうしても遅延が1分以上発生するので実用性はかなり低くなっていました。

なので、2020年04月より自分でサービス（有料）を作成した次第です。

## 気象業務支援センターからのデータ受け取り

気象業務支援センターからの情報受け取りはFTP-PUT、自前のFTPサーバーを構築し支援センターから情報が到達後、ファイル名をリネームすることによって送信完了を通知する方法をとっています。

本当にリアルタイム性を追求するならば、同センターが提供している「JMAソケット付きTCP/IP」を使用するべきなのですが接続回線の難易度により現在は断念しているところです。
接続できる回線は、専用線（自分で気象庁本庁まで引く）か、[NTT IP-VPN Arcstar Universal One](https://www.ntt.com/business/services/network/vpn/vpn.html)(法人向け)です。

仕方がないのでFTP-PUTを使っています。

しかし、それでも「JMAソケット付きTCP/IP」との遅延は1～2秒遅い程度でしょう。

### 発信システムの地理冗長受け取り
 
東京と大阪で同じ内容のデータを1通づつ受け取っています。
どちらか早い/遅いということがままありますが、どちらか早く到達した順に処理を実行していきます。

また、万が一気象庁・支援センター側での障害時にも適切に処理できるようになっています。
実際、2021年01月26日~27日の東日本アデス障害時や2021年03月02日の東日本アデス更新作業による遅延・未配信時にも正常に稼働していました。（一部サイトでは地震情報など更新されなかったところもありました）

### サービス構成

現在(2021年12月01日時点)のサービス構成を見ていきましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311703/be95d6f3-cb79-2ebe-d45d-2000507e25c1.png)

矢印の色は次の通りです。
黒：FTPやIP/TCPソケットなど
黄：WebSocket
緑：HTTP
紫：MySQL Connection
青：DNS

MySQLと一部を除き地理冗長化、基本同じ処理を並列で行うシステムを構築しています。
なので、どちらか一方が故障してもある程度は情報提供を継続できます。（最近すべての配信が止まったインシデントがありました）

FTPサーバー、IRES、Fileサーバー、WebSocket配信サーバー、APIv2サーバー、認可・認証サーバーはNode.jsで構築しています。
採用した理由ですが私がTypeScriptで開発したかったからと、ライブラリ等が豊富・開発経験がある程度あるからです。（サーバーサードではPHPとNode.jsしかできない）

サービス内で行う防災情報などのデータは、WebSocketによるやり取りを基本としています。
HTTPでもよかったのですが、双方向のデータのやり取り、常時接続によるオーバーヘッドの削減や切断時のリトライ処理など死活監視など併用できることからWebSocketを採用しています。

#### IRES

受信したデータはすべて「IRES」、情報中継編集システム(いっちょ前な名前)を経由してMySQLへのデータ登録、WebSocket配信サーバーやファイルAPIサーバーへ配信してそこから各利用者へデータが渡っていきます。

また、JSON化など別形式にデータを変換したい場合もIRESに接続して加工したデータを受信生データと同じ経路で配信しています。

このシステムを挟むことによって、データの一元的な編集・均一化とデータ送受信の手間を省くことや、セキュリティー上の対策が強化できるためです。
このシステムの処理時間は1~25ms程度です。

#### WebSocket配信サーバー

WebSocket配信サーバーでは、接続している利用者へのデータ配信を担当します。

WebSoketで配信行えば、20~100ms程度（通信環境にもよる）でデータを送り込むことができるので、リアルタイム狂にとってもうれしいものとなっています。

#### そのほか

HTTP APIサーバーなどは電文のリアルタイム性を強化するため、データベースのIndexや構成を適切にし、レスポンス性能を高め、多数のリクエスト(500~1000rps程度)に対しての処理能力に耐えられるように設計・構築をしました。

また、処理時間を短くするため、正常にデータベースや永続化データにデータを投入できなくともWebSocketサーバーに配信する仕組みになっています。
正常に投入できなかったデータはリトライ処理され、復旧すれば自動的に投入するようになっています。


## まとめ

最後のほうは投げやりになってしまいましたが、リアルタイム配信・障害耐性を行ううえでの工夫などを一部お見せ致しました。

これにて終わりにしたいと思います。
WEBアプリプログラマーがAWSクラウドプラクティショナーの資格勉強でハマったインフラ用語をご紹介

## はじめに
皆さん、はじめまして。~~（会社のアドベントカレンダーを埋めるべく）~~今回初めてQiitaに投稿させて頂きます。
私はWEBアプリ開発の現場でフロントエンドもバックエンドも薄く広く2年だけ経験してきた、フルスタック（？）でロースキルな新人プログラマーです。
そんなへなちょこエンジニアの自分が一念発起してAWSクラウドプラクティショナー資格取得を目指し勉強に励んだのですが、
その際にAWSのサービス名だけではなく、一般的なインフラ用語でも詰まってしまいました…。
そんなわけで、今回は私のような新人プログラマーには耳馴染みの無かったインフラ用語を列挙して解説していこうと思います。
自分のような『開発系プログラマーだけどインフラも勉強してみたい！AWSを使ってみたい！』という方に少しでもお役に立てば幸いです。

## 対象読者
- AWSクラウドプラクティショナー資格を取得したい人
  - その中でも基本的なインフラの用語が知りたい人

## 用語

### スケールイン
システムを構成する仮想マシン（≒サーバー）の台数を減らすこと。対義語は『スケールアウト』。
例えば深夜にリクエスト数が低下するようなWEBサービスを、AWSのEC2インスタンス複数台を利用して構築している場合、
深夜の時間帯には余剰なEC2インスタンスを停止することで、AWS費用の低下が期待できる。
このリソースの削減を**スケールイン**と呼ぶ。
また、t2.largeからt2.microに変更するといったように、利用している仮想マシンのスペックを下げることは『スケールダウン』と呼ばれる。


### 可用性
システムを極力障害で停止させること無く運用し続けられること。
単語としては『可用性のあるWEBサービス』のように使用される。
その指標としては、稼働率で表現される。
```総時間 = サービス提供時間（稼働時間） + サービス停止時間```
の関係にあるとき、
```稼働率 = サービス提供時間（稼働時間）/ 総時間```
で計算される。


### ホスティング
（物理・仮想を問わず）レンタルサーバーを借りること。
日本国内では『レンタルサーバーを利用する』というが、海外では『ホスティングする』と言うのが一般的らしい。
~~え、前者のほうが理解しやすくない？とか言わない。~~文化の違いですね。


### CIDR
Classless Inter-Domain Routingの頭文字をとったもの。
クラスを気にせずIPアドレスを使用するための仕組み。
端的な解説は困難なので、下記リンクを参照。

[CIDRとは](https://dev.classmethod.jp/articles/what-is-cidr/)


### ROI
Return on Investmentの頭文字をとったもの。
ざっくり言うと、費用対効果やコストパフォーマンス、などに相当する概念。
得られた利益に対してAWS利用にかかる費用を割ったもの。
ROIが高いサービスほど、ビジネス的価値が高いと言える。

厳密に言うと若干異なるので、詳しく知りたい人は下記リンクを参照。
[ROIの意味は？計算式まで理解して投資効果を正しく見極めよう！](https://www.innovation.co.jp/urumo/roi/)


### NAT
Network Address Translationの頭文字をとったもの。
効率的にネットワークを分離し、IPアドレスを変換するための仕組み。
数種類あり、詳細は下記リンクを参照。

[【図解】初心者にも分かるNATの仕組みと種類 ~静的/動的NAT/NAPT/(PAT),セキュリティ等メリット/デメリット～](https://milestone-of-se.nesuke.com/nw-basic/nat/nat-summary/)

### Zone Apex
以下のようなサブドメインを含まないドメイン名。

- sample.co.jp
- sample.com

つまり、```www.```のような接頭辞がつかないドメインのこと。
APEXとは頂点を意味する英単語であり、ゲームのApex Legendsもそれが由来と思われる。
つまりはVictory Royaleであり、ドン勝でもある。

…それはさておき詳細を知りたい人は以下のリンクを参照。

[Zone Apex (Naked Domain) CDN](https://tech.jstream.jp/blog/cdn/zone_apex_cdn/)

### CNAME
Canonical Nameの略。
ドメイン名のエイリアス（≒あだ名）である。
これを利用することで、IPアドレスの割り当てロジックと命名を分離することができるため、IPアドレスの変更に強くなる（らしい）。

詳細は下記リンクを参照。
[AレコードとCNAMEレコードを整理する](https://qiita.com/pirorirori_n712/items/9f9f1e7c3ee7e6850645)

### OAuth
ユーザー認証のプロトコルの1つ。
「Googleでログイン」はこのOAuth認証を利用している。
最近のユーザーログイン方式の流行りの１つなので、押さえておくと吉。


### ベンダーロックイン
特定ベンダー提供の機能を利用しすぎるあまり、他ベンダーへの乗り換えが困難になること。
例えば、某ベンダーのサーバーのAPIを利用してブートのロジックを実装していたら、
別ベンダーのサーバーに移行する際に開発工数が発生してしまう、など。


### モノリシック
ソフトウェア設計において、機能を少数のモジュールに詰め込むこと。
対義語は『マイクロ』。
```マイクロサービス化して疎結合なアーキテクチャを実現する```といった文脈で利用される。
AWSでは各サービスがAPIにより疎結合となっており、マイクロサービスの代表例ともいえる。

また、一般に、マイクロサービス化が進んだシステムのほうが運用しやすく追加開発も行ないやすいとされている。
ただ、初期開発はモノリシックのほうが工期やスキルの面で何かと都合がよいことも…？

そういえば先日、IPAがこんなものを出していました。
[～DXを実現するためのあるべきITシステム「スサノオ・フレームワーク」を紹介～](https://www.ipa.go.jp/about/press/20211116.html)
内容はさておいて、カッコイイ名前ですよね。


### ブート領域
コンピュータの起動に必要なプログラムや設定情報が記録されたディスク上の領域。
私にはこの知識だけで充分だったのでそれ以上は調べず…。

もし詳しく知りたい方は、下記リンクを参照。

[ブートセクタとは何か](https://pctrouble.net/storage/bootsector.html)

## まとめ
いかがでしたでしょうか。
あ～基本情報で見たことあるな～という用語もちらほらありましたね。
本記事が皆様のお役に立てば幸いです。

それでは皆さん、よいエンジニアリングライフを。
Ubuntuが「systemd-logind failed to get session PID XXXX does not belong to any known session」のエラーで起動しない時の対処

## 状況
ここ数ヶ月Ubuntu20.04で開発やネットなど普通に利用をしていて、先ほどAudacityをインストールしたり色々してたら急に画面が固まり、どうにもならないのでPCの電源ボタン長押しで強制終了したところ、今度は画面が真っ黒になって起動しなくなりました。

## 解決した方法
リカバリーモードで入り、rootユーザーでCUI起動。
`/var/log/Xorg.0.log`を見ると`(EE) systemd-logind failed to get session PID 1013 does not belong to any known session`のエラーが。

ここで`/etc/gdm3/custom.conf`の中にある`WaylandEnable=false`のコメントアウトを外して再起動。
これで無事デスクトップの表示ができました。（良かった、、、）

## 余談
これまでWindowsやMacを使ってきてバックアップ真面目にとらなくても運良く問題なかったので油断してましたが、特にLinuxを扱う時はこまめにデータをバックアップとっておこうと思います...。
【新卒1年目】学生時代にやっていて良かったこと、やってたら良かったこと、やらなくて良かったこと


この記事は、[上智大学エレラボ Advent Calendar 2021](https://adventar.org/calendars/6964)第2日目の記事です。

## はじめに

2021年の4月から某IT企業に新卒として入社し、サーバーサイドエンジニアとして7ヶ月ほど経ちました。

※本記事は私が現在所属する組織の公式見解を表したものではありません。また、ここに書いてあることをすべて信じたからと言ってつよつよエンジニアになれる保障もありません。1エンジニアの妄言だと思って読んでください。

## やっていて良かったこと

### 長期インターン

大学2年生の1月(2019年1月)〜大学4年生の3月(2021年3月)の間インターン生として開発業務をしていました。インターンといってもアルバイト代わりにやっていましたが、そこで諸々開発の経験を積んだおかげで下に上げるPython、Git、AWS、Dockerを満遍なく学ぶことができました。

### Python/Webアプリケーションの開発

今の仕事ではPythonを使っていないものの、Python(Django)を使ってエレラボの会計システムを作ったのはとても良い経験でした。ログイン機能の作成、REST APIによるCRUD操作、データベース関係の設定など学ぶことがとても多かったです。Webアプリは言語/フレームワークが変わっても基本的な概念は変わらないので好きな言語で一通りWebアプリケーションを作ってみると学ぶことが多いのではないかと思います。

### Git/GitHub

かなり基本的な技術ですが、開発をする上で絶対に使うものなので上げました。エレラボのシステムを作る上で色々コンフリクトを起こしたりトラブルに見舞われたものですが、そのおかげでトラブルが発生しても冷静に対応できるようになりました。
GitHub Actionsなどを使ってCI/CD周りも学んでおくと業務に役に立つかもしれません。

### AWS

AWSかGCPかAzureかは問わないですが、何かしらクラウドサービスに慣れていると、日常の業務で心配がなくなりそうです。言ってもエレラボではEC2サーバーやS3、Route 53、CloudFront周りしか触っていませんが、苦手意識はなくなりました。この5つくらいに慣れておくと新しいサービスを触るときでも感覚で触れると思っています。EC2サーバーを立てずにS3で静的サイト配信であれば月額数十〜百円で動かせるのでぜひやってみてください。

### Docker/Docker Compose

最近だとかなり普及しているので意識しなくても触る機会がありそうです。さっと本番環境に近いものを使い捨てで用意したり、新しいツールをホストマシンを汚さずに試したりできるので、覚えておくととても便利です。
2番目に挙げたWebアプリケーションをDocker化するなどして学んでいけば徐々に慣れていくと思います。

### GAS

Google Apps Script、スプレッドシートなどで動かすためのスクリプト言語です。大体の企業でGoogle Workspace(G Suite)導入していて、GASで組まれた社内システムがあるというのもあるある話だと思います。
流石にプロダクションのコードを開発することはないですが、覚えておくと自分用のツールを作ったり既存コードを直せたりするのでおすすめです。個人的なツールでは秘書botとして定期的なリマインドを管理するためのアプリケーションをGASで作っています。

## やってたら良かったこと

### 色々な会社でのインターン

チーム開発の経験を積むために色々な会社でインターンをしておけば良かったなと思います。インターン時代の会社と今働いている会社で2社しか経験していませんが、開発スタイルが結構違うので最初は戸惑う機会が多くありました。絶対に正しい開発スタイルというのはないと思いますが、色々経験しているとそれぞれのメリット/デメリットが見えてきて面白いと思います。

### Infrastructure as Code周り

TerraformやSAM(Serverless Application Model)、Cloud Formationなどコードでインフラの設定を管理するツールは色々あります。エレラボでサーバー構築をする際はとりあえず動けばいいやで色々設定をしたので、明文的に構成を残すことができませんでした。何かしらIaCのツールを使って残しておけば引き継ぎも楽だし、その知見を業務でも役に立てられたんじゃないかなと思います。

## やらなくて良かったこと

ないです！！！！！！
プログラミング周りで勉強する必要なかったなあと思うことは特に思いつかないです。強いて言うならもっと時間を有効的に使えていたら良かったかなあ。TwitterやYouTubeで浪費した時間は帰ってこないです。
この記事を最後まで読んでくれた皆様におかれましては有意義な開発ライフを送ることを祈っております。
Androidのゲーム開発まとめ

# 背景
どうも”おもり”です。

私の最近のハマりは、「ちいかわ」です。

https://twitter.com/ngnchiikawa/status/1453662945871863810?s=20

こんな可愛らしいキャラクターを自分で作って、Androidアプリでゲーム化したいなーという野望があるのです。
ちょうど、👇のようなアプリがあることも知って、可愛らしさに舌を巻きました。

https://youtu.be/ZnU_4PJFJ8s

そんな訳で、Androidでゲーム開発をするスキルを頑張ってみようと思った訳です。今月ちょっと頑張ってみます。

# 対象読者

* Androidでゲーム開発をしたことが無い人
* Androidアプリ開発はしているが、ゲーム開発にも興味がある人

# Androidでゲーム開発を始めるには？

https://developer.android.com/games?hl=ja

まず初めに辿り着くのは、こちらの記事でしょう。

* Android Game Development Kit（AGDK）の中にゲーム開発で必要なものが詰まっている。
* UnityやUnreal Engine4などのゲームエンジンを使ってゲーム開発ができる。

Youtubeなどで動画を探してみても、良さそうな勉強教材が見つかりません。
公式ドキュメントを読み込んで、ノウハウを学んでいくしかなさそうですね。

# どのゲームエンジンを使うのが良いのか？

ゲームエンジンには、UnityとUnreal Engine4などがあります。これ以外は特に見るつもりはありません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276053/634922b5-2d2b-5707-b65d-a5f124c70578.png)

https://zenn.dev/daichi_gamedev/books/unreal-engine-5/viewer/unity-vs-unrealengine

この記事がとても読みやすかったです。

## Unity
* ゲームアプリ開発の主流
* 開発のための情報が豊富
* ゲームエンジンのシェアがNo.1
* 言語はC#

## Unreal Engine
* PCゲーム開発の主流
* 描画の綺麗さはUnity以上
* Unreal Engine5の登場が控えており勢いがある
* 言語はC＋＋

https://note.com/withid/n/n9a38e91de609
こちらの記事の以下の文章を見る限り、私のやりたいこと的には、Unityなのだなと納得。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276053/a68ea31c-633f-285c-e24d-8fbe2808eab0.png)


私は業務でC++を4年間使い続けている関係もあり、Unreal Engineを使いたいなーって思ってたのですが、
やっぱりUnityなのかーって感じですね。VR技術も身に着けたいと感じていた今日この頃。Unity頑張ろう。


# UnityでAndroidゲーム開発を始めるには？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276053/6d08615d-c3ce-1d29-62d1-1f0b8042463c.png)

早速、Unityをダウンロード。

https://unity.com/ja/solutions/mobile/android-game-development

Youtubeにも参考になりそうな動画が見つかったので、これを通勤中に見ながら勉強を開始します。

https://www.youtube.com/playlist?list=PLBIb_auVtBwCKQk6blxNPYC5GEuaC4DGm

あとは、Unityのマニュアルを読みながら実践あるのみ。

https://docs.unity3d.com/ja/2018.4/Manual/android-GettingStarted.html

# Androidゲーム開発をする上で

追加予定。。。

# まとめ

Androidのゲーム開発をする上で、Unityがベストアンサーだと思います。
AGDKとUnityを連携させて、ゲーム開発を始めていきましょう！！
Dockerにて開発環境構築中、A server is already running. Check /ronstagram/tmp/pids/server.pid.というエラーが出た。

#はじめに
Docker ComposeでRailsの環境構築を行う際にDB作成時点でエラーが出たので備忘録メモ。
#エラー内容
Dockerfileとdocker-compose.ymlを編集後
`$ docker-compose up -d`を実行。
その後、`$ docker-compose run web rake db:create`を実行した際、

```
Database 'ronstagram_development' already exists
Can't connect to local MySQL server through socket '/run/mysqld/mysqld.sock' (2)
Couldn't create 'ronstagram_test' database. Please check your configuration.
rake aborted!
```
とエラー。
`$ docker-compose logs`でエラー文を見る。

```
web_1  | => Booting Puma
web_1  | => Rails 6.0.3.6 application starting in development
web_1  | => Run `rails server --help` for more startup options
web_1  | A server is already running. Check /myapp/tmp/pids/server.pid.
web_1  | Exiting
```
調べてみると、どうやら前のRailsサーバ起動時に作成されたserver.pidというファイルが残ってしまい、新たにサーバが起動できないらしい。
#対応
server.pidファイルを削除

```
rm -f tmp/pids/server.pid
```
その後、再び`$ docker-compose up -d`でupし直す。
`docker-compose run web rake db:create`した後`$ docker-compose logs`でlog確認。

```
web_1  | => Booting Puma
web_1  | => Rails 6.0.3.6 application starting in development
web_1  | => Run `rails server --help` for more startup options
web_1  | Puma starting in single mode...
web_1  | * Version 4.3.7 (ruby 2.6.9-p207), codename: Mysterious Traveller
web_1  | * Min threads: 5, max threads: 5
web_1  | * Environment: development
web_1  | * Listening on tcp://0.0.0.0:3000
web_1  | Use Ctrl-C to stop
```
うまくいっているようなので`$ docker-compose run web rake db:migrate`実行。
localhost:3000をブラウザで確認。アプリも立ち上がっているので成功。
Postgresで行集合1行ずつのリストを取得するとき、 ウィンドウ関数 と 副問い合わせ、どちらが早いか

概要
--
キー情報で一意になる行のリストを取得するときに、キー情報ではない列は適当に該当した一列から値を取得したいと思ったが、意外とやり方が難しかった。

いまいち使い方が分かっていなかったウィンドウ関数の勉強しながら、処理コストなど検討してみた。

ちなみにキーは複合キーである。

方法
--
やり方として、

A.DISTINCT　+　副問い合わせ
1 DISTINCTでキーが一意になるような行セットを取得し、
2 さらにそこに副問い合わせでlimit1で、適当な1行から値を取得する

B.ウィンドウ関数を使う
1 ウィンドウ関数で行集合内での行番号付与
2 行集合内の先頭行のみ取得

の2通りを考えた。
(もっといい方法あったら教えてください）

■Aの場合のサンプルSQL

--1意なキーのリストに、キーではない列の適当な1行を副問い合わせで加える
SELECT
  col_key1
  ,col_key2
  ,col_key3
  ,(SELECT col_prm1 FROM shohin_master mst2
    WHERE col_key1 = col_key1
    AND col_key2 = col_key2
    AND col_key3 = col_key3
    limit 1)
FROM
--1意なキーのリストを取得
  (SELECT DISTINCT
    col_key1
    ,col_key2
    ,col_key3
  FROM shohin_master mst1
  ) keylist
;

■Bの場合のサンプルSQL

--row_number = 1の行のみ取得（行集合ごとの、1行目を取得）
SELECT
  col_key1
  ,col_key2
  ,col_key3
  ,col_prm1
FROM
--キーごとの行集合を作り、行集合内での行番号を付与したリストを作成
  (SELECT
    col_key1
    ,col_key2
    ,col_key3
    ,row_number() over(partition by col_key1,col_key2,col_key3)
  FROM shohin_master mst1
  ) mst_with_num
WHERE row_number = 1
;


結果
--
マスタ数万件くらいで、Aパターンのほうが早かった。

件数ごとの処理コスト比較、ウィンドウ関数の使い方について、追記したい。

参考
--
■ウィンドウ関数のPostgresドキュメント
https://www.postgresql.jp/document/11/html/functions-window.html
SharePoint Online（MS365）へのファイル移行

# SharePoint Onlineへの移行について
数えられる程度のファイル数なら手作業で移行してもいいですが、ファイルが多いようならMicrosoft公式からSPMT（SharePoint Migration Tool）というツールが提供されているのでそれを使用するのが良いと思います。
このツールはGUIとPowerShellによるCUIの両方をサポートしています。
この記事ではCUIを使用してオンプレミスのファイルをMicrosoft 365（旧Office 365）のSharePoint Onlineへ移行する方法を記述します。

## SPMTインストール
以下より、SPMTをインストールしてください。
https://docs.microsoft.com/ja-jp/sharepointmigration/how-to-use-the-sharepoint-migration-tool

## PowerShellスクリプト作成
JSONファイル（spmt.json）から移行タスク情報を読み込んで実行します。
ユーザー名、パスワードは１行目で別ファイル（.env）から読み取っています。
３つのファイルは同じ階層に置きます。JSONファイルはSJISにしてください。

```powershell:migrationSharePoint.ps1
$conf = Get-Content .env -Raw | ConvertFrom-StringData

#Define SharePoint target#
$UserName = $conf.msUserName
$PassWord = ConvertTo-SecureString -String $conf.msUserPassword -AsPlainText -Force
$SPOCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $UserName, $PassWord

#Import SPMT Migration Module#
Import-Module Microsoft.SharePoint.MigrationTool.PowerShell

#Register the SPMT session with SharePoint credentials#
Register-SPMTMigration -SPOCredential $SPOCredential -Force

#Load JSON:
$jsonItems = Get-Content -Raw -Path "./spmt.json" | ConvertFrom-Json
ForEach ($taskItem in $jsonItems.Tasks)
{
    $jsonString = ConvertTo-Json $taskItem -Depth 100
    Add-SPMTTask -JsonDefinition $jsonString
}

#Start Migration in the console. #
Start-SPMTMigration
```

```properties:.env
msUserName=urushibata@example.onmicrosoft.com
msUserPassword=12345678
```

```json:spmt.json
{
    "Tasks": [
        {
            "SourcePath": "C:\\\\Users\\urushibata\\Desktop\\移行テスト",
            "TargetPath": "https://my-company.sharepoint.com/sites/traial",
            "TargetList": "Shared Documents",
            "TargetListRelativePath": ""
        }
    ]
}
```

SourcePath・・・移行元パス。ファイルサーバーへのパスでもオンプレミスのSharePointのURLでも可能です。
TargetPath・・・移行先のSharePointのサイトのルートパスを設定します。
TargetList・・・ドキュメントを指定しています。ここで結構はまったのですが、だいたいのMSのマニュアルには「Documents」と書いてあったのですが「Documents」では403エラーが発生します。「Shared Documents」が正しいです。ドキュメントのルートのURLが「Shared%20Documents」となっているのを確認してください。
TargetListRelativePath・・・TargetList以下のサブフォルダを指定する場合設定します。

## スクリプト実行
スクリプトを実行すれば完了します。
V11のトリガー変数$Trigger Value$をAutomation 360に移行

# はじめに
Automation Anywhere V11でフォルダトリガーを使い、とあるフォルダに新しくファイルが置かれたらBotが起動するとします。
このときV11では置かれたファイルのパス＋ファイル名をシステム変数\$Trigger Value\$で参照できます。このV11のBotをAutomation 360に移行したとき、この変数をどうするか、という話です。

# まずは公式ドキュメントを見よう
答えは以下です。
https://docs.automationanywhere.com/jp-JP/bundle/enterprise-v2019/page/enterprise-cloud/topics/migration/cloud-variable-for-migration.html
ここの「\$Trigger Value\$」の箇所。

でも、少しわかりにくいので以下簡単にやってみます。

# Automation 360でV11のBotを移行
まず、V11のBotをAutomation 360の「Botの移行」などで変換します。ただしV11のEnterprise Clientで定義していたトリガーの定義は変換されてきません。
そこで、Automation 360で新たにトリガーの定義を行います。
仮に、フォルダC:¥tmpの下にファイルが置かれたら起動させるものとします。
![trigger1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632535/f01addfc-0591-7af6-332a-bec8a2414268.jpeg)

ここで「割り当て先(任意)」の変数を定義します。この変数にトリガーが起きた情報が入ります。
注意すべきは要素ごとに型（種類）が異なるレコード変数になっている点です。
![trigger2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632535/720ea6a1-a03e-fbdc-499e-caf59f91c179.jpeg)

V11の\$Trigger Value\$に相当する情報は、\$FolderTriggerData(folder)\$に入ってきます。

# もうひと工夫
私はここで\$FolderTriggerData(folder)\$を\$TriggerValue\$に文字列アクションで代入しようとして、ハマりました。
\$TriggerValue\$は文字列変数、\$FolderTriggerData(folder)\$はファイル変数であるためです。

ファイルアクションの「パスを取得」を使って\$FolderTriggerData(folder)\$を\$TriggerValue\$へ代入します。

#おまけ
\$FolderTriggerData(fromFolder)\$にはファイル名を除いた監視対象のフォルダ名が入ります。
またファイルアクションの「名前を取得」を使って\$FolderTriggerData(folder)\$からファイル名だけを取り出せます。

このあたりはV11より便利になりました。
V11のときは\$Trigger Value\$から文字列操作して情報を取り出してましたので。
条件分岐で例外処理をする2通りの書き方

# はじめに

個人的に思ったことを書いているだけなのであしからず

# 2パターンの説明

## その1 - 特定の条件を例外にする

ある変数、 `foo` と `bar` を使って `foo / bar` を求めることにすると、以下のように例外処理を書くことができます

```cpp
if (bar == 0)
    throw Exception("Division by zero.");

# この先で foo / bar を計算
```

## その2 - ある条件以外を例外にする

数Aの集合でいうところの「補集合」で考えると、以下のように書くこともできます

```cpp
if (bar != 0) {
    # このブロックの中で foo / bar を計算
}
else {
    throw Exception("Division by zero.");
}
```

## どっちがよいか

0の除算の場合は、圧倒的に前者のほうが見やすいですね

後者だと、条件を補集合の形で書いているのでぱっと見で何を除外しているのかわかりづらいですし、さらに入れ子になったときに見づらくなってしまいます

# 別の状況を考える

では今度は、除算ではなく「簡単なパスワード認証」を考えてみましょう

`foo` の値が `"bar"` でなければ例外を投げることにします。

## 前者の書き方

```cpp
if (foo != "bar")
    throw Exception("Division by zero.");

# 以降の処理
```

## 後者の書き方
```cpp
if (foo == "bar") {
    # 以降の処理
}
else {
    throw Exception("Incorrect password");
}
```

## どっちがいいか

僕的には後者のほうがいいですね
後者のほうが条件が明確です

逆に前者の書き方だと補集合を考えることになるので分かりづらくなってしまいます

# 結論

状況に合わせて使い分けるのがよさそうですね
Ethereumハードフォークの日時を予測するスクリプト

# Ethereumハードフォーク

もうすぐ、EthereumのArrow Glacier Network Upgrade(Hard Fork)が行われます。

https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/arrow-glacier.md

12/8頃といわれていますが、具体的にいつになるか知りたいこともありますよね。

Bitcoin Cashは日時でハードフォークなので予定を立てやすいですが、
Ethereumはブロック高でハードフォークであり、ブロック生成スピードは刻一刻と変わるので、いつになるか分かりません。

そこで、少しでも予想の幅を知りたいので、スクリプトを作ってみましょう。

なお、Ethereumハードフォークカウントダウンサイトはあります。

ethernodeは毎回ハードフォークカウントダウンしてくれて結構精度高いけど、今回のArrow Glacierはなぜかやってくれず、前回のLondonのままです。

https://www.ethernodes.org/london

etherscanもカウントダウンがありますが、精度悪いです。

https://etherscan.io/block/countdown/13750000

というわけで、自分で予測するしかない！

# スクリプト

↓こちらにJS製の予測スクリプトがあります。

https://github.com/shu-kob/eth-web3apps

```bash
git clone https://github.com/shu-kob/eth-web3apps
cd eth-web3apps
npm install
```

https://github.com/shu-kob/eth-web3apps/blob/master/eth-upgrade-timing-estimation.js

ソースコードを見ると、

```eth-upgrade-timing-estimation.js
const INFURA_API_KEY = process.env.INFURA_API_KEY;
```

とINFURAのAPI Keyを環境変数から呼び出しています。

INFURAでアカウント作って、API Keyを取得しましょう。

https://infura.io/

無料のでOKです。

環境変数にセットします。

```bash
ETHERSCAN_API=XXXXXXXXXXXXXXXXX
```

```eth-upgrade-timing-estimation.js
const hardForkBlockNumber = process.env.ETH_UPGRADE_BLOCKNUMBER;
```

とハードフォークブロック高を環境変数から呼び出しています。

今回のArrow Glacierだと、ハードフォークブロック高は13773000。

```bash
ETH_UPGRADE_BLOCKNUMBER=13773000
```

環境変数にセットしてあげます。

これらは何回か使うことを考えて、Macなら ~/.zprofile などに書いてあげるのもよいでしょう。

```bash
vi ~/.zprofile
```

```~/.zprofile
export ETHERSCAN_API=XXXXXXXXXXXXXXXXX
export ETH_UPGRADE_BLOCKNUMBER=13773000
```

```bash
source ~/.zprofile
```

実行してみます。

```bash
node eth-upgrade-timing-estimation.js
```

結果は以下

```
現時点でのEthereum Mainnetハードフォーク予想日時(JST)
直近 10000  ブロック生成平均時間:  13.8458 秒    の場合:    2021/12/10 5:11:16
直近 50000  ブロック生成平均時間:  13.76354 秒    の場合:    2021/12/10 4:00:28
直近 100000 ブロック生成平均時間:  13.72382 秒    の場合:    2021/12/10 3:26:17
ブロック生成時間  12  秒の場合:    2021/12/9 2:42:50
ブロック生成時間  13  秒の場合:    2021/12/9 17:03:24
ブロック生成時間  14  秒の場合:    2021/12/10 7:23:58
ブロック生成時間  15  秒の場合:    2021/12/10 21:44:32
ブロック生成時間  16  秒の場合:    2021/12/11 12:05:06
ブロック生成時間  17  秒の場合:    2021/12/12 2:25:40
```

こう見ると、直近1万から10万のブロック生成平均時間が13秒台なので、
ブロック生成時間13〜14秒の2021/12/9夕方から2021/12/10朝くらいになるとわかります。

リアルタイム監視するなら日本時間では深夜になって辛そうですね。

INFURAのAPIは便利なので、ハードフォーク日時予測以外にもいろいろ活用してみましょう！