OmniAICreator/Qiita-1.07M huggingface dataset:
Absolute Solution for Unity Hub Sign In Opening Just A Blank Page

## The Environment
Windows 10, Chrome

## What you are seeing
When you hit the "Sign In" button in Unity Hub you see either a blank page whose url is like https://api.unity.com/v1/oauth2/authorize?client_id=unity_hub&response_type=code&code_challenge=XXXXX&code_challenge_method=s256&redirect_uri=unityhub%3A%2F%2Flogin&locale=en_US or, you are getting a login page but eventually ends up in that url and stuck. I'm only assuming this one particular case below

## What's the problem?
It is an innner problem that can't be entirely solved within an hour so I will just explain how to avoid that problem

## Do this and it'll be done
1. First, hit the sign in button again and make sure you get the latest of the blank pages Unity Hub opened
2. Inspect the page and see the console, then you can see the massege that goes with `Launched external handler for 'unityhub://login/?code=XXXXXX&locale=en&session_state=XXXXXX'.` then copy the url
3. Open up your terminal and do the following
    ```
    C:users\user> cd Where/your/UnityHub/is/installed
    C:Program Files\Unity Hub>"Unity Hub.exe" unityhub://login/?code=XXXXXX&locale=en&session_state=XXXXXX   #what you copied
    ```
4. You may close this page now, thank you

## In case the problem isn't solved
There's really nothing I can do about it, sorry
Adaloのカスタムコンポーネント開発環境構築

# 経緯
- NoCodeプログラミングツール「Adalo」でアプリを作成していたら、カスタムコンポーネントが欲しくなったので作った
- そのときの開発（シミュレーション）環境構築の流れを記載

# 実施環境
- Windows 11 + WSL2 + Docker + docker-osx（OSX Monterey）
    - 構築方法は下記を参照
        - [Windows（WSL2）でMacOSXを動かす](https://lethediana.sakura.ne.jp/tech/archives/steps-ja/1240/)
        - [docker-osxのマニュアルインストール手順](https://lethediana.sakura.ne.jp/tech/archives/steps-ja/1297/)
- 実施したのはiOSシミュレーション環境のみ

# 手順
## OSXの準備
1. XCodeインストール
    -  AppleStoreから普通にインストール
1. Homebrewインストール
`$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"`
1. Watchmanインストール
`$ brew update`
`$ brew install watchman`
1. Cocoapodsインストール
`$ brew install cocoapods`
1. Node.jsのver.14 をインストールしてリンク
`$ brew install node`
`$ brew install node@14`
`$ brew unlink node`
`$ brew link --force node@14`
    - versionを14にする理由は[こちら](https://lethediana.sakura.ne.jp/tech/archives/error-ja/1283/) 
1. yarnをインストール
`$ brew install yarn`
```
$ yarn --version
1.22.19
```
## mobile-previewerの準備
1. [mobile-previewer](https://github.com/AdaloHQ/mobile-previewer)をclone
`$ git clone https://github.com/AdaloHQ/mobile-previewer.git`
1. ディレクトリ移動
`$ cd mobile-previewer`
1. moduleをインストール
`$ yarn install`
1. iosディレクトリに移動
`$ cd ios`
1. Xcodeワークスペースの依存ライブラリをインストール
`$ pod install`
    - 遭遇したエラー1 `[configure: error: C compiler cannot create executables]`: [解決策](https://lethediana.sakura.ne.jp/tech/archives/error-ja/1292/)
    - 遭遇したエラー2 `xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools install` : [解決策](https://lethediana.sakura.ne.jp/tech/archives/error-ja/1280/)
1.  2 のディレクトリ（mobile-previewer）に移動して下記を実行
`$ yarn start`

## XCodeでエミュレータ起動
1. Xcodeを開き、Command Line Toolsを設定
    - Preference > Location > Command Line Toolsを設定
1. 前節4. のディレクトリ（ios）のAdaloApp.xcworkspaceを開く
1. 左上の実行ボタン「▶」をクリックし、エミュレータが立ち上がることを確認
1. 前節 7.で実行しているサービスと連携する
    - エミュレータ上で「Reload」を実行する
    - 上記で連携されなければ、前節7. のサービスをで r を入力する

以上で、iOSシミュレータでカスタムコンポーネントを試す環境構築が完了。
## 参考
- [**mobile-previewerでカスタムコンポーネントをimportする手順**](https://lethediana.sakura.ne.jp/tech/archives/steps-ja/1316/)
- docker-osxを使う場合は[**こちら**](https://lethediana.sakura.ne.jp/tech/archives/steps-ja/1260/)もどうぞ
Windows で IPv6 アドレスをランダム付与から EUI-64 固定にする

Administrator 権限で実行する事。

```txt:ランダム化を無効にする場合
netsh interface ipv6 set global randomizeidentifiers=disabled
```

```txt:ランダム化を有効にする場合
netsh interface ipv6 set global randomizeidentifiers=enabled
```
Shopify製のReactフレームワークHydrogenをHerokuにデプロイする

Shopify用のフロントエンドを開発する際に便利な Shopify製のReactベースのフレームワークHydrogenをHerokuにデプロイしてみます。

ここでは簡単のためデプロイ対象をHerokuとしていますが、Node.jsコンテナを使うPaaSならほぼ一緒です。

## 前提

- Hydrogen CLI で生成されるサンプルアプリである[DemoStore](https://shopify.dev/custom-storefronts/hydrogen/getting-started/quickstart#step-1-create-a-hydrogen-app)をデプロイするものとします。
- Heroku の設定やログインは済んでいるものとします。

## Hydrogen の npm scripts の修正

Hydrogen のルートにある`package.json`を開いて以下のように編集します。

Node.js コンテナ向けのビルドスクリプトと Hydrogen 内蔵のエントリポイント向けの起動スクリプトを設定しています。

```json
    "build": "shopify hydrogen build --target node",
    "start": "node dist/node/index.js",
```

## Heroku への デプロイ

```bash
heroku create -a アプリ名
git push heroku main
```

![hydrogen.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15414/4f9f1a36-7a96-2da8-ecd0-dd8a14ea8015.png)


以上です。
NIC の MAC アドレスから IPv6 リンクローカルアドレスに変換する。

MAC アドレスとは NIC 固有の識別アドレスで物理層の送受信に必要とされる物で、一応世界で一意の番号が付与されとる。
6 バイトから構成されて、前半 3 バイトと後半 3 バイトで区別され、前半が製造元 (VENDER) と、後半は前半の製造元が好きに割り当てられる事になっとる。

```txt:例えば
00:15:5d:00:ff:5a
```

00:15:5d ってのはマイクロソフトが製造元。
00:ff:5a ってのが、固有の躯体番号となる。

ほいで、IPv6 のリンクローカルアドレスは、この MAC アドレスから生成されとるんのじゃが、そのまま変換が出来ず、製造元と躯体番号との間に御呪いワードを付記しおる。

```txt:御呪いワード
ff:fe
```

これを列記しよったのが EUI-64 のアドレスって事。

```txt:EUI-64
00:15:5d:ff:fe:00:ff:5a
```

この時 MAC アドレスの先頭バイトの下から2bit目は反転させる必要がある。
MAC アドレスとリンクローカルアドレスでこのビットの意味が逆なんと。

```txt:IPv6 変換直前の御呪い
02:15:5d:ff:fe:00:ff:5a
```

リンクローカルアドレスの識別としてど頭に fe80:: をくっ付けちゃる。

で、先ほど書きよった EUI-64 のアドレスを 2 バイト事に区切り直してドッキングじゃ。

```txt:IPv6 リンクローカルアドレス
fe80::215:5dff:fe00:ff5a
```
azure　代表的な拡張機能

●代表的な拡張機能

■カスタムスクリプト拡張機能
仮想マシンのOSで、指定したスクリプトを実行するための拡張機能。
Windows仮想マシンに対してはPowerShellスクリプトを、Linux仮想マシンに対してはシェルスクリプトを実行できる。例えば、仮想マシンの初期設定を行うスクリプトを準備し、仮想マシンの作成時にこの拡張機能によってスクリプトを実行することで、仮想マシンの初期設定を自動化できる。

■PowerShell DSC拡張機能
PowerShellによるシステムの構成や展開を行う管理プラットフォーム。
Configurationと呼ばれるスクリプトファイルに宣言型構文と呼ばれる形式で定義。
PCからiPhoneなどのモバイル端末にPythonを使って簡易的なWebサーバーを立てファイルを送る方法

# はじめに
PCからiPhone端末に画像を送りたいときに「ケーブル持ってくるのが面倒」「jpegに変換するのが面倒」だったので、Pythonで簡易的なWebサーバーを立ててファイルを閲覧してブラウザからダウンロードして送ったのでその方法の備忘録

# 環境

Python バージョン３をインストールしている

送りたいPCと送られたい端末は同じローカルネットワーク内、または送りたいPCにアクセスできる環境で実行する必要がある。

# Command prompt

- カレントディレクトリに送りたいファイルを用意する。
- 以下コマンドを撃つ。`XXX.XXX`には実行しているPCのローカルIPを指定する

```bash
python -m http.server --bind 192.168.XXX.XXX 80
```

- 送られたい端末でWebブラウザを開き、上記で指定した`192.168.XXX.XXX`をアドレスに入力してアクセス
- ファイルを選んでダウンロード

# めんどくさい方向け

以下の文字列をバッチファイルに保存して実行するとバッチファイルの場所に保存してあるファイルが端末で表示できる。
IP等は自動で取得するため、表示されたアドレスにアクセスする

```bat
@echo off
setlocal enabledelayedexpansion

set count=1
for /f "usebackq delims=: tokens=2*" %%i in (`ipconfig.exe ^| findstr.exe /r /c:"IPv4 .*"`) do (
    set IP=%%i
    set IP!count!=!IP: =!
    set /a count=!count!+1
)

if defined IP1 (python -m http.server --bind %IP1% 80) else (echo IP was undefined)
```

# 以上
TJBot zero Update 2022

# TJBot zero Update 2022

Raspberry pi zero が手に入らなくなりかなりの時間が立っていますが、
TJBot zero関連のUpdateをお届けしようと思います。

## Raspberry pi zero2が発売されましたね

OSがRaspianからRaspberry pi OSに変わり時間が経過してきました
TJBot zero imageのRaspberry Pi OSバージョンのイメージ開発を行うプロジェクトを発足しました。

https://github.com/tjbotfan/tjbotzero-raspbian/issues

## TJBot フローを外部Project化しました

Node-REDのプロジェクト機能を利用して、GitHub上のNode-REDフローを使用する形にしています。
現在SunsetとなったNode-RED nodeなどの整理、新しいフローの見直しを実施中です。
https://github.com/tjbotfan/tjbotzero-node-red-flows

## 提供がなくなったnode-red moduleの見直しと再構築を目指します。

ハンズオンフローの中で使用していたいくつかのモジュールが公開終了となり
イメージに含まれているもの以降利用ができなくなってきています。
これらの見直しを行い、プロジェクトのアップデートとNodeの再構築を目指しています。

## Watson IoT Platformが2023/12/01でsunsetに

TJBot を使ってWatson IoT Platformを使っていらっしゃる方もいらっしゃるのではないでしょうか。
2022/11に発表がありましたがWatson IoT Platformがサービス終了となるようです。

代替えにはMQTTブローカーやHTTPなどで構築する必要があるようです。
./main.rbで実行できなかったけど、ruby main.rbで余裕で実行できた件


<h1>問題</h1>
<h5>・sinatraで書いたファイルをchmodコマンドを実行した後に./コマンドで実行することができない。</h5>

```
#/Users/ユーザ名/Work1
chmod +x main.rb #実行属性をファイルに付与
./main.rb        #カレントディレクトリ直下のコマンドを実行
./main.rb: line 2: require: command not found
./main.rb: line 4: get: command not found
./main.rb: line 5: Hello World: command not found
./main.rb: line 6: end: command not found
```
<h1>結論</h1>
・./コマンドの代わりにrubyコマンドで実行すればいけた。

```
#/Users/ユーザ名/Work1
ruby main.rb
[2022-11-30 23:18:57] INFO  WEBrick 1.6.0
[2022-11-30 23:18:57] INFO  ruby 2.7.1 (2020-03-31) [x86_64-darwin22]
== Sinatra (v3.0.3) has taken the stage on 4567 for development with backup from WEBrick
[2022-11-30 23:18:57] INFO  WEBrick::HTTPServer#start: pid=16096 port=4567
```
<h1>結論に至るまで</h1>
<h2>予想した原因</h2>
まず、この問題に直面したときに考えたのが、以下の二つです。
<h5>
<ul>
<ol>①sinatraをインストールできていない。</ol>
<ol>②sinatraはインストールできているけど、カレントディレクトリからライブラリにアクセスするためのパス設定ができていない。</ol>
</ul>
</h5>

というわけで、これらについて調べてみました。

<h2>計画</h2>
やることを整理すると、、、

<h6>
<ol>
<ul>・ローカルのsinatraパスを確認する。</ul>
<ul>・確認できたら、そのパスにカレントディレクトリからアクセスできるようにする。</ul>
</ol>
</h6>

です。早速実行してみました。

<h2>計画実行</h2>
まずはgemがどこに保存されているのかがわからなかったので、とりあえず確認してみます。

```
#/Users/ユーザ名/Work1
gem environment gemdir
/Users/ユーザ名/.anyenv/envs/rbenv/versions/2.7.1/lib/ruby/gems/2.7.0
```

次に、sinatraのgemがどこに保存されているのか確認します。

```
#/Users/ユーザ名/Work1
gem which sinatra
Users/ユーザ名/.anyenv/envs/rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/sinatra-3.0.4/lib/sinatra.rb
```
ついでに、rubyがどのパスから呼び出されているかも確認しておきます。

```
#/Users/ユーザ名/Work1
which ruby
/Users/ユーザ名/.anyenv/envs/rbenv/shims/ruby
```

<h2>振り返り</h2>
ここまで、計画を実行してみて、
<h6>
<ol>
<ul>・ローカルにsinatraはインストールされている。</ul>
<ul>・ruby,sinatraのパスはそれぞれ問題なさそう。</ul>
</ol>
</h6>

つまり、最初に予想した原因は問題ではないということが分かった。

そうなってくると、あとはコマンド自体に問題があるんじゃないかと考えた。



<h2>原因の再予想</h2>
<h6>・chmodコマンドか./コマンドのどちらかに原因がある。</h6>

<h2>計画</h2>
<h6>・他のディレクトリでchmodコマンドと./コマンドを試してみる。</h6>

<h2>計画実行</h2>
早速ディレクトリを変えてコマンドを打ってみる。

```
#/Users/ユーザ名
./ruby.rb
-bash: ./ruby.rb: Permission denied
chmod +x ruby.rb
./ruby.rb
./ruby.rb: line 1: puts: command not found
```

<h2>振り返り</h2>
<h6>
chmodコマンドを打ち忘れたときにPermission deniedが出た。<br>
再度chmodコマンドを打ったらPermission deniedが消えたので、このコマンドはちゃんと実行されている。<br><br>
つまり、問題は./コマンドにある。
</h6>

そこで次の記事を見てみた。
[rbenvを使ってSinatraの実行環境を整えるまで](https://qiita.com/keitakn/items/8a89a176943a44adbebb#%E7%92%B0%E5%A2%83%E5%A4%89%E6%95%B0%E3%81%AE%E8%A8%AD%E5%AE%9A)
この記事で、sinatraで書かれたファイルをrubyコマンドで実行していたので試してみたら、、、

```
#/Users/ユーザ名/Work1
ruby main.rb
[2022-11-30 23:18:57] INFO  WEBrick 1.6.0
[2022-11-30 23:18:57] INFO  ruby 2.7.1 (2020-03-31) [x86_64-darwin22]
== Sinatra (v3.0.3) has taken the stage on 4567 for development with backup from WEBrick
[2022-11-30 23:18:57] INFO  WEBrick::HTTPServer#start: pid=16096 port=4567
```

というわけで今回はコマンドを変えればいいだけでしたw

<h2>参考にしたサイト</h2>

[rbenvを使ってSinatraの実行環境を整えるまで](https://qiita.com/keitakn/items/8a89a176943a44adbebb#%E7%92%B0%E5%A2%83%E5%A4%89%E6%95%B0%E3%81%AE%E8%A8%AD%E5%AE%9A)



#執筆時間55分
VS Code（個人的に）おすすめプラグイン

自分が使ったことのあるプラグインの中でおすすめのものを紹介します．（一部今使ってないものもあるけど】
# 
## Code Runner
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2676391/047417fc-c473-05da-83ab-2ada4548a334.png)
ワンクリックで開いているファイルを実行することができる．
CodeRunnerの設定ファイルを書き換えることで，クリック時に実行されるコマンドを変更することができる．
**※Python3系を使う場合にはJsonファイルの書き換え必須**

## Excel Viewer
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2676391/d1037567-8ecf-7461-bd5a-445969331369.png)
CSVファイルやExcelファイルをVSCode上で表示する拡張機能．プログラムで生成したファイルを確認するのに便利．
表示だけでなく，簡易的なソート機能なども備える．
## Discord Presence
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2676391/3ca59fa3-50da-9782-89f4-c378d4294381.png)
Discordのアクティビティ欄にVSCodeのステータスを表示することができる拡張機能．
自分仕事してます感を示すのに便利．

使用しているソフトだけでなく，何のプログラミング言語で，どういったファイル（ファイル名）を編集しているのかも表示される．
ファイル名も相手に表示されるので，変なファイルや秘匿のファイルを開くときには注意．
ちなみに僕はこのファイル名が伝わるのが嫌でアンインストールしちゃいました．（設定で変えられる…？）
Dockerでnpm installが遅い問題を解決する

昔よく`docker npm install 遅い`などのワードで検索していたのですが、そもそもComposeファイルの書き方をあまりよく理解しておらず、自分のフォルダ構成に落とし込むことができなかった経験があります。
あれから学習し少しは分かるようになったのでその成果を記述します。
ともあれ、もし上記ワードで検索してこの記事に来たならば、できればComposeファイルの記述方法を学んでほしいです。
おすすめ→https://zenn.dev/suzuki_hoge/books/2022-03-docker-practice-8ae36c33424b59
# docker-compose.yml
```docker-compose.yml
version: '3.9'

services:
  front:
    container_name: ContainerName
    working_dir: /front
    tty: true
    build:
      dockerfile: ./Dockerfile
      context: .
    volumes:
      - type: bind
        source: .
        target: /front
      - type: volume
        source: node_modules
        target: /front/node_modules

volumes:
  node_modules:
```
ここの`services`の中の`volumes`と、一番下の`volumes`がミソです。

# 簡単な説明
`services`の中にある`volumes`の、`- type: bind`から始まる項目ですべてのファイルをバインドマウントしています。詳しくは調べてほしいですが、コンテナとホストでファイルを同期させています。
これを書かないとホストマシンで書いたソースファイルなどがコンテナに反映されないので、とりあえず何も分からずDockerを触ってNode.jsを起動させてみた場合でも書いてあることが多いと思います。

続いて`- type: volume`から始まる項目で、`node_modules`フォルダのみをボリュームマウントしています。一番下の`volumes`で名前をつけています。
ボリュームマウントはコンテナからは参照できますが、ホストマシンからは参照できません。
つまり、ホストマシンには同期されません。

`npm install`したときは`node_modules`フォルダ内に大量のファイルがダウンロードされます。
このとき、`node_modules`フォルダをバインドマウントしてると、ホストマシンとコンテナでこの大量のファイルが同期されるため、その分遅くなってしまうんですね。

# node_modulesフォルダが空なんだけど・・・
ボリュームマウントしたからです。コンテナ内にはあります。

# おわりに
きちんと学習することの大切さを最近実感しています。
おそらくこの記事内でもふわっとした知識で記載してしまっている部分があると思うので、引き続き学習していきます。
【OSS】JavaScript 地図ライブラリまとめ

## はじめに
この記事は#30DayMapChallenge2022 30日目の記事です。
テーマはRemixです。
主要なOSSのJavaScriptマップライブラリを主観でまとめてみます。

![image](https://raw.githubusercontent.com/tjukanovt/30DayMapChallenge/main/images/flyers/30dmc-2022.png)

https://30daymapchallenge.com/

## Leaflet
### 特徴
軽量ですが、必要な地図機能を網羅しています
デスクトップとモバイルの主要なプラットフォームで動作します。

### 個人的な印象
地図の作成、マーカーの表示など簡単な表示であればコード量も少なくさくっと実装できます。
初心者向けかなと思います。

### 地図表示
OpenStreetMapのラスタタイルを表示します。
```javascript
let map = L.map('map'); // 地図の生成
map.setView([35.7122128, 139.7779244], 15); // 緯度経度、ズームレベルを設定する

L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
}).addTo(map);
```


## OpenLayers
### 特徴
地図タイル、ベクトルデータ、マーカーを表示することができます。
ベクトルタイルも表示できます。
フリーかつオープンソースで、2条項のBSDライセンス（FreeBSDとしても知られています）の下でリリースされています。

### 個人的な印象
他のライブラリと比べると、少々コードが煩雑になります。
GISの基礎知識が必要になります。
投影法を指定したり、タイルを切り出せたりと、高機能なのでGIS技術者に向けかなと思います。

### 地図表示
```javascript
new ol.Map({
    layers: [new ol.layer.Tile({ source: new ol.source.OSM() })],
    view: new ol.View({
        center: ol.proj.transform([139.7779244, 35.7122128], 'EPSG:4326', 'EPSG:3857'),
        zoom: 15,
    }),
    target: 'map',
});
```

## MapLibre GL JS
### 特徴
Mapboxのオープンソースフォーク版です。
WebGLを使用してベクトルタイルとMapLibreスタイルからインタラクティブなマップをレンダリングできます。
3DモデルやMVTの表示も可能です。

### 個人的な印象
レイヤをスタイルファイルでカスタマイズできるのがよいです。
ベクトルタイルのこのデータだけ欲しい～みたいな時に便利です。Tippecanoeはちょっととっつきづらい。（私もまだ慣れていない）
Leafletよりも少し複雑ですが、OpenLayersほど複雑ではない印象です。
私の推しライブラリです。サンプルコードも見やすい！

### 地図表示
OpenStreetMapのベクトルタイルを表示します。
```javascript
var map = new maplibregl.Map({
    container: 'map',
    style: 'https://tile.openstreetmap.jp/styles/osm-bright-ja/style.json', // 地図のスタイル
    center: [139.7779244, 35.7122128], // 中心座標
    zoom: 15, // ズームレベル
    pitch: 0, // 傾き
});
```

## CesiumJS
### 特徴
世界クラスの3D地球儀と地図を作成できます。
3Dモデルや3D Tilesの表示も可能です。

### 個人的な印象
PLATEAUデータを表示するにはCesiumがメジャーな気がしています。
PLATEAU Viewにも採用されてます。
上3つのマップライブラリは書き方が似ていますが、CesiumJSは独特な書き方な感じがします。
3Dに関してはかなり高機能で、サンプルコードを見るとかなりリッチな表現ができそうです。

### 地球儀表示
```javascript
// Cesium ionのアクセストークン
Cesium.Ion.defaultAccessToken = 'your_access_token';

// Cesium ViewerをcesiumContainerというIDのHTML要素に初期化
const viewer = new Cesium.Viewer('cesiumContainer', {
    terrainProvider: Cesium.createWorldTerrain(),
});
// 初期表示時のカメラ位置
viewer.camera.flyTo({
    destination: Cesium.Cartesian3.fromDegrees(139.7779244, 35.7122128, 25000000),
});
```

## 参考文献
https://leafletjs.com/

https://openlayers.org/

https://maplibre.org/maplibre-gl-js-docs/api/

https://cesium.com/platform/cesiumjs/
【Bluetooth(BLE) / Swift】iOSからBluetoothのON/OFF状態を確認する

# はじめに

エンジニア1年目のminnです！（普段はFlutterやっています）
最近、仕事でデバイス接続関連の担当していて、少し詰まったりしたので備忘録残しときます🫡

iOSでBluetoothのON/OFF状態を確認する方法です。

## 1. CoreBluetoothを作成

```swift
import CoreBluetooth
```

## 2. CentralManagerを使用する

```swift
var centralManager: CBCentralManager!

init() {
        centralManager = CBCentralManager(
            delegate: nil,
            queue: nil,
            options: ["ShowPowerAlert" : false])
    }
```

:::note warn
注意
CentralManagerインスタンスを作成すると、自動的にBluetoothの許可ダイアログが表示されてしまいます。(Bluetoothがオフの場合)


<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/718109/16c7ae12-e996-9f07-78e7-198796e190cf.png">

意図しないタイミング(オンオフ状態を知りたいだけ)で表示されてしまうので困りましたが、**CBCentralManager**の**options**に**ShowPowerAlert**を設定してあげることで解決しました。


:::

## 3. Bluetoothのステータスを受け取る

```swift
func isBleAvailable() -> Bool {
        if centralManager.state != .poweredOn {
            return false
        }
        return true
    }
```

# おわりに

実はFlutterからオンオフ確認したくてFlutter_blue_plusなどのライブラリを使用していました。
しかし、ライブラリでも予期せぬダイアログが表示されてしまったので、Flutter MethodChannelを使用してiOSを呼び出す方法に変更しました。
解決できてよかったですが、もし他にいい方法がありましたらご教授いただけると幸いです。ご意見やご指摘もいただけると助かります。どなたかのお役に立てたら嬉しいです！
閉域網 とは

## 勉強前イメージ

閉ざされたネットワークなイメージ・・・

## 調査

### 閉域網 とは

インターネットに接続していないネットワークのことを指します。
閉域とは不特定多数に開かれていない、閉じたネットワークのことを言います。
専用の回線や通信事業者が用意した独自の閉域網など、物理的に分離されたネットワークを使って通信を行います。

### 閉域網のメリデメ

#### メリット

- セキュリティ性を高められる

そもそもインターネットに接続できないのでウイルス感染等のリスクを大幅に下げることができます。
また、故意じゃないとしても情報流出してしまう危険性も下げることができます。

#### デメリット

- コストが高くなる

専用線を使うためコストが高くなったり、複雑な設定が必要になったりします。

### 閉域網の種類

- 専用線

拠点同士を専用の回線で接続する方法。
外部からアクセスする方法もないのでセキュリティは高くなりますが導入時には拠点の距離によって費用が発生します。
また、1対1の拠点間でしか使用できないので複数拠点を結ぶ必要がある際は別の方法を考える費用があります。

- 広域イーサネット

通信事業者の通信網を使って構築するネットワーク。
IP-VPNと同じネットワークを使用しますがレイヤー2で通信するため、様々なルーティングプロトコルを設定できます。
自由度が高いですが初期投資が高かったりします。

- IP-VPN

広域イーサネット同様、通信事業者の通信網を使って構築するネットワーク。
ただし、広域イーサネットとは違いレイヤー3での通信なのでIPプロトコルを使って通信を行います。
広域イーサネットよりは自由度は限定されますが管理が楽になります。

## 勉強後イメージ

イメージとは合ってた。
インターネットに接続できないってことか。
ってことは、直接サーバにLANケーブル指してとかのイメージなのかな？

## 参考

- [最適な閉域ネットワークを導入するために着目すべきポイント3つ](https://business.ntt-east.co.jp/content/cloudsolution/column-238.html)
- [閉域網の種類について解説！セキュリティ対策もあわせて紹介](https://www.itscom.co.jp/forbiz/column/vpn/4542/)
なぜエンジニア学生は技術系学生コミュニティに参加するべきなのか

# まえがき
こんにちは。
CDLE youthで代表をしているRyuseiです！
コミュニティ内でAdvent Calendarをやろうとなったので、1日目を担当することになりました。
本記事では、エンジニア学生が技術系学生コミュニティに入るべき理由について、これまでの経験などを踏まえお話しできたらと思います！！

# なぜ技術系学生コミュニティに参加するべきか
学生の皆さんはこんなことを感じた経験ありませんか？
- 勉強のモチベーションが続かない。。。
- 仲間が欲しい
- 就活までにどんな準備していけばいいんだろう
- 就活中だけど、受ける会社のOB・OGが知り合いにいないからOB・OG訪問できない

これらの悩みは技術系学生コミュニティに参加すればだいたい解消されます！

仲間を持つことはとても大事で、毎日がより楽しくなるだけでなく、勉強・就活などあらゆる場面で有利に働きます！


## 就活をめちゃくちゃ有利に進められる
正直これはほんとにでかいです。
就活は情報戦です。もう一度言います。情報戦です。
必ずしも優秀な人だけが合格するわけでなく、他の就活生よりも受ける企業の情報を多く知ってるだけでも大きく有利に働きます。
そしてその就活に有益な情報を得られる場所の一つがが技術系学生コミュニティです。

例えばこんなメリットがあります。
- 就活が終わった先輩達に就活のアドバイスをもらえる
- 興味のある企業で働いているOB・OGにOB・OG訪問ができる
- インターン・本選考の有力情報が手に入る
- 早い段階で就活の対策ができる


## 勉強を楽しく効率的に進められる
学生コミュニティに参加することで、切磋琢磨する仲間を作れます。
特にプログラミングやり始めのころは何を勉強すればいいかもわからず途方に暮れ、最初はすごく高かったモチベも気付けばジリ貧となり、竜頭蛇尾に終わるなんてことはザラにあるので、一緒に学ぶ仲間を作るのはとても大事になってくると思います。

また、先輩から直接教えてもらうこともできるでしょう。
ずっと同じ箇所でつまづいて1日中やってるのに全く勉強が進まないなんてことも多々あります。初学者の頃にそれに直面すると精神的にも肉体的にも負荷がかかってしまいます。
同じコミュニティにいる有識者の方々の助けを求めましょう。


## 交流の幅が広がる
技術系学生コミュニティに入れば、あらゆる大学のあらゆる学年の方と繋がることができます。
中には将来一緒の会社で働く人もいるかも知れませんし、そこで知り合い切磋琢磨した仲間と卒業後も定期的にあって楽しく飲んでいるかも知れません。

少なくとも、大学生時代を最高の仲間と謳歌し、最高の仲間と就活を乗り切り、晴れて社会人となった方々にとって、技術系学生コミュニティでの活動はとても良い思い出の場となること間違いなしです！

# 技術系学生コミュニティに参加しよう！
冒頭でも書きましたが、僕はCDLE youthという技術系学生コミュニティに所属しています。少し、CDLE youthについて紹介させてください！

## CDLE youthとは
「AIを学ぶ学生の未来を広げる」を理念にAIやコンピューターサイエンス関連を学んでいる全国の学生を支援しているコミュニティです。

## 活動内容
活動場所: Slack
オンライン開催なのでどこにいても参加できます！


### 勉強会
以下のように興味別で勉強会を行なっています。
- 画像認識
- 自然言語処理
- テーブルデータ
- アプリ開発
など

画像認識・自然言語処理・テーブルデータ: Kaggle、Signateなどのコンペに挑戦しています。
アプリ開発: 協力し合い1つのWebアプリケーションの作成することを目標として活動しています。

今後はPython基礎勉強会を実施したりなど、初学者がより学んでいける環境を作っていきたいと思っています。

### その他
- キャリアイベント
    - 大きな企業さんのエンジニアをお招きし、自由に就活のお話しが聞けるイベントを実施
    - ベンチャー企業さんからエンジニアをお招きしたパネルディスカッションを実施
    ![img.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689272/fb0f9186-aecf-c041-a1bf-759537a154fc.png)
- コンペ・ハッカソン
    - 多くの企業と共にのべ300名以上のコンペ・ハッカソンイベントを実施など
![img.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689272/686d3c46-1f54-29b2-3cb1-929dc01eaeed.png)

## CDLE youthの活動に興味のある方へ
このようにCDLE youthでは、あらゆる活動を行っています。ご興味ある方は是非ご連絡ください。

### 学生の方へ
参加に条件があり、以下の2つです。
- AI系の資格である、G検定もしくはE資格を保有していること
- 学生であること

１つ目の参加条件が少し制約が大きいですが、持っていないけどお話しが聞きたいなどありましたら、気兼ねなくご連絡ください。


### 連絡方法
- [お問い合わせフォーム](https://sites.google.com/view/cdleyouthhp/%E3%81%8A%E5%95%8F%E5%90%88%E3%81%9B)
- [Twitter](https://twitter.com/CDLE_youth)
gcacheとは（golang）

# gcache とは
gcacheはgolangのキャッシュライブラリです。
データを一時的にキャッシュし、特定のキャッシュ削除を行う場合に便利なライブラリとなっています。

* 特徴
  * 様々な有効期限付きのキャッシュを作成できる
    * LFU、LRU、ARC
  * スレッド（goroutine）セーフ
  * エントリーを削除、削除、および追加するイベントハンドラーをサポートしている
  * キャッシュが存在しない場合、キャッシュを自動的に読み込んでくれる

# 使い方

インストールするためには、go getコマンドを実行します。

```
$ go get -u https://github.com/bluele/gcache
```

一番簡単な例はこのようになります。

```main.go
package main

import (
 "github.com/bluele/gcache"
 "fmt"
)

func main() {
 gc := gcache.New(20).
  LRU().
  Build()
 gc.Set("key", "ok")
 value, err := gc.Get("key")
 if err != nil {
  panic(err)
 }
 fmt.Println("Get:", value)
}
```

実行すると、次のようにコンソールに出力されます。

```
Get: ok
```

消去時間の設定もSetWithExpire()を使用することで簡単にできます。

```main.go
package main

import (
 "github.com/bluele/gcache"
 "fmt"
 "time"
)

func main() {
 gc := gcache.New(20).
  LRU().
  Build()
 // 消去時間の設定
 gc.SetWithExpire("key", "ok", time.Second*10)
 value, _ := gc.Get("key")
 fmt.Println("Get:", value)

 // Wait for value to expire
 time.Sleep(time.Second*10)

 value, err := gc.Get("key")
 if err != nil {
  panic(err)
 }
 fmt.Println("Get:", value)
}
```

実行すると、次のようにコンソールに出力されます。
最初は取得に成功していましたが、時間が経つとキャッシュが削除され取得できなくなります。

```
Get: ok
panic: Key not found.

goroutine 1 [running]:
~~~
exit status 2
```

有効期限付きのキャッシュの設定は、以下のように容易に変更できます。

```main.go
func main() {
    // size: 10
    gc := gcache.New(10).
    // ここでLFU、LRU、ARCを設定できる
      LFU().
      Build()
    gc.Set("key", "value")
  }

```

ハンドラの追加はAddedFunc()を使用して実装します。
（削除はEvictedFunc()を使用する）

```main.go
func main() {
  gc := gcache.New(2).
    AddedFunc(func(key, value interface{}) {
      fmt.Println("added key:", key)
    }).
    Build()
  for i := 0; i < 3; i++ {
    gc.Set(i, i*i)
  }
}
```

実行結果

```
added key: 0
added key: 1
added key: 2
```

シンプルで使いやすいキャッシュライブラリですね。


## 参考

* https://github.com/bluele/gcache
githubのpersonal access tokenの有効期限が切れたので更新してみた

参考サイト
https://style.potepan.com/articles/34189.html

githubからpersonal access token有効期限切れメールが来たので更新(再作成)をしてみた。

<img width="800" alt="mail" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99234/1addf808-cd2a-3c07-d27b-3ea5697b7aa7.png">

# githubでpersonal access tokenを再作成する
## menu > settingをクリック

<img width="200" alt="01" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99234/83bc4316-2bf8-a7be-3980-77a4c2f6c85c.png">

## Developer settingsをクリック

<img width="400" alt="02" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99234/604a7290-16cd-d86f-2e6d-241f43fd98e9.png">


## Personal access tokens > tokens(classic) > (更新したいトークン名)をクリック

<img width="400" alt="03" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99234/67a53f85-7de8-c48b-1099-a634fb648795.png">


## Regenerate tokenをクリック

<img width="400" alt="04" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99234/ecc814d9-a581-bfbc-0c93-a1d3f3ebaef5.png">


## 有効期限日を設定 > Regenerate tokenをクリック

<img width="400" alt="05" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99234/e3521665-bc2b-4c82-bd63-3a4932a9dc64.png">

## 新しいtokenが表示されるので保存する

<img width="400" alt="06" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99234/fcc8e57a-710c-02af-799b-b8430bb3ab31.png">


# eclipseのpersonal access tokenを更新する

## 証明書の変更をクリックする

<img width="400" alt="11" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99234/c53d1b89-eb3c-8bb6-d1b2-91c19ffa55fc.png">


## ユーザー名/personal access tokenを入力する

<img width="400" alt="12" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99234/77faedbe-9b9b-b36a-96b5-6c3b1f88c529.png">

問題なくコミットできたのでこれで問題ないと思われる。
Hotwireへようこそ

:::note
この記事は[Google翻訳](https://translate.google.co.jp/)の結果を編集したものです。
:::

https://hotwired.dev/

**Hotwireはネットワーク経由でJSONの代わりにHTMLを送信することにより、JavaScriptをあまり使用せずに現代的なWebアプリケーションを構築するための別のアプローチです。** これによってページの最初の読み込みが高速になり、サーバー上でテンプレートのレンダリングが維持され、従来のシングルページアプリケーションに関連する速度や応答性を犠牲にすることなく、任意のプログラミング言語でよりシンプルで生産的な開発体験が可能になります。

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

あなた自身のツールの単なるインスピレーションとしてHTML-over-the-wireアプローチに従うことも、[HEY](https://www.hey.com/)を強化する[Basecamp](https://basecamp.com/)のチームによって作成されたHotwireのフレームワークを使用することもできます。これらは連携して相互に補完し合い、すべてのプラットフォームで完全なソリューションを提供します。

# Turbo

Hotwireの中心はTurboです。ページの変更とフォームの送信を高速化して、複雑なページをコンポーネントに分割し、WebSocketを介して部分的なページの更新をストリーミングするための一連の補完的な手法です。JavaScriptを書く必要はまったくありません。また、iOSとAndroidのネイティブハイブリッドアプリケーションと完全に統合できるように最初から設計されています。

# Stimulus

通常、Turboは従来はJavaScriptが必要だった双方向性の少なくとも80%を処理しますが、少しのカスタムコードが必要になる場合もあります。Stimulusは状態と接続に対するHTML中心のアプローチにより、これを容易にします。

# Strada

モバイルハイブリッドアプリケーションのWebとネイティブの部分がHTMLブリッジ属性を介して相互に通信する方法を標準化します。これによりネイティブを置換してWebインタラクションを段階的にレベルアップすることが容易になります。

Stradaは2022年に登場します。
12月1日

<H3>はじめに</H3>
初投稿、スマホで入力しております。数日前より家のネット環境が繋がらなくなり、スマホのデータ使用量が制限オーバーとなり、ダイヤルアップ時代のような感じでやっております。事前に投稿方法を勉強し、予約投稿もばっちりしておく予定は崩れ去りました。書式や文体、内容がルールに反しておりましたら申し訳ありません。復旧したあかつきには修正して参ります。
<H3>自己紹介</H3>
大学まで、完全な文系学生でした。
社会人になってからは、色々なお仕事をしまして、気づけばIT業界の片隅で20年くらい生きてきたようです。
<br>
前職はWebディレクターをやっていました。Webディレクターといっても、会社の規模や方針などによって、担当する業務は色々なのかな、と思います。
私は1サイト専属で、立ち上げ準備から始まり、その後の運営に関わる中の人を長らくしていました。
<br>
具体的には
<ul>
<li>サイトの更新</li>
<li>企画の立案</li>
<li>制作進行</li>
<li>ライティング・編集</li>
<li>メルマガの作成・配信</li>
<li>データベースの登録</li>
<li>ユーザーサポート</li>
<li>営業</li>
<li>数値チェック</li>
</ul>

など。

長年育てたサイトを去ってから、今までおろそかにしていた家族との時間をたっぷり取りました。


<H3>そこから職業訓練校と出会うまで</H3>
<p>
ひと段落して、次は何か新しいことにチャレンジしたいな、と思うようになりました。</p>
<p>
そこで思い出したのが、前職は少人数で運営していたので、出来る事はなんでもやる、でしたが、その中で私が手付かずだった領域が、デザインとプログラミングだったこと、色々お願いするばかりで自分は何も出来ない事を、ちょっと悔しく思いつつ、憧れの気持ちも持っていた、ということでした。</p>
<p>
ただデザイナーさんについては、普段から一緒にお仕事をしていたので、どういう人がデザイナーに向いているか、ある程度分かっており、自分には難しいという認識でした。
<br>
そしてプログラミングは、というと、全く分かっていなかった。何となくカッコいいと思っていました。かつ、何となく自分も出来るんじゃないかと。</p>
<p>
いつかまた自分でWebサービスを作ってみたいという夢もあり、プログラミングの勉強を始めてみようと思いたったところで、偶然、職業訓練校の事を知りました。（明日へ続く）
</p>
<H3>勉強の記録11/30</H3>
帰りの電車でWi-Fi接続できたので、Javaの動画をを見ました。Objectクラス、Stringクラスについて。
【SQL Server】SQLServerの既定のデータベースを削除してしまった

【自分用メモ】
SQLServerの既定のデータベースを削除してしまった場合の対応手順
※SQLサーバーにログインするユーザーも知らなかった場合

■ SQLサーバにアクセスした時、発生したエラー（Windows認証でログインした時、発生したエラー）
ユーザーの既定データベースを開けません。ログインに失敗しました。
ユーザー'インスタンス名¥ログインユーザー名'はログインできませんでした。（Microsoft SQL Server、エラー:4064）

■ 対応した手順
① コマンドプロンプトでsqlcmdで接続する。
>sqlcmd -E -S (インスタンス名) -d master

② masterを使用するコマンドを入力する。
>USE master
>GO

③ 既定のデータベースが存在するかを確認するSQL
>select name, dbname from sys.syslogins where name='(ログインユーザー)'

④ SQLサーバーにログインするユーザー作成
>CREATE LOGIN [ユーザー名] WITH PASSWORD = 'パスワード',DEFAULT_DATABASE = [master]

⑤ 作成したユーザーに権限付与
>EXEC master.sys.sp_addsrvrolemember 'ユーザー名', 'ロール'
※今回、DB作成できるようにするため、データベースを作成できるロールが最適
※大体のPJが「createdb」ロールの名前を指定している

⑥ SQLサーバーにて「Server認証」方式で接続する
>このステップでは④で作成したアカウントでログインする

⑦ SQLサーバーにアクセスできたら、削除してしまった既定のデータベースを作成する
>操作手順としてはGUIでSQLサーバーの画面を直接操作する。

⑧ とっておいたデータベースのバックアップがあったら、データベースの復元を行う
>操作手順としてはGUIでSQLサーバーの画面を直接操作する。

全てが完了したら、SQLサーバーのタブを開き、Windows認証でアクセスできるか、試す。無事にアクセスできたら、成功である。

■参考になった記事
https://note.com/gotch59/n/n446b35e1d7eb
https://www.pine4.net/Memo/Article/Archives/114
よく使うVSCodeのショートカット集

# はじめに
よく使うVSCodeのショートカット集です。
すこしVSCodeから離れるとすぐに忘れてしまうので。

# 動作環境
Windows

# プログラム実行
| コマンド | 説明 |
|:---------|:-----|
|実行（デバッグ |F5 |
|Terminalウィンドウを開く |Ctrl + @ |
|外部ターミナル起動 |Ctrl + Shift + C |

# コーディング関連
| 内容 | コマンド |
|:-----|:---------|
|補完 |Ctrl + Space |
|選択中の複数行のtabインデント変更 |選択中に tab or shift + tab |
|選択中の複数行のコメントアウト・コメントイン |選択中に ctrl + / |
|フォーマット |Ctrl + Alt + F |
|タブを閉じる |Ctrl + W |
|新しいVSCodeを開く |Ctrl  + Shift + N |
|1行削除 |Ctrl  + Shift + K |
|行移動 |Alt + ↑、 Alt + ↓ |
|行複製 | Alt + Shift + ↑、 Alt + Shift + ↓ |
|リファクタリング-リネーム |F2 |
|宣言にジャンプ |F12 |
|ケース変更 |変更したい文字列を選び、Ctrl + Shift + P で コマンドパレットを開き、"upper"と入れると、「Transform to Upper case」が候補に出てくるので、これを選ぶ。ヘッダのifndef書くときとか。 |

# さいごに
Macだと`option + command⌘ + T`で現在選択中のタブ以外を閉じることができるらしい。
タブ開きすぎでごちゃつきがちなのでWindowsでもできるようにしてほしい。
JavaScript の雑ディープコピーについて

この記事はちゅらデータアドベントカレンダー初日の記事です。

アドベントカレンダーというと毎年けっこう気合の入った記事が目立つのでハードルが高いと感じてしまう人もいるかも知れない。せっかく初日なので「こんなんでいいんだよオラァ」とハードルを下げていきたいと思う。

今回は、JavaScript 経験がそこそこある人なら誰でも辿り着いたことがあるであろうあのディープコピー実装について話す。

## ディープコピーとは？
「ディープコピーとは何か？」「ディープコピーとシャローコピーの違いは？」あたりについては <del>説明が面倒なので</del> ググるとたくさん出てくるので割愛する。 → [deepcopy shallowcopy - Google 検索](https://www.google.com/search?q=deepcopy+shallowcopy)

## 実装
言わずと知れた <del>クソ</del> ディープコピー実装がこちら。

``` javascript
const cheapDeepCopy = (obj) => JSON.parse(JSON.stringify(obj))
```

「JSON 文字列に変換して戻す」というだけの簡単アプローチなので何も説明する必要がない。誰でも読める。

あと `cheapDeepCopy` って名前をつけておくとなんか語呂が良いし、雑実装であることも明示できて一石二鳥 (？)

また、TypeScript の場合はジェネリクスでいい感じにすると型も引き継げてよい。

``` typescript
const cheapDeepCopy: <T>(obj: T) => T = (obj) => JSON.parse(JSON.stringify(obj))
```

## 使用例
``` typescript
// 1. 適当な深いオブジェクトを用意する
const foo = { a: { b: { c: "yay!" } } }

// 2. ディープコピーする
const bar = cheapDeepCopy(foo)

// 3. コピー元オブジェクトを書き換えてみる
foo.a.b.c = "wow!"

// 4. コピー先オブジェクトに影響していないことがわかる
console.log(bar.a.b.c)  //=> "yay!"
```

## 使ってはいけない例
「雑」「cheap」を謳っているからには決してマトモな実装ではない。

「数値」「文字列」「真偽値」「null」「配列」「(ピュアな)オブジェクト」以外の値 (つまり、JSON で表現できない値) が含まれていた場合は変換時に消滅するか形が変わってしまうため、このような用途ではマトモなディープコピー関数を使ったほうがよい。

``` typescript
const obj = {
  undefined: undefined,  //=> 消滅する
  function: () => {},  //=> 消滅する
  date: new Date(2022, 11, 1),  //=> 文字列に変換される
}

cheapDeepCopy(obj)  //=> { date: '2022-11-30T15:00:00.000Z' }
```

## "マトモ" なディープコピー関数とは？
[clone](https://www.npmjs.com/package/clone) とか入れたら良いんじゃないでしょうか。(詳しくない)

もし immutable に state を更新したい用途であれば最近だと [Immer](https://immerjs.github.io/immer/) なども見てみると良いかも。(詳しくない)

## JSON 変換だと遅くない？
<del>パフォーマンス気にする人はこんな雑なコード書かない。</del>

そこまで遅いわけではない模様。
→ [JavaScriptのディープコピー速さ比較 〜7つの手法/ライブラリを比べてみた〜 - Qiita](https://qiita.com/suin/items/80e687dd1789b9d9d2fd)

## なぜ今更こんな話題を？
TypeScript がスタンダードになりデータ構造は TypeScript の型で十分に表現できるようになった現代ではもはや class はめっきり使わなくなってしまい、最近「このディープコピーって `JSON.stringify` でよくない？」というケースが多くなってきたので。
人生で一度言って見たい言葉「今日はソースコードを書くなど単純な作業をしよう」

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">今日はソースコードを書くなど単純な作業をしよう</p>&mdash; みつ (@mitsu48) <a href="https://twitter.com/mitsu48/status/1597747743006502912?ref_src=twsrc%5Etfw">November 30, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

熱をだしてはいませんが、仕事休みました。　

人によって単純な作業の種類、範囲が違います。
自分の場合は、「人生で一度言って見たい言葉」になるかどうか考えてみました。


<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">&quot;ソースコードを書くなど単純な作業は外部に委託するなど&quot;<a href="https://t.co/4Fe3689eO4">https://t.co/4Fe3689eO4</a></p>&mdash; ふじよし (@Fuji_Yos) <a href="https://twitter.com/Fuji_Yos/status/1597464163810693120?ref_src=twsrc%5Etfw">November 29, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

情報源の伝聞を記録します。

 <この項は書きかけです。順次追記します。>

# 作業の単純度・難易度


自分の作業では、Data解析、数式処理関係のお仕事の場合、ソースコードを書くのが相対的に難易度が低い方です。それ以外の場合は、ソースコードを書くのが、一番難易度が高いかもしれません。

Data解析、数式処理関係のお仕事の場合、ソースコードを書くのは、５段階作業のうち難易度が高い方が、数が大きいとすると、３に相当するかなって思うんです。


|難易度|内容|難易度表現|
|--:|--:|--:|
|5|未解決問題を方程式に整理する|いつまでにできるかわからず難しい|
|4|方程式を解く|とても難しい|
|3|ソースコードを書いて問題を解決する |難しい|
|2|表計算ソフトで処理する|やや難しい|
|1|そろばん、電卓を叩く|簡単|

そこで、表現をすこしづつ変えながら検討してみます。
未解決問題を方程式に整理するところを、ソースコードを書いて考えようとすると、難易度は５です。方程式を解くところも、ソースコードを書いて実施しようとすると難易度は４かもしれません。３番においたのは数値計算で解く方法です。あるいは近似計算をする方法です。



# ソースコードを書くなど単純な作業
自動生成プログラムができあがれば、ソースコードを書く処理は、単純処理に分類できるかもしれません。ソースコードを書くか、ソースコード自動生成プログラムを書くかは、場合によっては、難易度がすごく違うかもしれません。ソースコード自動生成プログラムを書くのも、ソースコードを書く一部です。　

ソースコード自動生成プログラムがある問題の、細部がうまく対応できていない部分のコード例として、ソースコードを書くのは単純な作業の場合があるかもしれません。


# ソースコードを書くなかでは単純な作業

これは、上記の最後の行をはじめ、いろいろあるかもしれません。　

個人的には、ソースコードを書き換える場合が単純な作業の場合がありました。


# ソースコードを書き換える単純な作業　

は結構しています。CPU、PCのOSへの移植という難し目の仕事から、　
コード生成プログラムを書いて変更してもいいが、そんなに量がないから、　
手で書き換えるような単純な作業までいろいろあります。　

書き換えるのが単純な作業ではありません。　

# ソースコードを書き換える作業のうち単純な作業

ソースコードを書き換える作業のうち単純な作業は、　
ソースコードを書くうち単純な作業の部分集合の可能性があります。　

# まとめに代えて

じゃ、「ソースコードを書くなかでは単純な作業」で問題なさそうです。


「今日はソースコードを書くなど単純な作業をしよう」は、自分では一生言えないことがわかりました。ありがとうございます。

 ＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞

# 文書履歴(document history)
ver. 0.01 初稿 20221130
GUIの改造2 cropデータの表示

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

今日もtestbedのメニューを自分が使いやすい様に改造していきます。

こちらの動画を拝見したところ、crop aabbの値をスクリーンショットでメモしていらっしゃいました。
https://www.youtube.com/watch?v=k67qHXRhdY4

面倒そうなので、テキストをコピペできるようにGUIを改造しようと思いました。

:::note
業務外の個人的な検討活動です。
:::

:::note alert
警告
環境や入力内容によっては現在使用できている状況が壊れることがあります。
あなたの責任と判断で試してください。私は責任を取りません。
:::

#### 通常
![3a-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103446/f8e1285b-078f-f27f-65cf-686cf882e4b1.png)

#### 改造
crop aabbの値をボックス内に表示します。
この内容をマウスで選んでコピーします。
![3a-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103446/4940e2e9-02f8-fa21-68aa-f0c1bada938b.png)

#### testbed.cu 
赤枠内を追加しました。
![3a-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103446/e7475cd2-50d5-c452-4cb9-b2c1353ac058.png)

#### 追加したコード
```
		char buf[256];
		snprintf(buf, sizeof(buf),
			"\"render_aabb\" : [[%0.2f, %0.2f, %0.2f], [%0.2f, %0.2f, %0.2f]], \n"
			, m_render_aabb.min.x(), m_render_aabb.min.y(), m_render_aabb.min.z(), m_render_aabb.max.x(), m_render_aabb.max.y(), m_render_aabb.max.z()
		);
		ImGui::InputTextMultiline("aabbs", buf, sizeof(buf), ImVec2(900, 50));
```

#### transform.json
コピーしたcrop aabbの文字列をペーストします。
![3a-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103446/af87e789-f261-7640-fed5-0dd604ed350b.png)

#### 実行
testbedを終了し再実行すると、開始時点で指定したcrop aabbが反映されました。
![3a-6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103446/a19bd623-c8af-70c5-0515-25847023ca38.png)
【Vue】railsにVueをインストールしてみた。

# バージョン情報
* ruby 3.0.0
* rails 6.1.6.1
* yarn 1.22.19

今回は、ここからVue3を導入していく。
# インストール
インストールコマンドは以下の通り。
```
$ yarn add vue@next vue-loader@next @vue/compiler-sfc
```
これを実行すると以下のように出力されてインストール成功。5分とかからない。
```
yarn add v1.22.19
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Saved lockfile.
success Saved 12 new dependencies.
info Direct dependencies
├─ @vue/compiler-sfc@3.2.45
├─ vue-loader@17.0.1
└─ vue@3.2.36
info All dependencies
├─ @vue/compiler-sfc@3.2.45
├─ @vue/reactivity-transform@3.2.45
├─ @vue/reactivity@3.2.36
├─ @vue/runtime-core@3.2.36
├─ @vue/runtime-dom@3.2.36
├─ @vue/server-renderer@3.2.36
├─ csstype@2.6.21
├─ hash-sum@2.0.0
├─ nanoid@3.3.4
├─ sourcemap-codec@1.4.8
├─ vue-loader@17.0.1
└─ vue@3.2.36
Done in 29.48s.
```
# 設定
各ファイルの内容をそれぞれ編集する。
```js:config/webpack/environment.js
const { environment } = require('@rails/webpacker')

const { VueLoaderPlugin } = require('vue-loader')
 environment.plugins.prepend(
     'VueLoaderPlugin',
     new VueLoaderPlugin()
)

environment.loaders.prepend('vue', {
    test: /\.vue$/,
    use: [{
        loader: 'vue-loader'
    }]
})

module.exports = environment
```
```yml:config/webpacker.yml
  extensions:
    - .vue #追加
    - .mjs
    - .js
    
   # 以下省略
```

# hello vueの表示
次にvueを使って「Hello Vue」という文言をviewに表示する。
以下のファイルを作成し内容を編集する。
```javascript:app/javascript/packs/hello_vue.js
import { createApp } from "vue";
import App from "../app.vue";
document.addEventListener("DOMContentLoaded", () => {
  const app = createApp(App);
  app.mount("#vue-app");
})
```
```vue:app/javascript/app.vue
<template>
  <p>
    {{ message }}
  </p>
</template>

<script>
export default {
  data() {
    return {
      message: "Hello Vue!"
    }
  }
}
</script>

<style scoped>
p {
  font-size: 2em;
  text-align: left;
}
</style>
```

そして、「Hello Vue」を表示したviewに以下の記述を追加。
```erb:view
<%= javascript_pack_tag 'hello_vue.js' %>
<div id='vue-app'></div>
```
すると以下のように表示される。![スクリーンショット 2022-11-30 23.07.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2449886/04a8f521-7b23-ff4f-52a3-a8314b09bf2b.png)

# turbolinksとの共存
SPAではなく、既存のrailsアプリケーションの一部にvueを使用する場合などでは、turbolinksの機能の影響で、例えばlink_toメソッドなどによるページ遷移時にvueの要素が表示されない。

そこで、vue-turbolinksの使用によりこれを解決することができる。

https://github.com/jeffreyguenther/vue-turbolinks

導入方法は以下の通り。まず次のコマンドでパッケージをインストールする。
```
$ yarn add turbolinks vue-turbolinks
```
application.jsに以下を追加する。

```app/javascript/packs/application.js
import Rails from "@rails/ujs"
import Turbolinks from "turbolinks"
import * as ActiveStorage from "@rails/activestorage"
import "channels"
import '@fortawesome/fontawesome-free/js/all';
import TurbolinksAdapter from 'vue-turbolinks' //追記

Vue.use(TurbolinksAdapter) //追記

Rails.start()
Turbolinks.start()
ActiveStorage.start()
```



# 参考
https://qiita.com/t0yohei/items/cd11b15642fbb26f71e2

https://sakurawi.hateblo.jp/entry/rails-vue
Javaで何か作ってみる(2022/11/30 Day41)

## 今日やった事
- Twitterで、ビンゴゲームの課題があったので、やってみた。  
&rarr;コミットした内容は[こちら](https://github.com/takamatsuryota3/Java/commit/d91d2406394620ee9ca6c33596e0f6a45703cf75)
## 参考にしたもの
- [Javaでビンゴゲームのコードを作成したい](https://teratail.com/questions/kav3aoefaf30b6)  
&rarr;ここに答えが書いてあるようなものだが、見てやっても意味ないので、極力見ないようにしている。
- [【Java】ビンゴカード作成問題を解く - Qiita](https://qiita.com/kim-shun/items/fee32cf0cb3cc009756a)  
&rarr;こちらも同様。

## 所感
- 今日は抽選回数をコマンドライン引数で指定できるようにしたのと、指定した回数内でビンゴになった場合と  
そうでない場合で、メッセージが変わるように修正した。
- リーチについては、全てのマスについて、管理しなきゃならなそうなので、面倒なので後回し。
- ビンゴゲームについては、いったんここまでにしようと思う。
## 明日の予定
- 動画教材を進めていこうと思う。（オブジェクト指向編かspringのどちらか）
Javaで何か作ってみる(2022/11/29 Day40)

## 今日やった事
- Twitterで、ビンゴゲームの課題があったので、やってみた。  
&rarr;コミットした内容は[こちら](https://github.com/takamatsuryota3/Java/commit/f5eae6a29604b5f8484885930dc8ad97825aacd9)
## 参考にしたもの
- [Javaでビンゴゲームのコードを作成したい](https://teratail.com/questions/kav3aoefaf30b6)  
&rarr;ここに答えが書いてあるようなものだが、見てやっても意味ないので、極力見ないようにしている。
- [【Java】ビンゴカード作成問題を解く - Qiita](https://qiita.com/kim-shun/items/fee32cf0cb3cc009756a)  
&rarr;こちらも同様。

## 所感
- 今日はビンゴ判定の追加、ビンゴの時のメッセージを追加した。
- リーチについては、全てのマスについて、管理しなきゃならなそうなので、面倒なので後回し。
## 明日の予定
- ビンゴゲーム作成を進めていく。
AWS + LINE でモーニングコールするBotを作ってみた（スライド版）

## 注意

この記事は「[AWS EventBridge + Lambda + LINE でモーニングコールするBotを作ってみた](https://qiita.com/nekolife/items/94d650d7a55cc583dd60)　」のスライド版です。
スライドモードで閲覧することをお勧めします。

---

## はじめに

「AWSを使って便利なチャットBotを作る」をテーマに掲げ、自分自身の勉強も兼ねて、その成果を記事にしています。
まず第１弾としてLINEにモーニングコールメッセージを送信するBotを作ってみました。
この記事が少しでも役に立てば嬉しいです。

---

## 完成イメージ

完成イメージは下図のような感じです。
毎朝6時にモーニングコールのメッセージを届けてくれます。

![IMG_4A2D169908D7-1 2（中）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24724/d4b7ec18-de43-8484-6c1d-ef75e319e141.png)

---

## システム構成

次のようなシステム構成でBotを作成していきます。

![Chatbot-LineMoningCall.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24724/4790bfa7-e9ed-b5bc-6999-9d11d7029315.png)

---

## 処理の流れ

1. EventBridgeのスケジューラで毎朝決まった時間にメッセージ送信を行うLambda関数を呼び出す
2. Lambda関数ではEventBridgeから指定されたメッセージをLIME Message APIを使用してLINEに送信する
3. LINEで受信したメッセージが表示される

---

## 使用技術

今回のシステムで使用する主要な技術は以下のとおり

- AWS Lambda
- AWS EventBridge
- LINE Messaging API
- Node.js (v1.6)

---

## 作成手順

モーニングコールBotを以下のような流れで作成していきます。

1. LINE Message APIの準備
2. LINEにメッセージ送信するLambda関数の作成
3. EventBridgeでLambda関数のcron設定

---

## LINE Message APIの準備

LINE Botを作成するためにLINE Message APIを使用します。
APIを使用できるようにするためには以下の手順を行います。
1. LINE Divelopersに個人アカウントを登録
2. アカウント登録後、Console画面に移動し、プロバイダーを作成
3. プロバイダー作成後、Message APIのチャンネルを新規作成
4. 「チャネル基本設定」でユーザーID、「Message API設定」でチャネルアクセストークンを取得

---

## LINEにメッセージを送信するLambda関数の作成

作業用のディレクトリを作成し、その中で`npm init`コマンドで実行します。
色々聞かれますがとりあえず全部デフォルトで進めます。

```text
$ npm init
```

@line/bot-sdkパッケージをインストールします。
```text
$ npm install @line/bot-sdk
```
---

Lambda関数を作っていきます。
index.jsファイルを作成し、以下のコードを記述します。`<LINE_ACCESS_TOKEN>`と`<LINE_USER_ID>`にはLINE Developersで取得したチャネルアクセストークンとユーザーIDを設定します。

```javascript:index.js
// LINE BOT SDKを用意する
const LINE = require('@line/bot-sdk');

/**
 * LINEメッセージ送信Lambda関数
 * @param {*} event
 * @returns
 */
exports.handler = async (event) => {
  // アクセストークンとユーザーIDを設定する
  const LINE_ACCESS_TOKEN = '<LINE_ACCESS_TOKEN>';
  const LINE_USER_ID = '<LINE_USER_ID>';

  // LINEへの送信クライアントを用意する
  const client = new LINE.Client({
    channelAccessToken: LINE_ACCESS_TOKEN
  });

  // 引数eventをmessageに詰めて送信する
  const message = event;
  await client.pushMessage(LINE_USER_ID, message);
};
```

---

# EventBridgeでLambda関数のcron設定

EventBridge Schedulerで定期的にLambda関数を呼び出す設定します。

1. AWSマネージメントコンソールから「EventBridge」を選択
2. Schedulerの「スケジュール」を選択し、「スケジュール追加」を押下
3. スケジュールを作成（今回は朝6時にモーニングコール）
4. スケジュールのパターンは「定期的なスケジュール」「cronベースのスケジュール」
---
5. cron式は (0, 6, *, *, ?, *)、フレックスタイムは「なし」、時間枠は「Asia/Tokyo」
6. ターゲットは「AWS Lambda Invoke」
7. Lambda 関数は今回作成したLambda関数を選択、入力は後述するJSONフォーマットを参照
8. スケジュールの状態は「有効化」オン
9. アクセス許可は「このスケジュールの新しいロールを作成」を選択
    
---

# JSONフォーマット
送信するメッセージをJSON形式で記述します。
メッセージの仕様は[公式ドキュメント](https://developers.line.biz/ja/reference/messaging-api/#text-message)で確認できます。

```json
{
  "type": "text",
  "text": "おはようございます！\n今日も頑張っていきましょう！"
}
```

---
# 最後に

以上でBotの作成は完了です。
成功すれば毎朝６時にモーニングコールが届きます。
時間とメッセージを変更しておやすみコールにしてもいいですし、誕生日にバースデーメッセージを届けてもいいです。
カスタマイズしてBotを自分色に染めてください。
18. Isolation Tree, Isolation Forest

# Isolataion Tree, Isolation Forest
　今回はIsolation Tree、Isolation Forestについてです。異常検知のアルゴリズムで非常に軽量でそれなりの精度が出るモデルだと思います。処理自体も理解しやすいです。

## 外れ値とは
　まず外れ値として、
1. 数が少ない
1. 通常のサンプルから離れている

上記を仮定しています。

## アルゴリズム概要
　決定木の分割条件を完全にランダムに決定しながら、分割を繰り返します。その際に外れ値は上記の仮定があるため、通常のサンプルに比べて少ない分割で孤立、もしくは同じ回数の分割でもノード中のサンプル数が少なくなります。概要としてはこれだけで、つまり、

1. ランダムに分割
1. 同じノードに含まれるサンプル数が少ないほど高い異常スコアを付与（sklearnでは逆。スコアでデフォルトの昇順ソートをした際に先頭からとれるようになっていると思われる）

という単純なものになります。

## アルゴリズム詳細
　RandomForestなど異なるハイパーパラメータとしてはmax_samplesで、これは一つのTreeに投入するサンプル数を設定します。scikit-learnのデフォルトでは256です。分割に関しては上述の通り、ランダムに決定するだけなので決定木の記事を参照ください。一つ異なる点としては、回帰木を作成しますが、予測を実施した際に各ノードが返す値は「学習時の深さ＋追加の深さ」です。この値を計算する方法について記述します。

　算出するために、まず全データを学習したモデルに投入します。この時上記の通り、まず各サンプルがアサインされたノードの学習時のノードの深さが与えられます。ただ、学習時には256個のサンプルだけ与えられましたが、予測時にはこれを大きく上回る数が与えられている可能性が高いです。したがって、学習時は1個しか格納されていなかったノードにも100個のサンプルがアサインされる可能性があります。「追加の深さ」とは、このような複数のサンプルをノードをさらに分割していき、ノード1個につきサンプル1個の状態までもっていくにはどのくらいの深さが必要かという値です。つまり、サンプルN個を与えた場合に、ノード1個につきサンプル1個になるまでに必要な深さは、ということですが以下の式で与えられます。ただしN=1の時は０です。
```math
\text{average_depth} = 2*\left( \log(N-1) + \gamma_E \right)- 2*(N-1)/N
```

　最後に異常スコアへの変換を行います。サンプルxの異常スコアは、
```math
\text{anomaly_score}(x) = 2 ** \left( - \frac{\sum^T_{t=1}h^t(x)}{T}\times \frac{1}{\text{average_depth}(N)}\right)
```
ここで$T$はアンサンブルの木のインデックス、$h^t(x)$はt番目の木におけるサンプルxの深さです。つまり$\times$記号の左側はサンプルｘの平均的な深さと考えられます。ここで外れ値の過程に戻って考えてみるとその平均深さは0に近いとと考えられます。一方通常のサンプルは記号の右側の分母と同じような値になることが期待されます。したがって異常スコアが
* 1に近い場合、異常値
* 0.5やそれを下回る場合は、通常サンプル

という風に考えることができます。

## その他：速度
　IsolationForestの速度がsklearnより非常に速い点（約100倍）が気になります。Sklearnの実装を見てみるとランダムな分割のために専用のBaseEstimatorも実装するのではなく、ExtraTreeRegressorをmax_features=1として利用しています。FortLearnerでは専用のクラスを作っているので、ここだとは思うのですが、それだけでここまで劇的に向上するのが非常に気持ち悪いと思っています。ただ違う点があるとすればExtraTreeは本来異常検知に必要のない引数もとっています。FortLearnerでは専用のクラスなので、必要がありません。これだけでこんなに違うものかと疑問に思っています。精度を検証した際には特に違いが見られなかったので、さらに疑問です。

## その他：精度改善
　非常に簡単な手法で精度を提案している[記事](https://www.scutum.jp/information/waf_tech_blog/2021/06/waf-blog-079.html "記事")があったためご紹介します。
　本当に簡単な手順で、
1. Treeを余分に作成する（例：max_estimators=100のところ1000に設定する）
1. 各Treeの平均深さを計算
1. TopN本のTreeのみ残す

後は通常のIsolationForestと変わりがないようです。一つの手法をいろいろな場面で使い、性能や傾向を確認することでこのようなアイデアが生まれるのではないかなと思います。

以上
12. DBSCAN

# [DBSCAN](https://dl.acm.org/doi/10.5555/3001460.3001507 "DBSCAN")
　Density-Based Spatial Clustering of Applications with Noiseの略です。アルゴリズムは非常に単純な部類に入ると思います。近傍探索アルゴリズムと組み合わせ、各サンプルの近くにある程度のサンプル数があればクラスターを形成し、サンプル数が少なければ外れ値となります。

Kmeansとの大きな相違点は以下のような2点があるかと思います。
1. 球以外の形状のクラスタにも対応可能
1. 外れ値検知にも使える

　一方、Kmeans（そのほかの機械学習モデルもですが）では一度学習したモデルを新規データに対しても適用できますが、DBSCANは新規データと既存データを合わせて再度学習をする必要があります。また異なる密度のクラスターがあった場合に、密度の濃いクラスターに合わせると薄い側がすべて外れ値となりやすく、逆の場合は濃い側に余計な点をクラスターに組み込んでしまう可能性があります。このようにハイパーパラメータの調整が難しいため、リアルタイムに異常検知を行わなければならない場合には不向きではないかと思います。


## アルゴリズム
　DBSCAN自体のアルゴリズムは非常に単純です。KDTreeなどの近傍探索アルゴリズムを実装する方が時間がかかりました。近傍探索アルゴリズムについてはまた後日実施します。

### ハイパーパラメータ
　ハイパーパラメータは半径Rと近傍点の数Mです。少ないですが、決定木などのようにとりあえずこれくらいにしておけばある程度の性能が出るということがしにくいと思います。

### 詳細
　3つの性質をもつ点が定義されています。
1. core点：半径R中に点がM+1個以上ある(自分自身を含んでしまうため1を足す)
1. 到達可能点：上記でない点の内、半径R中に1がある
1. 外れ値：上記のどれでもない

　以下の手順で進めます。
1. 近傍探索アルゴリズムを適用し、各サンプルの半径R中のインデックスを取得。もしくはクエリを投入すれば取得できる状態にしておく
1. 全サンプルをスキャンする
    1. 未スキャンであれば処理を継続。スキャン済みであれば（＝すでにラベルが付与されていれば）スキップ
    1. ラベルを付与
    1. 現在のサンプルからクラスターを拡張する
        1. 近傍点がM+1個以上であれば処理を継続。そうでなければ異常ラベルを付与。クラスターはcore点からしか広がらないため。
        1. 近傍点分のスキャン
            1. スキャン済みであればここでもスキップ
            1. ラベルを付与
            1. さらに近傍点を取得し、スキャン対象に加える
    1. ラベルをインクリメント


## イメージ
　言葉で説明するよりは[gif](https://data-analysis-stats.jp/python/dbscan%E3%82%AF%E3%83%A9%E3%82%B9%E3%82%BF%E3%83%BC%E3%81%AE%E8%A7%A3%E8%AA%AC%E3%81%A8%E5%AE%9F%E9%A8%93/#:~:text=%E5%B1%9E%E3%81%97%E3%81%BE%E3%81%9B%E3%82%93%E3%80%82-,DBSCAN%E3%81%AE%E8%A8%88%E7%AE%97%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9%E3%81%AE%E4%BE%8B%EF%BC%92,-%E4%BB%A5%E4%B8%8A%E3%81%AE%E4%BE%8B "gif")で見ていただいた方が良いと思います。非常にわかりやすいものを作成していただいています。
　まず、顔の輪郭に沿ってクラスターが成長しています。途中で上側で成長が止まっているのは半径R中にサンプルがなくなってしまったからです。輪郭部分をすべてスキャンして後は口、目ときて最後に外れ値をスキャンしています。

以上
特定の言葉がツイートされたらDiscordに通知が流れる仕組み

# 認知症フレンドリーについての情報を集めたい
私は在宅医療に携わる医師で、認知症の人を多く診療しています。
また、まちづくりにも興味があり、福岡市を認知症フレンドリーなまちとすべく活動を行なっています。
私自身がプログラミングを学び始めたこともあり、**テクノロジーを活用して認知症フレンドリーな取り組みを加速させたいと考え、認知症フレンドリーテックという言葉を作り記事を書いたりイベントを行なったりしました。**

https://zenn.dev/tarocl/articles/73efb5a39fafba

https://zenn.dev/tarocl/articles/dd6746a7ade88f

**そして今回、[認知症フレンドリーテックのアドベントカレンダー](https://qiita.com/advent-calendar/2022/dementia)を作るに至り、初日の記事としてこれを書いています。**

当初考えていた実装は、**「認知症フレンドリーに関する記事を自動で集めてくる仕組みを作ります」。**

なにせプログラミングの初学者なので手間取るかと思って取り掛かったのですが、IFTTTを使うとあっという間にできました。

# 特定の言葉がツイートされたらDiscordに通知が流れる仕組み
当初、[Make](https://www.make.com/en)を使って仕組みの実装を試みましたが、Makeの場合はツイートされたら反応するというものではなかったため、[IFTTT](https://ifttt.com/explore)を用いることにしました。

IFTTTの場合、Applets（Makeの場合のScenarios）を作っていきます。
![スクリーンショット 2022-11-30 22.55.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2051906/ddc8bd0b-f9a3-8b7f-38f4-9442e8daccf0.png)
この「Create」から新しいAppletを作成。
![スクリーンショット 2022-11-30 22.30.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2051906/8a4d4ed6-e21f-4646-6f1a-30ab7d93f947.png)
この「If This」で指示したことをトリガーにして、「Then That」で指示したアクションを行うという仕組みです。
今回のAppletはこちら。
![スクリーンショット 2022-11-30 22.30.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2051906/472aab6c-e13f-f147-0c2d-affbcc48f885.png)
中をみていくとそれぞれ、
![スクリーンショット 2022-11-30 22.29.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2051906/a8b25c7f-f0ee-3bd7-a1ee-278725fc5c10.png)
![スクリーンショット 2022-11-30 23.06.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2051906/198dbab9-aa93-c696-a86c-3685f602164f.png)
となっています。
Discordの部分にある、「TweetEmbedCode」によってツイート本文、「CreatedAt」でツイート日時、「UserName」でツイートしたアカウントのユーザーネームをひろってきています。
これによって、実際にDiscordに来た通知がこちら。
![スクリーンショット 2022-11-30 12.24.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2051906/60528c76-6f13-1afd-5951-3d1f8c1b6f76.png)
ということで、欲しかった機能が簡単にできました。
iPaas、すごい！！

実際に使ってみた欠点としては、リツイートも拾ってくること。

## 特定の言葉がツイートされたらGoogleスプレッドシートに記載される仕組み。
Discordだと流れていっちゃうので、同じ要領でGoogleスプレッドシートに情報がストックされる仕組みも作りました。
![スクリーンショット 2022-11-30 22.30.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2051906/ef422ee1-68eb-8f26-6a9e-9887c86f6449.png)
![スクリーンショット 2022-11-30 22.26.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2051906/3bf67c84-1934-abd8-4dc7-7aa2a15d8c52.png)
これだと、「FirstLinkUrl」で、ツイート内に書かれているリンクもひろってきています。

## 認知症フレンドリーテックのアドベントカレンダーへのご投稿をお待ちしています！
**さて、[認知症フレンドリーテックアドベントカレンダー](https://qiita.com/advent-calendar/2022/dementia)は、記事の投稿をお待ちしています！！
このように、簡単な実装記事で結構です。
ご投稿をよろしくお願いします！！**