OmniAICreator/Qiita-1.07M huggingface dataset:
React Node-REDダッシュボードを使ってみる

Node-REDで、ボタンや時系列グラフなどのユーザインターフェイスを作れるNode-REDダッシュボード、便利ですよね。サードパーティノードも開発できるようになったことで、Node-REDのエコシステム拡大に大きく貢献してきました。ただ、現在は内部で使用するAngularのバージョンがEOLになり、OSSの利用ポリシーが厳しいNode-REDのサービスでは採用が難しくなっています。そのため、代替としてReact Material UIを用いてNode-REDダッシュボード相当のノードを作ってみました。

# インポート方法
現在のところフローとして公開しているため、下記フローライブラリにアクセスして、フローのJSONデータをNode-REDフローエディタに読み込みます。

https://flows.nodered.org/flow/b4a1d13862f2aa092befe18f5c438185

本フローの実装にはサブフローの新機能を用いているため、Node-RED v3.0.0以上のバージョンを用いる必要があります。

フローを読み込むと以下の様なフローと、パレットのuikitカテゴリのノードが登場します。今回はシンプルなフローの作成方法を解説するため、一旦ワークスペースにあるフローは全て削除します。
![Screenshot 2022-12-21 at 23.03.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287766/11c4b167-26a5-d19a-4c7e-adb6d43ef6b7.png)

# フローを作成
sliderノードとchartノードをワイヤーで繋ぎ、フローを作成します。sliderノードは、マウスでドラッグして値を変化させることができるUI部品です。chartノードは、時系列グラフを表示するUI部品です。

![Screenshot 2022-12-21 at 23.12.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287766/1c5fac68-d6c0-6266-776d-b1de033b4f43.png)

本フローでは、sliderノードのUIが送出した値が、ワイヤーを通してchartノードに送られ、時系列グラフにプロットされます。

# ダッシュボード画面を表示
ダッシュボードの画面を表示するには「http://\<Node-REDのIPアドレス\>:1880/uikit」にアクセスします。下のスライドバーをドラッグして値を変化させると、上の時系列グラフに値がリアルタイムに反映されるダッシュボード画面を開発できました。

![Screenshot 2022-12-21 at 23.08.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287766/4b67c5f0-8350-f5e4-e369-cab9b5179d08.png)

# 従来のフローとダッシュボード画面
元のNode-REDダッシュボードで、作成した場合のフローとダッシュボードの画面は以下の様なものです。

・フロー
![Screenshot 2022-12-21 at 23.17.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287766/f3d5dd0a-8c5c-050c-699a-51e703ac1653.png)

・ダッシュボード画面
![Screenshot 2022-12-21 at 23.16.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287766/5fedb441-3ca2-0b51-cfa5-18344db9d1f0.png)

React Node-REDダッシュボードとオリジナルのNode-REDダッシュボードは、ほぼ同じ様な見た目であることが分かって頂けるかと思います。

# React Node-REDダッシュボードの今後
半年ほど機能拡充をしてきたReact Node-REDダッシュボードは、従来のダッシュボードと同じ操作感で使えるようになってきました。今後の開発については現在のところ、下記のアイデアがあります。

- カスタムノード化してノードとしてフローライブラリに登録
- タブやグループを用いたダッシュボードレイアウト機能
- テーブルノードやカメラノードなどのUI部品の拡充

今後も拡張してゆきますので、ご期待ください。
CloudFront vs Global Accelerator 

# 本記事について
この記事では３回目のANS-C01を受けるにあたって勉強した内容を整理するための記事です。
詳しくは[こちら](https://qiita.com/the13-HK/items/349cdf5f38e0ce1e47b1)をご覧ください。
今回はCloud FrontやGlobal Acceleratorをはじめとしたエッジロケーションに展開されるサービスについての記事となります。


# エッジロケーションとは
CDN（コンテンツデリバリネットワーク）によって低レイテンシな通信を実現させるためのサービス
- リージョンデータセンターよりも地理的に近い場所で情報をキャッシュできる。
- エッジロケーションを中継することで、リージョンデータセンターとの通信をユーザーと直接行うのではなく、AWSの専用線を使用した通信を行うことが出来る。
- リージョンデータセンター側のリソースの不可を軽減できる。（スパイクなアクセスにも対応可）

といった利点があります。
基本的に、各リージョンデータセンターに**オリジン**となるサービスがあり、そこに向けて通信を連携させる目的のサービスとなります。

エッジロケーションで利用できるサービスは以下です。
1. Cloud Front
1. Global Accelerator
1. WAF
1. AWS shield
1. Lambda@Edge

今回は特に特徴的なCloud Front, Global Acceleratorについて記載します。

また、エッジロケーションに似たようなサービスとしてoutpostsがあります。（ANS-C01試験にも出てくる。）
これは一定の条件を満たした任意のオンプレデータセンターにAWS管理の資源を置いてしまう、いわば**リージョンやVPC**を拡張するサービス（≒エッジロケーション）です。outpostsに置いたサーバーの管理もAWS側が行ってくれます。

これを使用するためにはオンプレとAWS間をDirect Connectで接続する必要があります。


## Cloud Front
エッジロケーションにサービスをデプロイして使用します。
各リージョンのリソースをオリジンに指定し、ユーザーに一番近いエッジロケーションからオリジンへの通信をオフロードします。

### 主な特徴
- 対応プロトコルはHTTP/Sのみ（レイヤー7）
    - 対応ポートは80/443
- webコンテンツのキャッシュが出来る
- AWSサービス以外のサービスをオリジンに指定可
- Cloud Front にもドメイン登録可。ただし、登録時はバージニア北部リージョンで証明書の登録を行うこと。

## Global Accelerator
同じくエッジロケーションにサービスをデプロイして使用します。
パフォーマンスに基づいて最適なエンドポイントにユーザートラフィックをルーティングすることが可能。
Route53のレイテンシールーティングをグローバルサービスとしてやってくれるイメージ

### 主な特徴
- 対応プロトコルはTCP/UDP（レイヤー4）
    - 対応ポートの制限なし（1~65535）
- コンテンツのキャッシュ能力はない
- 基本的に以下AWSサービスへのルーティングしかできない
    - Network Load Balancer
    - Application Load Balancer
    - EC2 インスタンス
    - Elastic IP アドレス
- AWS Global Accelerator として静的はIPアドレスを２つもつ。

## まとめ
CloudFrontとGlobal Acceleratorの違いはELBにおけるALBとNLBの違いと似ていると感じた。（名前は全然違うけども）
ANS-C01の試験ではグローバルな通信（複数リージョン間でリソースをハンドリングするような通信）を行う場合はどのような構成の時、低レイテンシーな通信ができるか、みたいな設問があったが、基本的にGlobal Acceleratorを使用した構成が正解のような気がしている。
洋書の技術書を読んでみよう

## 洋書読んだことありますか？
技術書は翻訳本が多いですね。
翻訳作業が間に入っているということは、発売されてから遅れて日本に入って来てるということです。

有名なエリック・エヴァンスのドメイン駆動設計の原書が発売されたのは「2003/08/20」で、翻訳本は「2011/04/08」と約8年も遅れて発売されています。


## Manning Publications
[Manning Publications](https://www.manning.com/)をご存知でしょうか？
**「〇〇〇 in Action」** などのタイトルの書籍を出版しています。
日本で発売されるときはタイトルが変わっているケースが多いのですが、以下のような本が翻訳されています。※他にもあります
Akka in Action → Akka実践バイブル
Rust in Action → 詳解Rustプログラミング

トップページにアクセスするとそのときのベストセラーが表示されています。
タイトルにスピーカーのマークが付いてる書籍は音声で聞くことができます。
※キャプチャは2022/12/11時点
<img width="450" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54521/07d5fd67-20ac-1a06-85a4-127c1a443fc5.png">

### MEAP
「MEAP」のマークが付いている書籍は「Manning Early Access Program」と言って、執筆中の書籍を読むことができます。また、ディスカッションフォーラムも設置されているので正誤や意見を投稿することができます。
MEAPについては、[こちら](https://www.manning.com/meap-program)に説明ページがあります。

### LiveBook
LiveBookは、Manning Publicationsが提供しているオンラインのブックリーダーです。
マーカーを引いたりブックマークを設定できたりします。
eBook(pdf)を買うとLiveBookも一緒についてきます。
LiveBookについては、[こちら](https://www.manning.com/livebook-program)に説明ページがあります。

LiveBookの良いところは、データがHTMLで表示されるのでブラウザの翻訳機能が利用できます。
これを利用しない手はありません！

## まとめ
洋書を読んでみようとタイトルに書いておきながら、結局は翻訳かよ！　って思われるかもしれませんが、自動翻訳で読めるというだけで洋書を購入するハードルがぐっと下がります。
全部を読み切る必要は無いと思います。今の海外で人気のある書籍の必要な部分をつまみ食いしてみてはどうでしょうか？

ちょうど年末の[カウントダウンイベント](https://www.manning.com/countdown-to-2023)で日替わりでセールが行われています。
意外とちょくちょくと割引イベントをやっているので、定価で買うのは躊躇しちゃいます・・・

あと、「〇〇〇 in Motion」 というのは動画コンテンツなのですが、会話の内容がすべてテキストに起こされているので、これも翻訳機能を使って翻訳を見ながら聞くことができます。
他にも有用なコンテンツがあるので利用してみて下さい。
「Notion」を使って、"かゆいところに手が届く"ToDo/スケジュール管理をご紹介

# はじめに
この記事は2022年Advent Calendar[身の回りの困りごとを楽しく解決！ by Works Human Intelligence Advent Calendar 2022](https://qiita.com/advent-calendar/2022/works-hi-1)の23日目の記事です。

普段の仕事でPMをしていますが、ToDo管理やスケジュール管理をどうしていくべきか悩むことが多いです。
それぞれのベストなツール・サービスは世の中にたくさんありますが、自分の感覚に合う、どちらも横並び管理できるツールが中々無いな～と思ってました。

そんな中、友人のBlogで「Notion」を知り、数か月前から使い始めたのですが、これがToDo/スケジュール管理に対する自分の悩みを解決できていると感じています。

本記事では、最近実践している **"自分なりのToDo/スケジュール管理方法"** を皆さんにご紹介します。

# ToDo/スケジュール管理の課題
自分が思うToDo・スケジュールの定義ですが、
- スケジュール
  - タスクの**実行期間(開始～終了)** や**実行順**を管理するもの
  - ガントチャートやWBSで**スケジュール**を確認することがメイン
- ToDo
  - タスクの**完了期限**を管理するもの
  - カンバンで**進捗状況**を確認することがメイン

と思ってます。

ToDoタスクは期限を管理しますが、自分としては**着手時期**も管理したいと思っています。

そうなると、ガントチャート上に表せそうですが、自分としてはスケジュールとしてみたいわけではなく、進捗状況を見たいので**カンバン**で管理したいと思ってます。

また、その日の作業量を把握するために、ToDoタスクとスケジュールタスクを並べて確認したいとも思っています。

ようは、**"自分なりのこだわりにマッチした形（かゆいところに手が届く）"** で管理できないところが課題だと思ってます。

# そもそも「Notion」ってなに？
最近はだいぶ有名になりましたので、細かい説明は省かせて頂きますw

自分が思う「Notion」の特徴としては、
- 様々な情報を集約管理できるオールインワンワークスペースツール
- 同じデータを様々な角度(ビュー)で確認出来るツール
- 管理項目を簡単に追加・変更できるカスタマイズ性
  - 他のツールによくある"あと一歩"を加えることができ、かゆいところに手が届くことができる

だと思っています。

# 「Notion」によるToDo/スケジュール管理方法
ここからはNotionを使った具体的なToDo/スケジュールの管理方法をご紹介します。

## ボード形式(カンバン)による進捗状況の確認
Notionでは基本レイアウトが幾つかあり、そのうちの一つである「ボード」でカンバン形式のビューを表示できます。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16977/7b0f86cd-64a0-9da6-0216-567c5d4ef04c.png)

- 一般的なカンバンの項目以外も追加して、進捗状況を管理しています。
  - 例えば、まだ実行前なのでステータスとしてはToDoなんですが、直近実行したいと思っているタスクを管理するために「エントリー」というステータスも追加してます。
- 「カテゴリ」という項目を追加し、どのプロジェクトのタスクか分かるようにしてます。
  - 全プロジェクトのタスクを並べてみることもできるし、フィルタをかけることでプロジェクト単位のタスクの状況を確認することもできます。
- 期限だけでなく、期間(開始・終了)への切り替えも可能なので、ToDoとスケジュールの両方のタスクを同じビューで確認できます。
- カンバンなので、各タスクのステータスはドラッグ&ドロップで簡単に移動も可能です。

## タイムラインビューによるスケジュールの確認
Notionの基本レイアウトの一つ「タイムライン」ビューを利用して、スケジュールが確認できます。
![無題2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16977/53b5cb9f-e442-92f1-2926-5f8c2bbc5953.png)

- ガントチャート形式でタスクを確認できます。ドラッグでスケジュールの期間もGUIで簡単に変更できます。
- 自分は全体タイムラインビューと別に、プロジェクト別タイムラインビューを用意し、それぞれガントチャート形式で確認できるようにしてます。
![無題3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16977/f74ed0ca-d51c-6e39-df51-72b65802b68c.png)

## その他のビュー(カレンダー)
カレンダー形式での確認もできます(あんまり使ってませんがw)
![無題4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16977/788b40c0-5d31-11d3-b44d-94930bfdb82e.png)

# 最後に
「Notion」はオールインワンワークスペースであると共に、簡単にカスタマイズが可能なツールです。

今回ご紹介したToDo/スケジュール管理は一例になりますが、何度も書いた通り **"かゆいところに手が届く"** ツールです。

世にある様々なツールの「あと一歩」の部分が気になる、**こだわりを持っている**方は、ぜひこのツールを使ってみて、「身の回りの困りごとを楽しく解決」してください。

以上、皆様の参考になれば幸いです。
リプレイスプロジェクトの失敗とそこからの学び

[「レガシー」を保守したり、刷新したりするにあたり得られた知見・ノウハウ・苦労話 Advent Calendar](https://qiita.com/advent-calendar/2022/works-hi-3)の21日目の記事です。

数年前になるのですが、長く運用しているシステムのフロントエンドのリプレイスに携わったことがあります。
最終的にはリリースできたのですが、その過程での経験した個人的失敗などを振り返り、プロジェクトマネジメントの観点からまとめることにしました。

## 背景

リプレイス対象のシステムは、長い期間運用されてきたサービスでした。その期間でじわじわ溜まっていた技術的負債が、普段のサイト改善の開発効率を下げているという問題がありました。

具体的には、

- 長年の機能追加･削除を通して生まれた、大量の不要なコード
- リポジトリの肥大化により、意図せぬ場所に依存関係があり、影響範囲の特定が困難
- コードが分割されておらず、再利用が難しい設計
- ドキュメント等が残っておらず、仕様はコードを読まないと(読んでも)わからない
- ノウハウが複雑化しており、正確に引き継ぐのは困難で、メンバーの入れ替わりごとにLPOの改善スピードは低下する

といったことがありました。

結果、軽微な修正であっても無駄な工数がかかってしまい、生産性が低下していました。その上、予期せぬ不具合が頻発してしまっており、事業の求める開発生産性を満たせない状況でした。

## 概要

リプレイスで一番解決したいポイントは、サイト改善の生産性を上げるという点に絞りました。

そこで、最も更新頻度が高いフロント部分をバックエンドから分離する設計としました。
バックエンドのAPIは存在していたため、フロント部分のみリプレイスしました。
7ヶ月程度のプロジェクトでした。

## 結論

たくさん学びはあったのですが、特に以下が重要だと感じました。

:::note info
1. 「成果物」「メンバー」「期限」を明確にすること
2. エンジニア以外のメンバーにも理解してもらえるようにきちんと説明し、巻き込むこと
:::

以下、プロジェクトでの失敗もふまえて、この学びに至った経緯を説明していきます。

### 1. 「成果物」「メンバー」「期限」が不明確だった

私がプロジェクトに参画したのはプロジェクトの中盤でした。その時点でのプロジェクトの計画は、リリース目標の月だけが大まかに定められており、タスクの分割や見積もりがされていませんでした。不確定な状態で調査から始まり、そのまま進んでいたようです。
また、人員のアサインも曖昧で、エンジニア以外はほぼ関わっていない状況でした。

当時は、プロジェクトが進んでいたというのもあり、参画した時点では大きな方向修正をせずに進めてしまいました。

しかし、開発中盤〜終盤に入ってくると、デザイナーやマーケターの工数が数人月単位でかかってきたため、計画外のリリースの遅れにつながってしまいました。

### 2. 仕様の変更を曖昧にしていた

リファクタリング等であれば、その機能のインタフェースを変更することはしません。もちろん機能追加も混ぜることはしないです。

一方、システムリプレイスとなると、完全に同じ機能を実装することばかりではなく、軽微な改善も入ってしまうことがあると思います。
例えば、

- 過去は必要だったが、現在は不要になった機能の削除
- 継ぎ足し実装されていたことで、非効率な実装になっており、それにより発生していた制約の撤廃
- 新しい技術を取り入れることによる機能アップ

などはあるのではないでしょうか。
この仕様変更について、実際に運用オペレーションをしているメンバーとの議論が不足していました。
一部、プロジェクト後半まで議論ができていなかったものもあり、リリース直前まで確認でドタバタしていました。

本来であればリプレイス時に、機能の変更、追加はできるだけ避けるべきです。しかし、不要だと分かっている機能を作り直すのは無駄なので、一定発生するのは仕方ないと思っています。
ただし、こういった仕様の変更をきちんと整理し、周知させておかないと、仕様自体だけでなく、リリース後のオペレーションの混乱などにも繋がりえます。

### 3. プロジェクトのゴール等を整理できていなかった

プロジェクトはエンジニア主導で開発を進めており、事業部内での説明と合意が不足してしまっていました。
特に「**リプレイスをすることでどのような成果を得たいのか**」について言語化できておらず、きちんと説明できていませんでした。

他にも色々ありますが、プロジェクトの途中になって初めて以下の点をまとめました。

- プロジェクトのゴール、スケジュール、関係するメンバー
- プロジェクトの全体像、具体的な変更点
- 成果の指標、切り戻し条件
- 他施策との優先順位の検討と工数割当の議論･合意

エンジニアからすると無条件で必要と感じる技術的負債の解消も、エンジニア以外の人にとっては何が嬉しいのか、どのような効果があるのかがイメージしづらいものです。
開発工数の削減と言っても、何%削減なのか、売上利益にどのような効果があるのかを伝えないと、人によって解釈が分かれて、優先度の判断ができない状態でした。

誰が見ても分かるように定量的に効果を示し、情報を集約しておき、いつでも見れる場所にまとめました。
そして、一度説明して終わりではなく、認識がずれないように根気強く何度も何度も説明をしました。

## 学び

:::note info
1. 「成果物」「メンバー」「期限」を明確にすること
2. エンジニア以外のメンバーにも理解してもらえるようにきちんと説明し、巻き込むこと
:::

まとめてみると、当たり前のことばかりですが、プロジェクトマネジメントの経験が少ない当時は分かっていても全然できないことばかりでした。
初期の段階でこれらを合意すべきですが、途中であっても「怪しい雰囲気」を感じ取った時点で、大きく舵を切る勇気も必要だなと思いました。

また、リプレイスというプロジェクトの特性上、「タスクが後から次々出てくる」「成果が計測しづらい」「エンジニア以外からは理解が難しい」のようなものもあり、プロジェクトマネジメントの難しさも感じました。

## まとめ

リプレイスというと、エンジニア起因のニーズからスタートすることが多いですが、プロジェクトには多くのリソースを使いますし、最終的には仕様が変わったり、運用オペレーションが変わったりすることで、今動いているサービスへ影響が大きいものになります。

そのため、エンジニア以外のメンバーにも理解してもらえるように粘り強く説明し、最初から巻き込んで進めていくことがとても大事なのだと学びました。
ECCV2022の枝刈り論文 (2)

# 概要

この記事では、[ECCV2022](https://eccv2022.ecva.net/)の枝刈り論文を紹介します。[^1]
[その1](https://qiita.com/kyad/items/82e29a08cea1488d9c13)

[^1]: 画像や数式は論文から引用しています。


# Disentangled Differentiable Network Pruning

https://www.ecva.net/papers/eccv_2022/papers_ECCV/papers/136710329.pdf

- 概要：学習による枝刈り
- 新規性：従来は幅・パラメータを同時最適化するため探索範囲が広くなってしまう課題に対して、幅とパラメータを別々に最適化するアプローチを提案した。
- キモ：Smoothなtop-kでマスクしながら学習する。
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448931/c151e9ad-36fc-1a69-986c-831c95b77fa0.png)
- 評価：ResNet, MobileNet, ImageNet等で実験した。精度はほぼ落ちない。
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448931/e54eeecf-deca-5dbb-5627-c47e7cdb7b91.png)


# FairGRAPE: Fairness-aware GRAdient Pruning mEthod for Face Attribute Classification

https://arxiv.org/abs/2207.10888

- 概要：FairGRAPE. 枝刈りで、データのバイアス対策をしているもの。
- 新規性：枝刈り後にバイアスが生じることがある課題を解決する。
- キモ：データをグルーピングし、各グループのノードの重要度を考慮して枝刈りする。
- 評価：グループ毎のばらつきを含めて評価した。


# Bayesian Optimization with Clustering and Rollback for CNN Auto Pruning

https://www.ecva.net/papers/eccv_2022/papers_ECCV/papers/136830480.pdf

- 概要：ベイズ最適化による枝刈りの自動チューニング。
- 新規性：ベイス最適化は高次元になるとサンプル効率が落ちる課題を解決する。
- キモ：(1)クラスタリングで低次元に次元圧縮する。(2)精度悪化を防ぐためにロールバックアルゴリズムを使う。(高次元に戻す)
- 評価：MobileNetやResNetに適用して評価した。
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448931/658d7ddb-f6c1-0e64-fa3a-d7e4713d3ccb.png)


# Multi-Granularity Pruning for Model Acceleration on Mobile Devices

https://www.ecva.net/papers/eccv_2022/papers_ECCV/papers/136710483.pdf

- 概要：JCW. 複数精度での枝刈り。
- 新規性：Channel pruningとweight pruning (Unstructured pruning)を組合せてトレードオフを改善する。
- キモ：チャネル数とsparsityのmulti-objective optimizationとして解く。
- 評価：MobileNetV1, V2, ImageNet等で確認した。
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448931/77d3dbca-c4e8-e702-fd09-324f1ec16262.png)
[Cesium]地球の内部を表示する

# 地図の内部を表示するには
地球の内部に埋もれてしまったオブジェクトは隠れて表示されなくなってしまうため、
見つけることができずに「あれ？オブジェクトがどこか行っちゃった？」となることがある。
その場合、地球の内部を見ることができるようにすることで見つけることができて便利。

- 参考にしたSandcastle[Globe Interior]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3077774/951b602f-aa85-3c6c-3869-8f63dfdf23c8.png)

- ソースコード
``` javascript
  const viewer = new Cesium.Viewer("cesiumContainer", {
    orderIndependentTranslucency: false,
  });

  const scene = viewer.scene;
  const globe = scene.globe;
  globe.translucency.enabled = true;
  globe.undergroundColor = undefined;
  globe.translucency.frontFaceAlpha = 0.001;
  globe.translucency.rectangle = Cesium.Rectangle.fromDegrees(
    -180.0,
    0.0,
    -30.0,
    45.0
  );
```
- 説明
translucency.enabled : 機能の有効無効を設定する？
undergroundColor : undefinedにすることで裏側に色がつかない。
translucency.frontFaceAlpha : 前面の空いている場所の透明度（0だと完全透明）
translucency.rectangle : 前面の空いている場所の範囲
イーサリアム 2.0：Casper FFG とは

イーサリアム 2.0 の PoS は、従来の PoS を改善し、vitalik が進めていた Casper FFG (Friendly Finality Gadget) を採用しています。
Casper FFG は、主にネットワーク上にブロックチェーンが分岐してしまった場合、どうやって１つだけの有効なブロックチェーンを選出するというところを解決しようとしています。

## Casper FFG の詳細
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4777/f4fed7e0-f61b-f34d-5797-89dce3ba0abe.png)
引用元：https://github.com/ethereum/annotated-spec/blob/master/phase0/fork-choice.md

ビーコンチェーンは、エポックとスロットという時間単位があります。さらに
- １エポックは、32 スロットを含める
- １スロットは、12 秒と規定されている

上記前提で、Casper FFG の大まかの流れとしては、

- エポック毎に、最初のスロットは「チェックポイント」になります。
- アクティブなすべてのバリデーターは、チェックポイントに対して、投票を行う
- 投票の件数ではなく、投票するバリデーターの預り金の金額を合計し、2/3 の超えたら、チェックポイントが「正当化」となる
- １個前のチェックポイントは、前の同じ投票・集計処理で既に正当化になっていたので、このタイミングで「確定」となる
- 一度確定となるブロックは変更することはできません

このように、ブロックの最終確定性を導入することで、ロング・レンジ攻撃を防ぐことができます。

## 極端ケースの対策
上記流れでは、投票が 2/3 を超える必要があるとなっていますが、極端のケースの場合、何かしらの原因で 1/3 以上のバリデーターの投票を収集できなかった可能性があります。
この場合は、Casper FFG に「inactivity leak」という仕組みを設けています。

- 1/3 以上のバリデーターの投票を収集できず、 4 エポック経過しても確定できなかった場合、「inactivity leak」処理が実行されます
- この処理は、正しく投票できている預り金の比率が 2/3 になるまで、収集できなかったバリデーターの預り金を少しずつ減らしていきます

こうすることで、このケースによる確定できないことを対応しています。

## まとめ
PoS は PoW よりエネルギーを大幅減らせた一方、新しいブロックを生成する難易度もそれに応じて変わっています。
よって、チェーン全体のセキュリティを担保する必要があります。
どんなに古くたって、ソースコードがあればなんとかなるんですよね

# 背景
「なんとかします」という言葉が気に入られて入社した今の会社
事業所内に情シ部門がなかったので、なんとか創設に漕ぎつけたのが数年前
今は何故か、研究開発に吹っ飛んでますけどが・・業務改善にいそしんだ際の記憶の記録です

# やったこと

## VB6 アプリの改修
いったいどんなけあるのよってレベルで 10 年以上前のアプリが業務で使われていた
改修が止まってから5年以上が経過していたものも多く、問題点はすべて手作業になっていた為、とても感謝されました

とはいえ、流石に Windows 10 移行に伴い、環境維持が難しくなったので改修は停止。

## .Net アプリの改修
C#/VB 両方ともあったものの、基本は IT 部門用ツール
ってことで、出来るところからGit 管理へ移行し改修＆再構築へ
申請処理が未だに Excel 全盛だったので Office VSTO で処理支援アプリなんかも

## Git 導入
GitBucket を当初稼働させたものの、Azure DevOps へ。やっぱりインフラ運用は面倒なので :(
組み込み系もいい加減 Git 主体にすべきですよね、と

## RPA 導入
WinActor/BizRobo などでシステムの自動化
Power Platform 導入支援で、業務効率化

## グループ会社間の連携 Team
市民開発者を育成して、実務をしている人が改善を回していけるようにしたかったので。
Teams で情報共有を図れるように、と
ただ、全体で共有出来る Git が無いのが難点

https://qiita.com/baku2san/items/1ac3f2a459253c3e4fa1

## 心残りは・・
1. ワークフローへの連携が出来なかった。
1. 社内基幹システム刷新時に、システム連携させられなかった。csv かよ・・と
1. 所内システムを Web で刷新出来なかった。
1. Power Platformの浸透がいまいち
1. グループ会社内 OSS の仕組みと基板となる Git には全く出来てない・・


# 何が一番大切だったのか
やっぱりソースコードという生き証人がそこにあったことで、わかんない仕様もなんとか読み解けたんだと思う。
ということで、ソースコード管理はなくとも、ちゃんとソースコードを zip 管理していた先人に感謝

とはいえ、コメントで履歴管理してるようなのは流石に・・・でしたけど :laughing: 

# あとがき
今は情シに属しながらも、日々新しいことを学びながら研究開発の支援してます。

やっぱり、学びは楽しいですね :laughing:
flutterflowでアンケートアプリ作ってみた

## flutterflowとは
![flutterflow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1935269/63cbbb18-8f03-1d4b-77ca-160e445a1eac.png)


以下flutter公式サイトによると
>FlutterFlowは、ネイティブモバイルアプリケーションを開発するためのローコードビルダーです。ドラッグ＆ドロップのシンプルなインターフェースで、従来の開発の10倍以上のスピードでアプリを構築することができます。

だそうです。

## どういう人向けか
・モバイルアプリ、webアプリ、windowsアプリなどの複数デバイスに対応したアプリ開発をしたい人
・flutterの知識がなくて開発した人
・エンジニア以外だけどアプリ開発してみたい人

## 使ってみた感想
正直開発スピードは格段に上がります。特にFlutterはフロントの開発がしやすいと思いますが、コードで書いたフロントをそのままローコードに反映できるような感じです。<br>
裏側の処理も設定が必要ではありますが、手順が簡単なので、こんなものがあるとコードを書くやる気が削がれそう。。。笑

## 作ったアプリ
アプリ：アンケートアプリ
きっかけ：自社のサービスの顧客情報を収集する目的で作成するために作り始めました！
期間：フロント（２日間）、各種設定(2日間)

UIの構築はテンプレートから編集したものなので、一日かければほとんど完成すると思います！
firebaseとの連携が英語だらけなので少し手こずりましたが。。。。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1935269/3694a429-178a-8066-a5dd-99832ba6f7a9.png">

## flutterflowでできること
* 画面UIの作成
* 画面の接続
* Firebaseとの接続
* コードのエクスポート

## どうやって作るのか
https://flutterflow.io/images/animate_TopLayer.svg

作り方は非常にシンプルで、必要なcontainerやcolumnをドラッグアンドドロップで配置したり、右サイドの各種設定項目でサイズや色を変更したりできます。

## 最後に
まだ自分もflutterflowを扱って間もないので詳しくは解説できなかったですが、このツールを扱えば開発効率が格段に上がるというのはわかりました！
↓こちらが公式サイトになるのでドキュメントなども見れます！現在英語のみですが、日本語翻訳のドキュメント作成中なので完成したら公開する予定です！

https://flutterflow.io/
Rustのエスケープ文字の一例(改行等)

## はじめに
Rustを勉強していて、覚えておくと便利だと思ったエスケープ文字をアウトプットしたいと思います。

## エスケープ文字

|  文字  |  内容  |
| ---- | ---- |
|  \n  |  改行  |
|  \t  |  タブ  |
|  \\  |  Backslash  |
| \'  | シングルクォート |

## 使用例

### 改行

```rust:Code
fn main() {
    let sentence: &'static str = "人生とは自分を見つけることではない。\n人生とは自分を創ることである。";
    println!("{}", sentence);
}
```

```rust:実行例
人生とは自分を見つけることではない。
人生とは自分を創ることである。
```

### タブ

```rust:Code
fn main() {
    let sentence: &'static str = "人生とは自分を見つけることではない。\t人生とは自分を創ることである。";
    println!("{}", sentence);
}
```

```rust:実行例
人生とは自分を見つけることではない。	人生とは自分を創ることである。
```

### バックスラッシュ

```rust:Code
fn main() {
    let sentence: &'static str = "人生とは自分を見つけることではない。\\人生とは自分を創ることである。\\";
    println!("{}", sentence);
}
```

```rust:実行例
人生とは自分を見つけることではない。\人生とは自分を創ることである。\
```

### シングルクォート

```rust:Code
fn main() {
    let sentence: &'static str = "人生とは自分を見つけることではない。\'人生とは自分を創ることである。\'";
    println!("{}", sentence);
}
```

```rust:実行例
人生とは自分を見つけることではない。'人生とは自分を創ることである。'
```


## 参考
https://tourofrust.com/61_ja.html

https://doc.rust-lang.org/reference/tokens.html
TypeScriptのinterfaceとtypeについて調べてみた

## はじめに
TypeScriptを勉強していて、`interface`と`type`というものに出会いました。パッと見た時にどちらもオブジェクトの型を指定するものなのかな？と思いました。今回は、それらがどういったものか調べまとめてみました。

## TypeScriptのinterfaceとtypeについて調べてみた
### interfaceとは
`interface`は、オブジェクトやクラスの構造を定義するものです。以下のような感じで構造を定義できます。
```ts
interface Book {
    name: string;
    price: number;
}

const book: Book = {
    name: "book",
    price: 1000,
};
```

`interface`は、`extends`キーワードを使って`interface`の継承を行うことができます。
```ts
interface Book {
    name: string;
    price: number;
}

interface Novel extends Book {
   category: string;
}

const novel: Novel = {
    name: "novel",
    price: 800,
    category: "mystery",
};
```
また、既に定義した`interface`と同じ名前のものを宣言することができます。宣言後、既に定義されたものと後から宣言されたものはマージされます。
```ts
interface Animal {
    name: string;
}

interface Animal {
   classification: string;
}

const animal: Animal = {
    name: "animal",
    classification: "mammal",
}
```

### typeとは
`type`は、型エイリアスと呼ばれ、型に名前をつけることができます。`interface`と違い、オブジェクトやクラスの型を宣言するだけではなく、プリミティブ型などに名前をつけることができます。またこれに加えて、`type`ではunion型やtuple型を扱えるのも`interface`と違うところです。

```ts
type Num = number;

type StringOrNull = string | null;

type Book = {
    name: string,
    price: number,
};

const book: Book = {
    name: "book",
    price: 1000,
};
```
`type`は`interface`と違い、継承を行うことはできません。しかし、交差型を使って継承と似たようなことができます。
```ts
type Book = {
    name: string,
    price: number,
};

type Novel =  Book & {
   category: string,
};

 const novel: Novel = {
    name: "novel",
    price: 800,
    category: "mystery",
}; 
```
また`interface`のように、既に宣言されたものと同じ名前を型エイリアスを宣言することはできません。
```ts
type Animal = {
    name: string,
};

type Animal = {
    classification: string,
};
// => ERROR
```

## さいごに
今回は、TypeScriptの`interface`と`type`の違いについてまとめてみました。状況や用途、開発のルールに従って、使い分けができるといいのかなと思いました。何かわかったことがあれば、追記しようと思います。
Google CloudでSpot VMを使ってみる

GMOアドマーケティングのT.Oです。
今回はGoogle CloudでSpot VMを利用する手順についてご紹介します。

# はじめに
Google CloudのSpot VMは、GCE(Google Compute Engine)で利用できる低価格なVMです。
すべてのマシンタイプ、リージョン、ゾーンで利用でき、標準のVMマシンタイプの料金と比べて60%〜91%の割引があります。さらにSpot VMに接続されているGPU、ローカルSSD、外部IPアドレスに対する割引も適用されます。

Spot VMは標準のVMインスタンスと同じように機能しますが、以下のようにいくつかの制限があります。特に「任意のタイミングでプリエンプトされることがある」点については注意が必要です。

* SpotVMはCompute Engineの余剰キャパシティを利用する機能です。このためキャパシティに余剰がない場合には、そもそもSpot VMのインスタンスが作成できないことがあります。
* Spot VMを作成できた場合においても、Google側で余剰のキャパシティがない場合は任意のタイミングでプリエンプト（強制終了）されることがあります。
* Spot VMはGoogle Cloudのサービスレベル契約の対象外であり、Compute EngineのSLA（サービス品質保証）から除外されています。

# Spot VMを作成する
Google Cloudのコンソール画面を使用して以下の手順でSpot VMのインスタンスを新規作成します。

1.「Compute Engine」のメニューから「VM インスタンス」を選択

2.「VM インスタンス」画面で「インスタンスを作成」を選択
![spot_vm_p0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36602/79031b99-4138-391a-0b4f-a72b439add07.png)

3.通常VMと同様にマシンの構成やネットワークなどの各種設定をします。次にSpot VMのインスタンスとするために「詳細オプション」→「管理」→「可用性ポリシー」の「VM プロビジョニング モデル」で「スポット」を選択します。
![spot_vm_p1mod.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36602/ca263213-6d8e-8242-555c-541491b05a7a.png)

4.プリエンプトされる直前に実行されるシャットダウンスクリプトを設定したい場合には「詳細オプション」→「メタデータ」で「項目を追加」を選択します。
![spot_vm_p2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36602/bfb78c0b-c535-81d4-9445-43be180971ff.png)

「キー」、「値」の入力欄が表示されますので、「キー」フィールドにメタデータキーとして「shutdown-script」と入力します。「値」フィールドにシャットダウンスクリプトとして任意の処理（例:実行中の結果データをGCSなど外部にバックアップするなど）を記述します。なお処理はインスタンスのプリエンプト開始後30秒内で実行完了する必要がありますので注意してください。
![spot_vm_p3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36602/cfca6955-01a4-9b71-6181-f79d3d4f984f.png)

5.各種設定を完了したら画面下部の「作成」を選択してインスタンスを新規作成します。

6.作成されたSpot VMのインスタンスの詳細画面を参照すると以下のようにSpot VMであることが確認できます。
![spot_vm_p4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36602/a617f3b1-e7e9-c3b7-267a-b4e9fd9c3ad5.png)

# 参考
Google CloudのCompute Engine ドキュメントを参照させていただきました。
[Spot VMについて](https://cloud.google.com/compute/docs/instances/spot?hl=ja)
[シャットダウンスクリプトの実行](https://cloud.google.com/compute/docs/shutdownscript?hl=ja)

# 次回のお知らせ
明日は、@masaseatさんによる「非エンジニアPdMがVertex AIで広告配信用の機械学習モデルを作成してみた」です。
引き続き、[GMOアドマーケティング Advent Calender 2022](https://qiita.com/advent-calendar/2022/gmo-am)をお楽しみください！
AWS Amplify DataStoreの遅延ロードと入れ子構造のフィルター機能を試す

この記事は[株式会社LabBase テックカレンダー Advent Calendar 2022](https://qiita.com/advent-calendar/2022/labbase) 21日目の記事です。

# 毎年恒例
今年もAWS Amplifyのさまざまな機能拡張が行われた中で、今回はDataStoreを触ってみようかと思います。


# AWS Amplify DataStoreとは
オフラインとオンラインのシナリオで追加のコードを書かずに共有・分散データを活用するプログラミングモデルを提供し、分散したクロスユーザーデータをローカルだけのデータと同じように簡単に扱えるようにします。([AmplifyDocsより](https://docs.amplify.aws/lib/datastore/getting-started/q/platform/js/))
つまりオフラインでもデバイス上にデータを保存することができ、オンラインになったときにはAppSyncとデータ同期をとってくれる優れものです。

# 新機能
今回はこちらの機能が増えました。詳しくはこちらをご覧ください.サンプルのリポジトリもあるので今回はそれを動かしてみます。

https://aws.amazon.com/jp/blogs/mobile/new-lazy-loading-nested-query-predicates-for-aws-amplify-datastore/

# 遅延ロード
スキーマ定義で hasOne, hasMany, belongsTo, manyToManyでリレーションされているデータを非同期に取得できるようになりました。
サンプルのスキーマ定義はこんな感じ

```ruby:schema.graphql
type Post @model {
  title: String!
  content: String! 
  comments: [Comment] @hasMany
}

type Comment @model {
  content: String!
  replies: [Reply] @hasMany
  post: Post @belongsTo
}

type Reply @model {
  content: String!
  comment: Comment @belongsTo
}
```
このデータを非同期に取得しようとすると

```javascript:App.js
const [posts, setPosts] = useState([]);//ここにDataStoreのオブジェクトが入る
~~~
for await (const post of posts) {
      output += `${post.title}\n\n`;
      output += `${post.content}\n\n`;
      output += `Comments:\n`;
      for await (const comment of post.comments) {
        output += `- ${comment.content} @ ${comment.createdAt}\n`;
        for await (const reply of comment.replies) {
          output += `  - ${reply.content} @ ${reply.createdAt}\n`;

          // Using `.toArray()` function
          const replies = await comment.replies.toArray();
          output += replies
            .map((reply) => `  - ${reply.content} @ ${reply.createdAt}\n`)
            .join("");
        }
      }

      output += `-------\n`;
    }
```
`await`は当然として、`toArray()`というメソッドで中身を非同期で取れるようになります。

# 入れ子構造のフィルター機能
入れ子になっている内部データを取得する際にフィルターをかけて取得できることができます。

```javascript:App.js
useEffect(() => {
    let sub;
    if (filter) {
      sub = DataStore.observeQuery(Post, (p) =>
        p.comments.replies.content.contains(filter) //ここではfilterに文字列は入る想定
      ).subscribe((snapshot) => {
        // ^ see new type improvements here
        setPosts(snapshot.items);
      });
    } else {
      sub = DataStore.observeQuery(Post).subscribe((snapshot) => {
        setPosts(snapshot.items);
      });
    }
    return () => sub.unsubscribe();
  }, [filter]);
```
数千件データを入れてみて動かしてみましたが結構高速に動いていました。数万は流石に怖いので試せてませんが汗

# おわり
毎年Ampfliyは進化していていいですね。今年は私自身はAmplifyをあまり触る機会は少なく、今後仕事ではあまり触りそうにないのですが、プライベートでちょこちょこ触っていこうと思います。

全然関係ないですが[前回の私の記事](https://note.com/guevara01/n/nd3488e6e0445?from=notice)も是非読んでみてください。

明日は[栗原さん](https://qiita.com/jqtype)です。ご期待ください。
CSSで兄弟を指定する方法メモ

# 動機

[CSSの仕様](https://developer.mozilla.org/ja/docs/Web/CSS/CSS_Selectors) には兄弟を指定するための構文として一般兄弟結合子(~)、隣接兄弟結合子(+)が定義されているものの、これで対象となるのは弟妹のみであって、兄姉を直接指定する方法は用意されていない.
:has() 疑似クラスを使用すれば兄姉を指定できるのだがパッと思いつかなかったりする.
なのでここにメモしておく.
ただし、:has() 疑似クラスが古いブラウザで動作しない点は注意.

# 環境

Google Chrome バージョン: 108.0.5359.125 で動作することを確認

# 具体例

## HTML

```html:具体例
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>Test CSS</title>
  <style>
    .me::after {
	  content: " [This is me!]";
	}
    .me + .sibling::after {
	  content: " [ひとつ弟]";
	}
    .me + .sibling + .sibling::before {
	  content: "[ふたつ弟] ";
	}
    .sibling:has(+ .me)::after {
	  content: " [ひとつ兄]";
	}
	/* :has(*) は入れ子にできないので、ふたつ兄を指定するためには使えない
     * ∴ [.sibling:has(+ .sibling:has(+ .me))::before] は不正
	 * ふたつ兄を指定するためには入れ子にせず指定する
	 */
    .sibling:has(+ .sibling + .me)::before {
	  content: "[ふたつ兄] ";
	}
	/* 弟妹全員 */
    .me ~ .sibling {
	  color: red;
	}
	/* 兄姉全員 */
    .sibling:has(~ .me) {
	  color: blue;
	}
	/* 兄弟全員 :not(.me) を取り除けば .me も対象となる */
    *:has(> .me) > .sibling:not(.me) {
	  background-color: yellow;
	}
  </style>
</head>
<body>
  <ul>
    <li class="sibling">First
    <li class="sibling">Second
    <li class="sibling">Third
    <li class="sibling me">Forth
    <li class="sibling">Fifth
    <li class="sibling">Sixth
    <li class="sibling">Seventh
  <ul>
</body>
</html>
```
## SS

![Chromeでの表示.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2329888/642ec0ee-c90c-25db-35f9-032175e5baa7.png)
gnuplotでepsとemfを同時に作ろうぜ

## はじめに
texに挿入するために，gnuplotでepsファイルを作成する事があるかと思います．
このepsをパワポで使うとき，どうしますか？オススメは，emfファイルでパワポに挿入することです．（理由は，ググってみて下さい）

どうすればいいのか．今まではInkscapeのコマンドラインを使い，batファイルにて処理していました．

しかし，この度直接emfを作成できそうになったので，ここに共有します．

## emf を作るには

gnuplotにて，以下を最後に挿入すればおｋです．

```gd:emfを作成するためのスクリプト
# 予めepsを出力するスクリプトがあり，出力し終えた上で，以下．
set term emf monochrome font "Times New Roman,24" enhanced lw 2
set output "output_sample.emf"
replot
set output
```

```:Italicを使うには
/TimesNewRoman-Italic
ではなく，
{/Times:Italic}
を使う
```

上記２点がミソでした．

## 実際にやってみる

用意したデータはこちら
ex.tsvと名付けています．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2536951/bbcbe7fa-6f9f-76e4-2a4a-f788b51ded27.png)

```gd:ex.plt
reset
set terminal postscript eps enhanced color "TimesNewRoman" 28
set output "ex.eps"
set xlabel "velocity, {/Times:Italic v} (m/sec^{-1})" 
set ylabel "hoge, {/Times:Italic y } (%)"
set rmargin 5 # 10^-4が見切れていたため

stats "ex.tsv" u "a":"b"
R = sprintf("{/Times:Italic r} = %.3f", STATS_correlation )
set label R at graph 0.05,0.9 font "Times,40"

# 以下はemfではできていない（22:40 2022/12/21現在は）
set label "{/Symbol \264 }10^{-4}" at graph 1.0, -0.15

plot "ex.tsv" every ::1 u 1:2 with points lc "cyan" pt 7 ps 1.5 notitle

set term emf font "Times New Roman,24" enhanced lw 2
set output "ex.emf"
replot
set output

```
そんでできたのがコレ
右：eps
左：emf
同じディレクトリにemfが出力されます．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2536951/39b4b344-d7e4-bff6-928f-01898a0d61bc.png)


このフォントのズレをどう捉えるか，ですが，今のところ自分は問題なく捉えています．
軸ラベル名のフォントのズレなどは，パワポに貼るときには上から修正してやればいいだけのこと．それよりプロットやxtics, yticsあたりが重要なんだわさ．

## 参考

https://tayublog.net/excel%E3%81%8B%E3%82%89gnuplot%E3%81%A7%E3%82%B0%E3%83%A9%E3%83%95%E3%82%92%E4%BD%9C%E3%82%8B%E6%96%B9%E6%B3%95/#toc3
Windows 10 Home から Pro へアップグレードして、ちょっと手間がかかった話

Windows 11 Home から Pro へアップグレードして、余計な手間がかかった話
https://qiita.com/nanbuwks/items/97c8aa6e102ca85bde6b

では、Microsoft Store を使ってアップグレードを行いました。
アップグレード自体はすぐ終わりましたが、Microsoft アカウント が登録されてしまいそれを解除するのがめんどくさかったですね。

Windows 10 Home ではどうなるでしょうか?

# 環境

- Windows 10 Home
- ローカルアカウントで設定

# 作業の流れ

Windows 10 Home の OS の初期設定が終わった状態

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/64ccc376-9f3b-9c7b-82e9-c88706e0ad38.png)

Microsoft Store を選び、「Windows」で検索すると Windows 10/11 Pro へのアップグレード画面が出てくるので、「購入」を押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/91d9a1a1-b1b2-d760-9d16-d166c77b3e58.png)

Microsoft アカウントにサインインして、支払いをします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/1cbc0375-bbcf-af21-7d46-e4df23cd0bc0.png)
クレジットカードで購入した後、「インストール」ボタンを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/98c716fb-706b-8a7d-8a55-1bbf1c661a66.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/1bc5953b-d069-42d8-d415-935a2ebc8a99.png)


2,3分後・・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/df73ced2-0325-d790-ec8f-58e83f186d1e.png)

Windows10 でも、エラーが出ました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/5abaed80-c730-2ee6-ea3c-83854596266f.png)

WindowsUpdate には何もありませんでしたが、実際には更新がバックグラウンドで用意されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/7d7b98d9-eebc-e9a9-2e4f-8fb849855873.png)
再起動後、再度 Microsoft Store で アップグレードしようとすると Workstations しか表示されなくなってました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/2931ce51-0d74-4298-cf98-a04d5a2ddfc2.png)

あれれ? と思ったら既に Windows 10 Pro にアップグレードが終わっていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/b35dc908-4e6c-3c67-2ae4-641e2491c8ea.png)


# Microsoft アカウントの紐付けを解除する

Proライセンスを購入するときに Microsoft アカウントにサインインしました。これを解除します。
Microsoft Store から「アカウントを表示」すると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/e01b226c-9b39-b5aa-9181-a29442e721b1.png)

ブラウザで表示されます。なお、この画面が出なかった場合は Microsoft Store から直接サインアウトする必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/849ee170-a59c-181e-a0bc-e624c216a27c.png)

ブラウザでこの画面が出た場合は「サインアウト」します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/1cce3a35-54de-e7ac-612b-f0f955eaa449.png)

Edge の「設定」からも、「サインアウト」する必要がありました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/504cb2fc-2cdd-12b3-3536-c64215d70182.png)

Windows11では、OneDrive に支払い情報が登録されてしまってましたが、Windows10 だとそんなことは無さそうで一安心。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/2c27db71-13ea-72a3-e38c-e65da1eb50ea.png)
【学習ノート】Pandas 〜基本操作②〜

# はじめに
データ分析が必要となり、学習を進める上でいつでも見返せるように毎日の学習をメモします。

# Dataframe
※ データ分析を極めたいため、seriesの記載は省略する。


#### index、columnを指定してDataframeを生成する
```py
df = pd.DataFrame([[1, 10], [2, 20], [3, 30], [4, 40]], index=['a', 'b', 'c', 'd'], columns=['col1', 'col2'])
print(df)

#    col1  col2
# a     1    10
# b     2    20
# c     3    30
# d     4    40
```

#### 辞書から生成する
```py
data = {'col1' : [1, 2, 3], 'col2' : [10, 20, 30]}
df = pd.DataFrame(data)
print(df)

#    col1  col2
# 0     1    10
# 1     2    20
# 2     3    30
```

### 統計量計算

```py
df.count()	#要素数
df.mean()	#平均
df.max()    #最大値
df.min()    #最小値
df.var()    #分散
```
↑ describeを使うことで基本的な統計量を一括で取得することが可能

```py
df.describe()
#        col1  col2
# count   3.0   3.0
# mean    2.0  20.0
# std     1.0  10.0
# min     1.0  10.0
# 25%     1.5  15.0
# 50%     2.0  20.0
# 75%     2.5  25.0
# max     3.0  30.0
```

### 取得
```py
# col1を取得する
print(df['col1'])
# または print(df.col1)

# a    1
# b    2
# c    3
# Name: col1, dtype: int64
```

#### loc・iloc 
locはラベル名、つまりindexを指定し、ilocはinteger-location、つまり位置を表す整数でアクセスする。
```py
print(df.loc[0]) 
# col1     1
# col2    10
# Name: 0, dtype: int64

print(df.loc[0]['col1'])
# 1
```
```py
df.iloc[1]
# col1     2
# col2    20
# Name: 1, dtype: int64
```
#### where
```py
import pandas as pd
df = pd.DataFrame([[1, 10], [2, 20], [3, 30], [4, 40]], columns=['col1', 'col2'])

# 添字でフィルタ条件指定
df[df['col1'] > 2]

#    col1  col2
# 2     3    30
# 3     4    40


# whereを使用

df.where(df['col1'] > 2)
#    col1  col2
# 0   NaN   NaN
# 1   NaN   NaN
# 2   3.0  30.0
# 3   4.0  40.0

df.where(df['col1'] > 2, 0)

#    col1  col2
# 0     0     0
# 1     0     0
# 2     3    30
# 3     4    40
```
VCI luaスクリプトでの文字列の連結　その１

# この記事は
バーチャルキャストでのVCIのluaスクリプトで使う文字列の扱いについてまとめます。といっても今回の内容は、ふつうのluaスクリプトでも同じ振る舞いをしてくれると思います。


## 文字列の連結
文字列を表示する際に、変数を文字列に埋め込んだり、複数個の文字列を連結したりしたくなることがあると思います。luaでの文字列の連結操作には二通りの方法があります。
・ 2連ピリオドによる単純連結
・ stringクラスによるsprintf風連結
今回はこのうち **2連ピリオド** による方法を紹介したいと思います。

## 2連ピリオドによる単純連結
文字列と文字列（もしくは変数）とをピリオド二つでつなぐ方法で、よく見る連結法です。単純で簡単なのでちょっとしたデバッグの際など、ちゃんと書かなくてもいいので **さっと書きたい時** に重宝します。


```lua:
local str = "おはよう".."ございます"
print(str)
```

```:出力
おはようございます
```
おそらくよく見るコードとしては、文字列に何らかの変数を埋め込んで表示するタイプでしょう。

```lua:
local num = math.random(1,10)
local str = "あなたが引いた乱数は"..num.."です。"
print(str)
```

```:出力
あなたが引いた乱数は7です。
```

この記法は改行を入れたときも有効なので、コードの上で文字列が長くなってしまって可読性が低くなってしまった際にも使うことができます。（物語や説明文などの長文などで起きがち）


```lua:長い例
local str = "拙者親方と申すは、御立会の内に御存知の御方も御座りましょうが、御江戸を発って二十里上方、相州小田原一色町を御過ぎなされて、青物町を上りへ御出でなさるれば、 欄干橋虎屋藤右衛門、只今では剃髪致して圓斎と名乗りまする"
print(str)
```


```:出力
拙者親方と申すは、御立会の内に御存知の御方も御座りましょうが、御江戸を発って二十里上方、相州小田原一色町を御過ぎなされて、青物町を上りへ御出でなさるれば、 欄干橋虎屋藤右衛門、只今では剃髪致して圓斎と名乗りまする
```

定義の際に以下のように直しておくと、結果は変わらず、かつエディタ上で見やすさを確保することができます。

```lua:短くしてコードの可読性を確保する例
local str = "拙者親方と申すは、"..
"御立会の内に御存知の御方も御座りましょうが、"..
"御江戸を発って二十里上方、相州小田原一色町を御過ぎなされて、"..
"青物町を上りへ御出でなさるれば、 欄干橋虎屋藤右衛門、"..
"只今では剃髪致して圓斎と名乗りまする"
print(str)
```

```:出力
拙者親方と申すは、御立会の内に御存知の御方も御座りましょうが、御江戸を発って二十里上方、相州小田原一色町を御過ぎなされて、青物町を上りへ御出でなさるれば、 欄干橋虎屋藤右衛門、只今では剃髪致して圓斎と名乗りまする
```

### レベル0開き括弧
今回の話題とは違った方法ですが、コード上での見た目を整えるだけなら、大かっこを使っても書けます。こちらはbrタグがなくても見た目通り改行が反映されます。

```lua:短くしてコードの可読性を確保する例２
local str = [[拙者親方と申すは、
御立会の内に御存知の御方も御座りましょうが、
御江戸を発って二十里上方、相州小田原一色町を御過ぎなされて、
青物町を上りへ御出でなさるれば、 欄干橋虎屋藤右衛門、
只今では剃髪致して圓斎と名乗りまする]]
print(str)
```

```:出力
拙者親方と申すは、
御立会の内に御存知の御方も御座りましょうが、
御江戸を発って二十里上方、相州小田原一色町を御過ぎなされて、
青物町を上りへ御出でなさるれば、 欄干橋虎屋藤右衛門、
只今では剃髪致して圓斎と名乗りまする
```

こちらは引用符で囲ったのと同じ扱いを受けるので注意です。
ただし、最初の括弧の直後の改行だけは無視されます。
つまり、以下でも同じ結果となります

```lua:[[直後の改行は影響しない
local str = [[
拙者親方と申すは、
御立会の内に御存知の御方も御座りましょうが、
御江戸を発って二十里上方、相州小田原一色町を御過ぎなされて、
青物町を上りへ御出でなさるれば、 欄干橋虎屋藤右衛門、
只今では剃髪致して圓斎と名乗りまする]]
print(str)
```

### 軽くまとめ

二連ピリオドによる方法は、"単純連結"と表現した通り、本当に連結しかできません。
もう一つのstringクラスによる方法では、数値の表示方法を細かく指定することができるほか、変数の数などを柔軟に対応させることが可能です。記事が長くなってしまったので、stringクラスによる方法は別記事でまとめたいと思います。
CRUD入門



| HTTP Method |  URI                 | ACTION  |
|     :---:   |:---:                 | :---:   |
|     GET     | /users               | index   |
|     GET     | /user/create        | create  |
|     POST    | /users               | store   |
|     GET     | /users/{userId}      | show    |
|     GET     | /users/{userId}/edit | edit    |
|  PUT/PATCH  | /users/{userId}      | update  |
|   DELETE    | /users/{userId}      | destroy |
Windows(WSL2)でとりあえずGo言語を書けるようにする

# はじめに
とりあえずGo言語を書く環境を用意したかったのでやったことのメモ。

# 前提
WindowsにWSL2インストール済
WindowsにVisual Stuidio Codeインストール済
WSL2にUbuntu 20.04.5 LTSインストール済
UbuntuにVisual Studio Codeインストール済

# UbuntuにGo言語をインストールする
このページの[Using PPA](https://go.dev/wiki/Ubuntu)の通りにコマンドを打つ（これで最新版が入る）。
> sudo add-apt-repository ppa:longsleep/golang-backports
sudo apt update
sudo apt install golang-go

# VSCodeにGoの拡張機能をインストールする
"Go"で検索すると出てくるこれをインストールする。
![2022-12-21 (14).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157491/b6b9c387-b260-ad9b-860e-c81e485c44ca.png)


# 適当なディレクトリにgoファイル作成する
> touch hello.go
> code hello.go

```go
package main

import "fmt"

func main() {
	fmt.Println("はろーわーるど")
}
```
> go run hello.go

結果
![2022-12-21 (15).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157491/f6853626-6016-7c6c-e813-bb3e3dd70b00.png)


# おわりに
数年前までWindowsに環境構築するの面倒なイメージあったけど動かすだけの環境を用意するのは思ったより簡単にできて拍子抜けした。
Makefileで上位階層の.envを参照する方法

# 本記事について
本記事は、初学者としてポートフォリオを作成する際に、検証して得た知見を自身の備忘録として記載しております。
初学者のため、もっと良い方法や、間違い等ございましたらご指摘頂けますと幸いです。


# 結論
まずは結論から、下記のようにすることで参照できるようになりました。

```java:Makefile
export APP_VERSION ?= $(shell git rev-parse --short HEAD)
include ../.env

# 検証
version:
	@ echo ${password}
	@ echo '{"Version": "$(APP_VERSION)"}'
```

備忘録として、commit IDの左から7桁（objectのhashの短縮表記）を取得するコードも。

Makefileが格納されている階層まで移動して以下のコードで正しく値を取得できるか確認してください。
```java:shell
$ make version
```
envファイルの情報と、commit IDが正しく取得できていたら完璧です。


またMakefileが格納されている階層にversionファイルが存在するとエラーになる（作成することなんて滅多にないと思いますが）なので
最上部に、以下を追加すると尚良しだと思います。

```java:Makefile
# 追加
.PHONY: version

export APP_VERSION ?= $(shell git rev-parse --short HEAD)
include ../.env

# 検証
version:
	@ echo ${password}
	@ echo '{"Version": "$(APP_VERSION)"}'

```

終わり

# 参考
https://qiita.com/karupanerura/items/721962bb7da3e34187e1
Rustはなぜ早いのか　備忘録

## Rustとは
Rustは2015年に正式リリースされたプログラミング言語。
Rustの特徴を端的にまとめると
* 実行速度が速い
*　安全性が強力に担保されている
*　幅広い実装が可能
*　モダンな文法がそろう
*　ツールの充実　　など

## 高速な実行速度
参考
[トップ12の最速プログラミング言語](https://jp.orientsoftware.com/blog/programming-language-speed-comparison/)
[「Rust」言語はCよりも遅いのか、研究者がベンチマーク結果を解説](https://image.itmedia.co.jp/ait/articles/1909/13/l_yh201909Rust_languages_590px.png)
![「Rust」言語はCよりも遅いのか、研究者がベンチマーク結果を解説](https://image.itmedia.co.jp/ait/articles/1909/13/l_yh201909Rust_languages_590px.png)

<B>Rustの実行速度はとても速く、最速？といわれるC言語に匹敵する速度を誇る！！</B>
⇒Rustは機械語に直接コンパイルされる
⇒ガベージコレクションを持たない
⇒「ゼロコスト抽象化」を追求している

## 機械語に直接コンパイル？？
PythonやJavaなどの言語は独自の仮想マシンを持っていて、様々な環境下でプログラミング言語を実行しやすくなるメリットが存在する。
⇒インタープリンタやコンパイラを介す仮想マシン用の言語を生成する。
⇒仮想マシンをソフトウェア上に実装するので、速度面で不利になってしまう。

一方、C言語やC++、Rustなどは、コンパイル後に機械語に変換するため、仮想マシンを返さないため、仮想マシンに起因した速度低下はおこらない。

## ガベージコレクション!?
Rustが速い理由として、仮想マシンを持たないことがあげられたが、実はGOも仮想マシンをもっていない。では、この仮想マシンを持たないもの同士の速度差の原因は何なのだろうか？

参考
[ガーベジコレクション - IT用語辞典](https://www.sophia-it.com/content/%E3%82%AC%E3%83%BC%E3%83%99%E3%82%B8%E3%82%B3%E3%83%AC%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3)

ガベージコレクションとは
…プログラムはコンピュータのメモリと呼ばれる領域をその都度確保、解放を行コストいながら計算処理を行っており、処理中に確保して使われなかった部分は不要メモリとなる。これを長時間確保し続けると使えるメモリ領域が少なくなっていくので、ガベージコレクションといわれる処理を行い、不要メモリを開放して使えるようにする。

この便利な機能にも落とし穴が存在する
* 不要メモリがいつ解放されるかわからない
* 不要メモリを開放するときに、計算処理をわずかに止めてしまう可能性がある。
⇒<b>ガベージコレクションを使うか使わないかという違いが、RustとGOの速度面での違いの理由といえる。</b>

CやC++は、ガベージコレクションを持たない代わりに手動でメモリ領域の管理を行う。
⇒これによって不要メモリがいつ解放されるかわからないという欠点を補うことに成功している。しかし、メモリ領域解放を忘れる、解放した領域を再度解放してしまう（メモリが安全ではない）という問題もある。

Rustは人間ではなく、プログラミング言語側でメモリ管理を行うようにしている。<b>「所有権」「借用」「ライフタイム」</b>といった新しい仕組みを実現することで安全で処理速度を低下させないことに成功している。

## ゼロコスト抽象化？？
ゼロコスト抽象化とは、C++で追求されてた概念で、抽象化の機能を追加コストを支払うことなく使用できることをいう。例えば、抽象化が例として挙げられる。抽象化を行うと何らかの犠牲を払う必要のある言語が多い中、Rustは、抽象化を「ゼロコスト」で行うことができるため実行速度が速い。


# 参考書
実践Rustプログラミング入門
pythonで株価を取得するstooq版

前回、pythonで株価を取得する記事を書いた。

https://qiita.com/tatsu_sekine/items/7d979c47177c64fb9677

しかし、yahooが落ちている、もしくはAPIの制限に引っかかる、などのことがあり使えない場合がある。そんな時でもエンジニアたるもの、代替手段を用意しておくべきだと筆者は考える。そこで今回はstooqの使用することを検討する。

前回同様、S&P500のデータを取得する。

早速だがソースコード。

```python
import sys
import pandas_datareader.data as pdr
import pandas as pd
 
start = '2021-01-01'
end = '2021-12-31'
df = pdr.DataReader('^SPX', 'stooq', start, end)

print(df)
df.to_csv('SP500_stooq.csv')
```
実行結果。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953203/27e8c974-152a-38f7-1f05-7de3986a9197.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953203/bcdb0436-7a47-34dc-5bad-055e7ae78ff7.png)

Yahoo版とデータの列の形式が異なる、また、ソースコードを見てもらえれば一目瞭然だがティッカーシンボルが異なる、のでそこは注意されたい。
Blenderでの3灯照明をざっくり簡略化する

## この記事の概要

私はBlenderを使って3DCGの練習をしています。
3DCGってモデリングに目が行きがちですが、ライティングも大事で、その中でも3灯照明は王道のセッティングなのでだいたい毎回使用しています。

そんな中、毎回繰り返し作業が発生していたのでPythonで効率化できる気がして記事にしました。

:::note
もしかしたら役立つかもしれないけど、正直そこまで期待はできない。くらいの内容です。
:::

## 3灯照明とは

あえて私が説明するまでもなく、世の中に分かりやすい記事がたくさん上がっているので詳細な説明はそちらにお任せします。

https://indieemotion.com/3point-lighting/

今回効率化できる気がしたのが、設定が以下のように意外とシステマチックにできるからです。
それぞれの角度が90度ずつくらい違って3灯を配置するので、計算で出せそうだなと思いました。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/d97452ca-48c6-39a2-5b04-dfa23e21a20d.png)

もちろん実際には見え方を考慮して少しずつズラしますし、ここまで単純な話ではありません。
ただ、雛形を一発で作れるだけでも便利なのではないか？という仮説です。

## 実行

Blender上でPythonを動かす方法は他の方が詳しく記事を書かれているので、そちらをどうぞ。

https://qiita.com/masterkeaton12/items/fb1e5b98f7bd2354b11e

今回の一旦の完成形は以下です。

```python
import bpy

current = bpy.context.view_layer.objects.active #1
key_light = bpy.data.objects[current.name] #1

target_name = 'Target_Empty' #2
empty = bpy.data.objects.new(name=target_name, object_data=None) #2
bpy.context.collection.objects.link(empty) #2

key_light.select_set(True) #1
bpy.ops.object.constraint_add(type='TRACK_TO')
bpy.context.object.constraints['Track To'].target = bpy.data.objects[target_name] #2

x = key_light.location.x
y = key_light.location.y
z = key_light.location.z

bpy.ops.object.duplicate_move(TRANSFORM_OT_translate={'value':(-2*x, -2*y, z)}) #3
bpy.ops.object.duplicate_move(TRANSFORM_OT_translate={'value':(x-y, x+y, -1.5*z)}) #3
```

迷い迷い書いたのでもっと良くできるのかもしれませんが、ポイントになりそうな箇所をピックアップします。

### 1. key_lightの取得とselect_set

最初はLightを選択しておけばいいのですが、後からEmptyを操作する都合でselectが奪われます。
そのため、あらかじめLightを取得しておいて後から再度選択状態を取り戻しました。

これができなくて、Lightを複製したいのにEmptyが複製されてずっと困っていました。

### 2. 名前付きEmptyの作成とTrack to対象への設定

素直な方法であろう`bpy.ops.object.empty_add()`だと、生成される要素の名前が`Empty`です。
それはそれで良いのですが、既に場に同名の要素があった場合は`Empty.001`になります。
というわけでユニークな名前を指定しておいた方が楽そうだなと思ってこのようにしました。

偉そうに言っていますがここを見ただけです。

https://blenderartists.org/t/accessing-newly-added-empty-object/1405372

### 3. 座標を頑張って計算する

90度回転と180度回転なので、xとyの加減だけで出せます。
ちなみにzもだいたいいつもこんな感じで高さをいじるので、ついでに設定しました。

## 最後に

挙動としてはこのようになります。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/cd7f6f7d-1335-c97b-0e5f-c7f5a2f1fb15.gif)

一応目論見通りの動きにはなりました。
まったく同じことをしたい人は少ないと思いますが、この手の「半ばプリセット化している」ような作業へのアプローチとしては使えるかもしれません。

---

最後まで読んでくださってありがとうございます！
Twitterでも情報を発信しているので、良かったらフォローお願いします！

https://twitter.com/xrxoxcxox

Devトークでのお話してくださる方も募集中です！

https://jobs.qiita.com/employers/qiita-inc/dev_talks/489
VMware ESXi&vCSA 6.0/6.5/6.7/7.0/8.0 バージョン間のライセンスキーについて(:3[▓▓]

# 概要
<!-- 発端や概要を記載 -->
現場の新規構築・増設や運用作業でマイナーバージョンアップやメジャーバージョンアップを経験したこともあり、
ESXiやvCSAのライセンスキーがそのまま使えるのか互換性がなくて新しいキーを取得しないといけないのかふと考えるときが来ます。
そんなときのまとめメモを残しておきます。

新規の場合はそのまま購入したバージョンのキーを払い出して使うかダウングレードして下位のバージョンを使うケースが考えられ、
既に特定のバージョンが運用中の環境の場合、つまり機器の増設をしたりする場合には既にある機器に合わせたバージョンで統一するため数の多い方に合わせてダウングレードして使う可能性が高いかと思います。
また、運用中の機器を定期メンテナンス日に一斉にアップグレード作業を行う事もあるかもしれません。
そんなときもアップグレードを行う場合に新しいライセンスキーをアップグレード対応して入手して登録する必要があったりなかったりします。

# VMware ESXi&vCSA 6.0/6.5/6.7/7.0/8.0バージョン間のライセンスキーはそのまま使えるの？使えないの？
|対象製品  |既存製品のバージョン  |アップグレード後のバージョン  |新しいキーの必要性 | Customer Connect ポータルでアップグレードできるか |
|---|---|---|---|---|
|vSphere または ESXi （Essentials、Essentials Plus、Standard、Enterprise、および Enterprise Plus）  |6.0  |6.5  |いいえ  |	既存のライセンス キーでもバージョン 6.5 と 6.7 がロック解除されます|
| |6.5  |6.7  |いいえ  |既存のライセンス キーでもバージョン 6.7 がロック解除されます|
| |6.7  |7.0  |はい  |はい。詳細については、「[How to upgrade license keys in Customer Connect (2006974)](https://kb.vmware.com/s/article/2006974)」を参照してください。|
| |7.0  |8.0  |はい  |はい。詳細については、「[How to upgrade license keys in Customer Connect (2006974)](https://kb.vmware.com/s/article/2006974)」を参照してください。|

|対象製品  |既存製品のバージョン  |アップグレード後のバージョン  |新しいキーの必要性 | Customer Connect ポータルでアップグレードできるか |
|---|---|---|---|---|
|vCenter Server （Standard、および Foundation）　　　　　　　　　　　　　　　  |6.0  |6.5  |いいえ  |	既存のライセンス キーでもバージョン 6.5 と 6.7 がロック解除されます|
| |6.5  |6.7  |いいえ  |既存のライセンス キーでもバージョン 6.7 がロック解除されます|
| |6.7  |7.0  |はい  |はい。詳細については、「[How to upgrade license keys in Customer Connect (2006974)](https://kb.vmware.com/s/article/2006974)」を参照してください。|
| |7.0  |8.0  |はい  |はい。詳細については、「[How to upgrade license keys in Customer Connect (2006974)](https://kb.vmware.com/s/article/2006974)」を参照してください。|

# まとめ
* マイナーバージョンアップ/ダウングレードはキーに互換性があるので新しいキーは不要。
* メジャーバージョンアップ/ダウングレードはキーに互換性がないので、6系、7系、8系でそれぞれ対応するバージョンのキーが必要。

例：ESXi6.0&vCSA 6.0 → 6.5 , 6.5 → 6.7はキーが変わらない。
　　6.7 → 7.0 や 7.0 → 8.0はキーが変わるのでキーのアップグレード作業をして新しいライセンスキーが必要になります。
　　やり方は参考文献のリンク先のKBにありますのでご参照あれ。(:3[▓▓]

例：逆に8.0の新規パッケージを購入したけど7.0を使うぞという新規構築erとかは、
　　ライセンスキーのダウングレードが必要になります。
　　やり方は参考文献のリンク先のKBにありますのでご参照あれ。(:3[▓▓]

# 参考文献
- [VMware 製品の新バージョンに対するライセンス キーの要件 (2059926) - VMware KB ](https://kb.vmware.com/s/article/2059926?lang=ja)
- [How to Upgrade or Downgrade License Keys in Customer Connect with troubleshooting steps (81665) - VMware KB ](https://kb.vmware.com/s/article/81665?lang=ja)
MRTK3 + Quest2 で移動処理を実装する

MRTK2では設置すれば移動できていたのですが、MRTK3では色々追加しないといけなくなったので
恐らく、問題ないと思われる実装方法をメモしておきます。
（たぶん大丈夫なはず）

結論から言うと、MRTK3自体に移動処理をするためのファイルなどは用意がないです。（たぶん）
InputSystemの設定はありますので、それをUnity標準のXRマネジメントを利用した形？で追加する
というイメージを自分は持っています。

ただ、あくまで自分が調べた結果なので
間違えていたらどなたかご指摘お願いしたく...！

## 環境
・Windows11 + Oculus Quest2
・MRTK3 (導入方法は詳しく書かれている記事があるので割愛）
・Unity Editor 2021.3.10f1

## Locomotion(cs)を追加する
場所はどこでもよさそうですが、面倒くささを省くため
「Camera Offset」に取り付けます。
その後、「XR Origin」のcsを入れ込んでおきます。
![aa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3009807/41f00b9a-5bde-910a-6cd5-1d973cd0e0a6.png)

## Continuous Move Provider（cs）を追加する
お勧めは「Action-based」がついたほうになります。
もう一つのほうは自分でInputSystem設定をする羽目になるので
熱意のあるひとはそちらのほうがいいかもしれません。

1.「System」という項目にLocomotion System を組み込みます
![bb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3009807/95e21bbc-0ba7-0afa-03f5-d60ddcd5f1cb.png)

2.（準備）適当にコントローラーを選択後、適用されているMRTKのファイルをクリックして
　MRTKで用意してくれているInputSystemをProjectに表示させておきます。

![cc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3009807/06ec2a9d-e500-e621-e43d-7d386516e781.png)

3.「Left Hand Move Action」の項目にチェックをいれ、2で表示していた「MRTK LeftHand/Move」を
　「Reference」に適用させます。

![dd.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3009807/2b8901d2-a2e6-18fa-babe-be8cd0ceb521.png)

これで、コントローラーのスティックで上下左右に移動できるようになります。

がしかし、回転ができませんので、引き続きcsファイルを追加します。

## Snap Turn Provider (cs) を追加
こちらも「Locomotion System」を追加しておきます。
（多分設定しないと動かないのではないかなと）
![ee.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3009807/6898ad0a-3437-186e-c1b2-fed578a48b38.png)

今度は、Right側の方をOnにして、「MRTK RightHand/Turn」を追加します。
Leftで完結したいときはLeftの設定にしてください。

![ff.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3009807/d3316e2e-d984-85e1-f34a-3589d72598b0.png)

## 最後に
あとは実機で動作をご確認ください。

MRTK3はまだ開発途中なので、この内容も変わってくるかもしれませんし
合っているかわからないので、ご利用は計画的にお願いします！
【ルール説明・shared】no-changed-when

こちらの記事は[Ansible lint Advent Calendar 2022](https://qiita.com/advent-calendar/2022/ansible-lint) 22日目の記事になります。

今回はルール [no-changed-when](https://ansible-lint.readthedocs.io/rules/no-changed-when/) について説明します。

### no-changed-when

[no-changed-when](https://ansible-lint.readthedocs.io/rules/no-changed-when/) は [ansible.builtin.command](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/command_module.html) モジュールおよび [ansible.builtin.shell](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/shell_module.html) モジュールにおいてタスクが冪等性を保証するか検証します。

Ansibleではほぼ全てのモジュールにおいて冪等性が保証されていますが [ansible.builtin.command](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/command_module.html) モジュールおよび [ansible.builtin.shell](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/shell_module.html) モジュールでは`ユーザーが処理が冪等になる条件を指定する`必要があります。

#### 冪等性とは

[Wikipedia](https://ja.wikipedia.org/wiki/冪等) には **冪等性** とは`大雑把に言って、ある操作を1回行っても複数回行っても結果が同じであることをいう概念`とあります。

#### 問題のあるコード

この処理は実行するたびに`changed`が返却されます。

```yaml
---
- name: Example playbook
  hosts: localhost
  tasks:
    - name: Does not handle any output or return codes
      ansible.builtin.command: cat {{ my_file | quote }} # <- 実行するたびに changed ステータスを返す。冪等性が保証されていない。
```

#### 修正されたコード

`changed`が返却される条件を指定しそれ以外では冪等性を保証するように変更します。


```yaml
---
- name: Example playbook
  hosts: localhost
  tasks:
    - name: Handle shell output with return code
      ansible.builtin.command: cat {{ my_file | quote }}
      register: my_output # <- コマンドの結果を変数にセットする
      changed_when: my_output.rc != 0 # <- 変数の値に対しステータスが changed になる条件を指定する
```







### 参考サイト

* [no-changed-when — Ansible Lint Documentation](https://ansible-lint.readthedocs.io/rules/no-changed-when/)