OmniAICreator/Qiita-1.07M huggingface dataset:
【Cats Effect3】MonadCancel解説

ライブラリを作成していていい感じに副作用なく非同期でIOを書きたくなったので改めてCatsEffectに入門したがドキュメントだけ見てもよくわからなかったので学習ついでにまとめることにした。
なので少し駆け足でゆるく描きます。

## 対象の読者
+ CatsEffect3のドキュメントが難しいよぉという方。

## MonadCancelとは
Catsの**MonadError**を継承したCatsEffect3で提供される**Unque**と**Clock**を除く全ての型クラスの親となる型クラス。
機能としては名前の通り処理のキャンセルについての機能を提供する。

### MonadErrorとの違い
一言で言うと回復可能かどうか。

```scala
/** MonadErrorはエラーから回復することができる。 */
val error = MonadError[IO,Throwable].raiseError[Int](new Throwable)
error.handleError(_ => 0).map(println)
// 0

/** handleErrorを使用してもキャンセルの状態が帰ってくる */
val canceled = MonadCancel[IO].canceled >> Applicative[IO].pure(1)
canceled.handleError(_ => 0).map(println)
// （出力されない）

/** 回復して値を返すのではなくキャンセル時のUnitを指定する */
canceled.onCancel(x: IO[Unit])
```

MonadCancel[F[_]].cancelはOption.Noneのような状態で、後続の処理は実行されない。
いくつか例：
```scala
IO.canceled     >> IO.println("a") //
IO.println("b") >> IO.canceled     // b

val c = IO.canceled >> IO.pure(10)
c.map(println)                                   //
c.map(println).onCancel(IO.println("canceled!")) // canceled!
```

### uncancelable
では特定の箇所のみキャンセルを許容したい場合はどうするか。というときに**uncancelable**を使う。
```scala
MonadCancel[F[_]].uncancelable { poll => 
    ???
}
```
この**poll**内の境界でのみキャンセルを許容する事が出来る。
例えば
```scala
IO.uncancelable { poll =>
    for {
        _ <- IO.canceled
        _ <- IO.println(1)
        _ <- poll(IO.canceled).onCancel(IO.println("canceled!"))
        _ <- IO.println(2)
    } yield ()
}
// 1
// canceled!
```
となる。
気を付けるべきポイントとしては**onCancel**の定義場所なのだが、
```scala
IO.canceled >> IO.println("hello").onCancel(IO.println("canceled!"))
//
```
と書いても何も表示されない。
というのもCanceledの後続は評価されないのが原因なので、上記の **IO.println("hello")** に対してキャンセル時の処理を定義したい場合は
```scala
(IO.canceled >> IO.println("hello")).onCancel(IO.println("canceled!"))
// canceled!
```
と書く必要がある。

### guarantee
日本語で言うと保証。
onCancel が **try-catch**文で言うところのcatchにあたるのならば、guaranteeはfinallyにあたる。
キャンセルされたかどうかに関係なく処理を実行する。
```scala
IO.canceled.guarantee(IO.println("canceled!")).map(println)
// canceled!
IO.pure(1).guarantee(IO.println("unit!")).map(println)
// unit!
// 1
```
怖いのは処理される順番。guaranteeで定義された処理が先に実行されるので要注意。


## まとめ
CatsEffectではCatsの知識も必要になるのでお勉強が大変。
それとソースにもコメントで説明が書いてあるのでわからない時はソース見るのもいいカモ。

以上、ありがとうございました。

[Twitter](https://twitter.com/AeroSmithBz)    
[GitHub](https://github.com/AsadaGuitar)
若手エンジニアに送る：｢努力｣×｢運｣×｢対応力｣で成果が決まる

昔、資格取得にはまってた時期がありました。
その時期は、とにかく資格に受かるのが楽しかった。社内でも誰も取ってない資格にチャレンジして、受かったりするとちょっとした優越感があったり、勉強する事による情報オタクにもなってる自分がありました。
新卒で入社した会社では資格で毎月の手当がでるので、何より手当が貰えるのも資格取得にハマった理由です。

# 結果を出してる人は努力している
そもそも、資格を沢山取ろうと思った経緯は、自分の価値を客観的に明確にできる手段としたいと思った経緯がありました。
社内でも評判も良く、給与ベースも評価されましたが、それ以上に自分の意見が通るし、結構わがまま放題に仕事ができたのが良かったと思う。
そんな時、同期から、｢いいよなぁー。森川は頭が良いから・・｣と言われてムカつきながらも呆れる毎日。心の中では、｢俺も毎日努力しとんやぁーーー！！｣と思ったりしてました。

# 運がよければ、結果が出るのも事実
運が良ければ、努力をあまりしなくても試験で良い点数を取れる人が沢山いるのも事実です。
運というのは、親ガチャではないですが、遺伝による頭の良い人がいます。当然ながら結果が出やすい。
スポーツも同じ最初からサッカーが上手な人もいます。ただワールドカップに出る様な選手は全員、とんでもない努力をしてると思います。運だけでは結果が出ません。

# ｢努力｣×｢運｣の掛け算が成果に繋がります。
成果が出ない場合は、｢努力｣を増やすか、｢運｣を増やす事により、成果の成功確立を挙げていく必要がる。
結果が出ない人は、努力を増やすしかありません。運が他の人の0.7の人は、2倍努力すれば、他の人よりも結果が出ます。掛け算は嘘つきません。諦めずに努力すれば、結果が出ます。
加えて、努力にも質が関わります。がむしゃらに努力するだけでは非効率です。幸いな事に昨今ではネット上に先人の知恵が溢れています。先人の知恵を借りながら、質の高い努力を心がけましょう。

# もう一つ大事なのが「対応力」
社会人・企業人としてビジネスの世界で生きていくには、更に、｢対応力｣という尺度も必要となります。
ビジネスの世界は、試験ではない。問題・課題に対して、一変通りの答えは存在しない。様々な外的要因や内的要因、利害関係者によって物事が左右されていく。
そのため、当初想定していたストーリから状況を把握しながらも、結果に導くための｢対応力｣が必要となる。
もちろん、ここには、｢努力｣も必要だし、｢運｣も必要となる。｢運｣が強い人であれば、少ない｢努力｣と少ない｢対応力｣で結果を導く事ができるだろう。
世の中は、偶然と偶然と重なりあう事により、結果が左右される。
とはいえ、｢運｣だけに頼っていては、確立が非常に低い物となってしまう。稀にシュートが決まっても、安定したシュートが決まらなくては意味が無い。
対応力は、様々な状況を自分都合にコントロールする力です。ここがビジネスでは大事なスキルとなります。
沢山の｢努力｣を行って準備を行い、様々な局面に対応できる｢対応力｣を持った人こそ、安定した打率の結果が出せるビジネスマンになる事ができる。

# 成果を出すには、｢努力｣、｢運｣、｢対応力｣
結果＝｢努力｣×｢運｣×｢対応力｣という事である。残念ながら運は、あまり磨くことが出来ない。伸ばせるのは、努力と対応力だ。質の高い努力と適切な対応力でビジネスの世界を乗り越えていく必要がある事を意識して仕事をしてみてください。
Agile Japan 2022に参加してきました（ショートレポート）

11/15,16でAgile Japan 2022が開催されました！
オンラインで開催されていたため、仕事をしながらでも聞けると思い、初参加しました
簡単ですがレポート程度に書いておきます

https://2022.agilejapan.jp/

Zoomでの配信がメインなのですが、discordでのショート講演、miroでの参加者同士の書き込みボードなどもあったので結構楽しめました

discordは私は初めて利用したのですが結構楽しいですね

後日Youtubeでの録画配信もあったので、聞けなかった講演も後から聞けたのはとても良かったです。

# 全体テーマと概要
ソーシャルインパクトがメインテーマだったので、社会問題の解決にアジャイルの手法がどのように活用されているか？という内容の講演が多かったように思います
「ソーシャルインパクト〜」というチャットが飛び交っていました😅

そのほか、IT業界では随分アジャイル開発が浸透してきているためか、社会人になった時点からアジャイルに触れているようなアジャイルネイティブな人々も増えてきているのを感じました

# アジャイル開発やってみよう
現在の職場でもビジネス変化は激しい中で、色々な要望か日々くる中で仕事をしている状況なので、
うまくアジャイル開発を利用できないかと思い、いろいろ試しているところです。

:::note info
とりあえずやってみていること
* Jira Softwareでのバックログ作成
* とりあえず2週間単位でスプリントを回しながら、プロダクトオーナーとミーティングを持つ
* テスト駆動開発の実施
* ドメイン駆動設計を導入して、モデリング内容をプロダクトオーナーにも見せながら作成してみる
* CI/CDの仕組み構築
:::

バックログの作成などは最初はGoogleSpreadSheetでやっていましたが、Jira Softwareを使ってみてます
前職ではRedmineも使っていましたが、なんとなくJiraの方がデザインも良くてモチベーション上がりそうです

一人アジャイル組織状態ですが楽しみながら試しているところです😊
とりあえずやってみる、は大事ですね
Nuxtのvuex-persistedstateをSSRで使ってみる

## 自己紹介

初めまして。私は都内でwebエンジニアをしています。

今の会社にインターンとして経て、入社しました。

業務では、Nuxtjs, Golang, Kubernetesを用いて運用保守開発や

最近はPandasを用いてデータ分析など日々苦戦している若輩者です。

vuex-persistedstateを使うにあたり、あまり情報がなかったので、記事にしました。

様々なご意見いただけると励みになりますので、よろしくお願い致します。

## 背景

NuxtのSSRを行うライフサイクルにて`vuex-persistedstate`によるvuexのデータの更新が行えなかったことが今回のつまずき、解決するのにかなり時間を要したので記事にしました。

## 前提

vuexの短所としてリロードをするとstoreのデータが消えてしまうため、`vuex-persistedstate`を用いてcookieに保存していました。
しかし、asyncDataなどのSSRのライフサイクルにおいて、vuexの更新はSPA(CSR)側のcookieに反映されず、
結果としてvuexの更新がなされない問題が生じておりました。
vue-persistedstateに関しては、[こちら](https://github.com/robinvdvleuten/vuex-persistedstate#api)を参考にしてください

## 実装方法（サンプルコード）

色々探してみたところ、こちらの[issue](https://github.com/robinvdvleuten/vuex-persistedstate/issues/130#issuecomment-653723343)で解決されており、[cookie-universal-nuxt](https://github.com/microcipcip/cookie-universal/tree/master/packages/cookie-universal-nuxt#readme
)を使うとSSRでもvuexの更新が行えるとのことでした。

### cookie-universal-nuxtをインストールする

以下のコマンドでcookie-universal-nuxtをインストールしてください

```zsh
# npmの場合こちら
npm i --save cookie-universal-nuxt
# yarnの場合こちら
yarn add cookie-universal
```

#### 設定を追加する

moduleを扱うためにnuxt.config.jsに追加する

```nuxt.config.js
{
  modules: [
    // 追加
    'cookie-universal-nuxt',
 ]
}
```

#### pluginを実装する

moduleに追加すると、勝手に`$cookies`として[inject](https://nuxtjs.org/docs/directory-structure/plugins/#inject-in-root--context)されます。

```nuxt.config.js
{
  plugins: [
    // 追加
    '~/plugins/persistedstate.js'
  ],
}
```

```plugins/persistedstate.js
import createPersistedState from 'vuex-persistedstate';
export default ({store, app}) => {
    // ...
    createPersistedState({
        storage: {
            getItem: (key) => app.$cookies.getAll()[key],
            setItem: (key, value) => app.$cookies.set(key, value, { path: '/', maxAge: 60 * 60 * 24 * 7, secure: true }),//　7日間保持
            removeItem: (key) => app.$cookies.remove(key),
        }
    })(store)
}
```

## 動作の例

以下のようにするとSSR時にもstoreが更新されます。

```pages/mypage.vue
// ログイン必須のページ
<script>
  export default {
    async asyncData({ store }) {
    .....
        if (!store.token) {
            const { data } = await login(this.input);
            this.$store.commit('setToken', data.token);
        }
    .....
    }
  }
</script>
```

こちらの情報が誰かに役立てれば幸いです！

## 参考

- [vuex-persistedstate](https://github.com/robinvdvleuten/vuex-persistedstate#api)について

- [cookie-universal-nuxt](https://github.com/microcipcip/cookie-universal/tree/master/packages/cookie-universal-nuxt#readme)について

- 参考になった[issue](https://github.com/robinvdvleuten/vuex-persistedstate/issues/130#issuecomment-653723343)
PowerToys で画面を整頓したくて知らなかったこと

2020 年からアドベントカレンダー期に毎日何かを投稿するという奇祭に参加する習わしがあり今年もゆるゆる参加してみようと思い書くもの。

[PowerToys のインストール | Microsoft Learn](https://learn.microsoft.com/ja-jp/windows/powertoys/install)

https://learn.microsoft.com/ja-jp/windows/powertoys/fancyzones

を使うようになった。待機させていつでも目線をずらせば気づける状態にする作業が増えたかもしれない。それでも画面はあまり使わない方だと思っている。

[生産性を高めたいなら、マルチディスプレイをやめたほうがいい理由 | ライフハッカー・ジャパン](https://www.lifehacker.jp/article/171010-ditch-the-dual-displays-to-improve-your-focus/)

こういう話もあるらしい。知らなかった :christmas_tree:
辞書ソースのつかっていないカラムの話 その1

## はじめに

[Sudachi](https://github.com/WorksApplications/Sudachi) の辞書ソースにはつかわれていない、あるいは何につかわれているかがあまり説明されていないカラムがいくつかあります。何回かにわけてそういったカラムについて説明していきます。

## 4カラム目の話

今回は4カラム目 (0はじまりで) のお話です。このカラムはユーザー辞書の[ドキュメント](https://github.com/WorksApplications/Sudachi/blob/develop/docs/user_dict.md) には「見出し (解析結果表示用)」と書かれています。0カラム目も見出しですがこちらには TRIE 用と注釈があります。さて、これらはどうちがうのでしょうか。

Sudachi が入力を受け付けるとまず文字正規化がおこなわれます。デフォルトでは半角カナを全角に、アルファベットを小文字に変換したり、`rewrite.def` の内容にしたがって文字列を書き換えたり、「ー」「〜」「〰」の連続を「ー」に正規化したりします。辞書引きはこの正規化後の文字列に対しておこなわれるので、たとえば0カラム目に大文字アルファベットがふくまれるエントリがあると絶対にマッチせず無視されます (ユーザー辞書でどうコスト調整しても出てこないのはだいたいこのパターンです)。

そのためシステム辞書ソースの0カラムはあらかじめ文字正規化がおこなわれたものが入っています。そうすると元の見出しが失われてしまうので正規化前の見出しが4カラム目も入っているわけです。(正規化を辞書ビルド時に実行して、0カラム目と4カラム目を統合して正規化前見出しを入れておくということもかんがえられますが、正規化が内部でおこなわれていると衝突などがおきたときに把握しづらいという理由でこのような状態になっています。)

## 「解析表示用」はうそ?

では4カラム目の情報はどこでつかわれるのでしょうか。じつは解析結果の表示にはつかわれていません。結果表示には入力文字列を切り出して出力しています。`Morpheme.getSurface()`で得られる文字列がそれにあたります。4カラム目の文字列は `WordInfo` という内部で形態素の情報を保持する構造に読み込まれてはいるのですが、それを出力するAPIは用意されていません。

ではなくてもいいかというとそうでもなくて、辞書形を得るときに `Morpheme.getDictionaryForm()` で利用しています (内部では辞書形の `wordId` しか保持していないので)。

## 文字正規化で同一になる語が複数ある場合

アルファベットの大文字、小文字ちがいのように文字正規化後おなじ文字列になる語が複数ある場合 (ABC, AbC, abc など)、どれが出るかは連接と単語コストによりますが、とくに連接IDがおなじ (≒同一品詞) ときは単語コストが最小のエントリが常に出ます。同コストであれば並び順が最初の語が出ます。ラティスが無駄に複雑になって計算量がふえるだけなので、ほかのエントリは削除した方がいいでしょう。分割情報で構成素として参照する場合は連接IDに-1を指定して辞書引きにつかわれないようにできます。

## まとめ

ユーザー辞書をつくるときなどに、0カラム目と4カラム目におなじような項目があってモヤモヤしてた方もおおいとおもいますが、0カラム目には文字正規化後、4カラム目には正規化前の見出し語を入れてください。ただし、正規化後の文字列がおなじで同一品詞の語が複数ある場合はそのうち1つしか出力されないので残りのエントリは削除するのがおすすめです。

ではよい Sudachi life を。
Winter '23 待望のFlow Builderの機能を試してみる ~ In/Not In 演算子編 ~

# Winter '23のFlow Builder新機能について

https://admin.salesforce.com/blog/2022/learn-moar-in-winter-23-with-flow-enhancements?utm_source=trailhead&utm_medium=trailmix&utm_campaign=learn_moar_winter_23&_ga=2.168438753.190521205.1667719829-1546668006.1603647587

- In/Not In演算子
- データテーブル

など今回のアップデートでFlow Builder使用者にとって嬉しいアップデートが多かったのではないでしょうか？

その中でも
最も既存のFlow Builderをリファクタリングできる可能性のある`In/Not In 演算子`について試してみます。

# この記事で詳しく書かないこと

この機能の利用者がFlowを使ったことがあると思いますので詳しく1から作成手順は書きません。

# In/Not In 演算子について

https://help.salesforce.com/s/articleView?id=release-notes.rn_automate_flow_builder_in_notnot_operators.htm&type=5&release=240

## 何が変わるのか？

今までは
取得したレコードコレクションに関連するレコードを複数取得しようと思うと

- レコードコレクションで ループを実行
- ループの中で関連レコードを取得

というステップになっていました
これは SOQLクエリのガバナ制限を超えてしまうためエラーメールで困った人も多かったのではないでしょうか？

もちろん
カスタムでApexを組めば対応できましたが、公式でサポートされそうな機能ではあったので
保守対象のApexが増やすことなくできるようになったのはやはり嬉しいですね！

|アップデート前|アップデート後|
|---|---|
|![スクリーンショット 2022-12-04 4.39.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/0f7cb98b-f518-05a9-f86e-64fe640df9d1.png)|![スクリーンショット 2022-12-04 4.39.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/6cb99ad1-b10e-fb02-c06b-eb632c1d8cf7.png)|

## サポートされる型

以下の型であればコレクションを そのままIn/Not In演算子で使うことができます。

- テキスト
- 数値
- 日付
- 日付/時間
- 通過
- チェックボックス

## サポートされていないもの

レコードコレクションは In/Not In演算子に対応していないため、
レコードを取得し、サポートされている型だけのコレクションに再度入れ直す必要があります。

:::note warn
Winter '23時点ではサポートされていませんが、
今後のアップデートではサポートされる可能性はあります。
:::

- レコードコレクション

# 試してみた

## やったこと

- AccountのAccountSourceがWebのものを取得
- 取得したAccountを元にContactをIn演算子で検索するため
    - テキストのコレクションにAccountのIDを再セット
- AccountのIDのコレクションでContactを取得

### 完成形

今回試しに作った検証用のFlowは [GitHub](https://github.com/takaHAL/sfdx/blob/main/force-app/main/default/flows/getWebContacts.flow-meta.xml)に公開しています。

![取引先ソースがWebの責任者を取得 - V1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/c7d9eed3-857b-2a81-d6d8-ae43b532d7cf.png)

### どうなったか？

Account Id の コレクション変数 `WebAccountIds`（**[0012w000017ipeMAAQ,0012w000017ipeQAAQ]**）で
ContactのAccountIdを対象に検索！

![スクリーンショット 2022-12-04 3.41.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/4cd764ae-a20f-c10d-e7c5-e7fb12e519a7.png)

![スクリーンショット 2022-12-04 4.42.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/23484593-7afd-a589-7e3c-c408248513d8.png)

次に含まれるで IN
次に含まれないで Not In の挙動になります。

https://help.salesforce.com/s/articleView?id=sf.flow_ref_operators_filter.htm&type=5

取得した取引先責任者のAccountId項目のコレクション変数`ContactsAccountIdList`(**[0012w000017ipeMAAQ,0012w000017ipeMAAQ,0012w000017ipeQAAQ,0012w000017ipeQAAQ**)

と比べた際に ContactはAccountに対して多なので複数レコードが取れていますが


**[0012w000017ipeMAAQ,0012w000017ipeQAAQ]** のみ取れているので

問題なくIN演算子を使うことでループでレコード取得することができました

# 最後に

In検索されてリファクタリングが捗りますね！
今回のアップデートでリファクタリングだけではなく、
ApexのFlowアクションで外部システムからID等のリストを取得→取得したID等でレコードをIN検索
のような使い方もできるようになるので非常にいいアップデートだったと思います。

データテーブル等のアップデート内容も見ていこうと思います！
SciPyの微分で振り子をシミュレートする

こんにちは、アドカレ四日目です。

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

## はじめに
PythonにはSciPyという数学処理ができるライブラリがあります。
SciPyではいろいろな種類の高度な数学処理ができます。
今回はSciPyの微分のサンプルとして、振り子をシミュレートしようと思います。

## 振り子のシミュレーション

### 前提

以降のコードは全てGoogle Colaboratoryで実行することを前提としており、ここに書かれた実行結果もまた、Google Colaboratoryで実行した結果です。
Google Colaboratoryはシミュレーションの結果をアニメーションとして再生したいため利用しています。

バージョン等に関しては、全て2022/12/04(記事執筆当時)のデフォルトを使用しています。

### ライブラリのインポート
使用するライブラリをインポートします。
SciPy : シミュレーション時に微分を行う
NumPy : 実際にシミュレーションによって座標を求める
Matplotlib : シミュレーション結果を描画する
```python
import numpy as np
from numpy import sin, cos, pi
from scipy.integrate import odeint
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from matplotlib import rc
from IPython.display import HTML
```

### 定数の定義
ここでは、シミュレーションに使用する定数を定義します。
`DURATION`と`INTERVAL`については、SciPyで微分する際に利用する値で、`INTERVAL`は微分する際の最小の微小時間で、`DURATION`は微分する期間です。
微小時間についての詳しい説明は、[**追加する！！！！！！！**]()で行います
```python
# 重力加速度
G  = 9.8
# 落下開始角度
INIT_RAD = pi/6
# 落下開始速度
INIT_V = 1
# 振り子の長さ
L = 1
# 微分に使う値
DURATION = 10
INTERVAL = 0.05
```

### 振り子の計算
#### 振り子の公式
振り子を計算する公式はラグランジュ力学から

```math
\frac{\delta\theta}{\delta t}=\omega
\\
\frac{\delta\omega}{\delta t}=-\frac{G}{L}\sin{\theta}
```

と微分の式で表せます。
~~Qiitaだと分数の長さが短いのなんで...~~

SciPyで微分をするためには、このまま式を関数にします。
引数の形は`(計算に使用する値, 微小時間)`にします。
```python
def pendulum(state, t):
    theta, omega = state
    dydt = np.zeros_like(state)
    dydt[0] = omega
    dydt[1] = -(G/L)*sin(theta)
    return dydt
```

#### 微分
SciPyで実際に微分をします。
SciPyでの微分の表現は離散的で、細かい値ずつ変数を変えていき、毎回その値を求めることによって微分を計算しています。
微分をするには`odeint`関数を使います。引数は`odeint(微分する式に当たる関数, 関数に使う変数, 微小に変わる値の配列)`です。
微分する式は先ほど定義した`pendulum`です。
関数に使う変数は、今回は`[θ, ω]`としています。
微小時間の配列は、少しずつ値を増加させた配列を使います。今回は、定数で指定したように、0から`DURATION`まで`INTERVAL`ずつ増加する配列を用意します。
```python
# 初期値
state = [INIT_RAD, INIT_V/L]
# 0からDURATIONまでINTERVALずつ増加する
t = np.arange(0.0, DURATION + INTERVAL, INTERVAL)
# 微分実行
solv = odeint(pendulum, state, t)
```

#### 極座標をxy座標に変換
solvは各t秒における角度と速度配列です。
なので、角度theta、大きさLの極座標として、三角関数で直交座標に変換します。
```python
theta = solv[:, 0]
x = L * sin(theta)
y = - L * cos(theta)
```

### 結果を描画
matplotlibを使用して、シミュレーション結果を描画します。
また、アニメーションとして出力します。

```python
fig = plt.figure()
ax = fig.add_subplot(111, aspect='equal', autoscale_on=False, xlim=(-L, L), ylim=(-L, L))
ax.grid()
 
line, = ax.plot([], [], 'ro-', animated = True)

def update(i):
    next_x = [0, x[i]]
    next_y = [0, y[i]]
    line.set_data(next_x, next_y)
    return line,

anim = FuncAnimation(fig, update, frames=np.arange(0, len(t)), interval=INTERVAL*1000, blit=True)

rc('animation', html='jshtml')
anim
```

## まとめ
実行結果
![result](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740492/05c31f62-be1c-400c-b464-5e7056147eb3.gif)
外部関数呼び出し規約を考慮した累積レジスタ割り付け

この記事は
[言語実装 Advent Calendar 2022 - Qiita](https://qiita.com/advent-calendar/2022/lang_dev)
の5日目のために書いた。

[累積レジスタマシンで命令単位JITコンパイラの夢を見る](https://abo-junghichi.hatenablog.jp/entry/2021/11/30/035741)で書いた去年の方法では、AOTコンパイラがJITコンパイラに伝達した情報は、

* 仮想レジスタの優先順位と、
* レジスタに格納される変数が外部関数呼出で破壊されてもいい「破壊変数」なのか、それとも、保存しなければならない「保存変数」か

だけだった。
外部関数で破壊される物理レジスタをcN(clobbered register)(Nは適当につけたレジスタ番号)、保存されるレジスタをsN(saved register)、仮想累積レジスタをVN(Virtual register)(累積レジスタなら、Nは適当ではなく優先順位)とすると、以下の図1のように仮想レジスタに物理レジスタが割り付けられることになる。

図1

    [V0][V1][V2][V3][V4][V5]...
    [s0][s1][s2][c0][c1]

累積レジスタ割付では、仮想レジスタの優先順位が高いほど高性能の記憶装置が割り付けられるというのが、AOTコンパイラに対するJITコンパイラのお約束だ。
なので、外部関数呼出を跨ぐ場合はメモリに保存場所がコンパイルされてしまう物理破壊レジスタは優先順位のやや低い仮想レジスタに割り付けられ、優先順位最高の仮想レジスタには物理保存レジスタが割り付けられる。
一方、変数にレジスタを割り付けるアルゴリズムの多くは、なるべく多くの変数に物理レジスタを割り付けるため、寿命の短い変数に優先度の高い記憶装置を割り付けがちだ。
このため、外部関数呼出により寿命の制限される破壊変数の方が、保存変数より優先順位の高い仮想レジスタを割り付けられがちになる。
つまり、優先順位の高い累積レジスタには破壊変数と物理保存レジスタが割り付けられ、優先度の低い累積レジスタには保存変数と物理破壊レジスタが割り付けられる。
変数と物理レジスタで、破壊・保存のミスマッチが生じるのだ。

これの改善策が11月に見つかった。

まず、累積レジスタ列をふたつ、仮想破壊レジスタの列と仮想保存レジスタの列を用意する。
そして、それぞれの仮想破壊レジスタに変数を格納する度に、その変数より優先度が高くて同時に生存する変数を格納する仮想保存レジスタの、最大レジスタ番号を付記するのだ。
仮想保存レジスタ側にも同様に、仮想破壊レジスタについての情報を付記する。
そしてJITコンパイル時には、図2のように、仮想破壊レジスタ列(図2での[Sn])と仮想保存レジスタ列([Cn])とで向きを反転させ、物理レジスタの数だけ重複させて、物理レジスタと対応させる。

図2

    ...[S5][S4][S3][S2][S1][S0]
    
                   [s0][s2][s3]
           [c1][c0]
           [C0][C1][C2][C3][C4][C5]...

破壊専用・保存専用に累積レジスタ列が別々になっており、変数と物理レジスタとの間での破壊・保存のミスマッチはなくなる。
問題は、破壊・保存のどちらにも使い回せる、物理保存レジスタの割付だ。
ここで変数格納時に付記していた、他方のレジスタ列についての情報が役立つ。
それにより、優先度の高い値を格納している仮想破壊レジスタ・仮想保存レジスタの最大個数をJITコンパイラは決定できる。
例えば、ある仮想破壊レジスタに割り付ける記憶装置を考える時。
優先度の高い仮想破壊レジスタの数は、当該仮想破壊レジスタのレジスタ番号そのものだし。
仮想保存レジスタの方は、付記された最大レジスタ番号になる。
これら、当該仮想レジスタより優先度の高い仮想レジスタの数と、扱える物理レジスタの数とを比べれば、当該仮想レジスタに物理レジスタを割り付けるかメモリで済ますか、JITコンパイラは判断できる。

[レジスタ割り付け - Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%AC%E3%82%B8%E3%82%B9%E3%82%BF%E5%89%B2%E3%82%8A%E4%BB%98%E3%81%91)では、各変数が別の変数と同時生存するか否かを表す二項関係を「干渉グラフ」と呼ぶ。
この干渉グラフは構築だけでも変数の数の二乗の計算量が掛かるので、線形の計算量しか掛けられないJITコンパイラでは扱えないが、処理時間の制限が緩いAOTコンパイラでは扱える。
変数に仮想レジスタを割り付けたあと、変数を仮想レジスタに置き換えて、同じ仮想レジスタを割り付けられた頂点を統合した干渉グラフも、AOTコンパイラで扱える。
なので原理上は、任意の変数や仮想レジスタについて、それより優先度が高くて同時生存し、破壊・保存の別が異なる変数・仮想レジスタの「集合」をAOTコンパイラは扱える。
なのに、その集合の最大レジスタ番号しかJITコンパイラに伝達しないのは、これもJITコンパイラの時間制限のためだ。

取り敢えずの概念実証コードを[GitHub - abo-junghichi/crjit](https://github.com/abo-junghichi/crjit)に上げた。
JITコンパイラまでの道程のスタート地点に過ぎないが、興味のある向きによる追試に役立てば良し。
2022/12/4主にITとかセキュリティの記事

会員管理システムにサイバー攻撃、情報流出の可能性 - 日本栄養士連盟
https://www.security-next.com/141310

改正個人情報保護法施行から半年--消費者の不安や嫌悪感に対応できているか(12/2)
https://japan.zdnet.com/article/35196843/

グーグル、商用スパイウェアを展開する「Heliconia」エクスプロイトに警鐘(12/2)
https://japan.cnet.com/article/35196856/

仮想通貨やNFTの取引に必要な「ウォレット」とは？ 定義と分類、おすすめウォレット6選まで(12/2)
https://seleck.cc/wallet

オンラインチャットアプリを用いたマルウェアの配布を確認――2022年10月 サイバーセキュリティニュース(12/2)
https://news.mynavi.jp/techplus/kikaku/20221202-2527070/

LastPassにセキュリティ侵害--8月のハッキングが原因(12/2)
https://japan.zdnet.com/article/35196854/

リーガルテックとは？注目されている理由や市場規模、サービスを解説(12/2)
https://www.digital-transformation-real.com/blog/what-is-legal-tech

MicrosoftとMozillaがアメリカ諜報機関との関係が報じられたルート認証局「TrustCor」の証明書を信頼しないことを決定(12/2)
https://gigazine.net/news/20221202-mozilla-microsoft-stop-trusting-trustcor/

2023年、ビットコインが再び上昇するためには？(12/2)
https://media.monex.co.jp/articles/-/20863

DeFiプロトコルのAnkr、数百万ドル相当の不正流出が発生(12/2)
https://jp.cointelegraph.com/news/ankr-confirms-exploit-asks-for-immediate-trading-halt

Google Chromeの拡張機能、約半数が個人情報漏洩など高リスクの可能性(12/2)
https://news.mynavi.jp/techplus/article/20221202-2527205/

ウクライナおよびロシアに対するレイヤー7狙うDDoS攻撃が減少(12/2)
https://news.mynavi.jp/techplus/article/20221202-2527207/

インフレが進むアルゼンチンで仮想通貨のデジタルウォレットで自分の持つペソを保護する地元民が増加中(12/2)
https://gigazine.net/news/20221202-argentines-inflation-digital-wallets/

サイバーセキュリティの草の根コミュニティ系勉強会(12/3)
https://qiita.com/sonodam/items/2b3add928a7d1ae0f657

「能動的サイバー防御」行使へ体制整備…政府、安保戦略案を与党に提示(12/2)
https://www.yomiuri.co.jp/politics/20221202-OYT1T50276/

日本も北朝鮮に追加制裁＝ハッカー集団の資産凍結(12/2)
https://www.risktaisaku.com/articles/-/74744
リスクアセスメント

# 問題１
情報資産の価値の評価理由をC、I、Aで組み合わせから選べ。
### C ,I,Aとは？
```情報資産 C I A```で検索。
CIAは「機密性（Confidentiality）」、「完全性（Integrity）」、「可用性（Availability）」の頭文字を略した表記です。
#### 出典 
https://www.secure-iv.co.jp/blog/4985#:~:text=CIA%E3%81%AF%E3%80%8C%E6%A9%9F%E5%AF%86%E6%80%A7%EF%BC%88Confidentiality%EF%BC%89%E3%80%8D%E3%80%81%E3%80%8C%E5%AE%8C%E5%85%A8%E6%80%A7%EF%BC%88Integrity%EF%BC%89%E3%80%8D%E3%80%81%E3%80%8C%E5%8F%AF%E7%94%A8%E6%80%A7%EF%BC%88Availability%EF%BC%89%E3%80%8D%E3%81%AE%E9%A0%AD%E6%96%87%E5%AD%97%E3%82%92%E7%95%A5%E3%81%97%E3%81%9F%E8%A1%A8%E8%A8%98%E3%81%A7%E3%81%99%E3%80%82

### 機密性 Confidentiality　= 機密情報漏洩の原因
```許可した人のみが情報に触れることができる```という意味。
個人情報の流出事故、機密情報の漏洩事故、機密性の侵害の典型的な例。

### 完全性 Integrity　= 改ざんの原因
```情報が本来想定した状態から改ざんされておらず、信頼に足る状態であること```を意味する。
Webサイトの改ざん事件などが典型的な例

### 可用性　Availability = サービス妨害
```情報にアクセスできる人は、いつでもその情報がアクセスできる```という意味。
攻撃対象にアクセスを集中させて過負荷状態に陥らせる。

#### 出典
https://www.sbcr.jp/product/4797388800/


# 問題２
情報資産に対するリスク分析評価の結果、脅威の数を選択肢選べ。
### 結果
わからなかった。何を言っているかわからない。
#### 気づき
問題の前の説明文を読むことで解答できた。
問題の意味がわからなかったら説明文を読むことにしよう。
これは計算問題だった。

# 問題３
セキュリティ事故と対策について対策の選択肢を選べ。
### 気づき
情報が漏洩しないことを心がけて選択肢を選ぶことで正解できた。
問題文を読むべきだったか？
その前の問題で使った内容も使っていた。（本問題解く際は補助的役割）
情報資産を扱う場合は、漏洩、改ざん、サービス妨害を意識することが大事だということがわかった。

# 出典
https://gihyo.jp/book/2022/978-4-297-12377-2
[Unity, Rider, バグ] ファイルを開こうとすると、Riderが新規Windowを開こうとする

# 本記事の概要
エディタの不具合ってたまに起きますが、とにかく無駄なことで生産性が下がるので困りますよね。今回はRiderエディタ中にバグに遭遇し、結構詰まってしまったので簡単に事例を共有したいと思います。


# バグ概要
すでにファイルを開いている状態で、追加でファイルを開こうとするとRiderが新しいWindowを開こうとする
↓こんな挙動
![スクリーンショット 2022-12-04 2.58.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1325527/bfa4d4cb-f591-a1f2-6c00-f17bf77fe08e.png)
ちなみにこれらは結局開かれることはありませんでした。
なおRiderを全て強制終了してファイルを開くと最初の数個は問題なく開かれるのですが、また同様の問題をすぐ繰り返す状態でした。
とても基本的な動作が使えなくなったため、かなり生産性が落ち、仕方なくVSCodeでの作業を余儀なくされました。

# 解決法： リブート！
先輩エンジニアに聞いた解法がドンピシャで

**「Gitのバージョン管理に載ってないもの一旦全部削除してリブートする」**

これで直りました。
てっきりRiderの問題かと思ってフォーラムを見たりしていたのですが、なるほど、まずリブートを考えるべきでした。ついでにエディタ全体の動きも軽快になったような気がします。
リブートでの解決だったのでピンポイントでこれが原因ということはわからないのですが、**何か不具合が起きたときはまずは可能な範囲でリブートする**、これが非常に汎用的で重要なアクションである、ということを今後は意識していきたいと思います。



# 補足
- 不具合があるとき、Riderからメモリが足りませんと言われた
maximum heap sizeがどうこう、ということが表示されていました。これを拡張しても問題は解決しなかったのですが、一応こういうことも併せて起きる事例であった、ということの共有として書いておきます。
HTTPのリクエスト/レスポンスが何を行っているのか深掘りしてみる。

## 執筆の背景

先輩エンジニアと職場で雑談している際に、
`「リクエストレスポンスの処理を詳しく教えて？」`
と不意打ちで質問されたのですが、あまりいい感じで説明できなかったため少し深掘りしてみました。

ということで、リクエスト - レスポンスに関して解像度を上げて、ブラウザから送られたHTTPリクエストが最終的にどのようにレンダリングされるのかを詳しく見ていきます。

※あくまでwebブラウザ-webサーバーの通信を前提としています。

## リクエスト - レスポンスの全体像

webのアーキテクチャには、クライアント/サーバモデルが採用されています。
そのため、webアプリケーションはクライアントがリクエストを送信し、サーバーがレスポンスを返却するという仕組みによって成り立っていますが、より具体的に見ると以下のような処理が行われています。

- クライアント（Webブラウザ）からのリクエスト送信
- DNSによる名前解決
- webサーバーのリクエスト受信、内部スクリプトの実行とレスポンスの返却。
- webブラウザがHTTPレスポンスを受け取り、レンダリングエンジンが解釈したドキュメントをブラウザ上に表示する

※他にももっと色々やってますが、大きな粒度でこんな感じかと。

それぞれの内容について少し詳しく見ていきます。

### クライアント（Webブラウザ）からのリクエスト送信

webブラウザから以下のようなタイミングで、webサーバーに対してHTTPリクエストが送信されます。

- ブラウザのアドレスバーに何らかのURIを入力した際
- webページ上のリンクをクリックした際
- フォームで何らかの値を入力し、submitした際

...など。

ブラウザから送信されるHTTPリクエストには、以下のような内容が含まれます。

```
- HTTPリクエスト行
    - 使用するHTTPメソッド、送信先のホスト、HTTPのバージョン情報
- リクエストヘッダ
    - メディアタイプ
    - 文字エンコーディングの方式
    - 使用する言語
    - その他メタ情報
- リクエストボディ
    - POSTメソッド等で何らかの処理を要求する際に、パラメータを含める
```

参考：

https://developer.mozilla.org/ja/docs/Glossary/Request_header

### DNSによる名前解決

クライアントの端末が、リクエストを送信したいコンピュータ（webサーバー）を特定するために、DNSサーバーに対して問い合わせを行い、DNSサーバーがドメイン名とIPアドレスの突き合わせを行います。

DNSサーバーからIPアドレスを取得する事ができたら、クライアントはリクエストの正しい送信先アドレスを把握する事ができます。

参考：

https://www.idcf.jp/rentalserver/user-support/knowledge/domain/dns.html

名前解決が行われた後は、クライアントとサーバーの間でコネクションを確立する必要があります。

HTTP（s）通信を行う事が決定しているため、クライアントは目的のサーバーの80（443）番ポートへのTCP接続を行います。

### webサーバーのリクエスト受信、内部スクリプトの実行とレスポンスの返却。

webサーバーが、クライアントから送信されたリクエストを解釈し、指定された処理を実行します。

私は業務でRailsを使っているためRailsの例で言うと、リクエストを解釈し、ルーティングによって指定されたコントローラが、DBへの問い合わせや出力する文字列のエスケープ等を行うアクションを実行し、最終的に出力されたHTML（もしくはjson等）のレスポンスをクライアントへ返却します。

参考：

https://qiita.com/shuntaro_tamura/items/ae55b99deb9e2a170754#http%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E3%81%AE%E6%AD%A3%E4%BD%93

HTTPレスポンスには、以下のような情報が含まれます。

```
- ステータスライン
    - HTTPのバージョン情報、ステータスコード、ステータスメッセージ
- レスポンスヘッダ
    - リクエストヘッダと同じような情報
- レスポンスボディ
    - POSTメソッド等で何らかの処理を要求する際に、パラメータを含める
```

### クライアントがHTTPレスポンスを受け取り、レンダリングエンジンが解釈したドキュメントをブラウザ上に表示する

クライアントがHTTPレスポンスを受け取ると、最終的な画面描画を行うために、レンダリングエンジンがHTML、CSS、JavaScript等の解釈を行い、DOMを構築して画面描画を行います。

外部のリソース等も必要に応じてこのタイミングで取得（HTTPリクエスト）が行われ、最終的にクライアントの端末でフォーマットされたHTMLドキュメントを閲覧する事ができます。

レンダリングエンジンの動作に関する細かい話は、ググれば無限に情報が出てくるかと思うので、ここはお茶を濁してMDNの短いドキュメントを添付させていただきます。

https://developer.mozilla.org/ja/docs/Glossary/Rendering_engine

## 補足

ちなみに、レンダリングエンジンがレスポンスを解釈してDOMを返すというのはブラウザの話で、ネイティブアプリ等がどのように描画を行なっているのかはちょっと分からないです。

また、キャッシュが使用されている場合も、上記とは処理の流れが異なります。

### おしまい

ざっくりですが、リクエスト - レスポンスの間で、どのような処理が行われているのかを少し深掘りしてみました。

これだけたくさんの処理を、1秒にも満たない時間で行っているというのが脅威的ですね。
本当に凄い技術だなと思います。

各動作を細かく見るとまだまだ奥が深いですが、ひとまず一般的なwebアプリケーションの作成において最低限このくらいの理解度は必要なんではないかというところまでをまとめました。

補足などあればコメントお願いします。
Podcastで学びをアウトプットする習慣をつくった話

### こんな人におすすめの記事
:::note info
- 本から学ぶ効率を高めたい人
- 自分の考えを整理して誰かに伝える技術を磨きたい人
- Podcastが好きな人、興味がある人　　　
:::

--- 

### はじめに

私は読書が好きで、常に何かしらの本を読みかけになっている。
そんな私は、読書に関していくつかの課題を感じていた。   


### 私が読書に関して感じていた課題
:::note warn
- [ ] 本を読んで学んだ内容をアウトプットする場がなかったこと
- [ ] 買ったのに読まないでおいたままになってしまったり、途中で読まなくなってしまったりすること
- [ ] 本を読みながら考えた自分の意見をしっかり整理せずに、ふわっとした理解のままで終わってしまうこと   
:::
私と同じ課題を感じている人には、ぜひこの後の記事も読んで頂きたい。


### Podcastを利用した解決策

2022年、友人と2人でPodcastを始めた。
このPodcastは、**２人で決めた本を収録日までにそれぞれ読み**、気になったところ、良いと思った箇所、著者と考えが一致した／しなかった部分、そして**自分が何を考えたかを整理して**おいて、収録日にお互いの考えを共有しあって、好きに語り合うというものだ。
そうして語り合った内容を、番組としてSpotify, Apple Podcasts, Google Podcasts, Amazon Musicなどのプラットフォームに投稿している。


### 効果

感覚的だが、効果を感じている。
具体的には、上記の「私が読書に関して感じていた課題」に挙げた３つをクリアできている。

:::note warn
- [x] ~~本を読んで学んだ内容をアウトプットする場がなかったこと~~ **Clear!**
- [x] ~~買ったのに読まないでおいたままになってしまったり、途中で読まなくなってしまったりすること~~ **Clear!**
- [x] ~~本を読みながら考えた自分の意見をしっかり整理せずに、ふわっとした理解のままで終わってしまうこと~~ **Clear!**  
:::

まず、「本を読んで学んだ内容をアウトプットする場がなかったこと」は、単純にアウトプットの場を作れたのでクリアできた。

次に、「買ったのに読まないでおいたままになってしまったり、途中で読まなくなってしまったりすること」は、他の誰かを巻き込んだマイルストーンの力によってクリアできた。友人と「XX日の収録日までに、この本を読んできて、語り合おう」と約束する。こうすることで、どんなに忙しくても時間を見つけて読み進めるし、準備を行う。やることの優先順位が上がるといった感覚だ。

最後に、「本を読みながら考えた自分の意見をしっかり整理せずに、ふわっとした理解のままで終わってしまうこと」は、語り合った内容をコンテンツとして公開するために、自分の考えを少しでもわかりやすく伝えたいと考えることでクリアできた。我々のPodcastは、編集が手間なので、ほぼ一発録りだ。そうなると、うまく話すために、本番で収録しながら考えるより、事前に整理しておこうかな、となる。準備時間も限られているので、アウトプットを意識した思考の整理を行うことができるのも良い点だ。



### Podcastをお薦めしてみる
というわけで、私と同じ課題を感じている方は、ぜひアウトプットの場としてPodcastを始めてみることをお勧めする。
※もし、我々とコラボしてくださる方がいれば、コメントでご連絡いただければ幸いです。
javascript プロゲート つまづいた所

# 変数の上書き
```let```をつけない

# 定数と変数の違い
定数は値を更新することはできません。
```const```

# if文の注意点
* 最後に```；```は不要
* インデントをつけて見やすくする。

# switch文の注意点
* 最後にセミコロンが不要
* ```breakがない```と、合致したcaseの処理を行った後、```その次のcaseの処理も実行```してしまいます。

# while文の注意点
* 最後にセミコロンが不要
* 条件式がtrueの間、{ }内の処理を繰り返す
* 変数```let```を書き忘れない。

```js
while(number <= 100) {
  console.log(number);
  number += number;
}
```
２乗の数になった。

# 厳密等価演算子と等価演算子
厳密演算子は ```===```
等価演算子は ```==```

# メソッドの注意点
* ```return```を書かなければならない。
ファイルを送信する

# NoMethodError in *******Controller#******
undefined method `original_filename' for "******.png":String


```html
<form method="post" enctype="multipart/form-data">
  <div>
    <label for="profile_pic">Choose file to upload</label>
    <input type="file" id="profile_pic" name="profile_pic"
          accept=".jpg, .jpeg, .png">
  </div>
  <div>
    <button>Submit</button>
  </div>
</form>
```
### 出典
https://developer.mozilla.org/ja/docs/Web/HTML/Attributes/accept#:~:text=%E3%81%BF%E3%81%BE%E3%81%97%E3%82%87%E3%81%86%E3%80%82-,%3Cform%20method%3D%22post%22%20enctype%3D%22multipart/form%2Ddata%22%3E,-%3Cdiv%3E

# 真似してみた。
成功。(一応)

```enctype="multipart/form-data"```で検索してみた。
以下のサイトでも同じやり方でファイルを送信していた。

https://mugenup-tech.hatenadiary.com/entry/2014/08/28/100910#:~:text=multipart/form%2Ddata%3A%20%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E9%80%81%E3%82%8B%E3%81%8A%E3%81%BE%E3%81%98%E3%81%AA%E3%81%84
山小屋物語その後と技術者にお勧め？の本

# はじめに
早いものでもう12月、Advent Calendarのシーズンになってしまっています。
![IMG_7407.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92380/80b739f0-05b6-86fb-2464-fba27d4abe88.jpeg)
山小屋にもささやかな飾り付けが・・・

今年（2022年）は、社内転職でハードウェア製品を主に取り扱う部署から離れ、ソフトウェアの販売を手がける部署に異動しての激動の一年。というわけで、今までよりさらに技術とは遠い場所に来てしまい、このAdvent　Calendarエントリを見渡しても、違和感は半端ないモノがありますが、気後れせず書きますね。

# 山小屋二重生活
山小屋との行ったり来たりの2重生活も早1年と9ヶ月、思えば2年前に在宅勤務の行き詰まりからワーケーションの場所を求めてさまよい伊豆、さらに熱海に第2の拠点の的を絞り始めたのがちょうど2020年12月ぐらいでしょう。
それから（格安）物件を見定めて、現地調査を繰り返し、購入したのが2021年3月、それから（お金をかけずに）内装を自分たちの好みのちょっと今風スタイルに家族ぐるみでリノベ、それでもインターネットがつながるまでさらに6花月かかって最終的に仕事場（アトリエと呼んでいますが）として使えるようになったのがちょうど今から1年前の今頃でした。

![IMG_7411.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92380/4ddf749d-90b2-ea02-dbf2-9659b9dceb98.jpeg)
今の仕事場です。

でも本日はその話をしようと思ったのではなく、最近読んだ本で、「おっ」と思ったネタをいくつかご紹介しようと。

# まず1つめは
「決定版 脳の右側で描け」
https://amzn.asia/d/45LPKAP
エンジニアというのはともすれば左脳を酷使する仕事、否、左脳に酷使されて疲弊してしまっているのでは？というのが前回（1年前ですが）のAdvent Calendarのネタでご紹介した「THE　MASTER　AND　HIS　EMMISSARY」という本でした。左脳は論理脳ともいわれそもそもモノを突き詰めることを得意としていますから、ともすれば暴走してバランスが悪くなる、つまり本来主人であったはずの右脳の出番がなくなり、番頭に母屋を乗っ取られるということが起きかねないわけですが、「じゃあどうしたらいいんだ〜」というというに答えてくれた一つがこちらです。
絵や写真を逆さにして写生する！です。他にもいろいろ書いてあると思いますが、私はまずこれにはまりました。左脳モード（L-Modeと呼んでます）を右脳モード（R-Mode）にスイッチするには、瞑想、アルコール、ドラッグ、断食、筋トレ（これは書いてなかったですが私の主観ではこれも）などがありますが、実際にやってみるとすーっと不思議なくらい自然に「ゾーンに入った状態」になりました。（個人の感想です。笑）
（ちなみに上の写真の窓辺に最近書いた習作が写っております）

![IMG_7413.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92380/78c67c9e-84fb-e889-988e-507477ef5dd5.jpeg)
最初に（上下さかさまにして）書いた結果も悪くないのでトイレに飾りました。

# 次におすすめなのは
「iberalism and Its Discontents」
https://amzn.asia/d/9fNRkRu
Francis Fukuyama
これも左脳に支配されることの悪い例だと思いますが、なぜ自由主義（Liberalism）は人々を満足させることができないのか？という素朴な疑問にある程度答えてくれるよい本だと思いました。トランプ主義とか習近平政権のもとAutocraticな国家がニュースを賑わす中、本来Fukuyamaさん自身「歴史の終焉」とまで言った自由主義陣営の勝利は遠い過去で今やまったくバラバラな感がありますが、その理由をわかりやすく説明してくれていると思います。日本語訳はまだ出ていないようですが、ハードカバーで192ページとそれほど長くもなく、Fukuyamaさんの以前の著述に顕著な百科事典のような網羅的ですがちょっと冗長で論文チックなところも、いい意味なりを潜めているきがします。お年を召して角が取れた感じでしょうか（失礼）
日本人は自由民主主義とつなげて1つと考えがちですが、本来別物であるという視点でみると今の世界情勢も多少わかりやすく整理される気がしました。

# 最後
「ジャンクDNA―ヒトゲノムの98%はガラクタなのか?」
Nessa Carey
https://amzn.asia/d/3Xb0zKj
これは左脳には関係ないです。人のDNAが30億文字（1文字は4つのレターからなる）で構成されていて、2001年にSquencingが完了（データとしてAGCTという4種類の塩基配列が判明）したときには「これで生命の神秘が解き明かされた！」と騒がれたものでしたが、それは全くの早とちりで、まだ入り口にも立てていなかったと言うこと、それが98％はガラクタにしか見えなかった理由である、というのが本書のスタートポイントです。かろうじて読めた2％は24種類のタンパク質がコーディングされていた部分を見つけたということですね。3,054,815,472文字というのは3Tのディスクがあれば圧縮しなくてもほぼ入ってしまうので昨今の情報量からすればたいしたことはないと思うのですが、逆に基本的に栄養分とか水分の部材以外はDNAの設計図しかない1細胞から始まって、60兆の細胞からなる人の体を作るのに必要な情報がこれだけって、どういうこと？。想像ですが、Pythonで書かれたプログラムをHEXのダンプファイルとしてみて、「何じゃこりゃ？あっ、でもここはASCIIかな？」って感じですかね？アルゴリズムだけでなく、時間の経過とともに外部からの刺激に反応してそれぞれが目になったり手足になったり、胃袋になって、さらには脳というさらに訳のわからないモノまで作ってしまう仕組みが入っているのだから残り98％がJUNK＝ガラクタな訳ないですよね。
ここ20年で分子生物学や進化生物学が飛躍的に進歩し、我々はモデナだのファイザーだのその恩恵にあずかっているわけですが、その一線で活躍する（真の）ライフハッカーたちの物語として読んでも面白いのではないでしょうか？

# というわけで
私は来週4回目ワクチンに行ってきまーす！
（お後がよろしいようで）
ファイルを削除する、存在を確かめる

# ファイルを削除する
```削除したファイルの数```を返します。
削除に失敗した場合は```例外 Errno::EXXX が発生```します。
```rb
File.delete("ファイル名")   # => 1
```

# ファイルの存在を確かめる
```rb
File.exist?("ファイル名")  # => true
```

# 感想
Fileクラスのメソッドを使うことができて嬉しい。
これからも頑張る。

# 出典
https://docs.ruby-lang.org/ja/latest/method/File/s/delete.html
ファイアウォール

# 問題１
### 被害１
Webサーバへの不正侵入があったことが確認された。秘密鍵への不正アクセスがあったかは確認できなかった。

### 不正侵入とは？
システムが抱える脆弱性や設定不備などを狙い、```正規のアクセス権がないにも関わらず、社内ネットワークあるいはコンピューターに入り込む```ことを指します。

不正侵入を防ぐ対策は、```侵入の対象や手口によって少しずつ違います```。

#### 不正侵入への対処が必要な理由
家という安全なスペースでさえも侵入される可能性がある。
侵入された場合貴重なものが金庫に隠されていないと簡単に盗られてしまうから。
なので外も中もセキュリティしっかりしておくことが重要。

### Webサーバ
Webサーバやメールサーバなどの外部へ公開するサーバーを設置します。これらのサーバーは、一定の保護の下、インターネットのユーザーからのアクセスを受け付けます。

#### 出典
https://www.sbcr.jp/product/4797386677/

#### 気づき
正規のユーザーと勘違いしたからなのか？
だったら新たな秘密鍵と公開鍵を生成した方がいいのかな？
い

# 問題２
FWを経由し、Webサーバに不正侵入され、さらにそこからDBサーバに不正侵入された。

### Telnetとは？
SSHが普及する前に利用されていた```旧来のリモートログインのためのプロトコル```。
```今ではリモートログインするためにTelnetが使われることはほとんどありません```。

https://www.sbcr.jp/product/4797388800/
### Telnetが使われなくなった理由
```安全性が低い```から。
* データの内容を```暗号化せず、 平文```で送受信するため。なので通信内容を```窃取される危険性```がある。

* 通信データを暗号化することも可能だが、安全性の高い```SSH``が普及されているためのメリットがない。

https://www.sbcr.jp/product/4797388800/

#### 気づき
選択肢は絞られた```SSH```のポートを開放しておくかどうかで正解する。

### ポートとは？
```インターネット通信プロトコル(TCP/UDP）用の通信送受信口```
通信プロトコルにおける窓口のようなもの。

### SSHとは？
```Secure Shell```の略。
```安全なリモートログインを実現```するために用いられる技術。
```「鍵交換」、「ホスト確認」、「ユーザー認証」、「通信データの暗号化」```の4つのフェーズを実現するプロトコル。
##### SSHの認証方法
２種類ある。
* パスワード認証
    `リモードログイン時のユーザー認証に、```パスワード利用```する方法
* 公開鍵認証
    ```秘密鍵を持っている人しかログイン```できないため、パスワード認証よりも安全性が高い
# 気づき
SSHがあってもいいのかな

### 解説
問題文８に「現在はリモートメンテナンスの必要性がなくなっている」と記述がある。
なので
SSHもTelnetのポートも閉じておく必要がある。

# 問題３
一部の会員については会員情報が漏洩したことがわかっているが、それ以外の会員については漏洩の有無を特定できていない。

# 気づき
一応全員のパスワードを変えた方が良さそう。

# 出典
https://gihyo.jp/book/2022/978-4-297-12377-2
[Android][ADB] adb devices unauthorized の修正法



# 概要

Android 実機をmacに繋ぎ 実機debugしようとしたが
adb に認識されない ( 以下

```
$ adb devices
List of devices attached
R58NC0HZ64J	unauthorized
```

# 原因

一般にAndroid実機に繋ぐと `USB接続を許可しますか` dialogが出る
が
(なんらかの理由で) 今回はそれが出てない

# 解決法

とりあえず以下をやってみる:

```
rm ~/.android/adbkey
adb kill-server
adb start-server
```

でUSB繋ぎ直してみる...

->
Android実機のSettings -> developer options

で `allow USB debug` を許可済み 確認をし
`Revoke USB debugging authorization`
でrevoke もしてみる


それでもだめなら
`Developer options` 自体をoff
にする

私(今回)の場合、
onにしたところ再度許諾のdialog が出たため
authorized された


# 参考

https://crieit.net/posts/adb-device-unauthorized
React 画面から入力できるHTMLタグに制限をかける

画面上のテキストエリアにユーザーがHTML文字列を入力する仕様だが
scriptタグなどはXSSリスクがあるので入力できないようにする方法を書きます

## 実装方法
ポイントは入力されたHTML文字列をstringのままチェックするのではなく、
HTMLElementとしてチェックするところです
そのためテキストエリアの下に入力した文字列をHTMLとして描画し、その要素を取得してタグのチェックを行います


文字列のHTML描画は`npm install interweave` でhtmlを安全に描画できるライブラリをインストールします

```tsx
import { Interweave } from "interweave";
import React, { useState } from "react";

// 入力可能なhtmlタグ
const allowedTags = ["p", "span", "div"];

const HtmlInput = () => {
    /** 入力内容 */
    const [text, setText] = useState("");
    /** チェック結果メッセージ */
    const [checkResult, setCheckResult] = useState("");
    /**
     * htmlタグチェック
     */
    const checkTags = () => {
        // interweaveでhtml描画している箇所のhtmlElementを取得する
        // children[0]にはinterweaveにより追加されたspanが入ってくるので、更にその子要素が入力内容のhtmlとなる
        const elements = document.getElementById("checkArea")?.children[0].children;
        for (let i=0; i < elements!.length; i++){
            // tagNameで取得したタグ名は大文字なので小文字化する
            if (!allowedTags.includes(elements?.item(i)?.tagName!.toLowerCase()!)){
                setCheckResult("チェックNG");
                return false;
            }
        }
        setCheckResult("チェックOK");
    }


    return (
        <div>
            <textarea value={text} 
            onChange={event => setText(event.target.value)}
            onBlur={checkTags}>
            </textarea>
            <div id="checkArea" className="hidden">
                <Interweave content={text}/>
            </div>
            <div>
            {checkResult}
            </div>
        </div>
    )
}
export default HtmlInput;
```

入力を許可しているpタグを入力後、フォーカスアウトするとチェックOKと表示されます
![スクリーンショット 2022-12-04 2.12.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530205/3d536b72-f845-62a3-c4a9-db15ec0d3f2b.png)

今度はpタグの下に許可されていないh1タグを追加するとチェックNGと表示されます
![スクリーンショット 2022-12-04 2.13.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530205/3bc7d6e7-620c-1bbe-e743-688c406066be.png)
Google Kubernetes EngineのWorkload Identityとは

既存のGoogle Kubernetes Engine（GKE）クラスターにWorkload Identityを導入する機会がありましたので、Workload Identityについて軽く紹介しようと思います。

# Workload Identityとは

[ドキュメント](https://cloud.google.com/kubernetes-engine/docs/concepts/workload-identity)にありますように：

> Workload Identity allows a Kubernetes service account in your GKE cluster to act as an IAM service account. 

Workload Identityを使えばGKEクラスター内のservice accountをGCPのIAM service accountに紐づけることができます。要するに、GKEで動いているアプリケーションがGoogle Cloud APIsに認証するための仕組みだということが分かります。

# Workload Identityが有効になっていない場合は

AutopilotモードではWorkload Identityがデフォルトになっていますが、Standardモードの場合、現時点ではまだデフォルトではありませんので、その場合Goocle Cloud APIsをアクセスするには以下のいずれかの仕組みを利用する必要があります：

- IAM service accountのkeyを発行して、secretとしてクラスターで持っておく
- Nodeに紐づけられているIAM service accountを利用する。こちらの場合、設定を変更しない限りCompute Engine default service accountが使われる

![no_workload_identity.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509832/4180732a-3ce5-e35a-9dcb-05690cbc8d6a.png)

# Workload Identityでどう変わるのか

Workload Identityを使う場合、事前にKubernetes service accountとIAM service accountの紐づけをしておく必要があります。そして、PodにそのKubernetes service accountを指定した場合、Google Cloud APIsをアクセスする際に該当のIAM service accountが使われるようになります。

この仕組みを使うことでもっと細かい権限の設定ができ、他の仕組みの以下の問題を解決することができます。

- IAM service accountのkeyを使った場合の漏洩のリスク、そしてkeyのローテーションの必要性がなくなります
- NodeのIAM service accountを利用する場合は、そのnodeで実行されている全てのアプリケーションが同じservice accountを共有することになりますので、権限を多く与えすぎてしまうという懸念があります。ですが、Workload Identityの場合、各アプリケーションに必要最低限の権限が付与できるようになります

![with_workload_identity.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509832/e7fd3fd0-68c4-24fd-b875-03724783218e.png)

# 導入の流れ

手順は[ドキュメント](https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity)でご確認いただけますが、大まかな流れとしては以下になります。

1. クラスターでWorkload Identityの有効化
1. Workload Identityが有効なnode poolの作成
1. Kubernetes service account、IAM service accountの作成、そして紐付け
1. アプリケーションのDeploymentなどのPod specでKubernetes service accountの指定：

```yaml
spec:
  serviceAccountName: KSA_NAME
  nodeSelector:
    iam.gke.io/gke-metadata-server-enabled: "true"
```

こちらの変更を適応することで、PodはWorkload Identityが有効なnodeに立ち上げられることになります。

# まとめ

GKEクラスターからのGoogle Cloud APIsへのアクセスにあたって、Workload Identityは以前存在していた問題を色々解決してくれますので、GCPに推奨され将来的にStandardモードでもデフォルトで有効になるとされています。

現在、利用したい機能によってはクラスターでWorkload Identityが有効であることが必要条件になっている場合があります。例：Backup for GKE。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509832/001c0812-4f17-28c9-9b50-c8727aad8db3.png)

# 参考

- https://cloud.google.com/kubernetes-engine/docs/concepts/workload-identity
- https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity
新しいMacでSSHしたら"no matching host key type found."と怒られた

Macを新しくして、ロリポップにsshしようとしたらエラーで怒られた。

```
% ssh -p xx22 xxxxxxxxxxx@ssh.lolipop.jp
Unable to negotiate with 133.130.xxx.xxx port 2222: no matching host key type found. Their offer: ssh-rsa,ssh-dss
```

```
% ssh -V                                      

OpenSSH_9.0p1, LibreSSL 3.3.6
```

新しいバージョンだと、脆弱性のある暗号化方式は使えなくなったみたい。
ログインできないと始まらないので、`~/.ssh/config`に以下を追記

```.ssh/config
Host ssh.lolipop.jp
  HostKeyAlgorithms=+ssh-rsa
  PubkeyAcceptedAlgorithms=+ssh-rsa
```
MacOSX の環境にて iOS アプリを Flutter で開発する前段階のお話

本投稿は [テクノロジー検証 Advent Calendar 2022](https://qiita.com/advent-calendar/2022/technology_validation) の 4日目として投稿しています。

はじめに　: 
---
テクニカルサポート業務に就いている nk-nara と申します。
1日目も見ていただいていれば、お気づきかもしれませんが、もう一人の中野となります。

本記事から数回は、Flutter って何だろねというところから始め、
環境作る時点から悩みつつ、簡単なアプリ実装していく記事を書いていければと考えております。

前提
---

私自身は、MS 系の Power Platform 一部 (※2) や
Javascript を独学で遊んだ程度の知識レベルとなります。

アプリ開発の経験値がない状態からスタートしています。

未学習や同様のスキルセットの者による
感想や意見などからしか得られない栄養素が投稿できれば良いな、と考える次第です。


Flutter について  : 
---

Flutter は、オープンソースのアプリ開発の環境 (※1) を指します。
開発およびサポートは Google が行なっており、
使用する言語はこちらも Google が発表した Dart を利用します。

Dart の書式は誕生経緯から Javascript に近いものとなっています。

**◾️初出時期と最新バージョンについて**

参考資料より、下記となります (投稿時点, OSX の場合)
参考: https://docs.flutter.dev/development/tools/sdk/releases?tab=macos#macos

```
* Flutter (2018 〜) : 3.3.9
* Dart (2011 〜) : 2.18.5
```

Flutter は 4才、Dart は 11才ということですね。
※ Flutter と比較して有名な開発環境では、React は2013年の 9才です。


パッと思い浮かんだ言語とも比較してみました。
見比べると、フレッシュさがよくわかります ( Wikipedia より雑に参照)

```
Javascript 先輩 : 1995年の 27才
HTML さん : 1997年の 29才
Python さん : 1991年の 31才
C 師匠 : 1972年の 50才
FORTRUN 先生 : 1954年の 68才
```

Python が 前二人よりも年上なことや、
C と FORTRUN の貫禄に圧倒されますねぇ...

  

**◾️ Flutter > 開発可能な環境について**
iOS と Android のアプリ開発時に、同コードを利用可能です。

iOS はふわっと Xcode や OSX の環境がいるような話を聞いていましたが、
そもそも両 OS の処理都合でコードを書き換える必要があるのが一般的です。
この点、マルチ環境を想定するなら強いですね。

その上、Flutter Version 3 はそれまでのバージョン 2.x からの拡張として、
今年3月の Google I/O conference で発表されています。

Version 3 による差異について網羅して把握しておりませんが、
大きな点として、6つの異なるプラットフォームで実行することができるようになりました。

具体的には iOS、Android に加えて MacOS、Linux、Web、Windows の
アプリケーションや UI 開発できるようになりました。

...なんというか、UI にさえ気をつければ提供先の充実具合がすごいですね。

**◾️ 補足**
Flutter 自体は Qiita でも人気のある素材です (4桁検索結果が出てますね)

趣旨に沿わない場合は是非是非、有識者の方の Advent Calender 等を見に行きましょう！
末に投稿時に参考にしたリンク群を列記しております。よろしければ、ご参照ください。


環境について
---

ざっくりと今後に予定している環境について触れて行きます。

* 採用バージョン
前述でも触れましたが ver 3.x がリリースしていますので
安定版の最新を採用しようと思います。


* 環境や制約紹介
開発環境としては、以下を採用します。 
```
Macbook Pro Early 2011 ( OSX 10.13.6 )
iPhone 6s Plus ( iOS 15.7.1 )
```
もっと新しいモデルも出ていますが、
私的な検証したアウトプットが主目的ですのでご容赦を。

注釈
---
* ※1 :  
厳密には違いますが、一家庭で戯れる程度の 
フレームワークへの理解として、ここでは記載しています。
* ※2 : 
中でも Power Apps, Power Automate です。 
残り２つとはまだ戯れていません.


参考文献
---

**基本的な情報**
1. Flutter とは　- https://aws.amazon.com/jp/what-is/flutter/
1. Flutterで始めるモバイルアプリ開発 第1回　 - https://codezine.jp/article/detail/12718
1. Flutterとは？始める前に押さえておきたい必須知識を解説 - https://www.sejuku.net/blog/124242
1. Flutter／Dartとは？ 将来性や勉強法、開発事例を分かりやすく解説 - https://type.jp/et/feature/18222/

**Release について**
* Flutter 3が、サポートされるすべてのプラットフォームに対して安定版となり、Material Design 3を拡張 - https://www.infoq.com/jp/news/2022/06/google-flutter-3-dart/

**有識者の Advent Calender**
1. Flutter Advent Calendar 2022 - https://qiita.com/advent-calendar/2022/flutter
1. Flutter大学 Advent Calendar 2022 - https://qiita.com/advent-calendar/2022/flutteruniv

*最新情報の回収**
* 2022 年のFlutterニュースまとめ - https://blog.flutteruniv.com/flutter-news-2022-summarize/

終わりに
---

次回は環境セットアップしてみようと思います。
テキストオンリーで情報が少ないですが、最後まで見ていただきありがとうございました。
拠点間接続に困った話 (1)

謎のアドベントカレンダー、第 4 話です。

今日から拠点間接続の話です。

## 東京事務所開設

筆者の勤務先グループでは 2000 年頃に、新事業の拡大を目指して地元（名古屋）だけでなくサービスを全国展開することになり、手始めに東京に事務所を構えることになりました。

ここで 1 つ大きな問題になるのが **ネット環境をどうするのか** です。

本社（名古屋）にはすでにインターネット接続用に光ファイバーが導入済み、さて拠点側はどうする？ということで、やはり ISDN（INS ネット 64）では遅すぎるので、今は亡き **[東京めたりっく通信](https://www.wdic.org/w/WDIC/%E6%9D%B1%E4%BA%AC%E3%82%81%E3%81%9F%E3%82%8A%E3%81%A3%E3%81%8F%E9%80%9A%E4%BF%A1)** の ADSL を引くことに。

これでインターネット接続は確保、しかし **本社との接続はどうする？** ということで、悩んだ末に出した答えは

**退役したノートパソコンに Linux を入れてルーター化し、名古屋と東京にそれを設置して暗号化トンネルを張れるようにする**

でした。

（「悩んだ末」というのは半分嘘で、ウキウキしながら「Linux VPN ルーター」を作っていました。はい）

## 当時のルーター

もちろん当時もルーターは市販されていました。

ただし数万円程度で買えるものは INS ネット 64 用のルーターばかりで、また VPN が張れるものは（PPTP を除いて）高価でした（ランニングコストとして発生するライセンス料も高額でした）。

そこで、 **何台も在庫がある古いノートパソコンに Linux（Enterprise じゃない古の Red Hat）を入れ、[Blowfish](https://www.schneier.com/academic/blowfish/) による暗号化トンネルが張れるよう設定** しました。

（一人で名古屋側のルーターを設置して東京へ向かい、ドキドキしながら東京側のルーターを接続して VPN で繋がったことを確認しました）

当時の ADSL のサービスはまだ固定 IP アドレスが使えるサービスを提供しておらず、東京側から（固定 IP アドレスを持つ）名古屋側に接続しに行く形で設定しました。

## でも、やっぱり（お約束の）

実際に事務所のメンバーが使い始めると通信断の問題が生じました。

当時の ADSL は（使用する場所にもよりますが）周囲の環境の影響を受けて通信が不安定になることが多かったです。

同じメタル線に重畳している遠隔検針などの付加サービスや一緒に引き込んだ別回線、AM ラジオの電波、電話局からの経路中にある建物の自動ドアなどなど、いろいろなものに影響を受けていました。

（フェライトコアなど、ある意味「スピリチュアルグッズ」的に機器や配線に装着していたのを思い出します）

また、光ファイバーのサービスが始まった後も、東京事務所が入るビルでは配管の関係で光ファイバーを通すことができませんでした。

## ところがその後

東京事務所の責任者の粘り強い交渉により、なんと **隣のビルを経由して光ファイバーが引ける** ことになりました。

その頃には数万〜十数万円程度の VPN ルーターも市販されるようになっていたので、自作 Linux VPN ルーターを「卒業」し、市販品のルーターで IPsec VPN 接続することができました。

（いい時代になったな、と当時は思いました）

---

それから紆余曲折があり、東京事務所は何度か移転を繰り返して現在に至ります。

（ちなみに筆者は現在の東京事務所には一度も行ったことがありません。話によると[『あ、安部礼司』](https://www.tfm.co.jp/abe/)の話の舞台あたりらしいですが）

そして、現在は大阪・福岡などさらに拠点を増やしています。

## 余談 (1)

今から振り返ると、我ながらなかなか無茶なことをしたな…と思わなくもないですが、東京事務所との VPN 接続にチャレンジしたことを理由に、その年の社内表彰を受けることになりました。

（いや、トラブルの元にしかなってないはずなんだけど、なんでだ？）

## 余談 (2)

古いパソコンに Linux を入れてルーター化する話はこのあと何度か出てきます。

もう今はそんなことをする必要はないのですが、2000 年代の初め頃まではこの技に結構助けられました。

## 余談 (3)

実は別件で **[名古屋めたりっく通信](https://www.wdic.org/w/WDIC/%E5%90%8D%E5%8F%A4%E5%B1%8B%E3%82%81%E3%81%9F%E3%82%8A%E3%81%A3%E3%81%8F%E9%80%9A%E4%BF%A1)** の ADSL も本社に引いていました。

当時の、通信を取り巻く時代の流れの速さが懐かしいです。

ほんとに。

---

5 日目の記事に続きます。

- **[拠点間接続に困った話 (2)](https://qiita.com/hmatsu47/items/ad410042d39d4d33ab56)**

https://qiita.com/hmatsu47/items/ad410042d39d4d33ab56
React Datepicker実装パターン

## html5標準Datepickerを使う

inputタグに `type="datetime-local"` を指定すると利用できます

```tsx
import React, { useState } from "react";

const DatePicker = () => {
    const [selected, setSelected] = useState("");


    return (
        <div className="form-check">
            <input type="datetime-local" value={selected}
            onChange={event => setSelected(event.target.value)}></input>
            
            <div>{selected.replace("T", " ")}が選択されました！</div>
        </div>
    )
}
export default DatePicker;
```

Chromeだとカレンダーと時間選択ポップアップが表示されます
![スクリーンショット 2022-12-04 0.16.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530205/83ade48f-e7e2-21ce-999f-346f068b8e70.png)

Safariだと時間はキーボード入力する必要があります
![スクリーンショット 2022-12-04 0.17.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530205/6edfb4e5-dd2e-05c3-81e4-691421064421.png)

## react-datepickerを使う

[react-datepickerスタート手順](https://www.techpit.jp/courses/15/curriculums/16/sections/150/parts/578)に沿って必要なライブラリをインポートして利用します

```tsx
import React, { useState } from "react";
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css"

const DatePickerComponent = () => {
    const [selectedDate, setSelectedDate] = useState<Date>();


    return (
        <DatePicker 
            dateFormat="yyyy/MM/dd HH:mm"
            locale="ja"
            selected={selectedDate} 
            onChange={date => setSelectedDate(date!)}
            showTimeSelect
            timeIntervals={30}/>
    )
}
export default DatePickerComponent;
```

react-datepickerライブラリのcssが適用されるためブラウザ間でのレイアウト差異がなくなります

Chrome表示
![スクリーンショット 2022-12-04 0.50.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530205/5d5dc99b-4613-1907-dc62-5aec112d1b15.png)

Safari表示
![スクリーンショット 2022-12-04 0.50.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530205/6a23db69-6192-b39f-c588-1d0608915d35.png)

### react-datepickerの注意点
#### dateFormatに時間のフォーマットまで指定する
`timeFormat` 属性に値を指定しても入力内容に反映されません。。
`dateFormat` 属性に `yyyy/MM/dd HH:mm` まで指定する必要があります


```tsx
        <DatePicker 
            dateFormat="yyyy/MM/dd"
            locale="ja"
            selected={selectedDate} 
            onChange={date => setSelectedDate(date!)}
            showTimeSelect
            timeIntervals={30}
            timeFormat="HH:mm"/>
```
![スクリーンショット 2022-12-04 1.00.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530205/0b1b210a-faf6-cb5b-b39a-4f04cce3a756.png)

#### showTimeSelect属性を記述しないと時間が変更できない
`dateFormat="yyyy/MM/dd HH:mm"` とすればキーボード入力で時間が変更できそうに見えますが、、
![スクリーンショット 2022-12-04 1.05.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530205/b4b4d101-9ed7-9b12-9a50-b987237593e2.png)

キーボードから時間を変更してもフォーカスを外すと元の時間に戻ってしまいます
![スクリーンショット 2022-12-04 1.06.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530205/246eadf4-ac29-4e3e-a9f1-77fc0bd9f60f.png)