OmniAICreator/Qiita-1.07M huggingface dataset:
Go 1.15 → 1.19

この記事は[Howtelevision Advent Calendar 2022](https://qiita.com/advent-calendar/2022/howtelevision)の12日目の記事です。

弊社が運営する外資就活ドットコムではバックエンドに`Go`を採用しています。
`Go`のバージョンが`1.15`のままとなっていたので`1.19`にバージョンを上げたのですが、本記事ではバージョンアップの際に行った変更を備忘録的なものとしてまとめておこうと思います。

# Goのバージョンアップ(1.15->1.19)
手始めに`Dockerfile`を
```Dockerfile
FROM golang:1.15.3
```
から
```Dockerfile
FROM golang:1.19.3
```
にバージョンの指定を変更しました。

これだけでうまく動いてくれればよかったのですが、そううまく事は運ばずmodule関連の変更も必要でした。
具体的には
- `go get`がDeprecatedされたことへの対応
    - `go get`から`go install`への変更
- `go.mod`の変更
    - `1.16`や`1.17`でmodule関連に変更があったらしく、`go.mod`ファイルに変更を反映させるために`go mod tidy`を行う必要がありました

を行いました。

https://go.dev/doc/go-get-install-deprecation

https://tip.golang.org/doc/go1.16

https://tip.golang.org/doc/go1.17


# CircleCIの変更
CIに`CircleCI`を利用しているので、`CircleCI`の設定ファイルを書き換える必要がありました。
`Dockerfile`と同じようにバージョンの指定を変えるだけかと思ったのですが...
```
Starting container circleci/golang:1.19.3
Warning: No authentication provided, using CircleCI credentials for pulls from Docker Hub.
  image cache not found on this host, downloading circleci/golang:1.19.3
```
どうやら、`go:1.19`は次世代イメージしかないようです
https://circleci.com/docs/ja/circleci-images/#next-generation-convenience-images

ということで、`CircleCI`の設定ファイルを
```yaml
image: circleci/golang:1.15.3
```
から
```yaml
image: cimg/go:1.19.3
```
に変更して再チャレンジしてみると
```
ln: failed to create symbolic link '/go/src/app': No such file or directory
```
設定ファイル内でシンボリックリンクを貼るコマンドがあるのですが、ディレクトリが存在せず失敗してしまいました。

調査してみると、`CicleCI`の次世代イメージではPATHが変わったようです。
     
```yaml
environment:
 - APP_DIR: /go/src/app
```
から
```yaml
environment:
 - APP_DIR: /home/circleci/go/src/app
```
に変更することで、無事CIを実行することができました。

`CircleCI`の設定ファイルを変更するにあたって下記のブログを参考にさせていただきました:pray:
[[Go]次世代イメージcimg/goとcircleci/go Orbsを使った2020年版CircleCIの環境構築](https://budougumi0617.github.io/2020/06/08/circleci_cimg_go_2020/#:%5C~:text=%E3%82%8C%E3%81%A6%E3%81%84%E3%82%8B-,GOPATH,%E3%81%AF%E5%A4%89%E6%9B%B4%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%82%8B%E3%81%AE%E3%81%A7%E6%B3%A8%E6%84%8F%E3%81%99%E3%82%8B,-/home/circleci/go)


# 最後に
ハウテレビジョンでは、一緒に働いてくれるエンジニアを募集しています。

https://recruit.howtelevision.co.jp/
フロントエンドで、全てのフレームワークが同時に使える

# ゼロJS からビルドしましょう

## はじめに
**※これは KWC Advent Calendar 2022 の11日目の記事です。**

こんにちは、[(株)KDDIウェブコミュニケーションズ](https://www.kddi-webcommunications.co.jp/)でフロントエンドエンジニアをやっているPikeです。 初めてのQiitaです。
紹介したいのは「Astro」。Astroを使えば、front-end framework (vue, angular, react など)の全てを使えます。Astroも自動的にgithub actionsでデプロイが出来ます。

## なぜAstroへ移動する？
- github actions が既にある
- ゼロJS からビルドする（ユーザーさんに早い, bundleが小さい、lazy loadingもあり）
- 「framework」はどれでも良い (bring your own framework)
- 他の「framework」(next, nuxt, remix)　と似てる
- JSXでかける

## ビルドは何が変わってる？
- サーバファスト：必要のJSのみを使う。(lazy loading, server side rendering)
- folder-based-routing: react-routerなどは必要ない

### Let's get started
```
npm create astro@latest
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2991781/dc895f2c-e4c0-079b-9c77-c9cd4c88003a.png)

コードが出来ました：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2991781/5c04fe9c-c4fb-c016-985a-d899179232b1.png)

### Github Pagesへデプロイ

- [deploy instructions](https://docs.astro.build/en/guides/deploy/github/)
- astro.config.mjs を編集して
    ```
    import { defineConfig } from 'astro/config'
    
    export default defineConfig({
      site: 'https://astronaut.github.io',
      base: '/my-repo',
    })
    ```
- .github/workflows/deploy.yml を作って


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2991781/f8a8c8e7-ec15-faf4-1723-c7c794416136.png)

- 確認する：
    - [AstroTemplate](https://pike-kwc.github.io/astroTemplate/)

### Reactの追加

- `npm install --save-dev @astrojs/react react react-dom`
- `$: vi components/ReactComponent.jsx`
```
import React from "react";

const ReactComponent = () => {
    return (
        <div>Hello I'm a ReactComponent</div>
    )
}
export default ReactComponent
```
- astro.config.mjs　に　reactを追加する。
```
import { defineConfig } from 'astro/config'
import react from '@astrojs/react';

export default defineConfig({
  site: 'https://pike-kwc.github.io',
  base: '/astroTemplate',
  integrations: [react()]
})
```
- pages/index.astroに追加する。
```
import ReactComponent from '../components/ReactComponent.jsx'
...
<ReactComponent />
```

- ほかのframeworkも自由に追加できます！
```
import react from '@astrojs/react';
import preact from '@astrojs/preact';
import svelte from '@astrojs/svelte';
import vue from '@astrojs/vue';
import solid from '@astrojs/solid-js';
import lit from '@astrojs/lit';
import alpine from '@astrojs/alpinejs';
```
- ステートを共有が必要であれば、`nanostore`が　使える。
```npm install nanostores @nanostores/react```
### Performance
- Reactいれても、ダウンロードしなかった　(150b)：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2991781/ee3b5609-7f87-f5e6-b515-f9fd8214f760.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2991781/e2c38d06-acd0-2167-a8e0-87cc1c05cc57.png)



## おわりに
ここまで読んで頂いた方ありがとうございました。ほぼ手順書みたいな内容でしたが、エンジニアの皆様の一助となれれば幸いです。
[KWC Advent Calendar 2022](https://qiita.com/advent-calendar/2022/kwc) はまだまだ続きます！明日もお楽しみに！！
Google Colab から Wiki-40B をダウンロードする

自分んとこのサーバで Wiki-40b 使いたいけど、コーパス使いたいだけなのに Tensorflow のインストールからとかやってらんねえ。というときのメモ。

## 事前知識

- Wiki40-b:
-- [https://hironsan.hatenablog.com/entry/how-to-use-wiki40b](https://hironsan.hatenablog.com/entry/how-to-use-wiki40b)
- Google Colab から Google Drive へファイルアクセス可能する
-- [https://www.teamxeppet.com/colab-googledrive-mount/](https://www.teamxeppet.com/colab-googledrive-mount/)

## コード

Google Colab で以下を実行。

```python3:コード
import tensorflow_datasets as tfds
(ds_train, ds_valid, ds_test), ds_info = tfds.load(
  name='wiki40b/ja', split=['train', 'validation', 'test'], with_info=True)
```

```:結果
Downloading and preparing dataset Unknown size (download: Unknown size, generated: 2.19 GiB, total: 2.19 GiB) to ~/tensorflow_datasets/wiki40b/ja/1.3.0...
Dl Completed...: 100%
20/20 [00:09<00:00, 6.21 file/s]
Dataset wiki40b downloaded and prepared to ~/tensorflow_datasets/wiki40b/ja/1.3.0. Subsequent calls will reuse this data.
```

```python3:コード
print(tfds.__version__)
```

```:結果
4.6.0
```

書き出し先のディレクトリ（ここでは「wiki40b」）をあらかじめ GoogleDrive に用意しておく。

```python3:コード
import zipfile

with zipfile.ZipFile('/content/drive/MyDrive/wiki40b/wiki40b_tfds_'+ tfds.__version__ +'.zip',
                     'w', compression=zipfile.ZIP_DEFLATED) as zf:

  for ds, split in [[ds_valid, 'validation'], [ds_test, 'test'], [ds_train, 'train']]:

    with zf.open(split+'.txt', 'w') as fout:
      for ds_elem in ds.as_numpy_iterator():
        fout.write(ds_elem['text'])
```

tensorflow_datasets から呼び出した Wiki-40b は文字列型がバイナリなので、デコードせずにそのまま zipファイルの中に流し込んでる。

実行したら上で用意しておいたディレクトリ内に「wiki40b_バージョン.zip」というファイルができている。
zip を解凍すると、
- train.txt
- validation.txt
- test.txt

というテキストファイルが3つ入っている。
スマホVRのススメ

この記事は, [VR・メタバース教育 Advent Calendar 2022](https://qiita.com/advent-calendar/2022/vredu) の10日目の記事です.
# VR機器の種類

みなさんは, VRを使用する際, どのようなデバイスを使います? 現状で購入できるデバイスとしては, 次のようなものがあります.
- 高性能VR機器 (それなりの性能を持つパソコンが必要なタイプ, 例えば HTC Vive Pro)
- スタンドアローンVR機器 (VR機器単独で動作するタイプ, 例えば Meta Quest 2)
- スマートフォンVR (Cardboardに代表されるもの. 動作にはスマートフォンが必要)

これ以外にも, 部屋をまるごと使ったVR機器やメガネ型デバイス(例えば, Google Glass)などもあります.

さて, ここに上げたVR機器は, 値段に差があります. 
- 高性能VR機器: 本体 10万円程度 + パソコン = 30万円弱
- スタンドアローンVR機器: 6-7万程度
- スマートフォンVR: 500円から3000円程度 + スマートフォン
費用に比例して, 体験の質や解像度は良くなります. つまり, 体験という面で言うと次のような順になります.
<pre> 高性能VR機器 > スタンドアローンVR機器 > スマートフォンVR </pre>
細部が気になる, レイテンシーがというと, 高性能VRしか使用に耐えないでしょう. 手軽にというとスタンドアローンやスマートフォンVRに軍配があがります. 当然ながら価格は, (スマートフォンにかかる費用を除けば,) スマートフォンVRが最も安くなります.

# 教育現場へのVR機器の導入
さて, ここでVR機器を中等教育や高等教育で導入することを考えてみましょう.
1クラスが 30人から40人程度と考え, スタンドアローンVR機器を人数分揃えると,210万円から280万円となり, 簡単に揃えることはできません. かといって, 1台から2台程度では一回の講義の中で, 全員が体験するというのも難しいところでしょう. 少なくとも 1クラスの 1/3程度の台数が必要になってきます. つまり, 10台購入するとして, 購入費用として60万から70万が必要となります. この費用を結構大きな金額となっています.

また, 実際に体験をおこなう際は, 2/3の生徒の相手をする教師, 1/3の生徒の体験を担当する補助員(できれば2名)がいたほうがよいでしょう. 

以前に私立の高等学校の先生と話したときに, 授業料以外に特定の科目だけで使うような機器やシステムを購入するのは難しいと聞いたこともあります. 逆に言えば全教科で使うということであれば, 初期費用として, 導入することも可能であるということです. パソコンのBYODはこれにあたります. 実際, N高/S高では[VR教育を導入](https://nnn.ed.jp/learning/vr/)しています.

# スマホVRのススメ
ここまで, VR機器の種類と導入のための費用について話をしてきました. 
費用面からみると, 中学校や高等学校で導入ができそうなのは, スマホVRということになります. スマホVRを使うために, 次のような枠組みを考えました.
- 生徒のスマートフォンを活用 
- 学校でVRデバイス(Cardboardベースのもの)を購入
- VRアプリは開発者が作成したものを利用

この枠組に沿ったアプリとして, 次のようなアプリがあります. 
- [VR科学の実験](https://play.google.com/store/apps/details?id=com.abacus.vrsciencelabjapanese)
- [VR Education Museum](https://play.google.com/store/apps/details?id=com.marcelosuzumura.VREducationMuseum)
- 分子運動力学計算 VR-MD, [2022 VR学会](https://conference.vrsj.org/ac2022/program/2F2.html)
- 斜方投射 [Fly Ball]( https://play.google.com/store/apps/details?id=jp.ac.tokai.ss.onishi.FlyBall)[^1]
- 音声入力による曲面描画 [VVrplot for smartphone](https://play.google.com/store/apps/details?id=com.Oonisi.VVrplot)[^2]

これ以外にもありますので, Google Play(Android)やApp Store(iPhone)で VRやEducationで探してみてください. 

# スマホVRの問題点
スマホVRには, 次のような問題点もあります.
- 生徒のスマートフォンが使えるのか? Android と iPhoneに対応しているアプリがあるのか?
- Cardboardがクラスの人数分買えるのか? (ここは買うしかないところです)
- 自分の目的にあったアプリがあるのか?
- UIはどうなっているか. 

最後のUIは少し大変な部分を含んでいます. 高性能VRやスタンドアローンVRでは, 基本的に入力デバイスがあります. しかし, スマホVRでは,(標準で)入力するための機器がなく,視線での入力(しばらく対象を見る)ことが多くあります. 
これ以外の手法として, 音量ボタンを入力として使う方法や音声での入力もあります. 音声ボタンだけでは簡単な入力しかできず, 音声入力には慣れが必要です. 今後は, ハンドトラッキングを使う方法もあるかとは思いますが, バッテリー消費もあるので, 万能ではありません. そのため, VRでおこないたいことを考え, それに応じたUIを利用する必要があります.

# まとめ
現状で, 中学校や高等学校で VRによる教育を導入するには, スマホVRが最も適しているのではないかと思います. 
色々と問題点もありますが, 今後ともVRを用いた教材開発を進めていきますので, こういうものが欲しいというのがありましたら, 連絡をもらえればと思います.

[^1]: これらは, 当研究室で開発したものです. もし, 感想等ありましたら, お知らせください.
[^2]: 同上
kintoneのバックアップ手段について

これは [NTTテクノクロスアドベンドカレンダー2022](https://qiita.com/advent-calendar/2022/ntt-tx) の14日の記事です

こんにちは、NTTテクノクロスの竹村(@TACK_TX)です
リモートワーク製品の開発とともに、kintoneによる社内業務系の管理アプリ開発、維持管理保守を担当しています

kintoneを顧客情報の管理等に利用しており、非常に重要なデータを扱っています
そこで不慮の事故に備えて、日々のバックアップについて検討・導入したので、そちらの共有をしていきます

## ■プラグイン導入による有料バックアップ
### ●アプリのバックアップ
gusuku Deploit

https://deploit.gusuku.io/

アプリ自体のバックアップを取っており、バージョン管理が可能です
変更履歴なども取れるため、特定バージョンへの巻き戻しも可能です

リリース用と試験用に別アプリを作るなどの運用対処をしている場合は、
同期も出来るため大幅な改善が見込めます

後から導入するとアプリのフィールドの制約で効果が出にくいため、
最初にアプリを作る段階で入れておきたいです

### ●レコードのバックアップ
kBackUP

https://kb.kintoneapp.com/

定期バックアップを自動で取ってくれます
標準機能ではバックアップできない添付ファイルも取ってくれるのが個人的に嬉しい点です
レコードの追加・編集・削除のGUI操作がされたタイミングで、自動的にオンラインバックアップします
ただし、CSVやAPIを経由する操作にはオンラインバックアップが機能しません
オンラインバックアップの保管期限が30日間なのも注意点です


## ■標準機能による無料バックアップ ##
### ●標準機能によるレコードのファイル書き出し ###
https://jp.cybozu.help/k/ja/user/app_collectdata/export/data_export.html

権限付与さえしておけば、誰でもワンボタンでバックアップが取れます
ラベル、添付ファイル、関連レコード一覧、コメント、変更履歴は取れないため、
それらも取りたい場合は前述したkBackUPなどを導入したほうがよいです
手動であるため、誰かが定期的に実施しないといけない点は注意です

### ●API＋スケジューラによるレコードのファイル書き出し ###
コマンドラインツールのバックアップ処理を定期実行してみよう

https://developer.cybozu.io/hc/ja/articles/115002220086

コマンドラインツールのバックアップ処理を定期実行してみよう

https://developer.cybozu.io/hc/ja/articles/115003155026

kintoneコマンドラインツールで自動バックアップを実施します
コマンドラインツール+batファイルで該当アプリのレコードをバックアップします

```
>cli-kintone.exe --export -a <バックアップ元のアプリID> -d <バックアップ元のドメイン名> -t <バックアップ元のAPIトークン> -e sjis -c "<バックアップしたいフィールドのフィールドコード(カンマ区切り)>" -b <添付ファイルのエクスポート先ディレクトリ> > backup.csv
```

上記を記載したbatファイルをcronやタスクスケジューラーで自動実行すれば自動バックアップになります
出力されるCSVファイルは標準機能によるレコードのファイル書き出しとは違う形式となるため、互換性がない点には注意です
具体的な差分の一部としては、「ヘッダが異なる」「文字コードが違う」などになります

余談ではありますが、cli-kintoneを使うと、特定の条件分岐でレコードの一括更新などができます
例えば「契約満了日を迎えた顧客のレコードステータスを変える」、「解約された顧客を非表示にする」などです

具体的には
1.特定のアプリからレコードを取得
```
>cli-kintone.exe --export　-a アプリID -t APIトークン -e エクスポートするファイルのエンコード方式 > 上書き エクスポートファイル
```

2.エクスポートしたcsvファイルに対して、条件指定してインポートファイルを生成

3.アプリにインポートファイルを取込
```
>cli-kintone.exe --import　-a アプリID -t APIトークン -e インポートするファイルのエンコード方式 -f 取り込むインポートファイル
```

となります

このようにバックアップ以外でも様々なことが出来るので、現在はこちらを利用しています

## ■終わりに ##
個人の見解ですが、

手間をかけたくない　かつ　管理者のみバックアップを取る場合は以下がおすすめです
　リリース毎にアプリやレコードを管理したい場合は gusuku Deploit
　レコードのバックアップだけでいい場合は kBackUP
　有料アドオンの導入が難しい場合は　API＋スケジューラによるレコードのファイル書き出し
手間をかけてよい　かつ　誰でもバックアップを取る場合は　標準機能によるレコードのファイル書き出し がおすすめです

こちらの記事が皆様の一助になれば幸いです

NTTテクノクロスアドベンドカレンダー2022 、明日は@kn-tomさんです。お楽しみに！
【Nuxt】SPAで遷移するたび関数を発火させたい 💥


`watch`で下記のように記述し、遷移元と遷移先のpathが異なる場合にtest()が発火する。
```js
watch: {
    $route: function (to, from) {
      if (to.path !== from.path) {
        this.test()
      }
    },
  },
methods: {
     test() {
       console.log('urlが変わったよ')
    }
```
Qiitaに記事を書くきっかけと今思うOUTPUTするということ

# はじめに
Qiitaで記事を書き始めて1年位？になりました。Qiitaではまだまだ駆け出しのエンジニアです。
当記事はタイトル通り『なぜQiitaに記事を書こうと思ったのか』、『記事投稿してみて思うこと』を書こうと思います。
初心を忘れないように記録したいと思っていたら、『Qiita史上最多記録をつくろう！アウトプットはいいぞカレンダー Advent Calendar 2022』という企画を目にしてこれに便乗しようということで記事を投稿します:pen_ballpoint:。
AdventCalendarにも参加したいという思いもあったので、一石二鳥な感じです。

どんなやつが書いているねん？という方もいるかと思いますので、簡単に **2022年12月9日現在の自己紹介** 的なことを書きます:boy:。
【自己紹介】
地方のSI企業でメインフレームからWebシステム開発までこなすド田舎のエンジニアです。
キャリアのスタートはメインフレーム（汎用機）をメインアーキテクチャとしている現場に配属されて、[JCL](https://e-words.jp/w/JCL.html)、[EASY PLUS](http://yfuku.sakura.ne.jp/mvs/es1.html)やCOBOLで業務システムを開発してました。
最近は、メインフレーム関連からWebシステムの開発まで幅広く開発しつつ、プロジェクトリーダとして開発案件に参画することも多くなっている今日このごろです。

あと、[OUTPUTの一貫でTwitterで細々つぶやいています～！](https://twitter.com/littlebear_6w6)
:point_up:ほぼくだないことをつぶやいていますが、得られた技術的な知見等もつぶやいています。

# Qiitaの門を叩く
けっこう脇道からQittaの門を叩いた感じだと思う。ちょっと略記になりますが、お付き合いください。
WebシステムをNuxt.jsで開発することになった。あんまり聞いたことないフレームワークだな。
仕事してやるし、短期間で一通りの要素を学習するには・・・、『本』だな。
ということで、入門した書籍がC&R研究所から出版されている[『Nuxt.jsビギナーズガイド―Vue.js ベースのフレームワークによるシングルページアプリケーション開発』](https://www.c-r.com/book/detail/1253)です。
この書籍の最初の課題がQiita APIを使用してNuxt.jsのタグ付された記事を取得して画面表示するものです。ここでQiitaの門を叩いたわけです:grin:
「色々な方が色々な情報を発信しているは知っていたけど、こんなAPIも提供しているのね」くらいの感覚でしたが、２～３ヶ月経ってせっかく門を叩いたからには記事を投稿してみようかなというレベル感で「[Virtual BoxにインストールしたKali Linuxが起動しない事象への対処](https://qiita.com/LittleBear-6w6/items/0dc6c3871b3e1247377a)」というお題で投稿してみました。
viewsの数が出て結構な人が見てくれているんだなと思い、投稿することが楽しくなってきた:laughing:
残念ながら「いいね」はついていないですが・・・・・・・・。

# OUTPUTをするということ
単純に記事投稿してviews数が増加したり、「いいね」がついたりするとモチベーションが上がって楽しい:bangbang:
これが一番大きいのは間違いないと思う:blush:
でも、もっと大きいのは学習の記録が残るということ。そして何より記事投稿することでより知識・考えが整理されてブラッシュアップすることがメリットだと思う。
わかった気になっていた事がいざ書こうとすると、「:thinking:？」となることが多々ある。
この時に更に調べて考えてブラッシュアップされて洗練された知見となる。これが大きな喜びだと思う。
:warning:___私の記事が他の方にとって洗練された知見とは限りません。___
:point_up:__でもこれがでも大事なことだと思っている。__
自分が調べて得られた知見は**自分の財産**であると思っている。これは揺るがない事実であると思うし、他人に文句を言われる筋合いはないこと。
この財産は、頭の中に秘めとくだけだと形にならないし、人は忘れる生き物であるのでこの大事な知見を忘れてしまうことも多々あると思います。
OUTPUTしておくことで、忘れた頃に同じ課題に直面した際に見返して解決することができると思う。
これだけでもOUTPUTしておく価値があると思う。
このOUTPUTがQiitaであれば、インターネットを通じてあらゆる場所で知見を見れる。
また、このOUTPUTが同じ課題に直面している人の役立ったりする。
詰まるところ、１つものを見たときに価値があると感じる人もいれば全く価値がないと感じる人もいる。一人でも価値があると感じれば、それば立派なOUTPUTであり財産となる。その１人が自分だとしても:thumbsup::bangbang:

# OUTPUTするものがない？
私もQiitaに初めて投稿するまでは、OUTPUTするものないと思っていました。
でも、OUTPUTは**自分の財産**なのだと思うと、OUTPUTの内容は何でも良いんだとなりませんか？
日記でも単純なメモでもそれは重要なOUTPUTなのだと思います。
なので、私はこれからも何でも良いからOUTPUTしていこうと思います:grin::bangbang:
そのOUTPUTが誰かの興味を引いて、役立てば尚良しという感じやっていければと思います。
PHPで文字エンコーディングがWindows-31JのJSONを作る

これは [エキサイトアドベントカレンダー2022](https://qiita.com/advent-calendar/2022/excite-hd) の記事です

# 前提
通常、JSONの文字エンコーディングにはUTF-8を使用することになっています。
またphpでは`json_encode()`を使うと、デフォルトでは日本語のような文字列は`\u65e5`のようにUnicodeの16進数表現にエスケープされます。

だがしかし、文字エンコーディングが`Windows-31J`のJSONをphpで作りたい。という時の記事です。

## Windows-31J とは？
`Shift-JIS`のWindows用の拡張の一種のようです。`MS932`とか呼ばれることもあるようです。
`Windows-31J` というのは割とJava界隈での呼び方？（筆者の私見です）のようで、phpでいうと`SJIS-win`です。

# やり方

日本語部分をUnicodeエスケープされないようにしたうえで、`mb_convert_encoding()`で変換してやりました。

```php:エンコード時
$data = ['data1' => '日本語'];

$rawJson = json_encode($data, JSON_UNESCAPED_UNICODE);
$result = mb_convert_encoding($rawJson, 'SJIS-win', 'UTF-8');
```

```php:デコード時
// $encodedStr はSJIS-winのjson文字列とします。

$jsonStr = mb_convert_encoding($encodedStr, 'UTF-8', 'SJIS-win');
$result = json_decode($jsonStr, true);
```

# 参考記事
https://www.php.net/manual/ja/function.json-encode.php

https://www.php.net/manual/ja/mbstring.supported-encodings.php
DjangoとConohaでファイルアップロード掲示板作ってみた！

# はじめに
<a href="https://qiita.com/gakusei_programmer/items/2f87497b49472da55b11">前回まで</a>は主にフロントエンドの紹介をしていましたが書くことがなくなってきたのでバックエンドとかサーバー周りの紹介に移りたいと思います。


トップはこんな感じです。ここから見れます！http://colorful-wall.com/board/boards/
![スクリーンショット 2022-12-09 16.10.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1467169/4d5be015-e5bf-c300-2c60-9565590bebf3.png)

# Django環境構築
<a href="Djangoの初期設定までは<a href="https://gadgelaun.com/?p=32674">【簡単】ConoHa VPSにDjango環境を構築する方法！</a>を参考にさせて頂きました。
このページを参考にして最も価格の低いConohaVPSのメモリ512MBプランを選択し、アプリケーションはDjangoを選択します。
私はネットに情報が多かったCentOS9をOSに選びました。

設定をしたら、サーバー->ネットワーク情報->IPアドレスの欄からIPアドレスをメモします。
![スクリーンショット 2022-12-09 16.42.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1467169/a1b9ace9-489d-2377-c069-00ede1cb3f29.png)
自分のブラウザのURL欄にメモしたIPアドレスを入力し、ロケットのイラストが表示されれば成功です！

# DNS
次にConohaでドメインを取得しました。
Conohaの設定画面でDNS -> ドメインリスト -> 自分のドメインの画面でドメインから先ほどのサーバーにアクセスできるように設定します。
タイプがNSになっているものは全て元からあるのでタイプA(通常) @ 3600 (自分のIPアドレス)
となる値を設定しましょう。
![スクリーンショット 2022-12-09 16.32.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1467169/60029323-4d8a-8387-5a84-3f8d776c347d.png)
ドメインは設定から反映まで時間がかかるかもしれないので少し待ちましょう。

# 最後に
ここまでできるとひとまずOKです。
次回は自作のDjangoアプリのアップロード方法について書こうと思います！
インスタグラム　制限との戦い

コメントしすぎて、コメント投稿ブロックされてしまいました。
ブロック期間は三日。

簡単にググってみたところ、一時間に15個以上のコメントをすると、引っかかるらしい。
一時間に15個、、、4分に一回か。少ない、、、話にならない。バイトにならない。

コメント仕事ができないので、手持ちのインスタアカウントリストがALIVEかどうかを調べるために、順にページを開いて、投稿があるのかどうかチェックしてみた。投稿がないアカウント＝デッドアカウント。

アカウント一つにかける時間は5秒。

これでもしばらくやると（離席してたので正確な時間はわからない）、通常のページは表示されなくなり、本人確認のため、暗証番号をメールで送ったからその数字を入力しろ、というポップアップが出てしまったよ。

何も書き込んでない。ただ調べているだけ。しかも5秒に一回。それでもダメか。

ボットがそんなに憎いのか。別に5秒に一回くらいなら、サーバーにかかる負荷は大したことないし、なんなら必死の人間がやる速度よりも遅いくらいなのに。

厳しい、あまりに厳しい。

ただ暗証番号を入力したら、すぐ使えるようにはなりましたけど。

なんだかなんだか。

====

ところが。

数時間後同じ作業をしようしたら、ログインはできるが、個別のページを表示してくれません。
しばらく作業はやるな、と、こうおっしゃるわけですね。

分かりました。じゃあもう一個別のアカウント作ってやる。

と思い、GMAILの数あるサブアカウントの一つでサインアップしようとしたら、これも拒否される。
「このメールはすでに使用されています」の表示が。
あれ？おかしいな。このサブアカでインスタグラムのアカウントなんか作ったっけ。。。

もちろん作った記憶もないくらいだから、パスワードなんて覚えていない。
なのでFORGOT PASSWORDでパスワードの再設定をしようとすると、、、、
「そんなアカウントはありません」との表示が。

なかなか手強い、手強いよ。
TextViewで文字列があふれたときに自動スクロールさせる

リソース側
```
<TextView
・・・
    android:singleLine="true"
    android:ellipsize="marquee"
    android:marqueeRepeatLimit ="marquee_forever"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:scrollHorizontally="true" />
```

ソース側
```
binding.textView.setOnClickListener {
    it.isSelected = true
}
```
AzureADB2CはBtoCじゃないの？

# AzureADB2CはBtoCじゃないの？

## 疑問
開発しているアプリケーションに認証機能を実装しようとしてAzureADB2Cについて調査していた。
AzureADB2Cは企業向けの認証情報管理に使用されているAzureADの対一般顧客向け版で、アプリに対して認証機能や二段階認証・外部のアカウントを使用した認証などを付けることができる。
ところでこのB2Cという名前はなぜB2Cなのだろうか。
BtoCとは「Business to Consumer」の略称で企業対一般顧客向けのサービスやビジネスのことを指す。
そのBtoCのtoが数字の2で表記されている。

## toを2と表す英語スラング
toを2と表記するのは英語のスラングである。
単純にtoと2の発音が近しいためであり、toと2以外にも以下のような発音が同じで意味が異なる文字を当てているスラングが多数ある。
`for=4`
`you=U`
`see=C`

## まとめ
調べてみるとこのtoを2とする表記はAzureに限らずビジネス全般において使われるB2B（BtoB）、C2C(CtoC)など幅広く使われているようだ。
意味合いとしても特に変わらずtoと発音が似ているため使われている。
社会人になってからアルファベット3文字の略称を何個も見てきて少し嫌になってきていたが、
このような遊び心のある略称は少し楽しい気分になれる。
新卒3年目エンジニアのひとりごと

# はじめに
こんにちは。オークファンの新卒３年目エンジニアの@af-2784です。
入社してから約2年8ヶ月が経ったので、これまでの会社生活を振り返ってみようと思います。

# プロフィール
- ハワイ生まれハワイ育ち
  - 高校卒業までハワイにいました
- 都内某大学の情報理工学科卒
- 大学入学までプログラミングは未経験
- 2020年にオークファンに新卒入社

# 入社した経緯
お寿司屋さんでスカウトされました。
冗談に聞こえるかもしれないですが、本当の話ですw

私は大学４年の時、就活の合間に大学の近くのお寿司屋さんでバイトしていました。
お寿司屋さんに来るお客さんはフレンドリーな方が多く、お客さんとよくお話することがありました。

バイト中のある日のこと。
お客さん: 「君、○○大学の学生？」
私: 「はい」
お客さん: 「何年生？」
私: 「４年です。就職活動が大変で(笑)」
お客さん: 「何学部？」
私: 「理工学部で情報系の勉強をしています」
お客さん: 「YOUうちの会社に来なよ！」
私:　!?!?

なんと、そのお客さんは弊社の人事部長でした。
後日、正式に会社を受けることになり、無事内定をいただくことができました。

# 入社３年目になって気づいたこと・思ったこと
## コーヒーが美味しい
弊社には、部活制度があり、中にはコーヒー部というものがあります。
コーヒー部では、特に特別な活動を行っているわけではないですが、お昼休みによく会社の給湯室でコーヒーを淹れています。
給湯室には、サイフォンやコーヒーミル、エスプレッソメーカーなど、あらゆるコーヒー機材が揃っています。

初めてコーヒー部のコーヒーを飲んだ時、こんなに美味しいコーヒーを飲んだのは人生で初めてだと思いました。
オークファンに入ってからコーヒーに対する考え方が変わりました。
先日、都内のカフェで１杯1300円のコーヒーを飲みましたが、会社で淹れるコーヒーの方が美味しいと思ってしまいました 笑

## 自分の得意なこと、苦手なことが明確になった
入社して１年半くらいはGoを使ったバッチやAPIの開発など、バックエンド側の開発をメインにしていました。

入社したての頃は、分からないことだらけでしたが、頑張ってやっていれば、そのうちできるようになるだろうと思っていました。
しかし、入社して１年が経ち、案件の難易度が上がり、バックエンドの開発は、自分に合わないと感じ始めました。
ネットで調べても分からない、先輩に教えてもらっても分からない、何が分からないのか分からない、ということもよくありました。

自分はエンジニアに向いていないのかもしれない、今後エンジニアとして生きていくのは無理かもしれないと本気で絶望しました。
そんな時に見た、「日曜日の初耳学」というテレビ番組の[森岡毅さんの回](https://www.mbs.jp/mbs-column/mimi/archive/2022/06/15/023934.shtml)で`弱みを克服するより強みを伸ばすべき`というお話が心に刺さったのをよく覚えています。

2022年に入ってからは、もっとフロントエンド寄りのPHP開発をメインで作業することになりました。
PHPの開発をするようになってからは、バックエンドの開発をしていた時より比較的にスムーズに仕事を進められるようになりました。
こっちの方が自分に合っていたんだなと思います。

新卒のうちは、分からないことやできないことの方がが多く、自分は何ができるのか、自分は何が得意なのかに気づくのは難しいかもしれません。
しかし、自分の強みや、やりたいことを見つけられれば、きっと見える景色が広がり、新しい世界の扉を開くことができると思います。

## 同期の存在は大事
私には、現在４人の同期がいます。
会社に出社した時は、よく同期とお昼を食べに行ったり、コーヒーを淹れたりします。

同期は、会社の中では１番話しやすい存在だと思います。
最近は、同期と直接仕事で関わることも多く、案件に関する相談も同期だと気軽にできます。

また、同期は仕事のグチを話せる相手でもあります。
仕事でメンブレした時は、仕事帰りにマックで同期にグチを聞いてもらったりしました。

入社したばかりの時、先輩に「同期は大事にしなさい」と言われましたが、あの話は本当だなと今思っています。

# 最後に
入社１年目、２年目の時は、一年が３年~５年くらいに感じましたが、2022年はあっという間だった気がします。仕事が慣れてきたからでしょうか。
これからも頑張っていきたいと思います。

みなさま、良いお年を。2023年も素敵な年になりますように。
PagerDutyからの電話にマナーモードを貫通させる方法

PagerDutyなどオンコールが深夜に鳴ったとき、スマホがマナーモードになっていた結果対応できなかった、ということはないですか？
しかし、オンコールに対応するためスマホのマナーモードを常に解除しておくとそれ以外の電話も音が鳴ってしまいます。

# 問題

マナーモードがONでもPagerDutyからの電話だけは音を鳴らしたい。

# 解決法

PagerDutyの電話番号を特別な連絡先に追加して、マナーモードを貫通するようにしましょう。

## ステップ1. 電話帳への登録

[^10]: ファイル名が変わる可能性があるため、リンクが切れていたら　https://support.pagerduty.com/lang-ja/docs/notification-phone-numbers から辿ってください

1. スマホでhttps://s3.amazonaws.com/pdpartner/PagerDuty+Outgoing+Numbers.vcf を開く[^10]
    ![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30316/3f3993a5-43db-63e3-f8fe-5a6635b90468.png)

1. 「Download the PagerDuty vCard」を開いて電話帳に登録

## ステップ2. PagerDutyの連絡先を特別な連絡先に登録

### iPhoneの場合

[iPhoneで特定の人からの着信は常に音を鳴らす方法 \- 週刊アスキー](https://weekly.ascii.jp/elem/000/001/860/1860259/)

### Androidの場合

AndroidはOSによって方法が違います。

#### Galaxy等の場合

お気に入りを使用します。
[Androidスマホの「サイレントモード」とは？ 設定・解除からマナーモードとの違いまで解説 \| アプリオ](https://appllio.com/android-smartphone-quickly-turn-off-ringtone)

#### Pixelの場合

こちらもだいたいお気に入り設定。
[Pixel5aをandroid13で使っています。マナーモード時に特定の電話番号からの着信時に着信音を鳴らす方法を教えて下さい。 \- Google Pixel コミュニティ](https://support.google.com/pixelphone/thread/185787299/)

#### Xperiaの場合

http://menulist.mb.softbank.jp/feature_20190603/

#### ColorOS(Oppo)の場合

PagerDutyの電話番号をVIP連絡先に追加

https://ipics.oppo.com/oppo/others/ColorOS_6.0_User_Guide_JP.pdf

## 制約

Androidの場合、この方法で貫通させられるのはサイレントモードのみで、マナーモードやバイブレーションモードでは結局音がなりません。こういったときの対処法は現在調査中です。

# この記事は

[Speee](https://tech.speee.jp/)での業務中に得た知識を元に業務中に書きました。
UI ElementsでReorderableList 

## 概要
UIElements(UI Toolkit)でListViewを使ってReorderableListを作った際に子要素のバインドでつまづいたのでメモ。

バージョン : Unity 2022.1.24f1

完成イメージ : 
![InspectorWindow004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133834/f4263556-cebe-5105-94a3-ccee1a5a7971.png)

## コード
Runtime
```cs
using System;
using UnityEngine;

public sealed class Sample : MonoBehaviour
{
    [SerializeField] private ListItem[] items;
}

[Serializable]
internal sealed class ListItem
{
    public string name;
    public Type type;
}

internal enum Type
{
    None,
    Normal,
    Advanced
}

```
Editor
```cs

using UnityEditor;
using UnityEngine.UIElements;

[CustomEditor(typeof(Sample))]
public sealed class SampleEditor : UnityEditor.Editor
{
    public override VisualElement CreateInspectorGUI()
    {
        var bodyElement = new VisualElement();
        
        var listView = new ListView
        {
            bindingPath = "items",
            reorderMode = ListViewReorderMode.Animated,
            showAddRemoveFooter = true,
            showBorder = true,
            showFoldoutHeader = true,
            headerTitle = "List Items",
            virtualizationMethod = CollectionVirtualizationMethod.DynamicHeight,
            makeItem = () =>
            {
                // 返すルートをBindableElementにしないと、子要素がバインドできないので注意
                var root = new BindableElement { style = { flexDirection = FlexDirection.Row }};

                var textField = new TextField { bindingPath = "name", style = { flexGrow = 1 } };
                root.Add(textField);

                var popupField = new EnumField {bindingPath = "type",  style = {width = 120}};
                root.Add(popupField);

                return root;
            }
        };
        
        bodyElement.Add(listView);

        return bodyElement;
    }
}
```
Site Reliability Engineering

これは [3-shake Advent Calendar 2022](https://qiita.com/advent-calendar/2022/3-shake) 9日目の蝉です。

ポエムです。組織の Advent Calendar ですが、組織としての意見ではありません。

早く SRE って3文字バズワード終息しないかなあ。ずっとモヤモヤしてるんです。

サイトの信頼性ってずーっと昔から大事でした、インフラの人だって開発の人だって運用の人だってみんな信頼性なんてどうでもいいから機能を追加しようぜなんて考えてはいないはず。

SRE チームを作らなければいけないとか、SRE を導入しなきゃいけないとか全然そんなことないと思うんです。みんなで信頼性を上げるための何かをやれば良いと思うんです。やってると思うんです。

SRE として独立して存在すると、SRE としてやったことを評価しなくてはなりませんから指標が必要ですね、SLI です SLO です。これも大事だとは思うんですけどそもそもそんなエラーばっかり出てたら放置はしませんよね。

100% の信頼性っていうのは無理がありますから妥協が必要です、エラーバジェットですね。再現性の無いエラーの調査に無限に時間を使うのは無駄ですね。それより機能追加などでサービスの価値を上げましょう。

可観測性は大事です、もうツールは揃っているのでやりましょう。

信頼性向上のために自動化できるところは自動化しましょう。半自動化からだっていいじゃない。

自動化したらテストもデプロイも簡単になってデプロイ頻度も上がりそうですね。 Four Keys っていう指標があるみたいですよ。

次は DevSecOps ですね。そうそう [Securify](https://www.securify.jp/) っていうサービスがあるんですよ。

これまで通りみんなでサービスをより良くして行きましょう。

「SRE 何それ美味しいの？」
「SRE ひとつください。」
「これって SRE なのかなあ？」

がなくなるといいな。

https://sreake.com/
Symfonyのデバッグツール、"Profiler"

[Symfony Component Advent Calendar 2022](https://qiita.com/advent-calendar/2022/symfony-component)の18日目の記事です。

## 最初に
[Symfony](https://symfony.com)はPHPのフレームワークのひとつです。しかし、公式サイトの説明文には

> Symfony is a set of PHP Components, a Web Application framework, a Philosophy, and a Community — all working together in harmony.
  （SymfonyはPHPコンポーネントのセットで、Webアプリケーションフレームワークで、哲学、そしてコミュニティです。それらがハーモニーを奏でながら動作しています。）

と書かれている通り、PHPコンポーネントのセットで、たくさんのコンポーネントを提供しており、それらを組み合わせてひとつのフレームワークとして動作しています。Symfonyのコンポーネントは、Symfony上だけで動作するのではなく、他のPHPフレームワークやアプリケーションでも動作している強力なものが揃っています。

今回はそれらの中から、役立ちそうなもの・お薦めしたいものを紹介していきたいと思います。

※記事内ではautoloadのインポートは省略します。


## Symfonyのデバッグツール、"Profiler"

[Profiler(もしくはWebProfiler Bundle)](https://symfony.com/doc/current/profiler.html)は、アプリケーションがどのように動いたかを確認するための、デバッグツールです。


### インストール

```shell
composer require symfony/profiler-pack --dev
```

:::note warn
開発専用ツールなので、--devをつけましょう
:::

### 使い方

インストールすると自動で、画面下部にツールバーが表示されます。
![スクショ](https://symfony.com/screenshots/symfony-demo.png)

それぞれをクリックすると、それぞれの内容が表示されます。
![スクショ](https://symfony.com/screenshots/symfony-profiler.png)

ツールバーなどのメニューはインストールされているコンポーネントにより表示が変わります。
例えば`Mailer`がインストールされていれば`E-Mails`が活性化されますし、`ORM`がインストールされていれば`Doctrine`が活性化されます。

また、そのほかにも画面上でAjax通信してアプリケーションにアクセスした場合は、その結果がリアルタイムにサブリクエストとしてツールに追加されたり、Dockerを使ってMailhogなど使っている場合は、Mailhogへのリンクを`docker-compose.yml`の設定を参考に自動的に貼ってくれます。

### テストでProfilerをつかう

そして、機能テストでもこの`Profiler`を使うことができます。
利用するには２通りのやり方があり、１つは設定ファイルで有効化する方法

```yaml:config/packages/web_profiler.yaml
when@test:
    framework:
        profiler: { collect: false, enable: true }
```

もう一つは、`WebTestCase`上で有効にする方法です。

```php:SomeTest.php

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class SomeTest extends WebTestCase
{
    public function test()
    {
        $client = static::createClient();
        $client->enableProfiler(); // テストでProfilerを利用するようにする
    }
}
```

テストでそれぞれの値を取得する場合は、以下のようになります。

```php:SomeTest.php
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class SomeTest extends WebTestCase
{
    public function test()
    {
        $client = static::createClient();
        $client->enableProfiler(); // テストでProfilerを利用するようにする

        $client->request('GET', '/some/path');
        
        $profile = $client->getProfile();

        $profile->getCollector('db')->getQueryCount();
    }
}
```

`getCollector()`で該当のメニューのコレクターを取得し、それぞれのコレクターのメソッドを呼び出すことで、値を確認できます。
上記の例では`ORM`のコレクターの`getQueryCount()`を実行してクエリー実行回数を取得しています。

それぞれのコレクターのメソッドは、インストールしたコンポーネントの`DataCollector`ディレクトリに入っています。

## まとめ

今回は`Profiler`の紹介でした。機能テスト内で使えるのは最近知ったので、メールが送信されたかであったり、イベントが実行されたかなどもテストすることができるようになります。
Ubuntu 22.04 - hostname/domainname設定

## 前提
連日 DNS に悩まされて辛かったので、今日は簡単な内容にする。簡単だけど、どこかで設定しないといけない内容だったので万事OK！

## hostname 設定
恒久的に名前を変更する方法。
```
$ sudo hostnamectl set-hostname dns
```
確認
```
$ hostname -b
dns
```
## domainname 設定
ドメイン名を設定。
```
$ sudo vi /etc/hosts

127.0.0.1 localhost
127.0.1.1 dns.j-fortidemo.com dns
```
確認
```
$ hostname -d
j-fortidemo.com
```
## FQDN 確認
```
$ hostname -f
dns.j-fortidemo.com
```
プログラミング初心者にこそRを使ってほしい

こんにちは、akkerina です。
先月からドワンゴで[N予備校プログラミング](https://www.nnn.ed.nico/pages/programming/)教材制作に携わっています。
今日は、私の推しプログラミング言語、Rについて熱く語ります。

## R って何？
R とは、統計学者が好んで使うプログラミング言語です。
めちゃくちゃ使い勝手がよいのですが、一般にはあまり知られていません。
Web エンジニアからは見向きもされません。悲しい。

本気でウェブページ作りたいなら、がっつり JavaScript を勉強してください。
本気で機械学習やってみたいなら、がっつり Python を勉強してください。
本気で競技プログラミングしたいなら、がっつり C を勉強してください。

でも、手軽にデータ分析・可視化したいのであれば、断然 R をおすすめします！
なぜなら、R は始めやすいプログラミング言語だからです。
教材としてもぜひ使ってほしいです。

## R をおすすめする理由
### 1. セットアップが簡単
R をインストールする。RStudio をインストールする。終わり。
誰がやってもこの手順！

これに対して、某プログラミング言語を始めようとすると、VS Code? PyCharm? Anaconda? Spyder? Jupyter Notebook? 結局何をインストールすればいいの？ってなって、この時点でやめたくなる。

### 2. パッケージのインストールが楽
コンソールから `install.packages()` でインストールできる。
もちろん、GUI からボタンクリックでインストールしてもオッケー。
依存関係のあるパッケージも自動でインストールしてくれる。

conda? pip? コマンドウィンドウ？
ソンナノワカラナクテモダイジョウブ。

### 3. 代入が矢印
R では、たとえば、x に 10 を代入したいとき、 ```x <- 10``` と書きます。
誰がどう見ても代入ですね。

これが他のプログラミング言語だと ```x = 10``` となり、初学者にとっては分かりづらい。

### 4. 添え字が 1 から始まる
これはもう R の勝ちでしょ。
これだけの理由で R を選ぶのもありだと思います。

### 5. 配列の範囲選択の仕方が明白
array という名前の配列に、10, 20, 30, 40, 50 の五つの数字がこの順番で入っていて、二番目から四番目の要素を取り出したいとします。
普通に考えたら ```array[2:4]``` でしょ。これ以外ないっしょ。

余談ですが、某プログラミング言語で、```array[::-1]``` とすると、要素が逆向きになった配列が返ってくる件。
```array[0:4:-1]``` だと空配列が返ってくるのにな。
お前もプログラミング言語の端くれなら一貫性を持ってくれ、と言いたい（端くれじゃなくて大御所だけど）。

### 6. 元からいろんな関数が入っている
パッケージのインストールなしで、```mean()``` や ```sd()``` が使える。
円周率も ```pi``` に入ってる。

ちなみに、英語では、円周率に対応する単語がないらしい。
円周率のことを pi と呼ぶそうです。不便じゃね？

### 7. 要素ごとの計算がシンプルに書ける
秒を分に変換したいときなど、```min <- sec / 60``` とすれば、sec の要素一つ一つを 60 で割ってくれる。

データフレームも元から入ってるよ。
pandas ナンテイラナイヨ。

### 8. 行列の計算ができる
```A %*% B``` で行列の掛け算をしてくれます。
教育現場では重宝するのでは？

と思ったら、高校数学では行列ってやらないの？
お偉いさーん、高校で行列教えたほうががいいよー。
あと、個人的にはインド英語にも慣れさせたほうがいいと思う。

### 9. グラフが最強
基本的なグラフ（散布図、ヒストグラム、箱ひげ図など）なら、パッケージのインストールなしで描ける。
ggplot2 を使えば、きれいなグラフが描ける。
グループごとに色を変えたり、グラフを並べたりも簡単！

### 10. R 推しの人と仲良くなれる
自分の好きな漫画とかキャラがポピュラーじゃなくて、同じくそれを好きな人と出会ったら、盛り上がりますよね。

近い将来、きっと、みんなプログラミングができるようになって、合コンとかで「推しプログラミング言語は何ですか？」なんて質問が飛び交うようになるはずです。
そんなとき、同じ R 推しで恋が芽生えたら最高じゃないですか？

R への投資は未来の幸福への投資です！
（ちなみに R はオープンソースなので、投資にかかるのは時間だけです。）

## R を学ぶデメリット
ただ、R を学ぶことには、いくつかデメリットもあります。

まず、R を使う人が少ないので、チームプロジェクト向きではない。
ゆえに、仕事で使う可能性は極めて低い。

よって、履歴書に書いても素通りされやすい。
Java や Python のほうが間違いなく企業受けする。

しかし、最大のデメリットは、R に慣れてしまうと、他のプログラミング言語がまどろっこしく感じること。

なので、私は、さくっと何かを確認したいときは R、人と共有するコードは他のプログラミング言語、と使い分けています。

## おわりに
R はデータ分析用の言語なので、某プログラミング言語と比べる形になってしまいましたが、某プログラミング言語をディスっているわけではないです。
誰でも手軽に機械学習が使えて便利だと思います。

Java も Python も C も JavaScript も、みんな違ってみんないい。

でも、やっぱり、私にとっての一番は R だなぁ（エモい）。
この記事を読んで、R いいかもって思ってくれた方、ぜひ使ってみてください！

いやいや、やっぱり JavaScript でしょうって思った方、[N予備校](https://www.nnn.ed.nico/pages/programming/)でお待ちしております。
eth.rb を使ってスマートコントラクトの関数を呼び出す

web 3.0 業界は js が多い印象ですが、ruby からも使いたいですね。ここ数年間は、ruby の gem も増えているように見えます。
イーサリアム公式サイトのページに載せている eth.rb を使ってみました。

https://github.com/q9f/eth.rb

## mint するコード

```rb
@key = Eth::Key.new(priv: 'プライベートキー')
@client = Eth::Client.create('イーサリアムの RPC ノードの URL')
@contact = Eth::Contract.from_abi(abi: 'abi の情報', address: 'スマートコントラクトのアドレス', name: 'RBT')
@client.transact_and_wait(@client, 'mint', 'mint 先のアドレス', sender_key: @key)
```

以前 [ethereum.rb](https://github.com/EthWorks/ethereum.rb) を使ったことがありましたが、それほど差が感じられませんでした。

## 改修した箇所
トランザクションの結果を待つ必要があるため、gem に `transact_and_wait` メソッドが用意されています。
ただ、タイムアウトの値が固定になっているため、設定できるようにしています。

https://github.com/q9f/eth.rb/blob/main/lib/eth/client.rb#L389-L403

```rb
module Eth
  class Client
    attr_accessor :wait_timeout

    def wait_for_tx(hash)
      # もとの実装の timtout は 300（５分）、かつ、設定できない
      start_time = Time.now
      timeout = wait_timeout || 300
      retry_rate = 0.1
      loop do
        raise Timeout::Error if ((Time.now - start_time) > timeout)
        return hash if is_mined_tx? hash
        sleep retry_rate
      end
    end
  end
end
```

## まとめ
eth.rb だけではなく、Rails 用の gem もいくつあるので、また使ってみていたいです。
Railsで画像をpublic配下ではなくアセットパイプラインを通して配置する

## 指摘されたこと

RailsとReactで動く画像を表示したかったので、画像を`public/img/`フォルダに置いてこのように書きました。

```react:Hoge.tsx
return (
  <>
    <img src="/img/hoge.jpg" alt="hoge" />
  </>
)
```

すると先輩から下記のように指摘を受けました。無断で転載します。

>画像のパスはRailsから渡したほうがいいと思います。
public配下ではなく、アセットパイプラインを通したやつを渡してください。
動きはするんだけど、もし画像を差し替えるとなったときに、パスが固定だとしばらくブラウザのキャッシュが働いてすぐに切り替わらないので。アセットパイプラインを通すと、ファイル名にランダムな文字列が付いて、画像が変わるたびに別のパスになります。

なんとなく言いたいことはわかるんだけど、「なんとなく」を潰したいので、きちんと咀嚼しながら修正します。

## アセットパイプラインとは？

JS,CSS,画像などのファイルを最小化して連結するためのフレームワーク。

https://railsguides.jp/asset_pipeline.html

Railsガイドでも、アセットパイプラインが推奨されているとのこと。

>以前のRailsでは、すべてのアセットはpublicディレクトリの下のimages、javascripts、stylesheetsなどのサブフォルダに置かれました。アセットパイプライン導入後は、app/assetsディレクトリがアセットの置き場所として推奨されています。
[Railsガイドv7.0 - アセットパイプライン「2 アセットパイプラインの利用方法」](https://railsguides.jp/asset_pipeline.html#%E3%82%A2%E3%82%BB%E3%83%83%E3%83%88%E3%83%91%E3%82%A4%E3%83%97%E3%83%A9%E3%82%A4%E3%83%B3%E3%81%AE%E5%88%A9%E7%94%A8%E6%96%B9%E6%B3%95)

## なぜアセットパイプラインを通すのか

先輩のコメントそのまんまなんですが、パイプラインを通すとアセットにランダムな文字列を生成して割り当てるみたい。
将来、「画像を置き換えたい、だけど同じファイル名で」となった時に、public配下だと、ファイル名が一緒なので、ブラウザがキャッシュに「あ、そのファイルの画像名なら取りに行かなくてもキャッシュで持ってるぜ」となってサーバーに新しい画像を取りに行ってくれない。アセットパイプラインを通すと、名前が同じであっても違うアセットとみなされてファイル名が別になる。それで置き換えたら即時にその変更が反映されるようになるということですね。これ本記事の最後で検証します。百聞は一見に如かず。

## どうやってアセットパイプラインを通したやつを渡すか

画像を`app/assets/images`配下に置きます。
画像のパスを取得するには、Railsのメソッド`image_path`が使えそうでした。

https://railsdoc.com/page/image_path

ビューで下記のように書きます。

```erb:erb
<%= react_component(
  "App",
  props: {
    hogeImage: image_path("hoge.jpg"),
  },
  prerender: false
) %>
```

本課題とは関係ないですが、コントローラなどで画像のパスを取得したい場合は、`view_context.image_path`とすると取得できそうです。これでReactの画面で画像を表示できました。

## 画像のパスはどうなったのか

先輩の指摘「アセットパイプラインを通すと、ファイル名にランダムな文字列が付いて、画像が変わるたびに別のパスになります。」を検証するために、パスがどうなるのか見てみます。HTMLのimgタグのsrcに何が入るのか。

public配下に置いた場合。

```plaintext:public配下
/img/hoge.jpg
```

アセットパイプラインを通した場合。ほほう。画像ファイル名の後にランダムな文字列が入っている！

```plaintext:アセットパイプライン
/assets/hoge-c0d7ed0a339ac8017a3cc703c3bc1353574cc4d5aad524b43046ff35a9cf495c.jpg
```

ブラウザをリロードしてもう一度表示してみる。当然ながらランダムな文字列は変わっていない。

```plaintext:アセットパイプラインでリロード
/assets/hoge-c0d7ed0a339ac8017a3cc703c3bc1353574cc4d5aad524b43046ff35a9cf495c.jpg
```

同じ名前だが中身は違うファイル名で置き替えてみる。文字列が変わった！

```plaintext:アセットパイプライン（画像を置き換える）
/assets/hoge-2e64510ea882790984b0353c7c7b0ca5c31c78af933d5c09070c7d79aad5204c.jpg
```

試しに同じファイル名で中身はさっきのファイルに戻してみる。文字列はさっきのに戻るのか、新しいのが生成されるのか。。。さっきのに戻った！ほほう。

```plaintext:アセットパイプライン（同じファイル名で前の画像に戻す）
/assets/hoge-c0d7ed0a339ac8017a3cc703c3bc1353574cc4d5aad524b43046ff35a9cf495c.jpg
```
EditTextでエンターキーが押されたらSWキーボードを閉じる

```
binding.editText.setOnEditorActionListener { _, actionId, keyEvent ->
    val isPushedEnter = actionId == EditorInfo.IME_ACTION_SEARCH ||
            actionId == EditorInfo.IME_ACTION_NEXT ||
            actionId == EditorInfo.IME_ACTION_DONE ||
                (keyEvent != null && keyEvent.action == KeyEvent.ACTION_DOWN &&
                        keyEvent.keyCode == KeyEvent.KEYCODE_ENTER)
    if (isPushedEnter) {
        // ソフトキーボードを消す
        val imm = requireContext().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        imm.hideSoftInputFromWindow(rootView.windowToken, InputMethodManager.HIDE_NOT_ALWAYS)
        return@setOnEditorActionListener true
    } else {
        return@setOnEditorActionListener false
    }
}
```
【備忘録】業務で実際使用したcurlコマンドメモ②（GET/POST）

# 1.curlコマンドとは
curlコマンドとは、様々な通信プロトコル（手段）でデータの送受信を行うことができるコマンドです。
[curlコマンド・オプション表はこちら](https://qiita.com/matsumotojanai/items/21a7db1fcdec78a0bbaf)

# 2.主なメソッド一覧
|メソッド|説明|
|:---:|:---|
|GET|指定したターゲットをサーバから取り出す|
|HEAD|指定したターゲットに関連するヘッダ情報を取り出す|
|POST|指定したターゲットにサーバ(プログラム)へデータを送る|
|PUT|サーバ内にファイルを書き込む|
|DELETE|サーバ内のファイルを削除する|

curlコマンドでは主に、GETコマンドを何か情報を検索したり取得するために使うために使用し、
登録処理や更新処理などの、書き込みがありリソースが更新される可能性のある処理に対してPOSTメソッドを使用する。

curlの-Xオプションでメソッドを指定することができる。（指定しない場合、デフォルトのGETとしてコマンドは実行される）


# 3.GET/POSTメソッドの使用例
***GETメソッドの例）***
```
curl -I https://www.yahoo.co.jp


HTTP/1.1 200 OK
Server: ATS
Date: Fri, 09 Dec 2022 05:41:38 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 0
Etag: W/"0-2jmj7l5rSw0yVb/vlWAYkK/YBwk"
Vary: Accept-Encoding
X-Vcap-Request-Id: 1cff7ce3-22c7-4de1-4ee0-5171ec43fa47
X-Xss-Protection: 1; mode=block
Age: 0
Connection: keep-alive
```
-Iオプション：HTTPヘッダー（レスポンスヘッダ・一般ヘッダ・エンティティヘッダ）の情報のみを表示

***POSTメソッドの例）***
```
curl -X POST --data -urlencode 'name=花子' -d 'age=25' https://xxxx.net/yyyy
```
送信したいデータが日本語文字列（花子）のため、–data-urlencodeオプションで指定する。
エンコードする必要がないデータを送信する場合は-d(--data)で指定する。
nRF52840 UARTの有効化／無効化の制御

ncs v2.0.0にて、nRF52840dkでuartの有効化／無効化の制御を行ってみた。

NRF_UART0->TASKS＿STOPRX ＝　１；
すれば大幅の節電になるが、残り20uAほどのオフセット電流を消すにはUARTを完全に沈黙させる必要がある。
BLEデバイスでの20uAはかなり大きな電流値なので、放置できない。



```
NRF_UART0->ENABLE = (UART_ENABLE_ENABLE_Disabled << UART_ENABLE_ENABLE_Pos);
k_sleep(K_MSEC(5000));
NRF_UART0->ENABLE = (UART_ENABLE_ENABLE_Enabled << UART_ENABLE_ENABLE_Pos);
```

でいけるかなっと思ったら、戻らなくなる＆300uAくらいまでアヴェレージ電流が跳ね上がることが判明。


```
NRF_UARTE0->ENABLE = (UARTE_ENABLE_ENABLE_Disabled << UARTE_ENABLE_ENABLE_Pos);
k_sleep(K_MSEC(5000));
NRF_UARTE0->ENABLE = (UARTE_ENABLE_ENABLE_Enabled << UARTE_ENABLE_ENABLE_Pos);
```

UARTEにしてみたらちょっと安定、でもしばらくすると上記の症状が再現する。


ソースコードを見直して、TASKS_STARTTX のトリガーポイントなどを整理してみたところ安定した。

１００時間ほど連続運転してみたが不具合は確認できなかった。

レジスタを直接制御するので、排他処理など十分に考慮する必要があるようだ。

以上。
pythonのenumerateのこと（備忘録）

## for文で、数字と要素を出力してみる

~~~python
list_sample = ["おはよう", "こんにちわ", "おやすみ"]

for i in range(len(list_sample)):
    greeting = list_sample[i]
    print(f"{i+1}: {greeting}")

>>> 
1: おはよう
2: こんにちわ
3: おやすみ
~~~

## enumerateを使ってみる
enumerateは遅延評価です。つまり、リスト型のような一度の呼び出しですべて呼び出されるわけではなく、値を要求されたら1個、再度要求されたらまた1個…と要素を評価する。

enumerateを使うと以下のようにコードが簡潔になる。
~~~python
list_sample = ["おはよう", "こんにちわ", "おやすみ"]

for i, greeting in enumerate(list_sample, 1):
    print(f"{i}: {greeting}")

>>>
1: おはよう
2: こんにちわ
3: おやすみ
~~~
## 遅延評価のメリット

例えば、膨大な量のデータを格納したリストを想像する。このリストの要素をすべて一気に呼び出すのと遅延評価で、必要な分だけ呼び出すのはどちらがいいだろうか？
メモリの消費量や実行時間を考えた時、後者の方が圧倒的に優勢だろう。
【Nuxt.js】クライアントサイドのpluginsでエラーを処理する

この記事は [アイスタイル Advent Calendar 2022](https://qiita.com/advent-calendar/2022/istyle) 12日目の記事です。

こんにちは、アイスタイルではフロントエンド周りをちまちま触っているsakaguchiiと申します。2022年はNuxt.jsと戯れることが多く今年もいくつか学びを得ることが出来た年となりました。
そのうちのひとつをご紹介したいと思います。

# 前提
Nuxt.js v2系

# やろうとしたこと
- ルートが変更されたら「Success」というログを表示
- 404ページに遷移したら「Not Found」というログを表示
- クライアントサイドで実行する

## ルートが変更されたら「Success」というログを表示
plugins配下にjsを作成し、app.router.afterEachを使います。ここで記載された処理はルートが変更されたら（＝ページ遷移したら）実行されます。
また、クライアントサイドで実行したいので `{任意}.client.js` という名前でファイルを作成します。
参照：[プラグイン名の規約](https://develop365.gitlab.io/nuxtjs-2.8.X-doc/ja/guide/plugins/#%E3%83%97%E3%83%A9%E3%82%B0%E3%82%A4%E3%83%B3%E5%90%8D%E3%81%AE%E8%A6%8F%E7%B4%84)
```js
export default ({ app }) => {
  app.router.afterEach((to, from) => {
    // ページ遷移したらログを表示
    console.log('Success') 
  })
}
```

## エラーページに遷移したら「Not Found」というログを表示
Nuxt.jsのエラーをキャッチするために`app`内の`nuxt.err.statusCode`を参照します。
```js
export default ({ app }) => {
  app.router.afterEach((to, from) => {
    if(app.nuxt.err.statusCode === 404) { // 判定追加
        // 404ページに遷移したらログを表示
        console.log('Not Found') 
    } else {
        // ページ遷移したらログを表示
        console.log('Success') 
    }
  })
}
```

しかしこの方法では**ステータスコードは取得できません**。
（表示上はエラーページに遷移しているのにapp.nuxt.errの中身は空っぽというへんてこな結果が返ってきました）

これはクライアントサイドのNuxtプラグインではredirectやerrorを使用することが出来ないためです。

参照：[nuxtjs.org-コンテキスト](https://nuxtjs.org/docs/internals-glossary/context/)

上記のドキュメントに記載の通り、`window.onNuxtReady(() => { window.$nuxt.... }) `を使ってこれを回避します。

```js
export default ({ app }) => {
  app.router.afterEach((to, from) => {
    window.onNuxtReady(() => { // 追加
      if(window.$nuxt.nuxt.err.statusCode === 404) {
        // 404ページに遷移したらログを表示
        console.log('Not Found') 
      } else {
        // ページ遷移したらログを表示
        console.log('Success') 
      }
    })
  })
}
```

これで通常遷移したときも、404ページに遷移したときもログを表示することが出来ました。

# おわり
以上になります。まとめてみるとサラッとしたものですが、当初この話を聞いた時は「ステータスコードが取れないならエラーページに遷移するはずがないのに遷移してて…でもステータスコードは取れない？？？？なんで？？？？🤔」と大分混乱していました。
まずはapp.nuxtの状態から確認しようと思いコンテキストのドキュメントをざっと眺めて、たまたま「It's not possible to use redirect or error in client-side Nuxt plugin」の文章を見つけたことで運よく回避することが出来ました。
これが正攻法か不安なところではありますが、期待通り動いてくれたのでとりあえずヨシということで。

ここまで読んでくださりありがとうございました😊

## 参考文献
- [プラグイン名の規約](https://develop365.gitlab.io/nuxtjs-2.8.X-doc/ja/guide/plugins/#%E3%83%97%E3%83%A9%E3%82%B0%E3%82%A4%E3%83%B3%E5%90%8D%E3%81%AE%E8%A6%8F%E7%B4%84)
- [nuxtjs.org-コンテキスト](https://nuxtjs.org/docs/internals-glossary/context/)
GENESISが動作するdocker環境の構築

# はじめに
* [GENESIS](https://www.r-ccs.riken.jp/labs/cbrt/)が動作するdocker環境があまりなかったので作ってみました

# 流れ
1. cudaが動くubuntu20.04のイメージを使用
1. minicondaをインストール
1. pytorchをインストール (任意)
1. openbabelやrdkitなど必要なものをインストール
1. GCCなどのコンパイラのインストール
1. VMDのインストール (workflowの自動化の時に便利だが任意)
1. openMPIをソースからインストール (ソースからじゃないとダメ！）
1. GENESISをインストール

# コード
```Dockerfile
FROM nvidia/cuda:11.3.1-cudnn8-devel-ubuntu20.04

RUN apt-get update --fix-missing && \
    env DEBIAN_FRONTEND=noninteractive apt-get dist-upgrade --autoremove --purge --no-install-recommends -y \
    build-essential \
    bzip2 \
    ca-certificates \
    curl \
    git \
    libcanberra-gtk-module \
    libgtk2.0-0 \
    libx11-6 \
    sudo \
    graphviz \
    vim-nox

# Install miniconda
ENV LANG=C.UTF-8 LC_ALL=C.UTF-8
ENV PATH /opt/conda/bin:$PATH
RUN apt-get install -y wget bzip2 ca-certificates \
    libglib2.0-0 libxext6 libsm6 libxrender1 \
    git mercurial subversion
RUN wget --quiet https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O ~/miniconda.sh && \
    /bin/bash ~/miniconda.sh -b -p /opt/conda && \
    rm ~/miniconda.sh && \
    ln -s /opt/conda/etc/profile.d/conda.sh /etc/profile.d/conda.sh && \
    echo ". /opt/conda/etc/profile.d/conda.sh" >> ~/.bashrc && \
    echo "conda activate base" >> ~/.bashrc

#RUN pip install --upgrade pip

RUN mkdir /app
RUN mkdir /work
ADD . /app
WORKDIR /app

#RUN conda update -n base conda
#RUN conda update --all

# T-Zone
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update -y
RUN apt-get install -y tzdata
ENV TZ=Asia/Tokyo

# Torch / CUDA
RUN conda install pytorch torchvision torchaudio cudatoolkit=11.3 -c pytorch 
RUN nvcc -V
RUN python3 -c "import torch; print(torch.cuda.is_available());"

# Chemistry
RUN conda install -c conda-forge openbabel -y
RUN pip install rdkit_pypi
RUN conda install -c conda-forge pdbfixer


# GCC GFORTRAN LAPACK BLAS
RUN apt-get install -y gcc gfortran
RUN apt-get install -y libgsl0-dev liblapack-dev libatlas-base-dev
RUN apt-get install -y libopenblas-base
RUN apt-get install -y libopenblas-dev



RUN apt-get clean && apt-get purge && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
RUN apt-get install -y sudo

# VMD
WORKDIR /app/src
RUN tar xvzf vmd-1.9.4a57.bin.LINUXAMD64-CUDA102-OptiX650-OSPRay185.opengl.tar.gz
WORKDIR /app/src/vmd-1.9.4a57
RUN ./configure
WORKDIR /app/src/vmd-1.9.4a57/src
RUN make install

# OpenMPI
WORKDIR /app/src
RUN wget https://download.open-mpi.org/release/open-mpi/v4.1/openmpi-4.1.4.tar.bz2
RUN tar xvfj openmpi-4.1.4.tar.bz2
RUN mkdir /opt/openMPI
WORKDIR /app/src/openmpi-4.1.4
RUN ./configure --prefix=/opt/openMPI CC=gcc CXX=g++ F77=gfortran FC=gfortran
RUN make
RUN make install
ENV PATH=/opt/openMPI/bin:$PATH
ENV LD_LIBRARY_PATH=/opt/openMPI/lib:$LD_LIBRARY_PATH
ENV MANPATH=/opt/openMPI/share/man:$MANPATH
RUN export PATH LD_LIBRARY_PATH MANPATH

# GENESIS
WORKDIR /app/src
RUN tar xvfj genesis-2.0.0.tar.bz2
WORKDIR /app/src/genesis-2.0.0
RUN ./configure -enable-single --enable-gpu
RUN make
RUN make install


```
公開鍵技術による認証方式の紹介

公開鍵技術は、web 2.0 でもいろいろ使われていながらも、web 3.0 の基本構成の技術の１つではあります。

## 公開鍵技術とは
公開鍵技術とは、暗号化や電子署名などの情報セキュリティにおいて、パブリックキーとプライベートキーを二つ持つ技術です。
- パブリックキーは公開され誰でも利用できる
- プライベートキーは秘密にされ、キーの持ち主だけが利用できる

特徴の１つは `暗号化と復号化が異なる鍵を使う` ことです。パブリックキーで暗号化した内容は、プライベートキーでしか復号化できません。秘密のメッセージを送信したいケースで例をあげますと、

- 送信者が送信先の `パブリックキー` を使って送信内容を暗号化して送信する
- 受信側は `プライベートキー` を使って復号してメッセージを確認できる

流れになります。この送信内容は公開されても、`プライベートキー` を持たない限りでは復号化できません。

もう1つの特徴としては、`プライベートキー` で署名したデータに対して、`そのパブリックキーでの署名であるかどうかを検証できる` ことです。
例をあげますと

- 検証者は、特定の内容を署名者に送信する
- 署名者は、`プライベートキー` でその内容の署名を生成して返す
- 検証者は、`元の内容` + `署名者のパブリックキー` を使って `署名した内容` は正しいかどうかを検証できる
    - ここでいう `正しい` というのは、 `指定した署名者のプライベートキーで署名した` ということです。

この2番めの特徴は、認証としても使えるので、その流れを説明します

## 公開鍵での認証方式
イーサリアムの場合は、 [web3.eth.accounts.recover](https://web3js.readthedocs.io/en/v1.2.11/web3-eth-accounts.html#recover) 関数を使って、元データと署名を渡せば、その署名で使っているアドレスが返されるので、よりカンタンに検証できます。

```mermaid
sequenceDiagram

participant user as ユーザー
participant ws as Webサイト

user->>ws: ログインリクエスト
ws->>user: 認証用データ（ランダム値が入っている内容）を返す
user->>user: プライベートキーを使って認証用データの署名を生成する
user->>ws: 署名データを送信する
ws->>ws: 認証用データと署名データを使って署名したアドレスを recover する

alt アドレスがログインしようとするアドレスと一致する場合
  ws->>user: ログイン成功
end
alt 一致しない場合
  ws->>user: ログイン失敗
end
```

面白いところは、このフローでは、web サイト側はユーザーのパスワードやプライベートキーなどの秘密情報を一切持っていません。
ユーザーがログインしようとする際、「0xab...f というアカウント（アドレス）です。これでログインしたい」の時、web サイトとして「このユーザーが本当に 0xaa...f のアカウントの持ち主であるかどうか」を検証できればよい。web サイト側が推測不可能な認証用データ（署名する元データ）を用意すれば、後は署名データを使って、本当に 0xaa...f のアドレスで署名したかどうかを検証すれば済みます。

## EIP 4361
まだレビュー中ですが、この仕組を適用する EIP もありました。

https://github.com/ethereum/EIPs/blob/master/EIPS/eip-4361.md

## まとめ
公開鍵技術は、非対称暗号化技術である為、この「非対称性」をうまく使えば、もっと活用できそうですね。
MantineでCSSを理解するためのサイト作った（作ろう）

こちらは金属加工プラットフォームを開発・運用する[Catallaxy](https://catallaxy.me/)の[Catallaxy Advent Calendar 2022](https://qiita.com/advent-calendar/2022/catallaxy)の12/12の記事となります。

## Mantine

React component library、Typescriptベースで、Next.jsにも対応しており、

- 見た目がかわいい
- デフォルトの色が青色ベース

なので使ってみたくなりました。

https://mantine.dev/

クライアント側だけで完結するもので、何か面白そうなものはないかと2分ほど考えました。CSSの使い方で特にflex、すぐに分からなくなって使うたびに調べるなあと思ったので、視覚的にflexの動きを追えるようなサイトでも作るかと思い作ってみました。

## CSS sandbox

https://css-sandbox-liard.vercel.app/

ソース

https://github.com/h64m1/css-sandbox

デモ

![css-sandbox-demo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/187353/07559173-0f2d-cd1d-9ddb-871655662d12.gif)

最大の問題は作ろうと思っていたflexの表示が全然できてないことですが、とりあえず動くものができたのでヨシ！少しずつ作っているので、そのうち出来るかもしれません。

最近見た以下のサイト、まさにこんな感じの見た目を実装したかったというのが出来ているのでおすすめです（宣伝）！

https://www.joshwcomeau.com/css/interactive-guide-to-flexbox/

## 構成

以下の構成で作っています
- Next.js
- Mantine
- pathpida
- Recoil
  - client stateのみで、かつコンポーネントで共有するstateが多いので、使ってみてます
  - 単純に`Context`を使う場合よりも記述量が減って楽な気がする

### Next.js + Mantine

Next.jsベースで必要なMantineの最小限のパッケージをインストール

```bash
yarn create next-app --typescript
or
npx create next-app --typescript
```

```
yarn add @mantine/core @mantine/hooks @mantine/next @emotion/server @emotion/react
or
npm install @mantine/core @mantine/hooks @mantine/next @emotion/server @emotion/react
```

:::note info
以下の公式サイトにNext.js用テンプレートのGitHubへのリンクがあるので、それをcloneして使う方が便利かもしれません。
:::

https://mantine.dev/guides/next/

### Pathpida

また、Next.jsの内部pathを取り扱うために、pathpidaを入れてます。

https://zenn.dev/solufa/articles/renewed-pathpida

例えば、今回のサイトでマージン用ページの内部pathは
```ts
/styles/margin
```

なのですが、pathpidaを使うとpathを文字列ではなくネストしたオブジェクトとして取り出せて、かつそのまま`next/router`に渡せば画面遷移できます。
```ts
import { useRouter } from 'next/router'
import { pagesPath } from 'lib/$path'

...
  router.push(pagesPath.styles.margin.$url())
```

pathpidaをwatch状態にしておけばpathの変更は自動検知してくれるので、内部リンク指定で文字列を使うことなく安全にpathが設定出来るので便利です。

### コンポーネントの配置

![css-sandbox-screenshot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/187353/d0b166af-6cc5-6373-db7d-3a8eeb688d70.png)

Mantineがデフォルトで用意している`AppShell`を使うと、header + navbar (左メニュー) + aside (右メニュー)という構成を用意してくれるので、それをそのまま利用。右メニュー（aside）に表示されたつまみなどを調整すると、真ん中に表示されている図形の位置や形状が変化したり、右ニュー上にあるテキストが変化します。

CSSのmargin値の指定方法が全部で4種類あり、数字3つの場合どこのmargin指定だっけ？というのがすぐに分からなくなるので、

- 視覚的にどこのmarginが変わっているのか？
- 設定値としてどう変わっているのか？

というのが同時に分かるような作りにしてみました。

## Mantineの良いところ

- デフォルトの見た目が良い（2回目）
- デフォルトが青い（2回目）
- コンポーネントが充実してる
- Typescriptサポート
- 基本的なhooksが充実している
  - `use-disclosure`: モーダル開閉制御など
  - `use-debounced-state`: フォームの`onChange`で保存するときなど
  - `use-resize-observer`: コンポーネントのリサイズ検知
  - 他にもたくさん
- 公式のドキュメントが充実している
  - 例もあって、基本的に公式ドキュメントを見ればわかる
  - 各種コンポーネント・カスタムフックドキュメントに、それぞれのソースのリンクがあるのも良い
- 更新が早い
  - 作り始めたときは5.6.3だったけど、今最新は5.9.2（2022/12/8時点）

## まとめ

Mantine使いやすくて良いですね。Flexは気長に実装したいと思います。