OmniAICreator/Qiita-1.07M huggingface dataset:
Cassandra概要

### Apache Cassandraとは
ウィキペディアによると
> Apache Cassandra（アパッチ カサンドラ）は、オープンソースの分散データベース管理システムである。
https://ja.wikipedia.org/wiki/Apache_Cassandra

### 特徴
1. CQL (Cassandra Query Language)：SQLに似たクエリ言語CQLを提供しています。比較的容易にデータの取得、更新、削除が行えます。
1. スケーラブルで高い可用性：大規模なデータセットを処理するのに適しています。
1. マスターレス：全てのノードは対等な地位で動作します。データの書き込みや読み取りは、任意のノードによって処理されます。
1. Column Family：柔軟なスキーマ設計が可能であり、各行が複数のカラムを持つことができます。また、カラムは任意のタイプのデータを格納できます。
1. 高可用性と耐久性：データのレプリケーションや自動障害回復機能を提供しています。データは複数のノードに分散して保存されるため、単一のノードの障害が全体のシステムに影響を及ぼすことはありません。

### 注意点
データの整合性を保つことがリレーショナルデータベースよりも難しい

### 基本的なクエリ
以下はCassandraの基本的なクエリの一部です。

1 . テーブルの作成:
```sql
CREATE TABLE tablename (
    column1 datatype1,
    column2 datatype2,
    ...
    PRIMARY KEY (column1)
);
```
2 . データの挿入:
```sql
INSERT INTO tablename (column1, column2, ...) VALUES (value1, value2, ...);
```

3 . データの更新:
```sql
UPDATE tablename SET column1 = new_value1, column2 = new_value2, ... WHERE condition;
```

4 . データの削除:
```sql
DELETE FROM tablename WHERE condition;
```

5 . 全データの取得:
```sql
SELECT * FROM tablename;
```

6 . 特定の条件を満たすデータの取得(partition keyとclustering keyを指定していない場合は最後にALLOW FILTERINGをつける):
```sql
SELECT column1, column2, ... FROM tablename WHERE condition;
```

7 . キーによるデータの取得(partition keyとclustering keyを指定していない場合は最後にALLOW FILTERINGをつける):
```sql
SELECT * FROM tablename WHERE column1 = 'key_value';
```

8 . 複数のキーでデータを取得(partition keyとclustering keyを指定していない場合は最後にALLOW FILTERINGをつける):
```sql
SELECT * FROM tablename WHERE column1 IN ('key_value1', 'key_value2', ...);
```
Google Nest HubはローカルIPにアクセスできない

## 免責事項
当記事では同じ思いつきで時間を無駄にする人を出さないよう試みた内容を記載しましたが、十分に検証できなかったため、以下の記述には誤りが含まれている可能性が高いです。それでも参考にしたい方はどうぞ。

記事の動作は2023/5/6現在のものです。ファームウェアのアップデートなどにより動作が変更される可能性があります。

---

## 要約
Google Nest HubとローカルDNSを組み合わせてLAN内のサーバーにアクセスさせようとしたが、出来なかった。

## 環境
+ Google Nest Hub(第2世代)
+ CoreDNS 1.10.1 (Docker)
+ Ubuntu 22.04 LTS(デスクトップ版, 20.04からのアップグレード)
+ Docker 23.0.5

## 動機
Googel Nest HubにLAN内のサーバーにある情報を表示させたり、音声操作でサーバーコントロールとか色々してみたかった。しかし、Googel Nest Hubに何かさせようとするとアクションの開発とか認証とか色々と面倒そうな(上に[Action自体も2023年6月13日に廃止になった](https://qiita.com/H-Kz/items/0efe54d17f31a4500604))ので、お手軽な方法が欲しかった。

## 構想
Google Homeアプリの「ルーティン」にURLを登録すればアクセスできるかなと思ったのだが、いくつか試してみた所、`https://www.example.com/`のような各サイトのトップページには`www.example.comを開く`でアクセスできたが、`https://www.example.com/sample.html`のような任意のページを指定することは出来ないようだった。また、`https://www.example.com:8080/`のようなポート指定も受け付けなかった。

そこで、以下のように考えた。

+ LAN内部にDNSを立ててドメイン名をLAN内サーバーのIPに解決してあげれば、ドメイン名でLAN内のサーバーにアクセスできそう。
+ Googel Nest Hub自体はDHCPでLAN内IPアドレス等を取得するので、その際に内部DNSを指定することは可能なはず。

[2023/6/21追記]
後述するが、実際には処理内容が違って`www.example.comを開く`はURLでなく検索キーワードとして解釈されているようだった。

## 手順
### ローカルDNSの立ち上げ
CoreDNSを使用したが、長くなるので詳細は[**別の記事**](https://qiita.com/sskki/items/582b4a7ff8d0a9540c4a)に記載した。

### Googel Nest Hubへの設定反映
Googel Nest Hubの電源を抜き差しして再起動すると、DHCPサーバー側ではDHCPのリース期限がリセットされていたので、DHCPサーバーの設定が反映されていると思われた。

## 結果
### PCから
DNSサーバー以外のPCから`dig`を使って確認した所、予定通りLAN内Webサーバーのアドレスに名前解決されていた。しかし、DNSサーバーを内部のDNSに指定しているにもかかわらず`nslookup`による結果はNXDOMAINと言われたり、時間が経つと名前解決できたりと安定しなかった。

### Googel Nest Hubから
たとえばCoreDNSのhostsファイルに
```
192.168.3.3 myhome.example.com
```
のように設定して`myhome.example.comを開く`というルーティンを実行すると、[myhome.nifty.com](https://myhome.nifty.com/)が表示されるといったように、検索して見つけてきたであろう外部のページが表示された。

前述のようにDNSの結果が安定しなかったので、もしかしてDNSにアクセスできていないのかと考え、

```
93.184.216.34 example.test
```

のように存在しないドメインを既存のIPに解決した場合は、想定通り表示された。[2023/6/21追記]ように思ったが、ドメイン名から検索された結果のような気もする。

### 推論
以上の動作から推測するに、

+ Googel Nest HubのDNSサーバーをDHCPサーバー経由で変更すること自体は可能。
+ ただし、名前解決されたIPがローカル用のIPアドレスだった場合はDNSサーバーの回答を無視して、ドメイン名ではなく検索語のように扱う。

といった動作をしているのではと考えた。

ちなみに`myhomeを開く`は「うまく理解できませんでした」になる。PCで"myhome"を検索すると[myhome.jp](https://myhome.jp/)がトップに来てmyhome.nifty.comは2番手だったのだが、この辺りはどうやって選ばれているのかは不明である。

他にも試したが、どうもドメイン名なら必ず開くことが出来るというわけでもないようだ。

開くサイトがhttps接続でないと、「接続に失敗しました」と表示される模様。

DNSがLAN内のIPアドレスを返すとGoogle Nest Hub側で自動的に無効扱いされるようだ。

[2023/6/21追記]
そもそも、`www.example.comを開く`はyahooのような有名なサイトでは機能するが、マイナーなサイトではうまくいかず、ドメイン名にそのままアクセスするのではなく、一旦検索してマッチしたサイトにアクセスしているのではないかという気もする。

## 考察
セキュリティなどの事情で、想定外の動作を起こさないように色々制限することは必要な理解できるが、URLを開くというごく基本的な動作くらいは出来て欲しかった。

音声認識は便利だが、意図しない動作になった時にそれを修正するのは難しい、あるいは不可能だったりする。

Chromeにキャストという機能があり、LAN内のGoogel Nest HubにブラウザやPCの画面を投影できる。目的によってはキャスト機能を用いる方が簡単な場合もあるように思えた。


## 改訂履歴(表現の修正などは除く)
+ 2023/5/6: 作成開始
+ 2023/5/7: DNSサーバーの話を分離
+ 2023/6/21: 仕上げようとしたが、正しく仕様を把握できていると思えず棚上げ
+ 2023/8/2: これ以上置いても改善する見込みがないので投稿。
組み込み機器（IoT機器）にtftpでデータを送る

# 現在の環境

## tftp server

hyper-v上に建てたcentosに、tftp serverをインストールしています。

## tftp cliant
とあるIoT機器です。　busyboxが動いています。
```
+-------------------------+
|     Hyper-V Host        |
|                         |
|    +--------------+     |
|    | CentOS VM    |     |
|    |              |     |
|    | IP         　|     |
|    | 192.168.11.12|     |
|    |              |     |
|    | TFTP Server  |     |
|    +--------------+     |
|            |            |
|            |            |
|            |            |
|    +--------------+     |
|    |  IoT Device  |     |
|    |           　 |     |
|    | IP:       　 |     |
|    | 192.168.11.19|     |
|    |              |     |
|    +--------------+     |
|       TFTP Client       |
|       　　　　　　　　　　|
+-------------------------+


```

# tftp serverのインストール、設定の変更

```
yum -y install tftp-server xinetd
```
  
 ## /etc/xinetd.d/tftp を以下のように変更してください

変更項目は
1. server　:  -s /var/lib/tftpboot  **->** -c -u root -s /var/lib/tftpboot 
1. disable : yes **->** no

この2つです。

```
cat  /etc/xinetd.d/tftp
# default: off
# description: The tftp server serves files using the trivial file transfer \
#       protocol.  The tftp protocol is often used to boot diskless \
#       workstations, download configuration files to network-aware printers, \
#       and to start the installation process for some operating systems.
service tftp
{
        socket_type             = dgram
        protocol                = udp
        wait                    = yes
        user                    = root
        server                  = /usr/sbin/in.tftpd
        server_args             = -c -u root -s /var/lib/tftpboot
        disable                 = no
        per_source              = 11
        cps                     = 100 2
        flags                   = IPv4
}
```

# 設定が完了後は、起動！

```
sudo systemctl statart xinetd
```

# 送信したいファイルをtftp serverの指定の場所に置く

ファイルを置く場所は、以下の場所です。

```
 pwd
/var/lib/tftpboot
```


# ファイルをIoT機器(cliant)の方からgetしてみます。

## tftp serverのファイル状態
```
/tftp_server
|-- hello.txt
|-- helloworld.o
```

## IoT機器(cliant)のファイル状態

```
/IoT機器
|-- (None files)

```

## IoTの方からgetしてみます。

```
tftp -g 192.168.11.12 -l hello.txt
ls
hello.txt
cat hello.txt
hello
````
無事、ファイルの転送ができました。

# 最後に

組み込み機器はbusyboxが入っていますが、SCPのような使い慣れたツールは入っておらず、後天的にパッケージをインストールすることもできないので、tftpというものを使いました。

getだけではなく、putもできるようなので、時間があれば記事の方を更新します。

# 参考にしたサイト様

https://server-network-note.net/2018/01/tftp/
社内のAWS JAMイベントに参加した

今日社内でAWS JAMのイベントがありましたので参加しました。

# AWS JAMとは？

https://aws.amazon.com/jp/blogs/news/aws-summit-tokyo-2023-aws-jam-intro/

AWS Summit Tokyo 2023のページで紹介した内容と似ています。チーム分けでAWS関連の課題を解決してポイントを獲得し、競い合うゲームです。
課題は簡単なものから難しいものまで色々あります。
実際にAWSのコンソールから操作して、必要な設定を弄って、結果をチェックする感じです。
ヒントがありますので、全然わからなくてもヒントを見ればどうすればよいのかわかります。

# 今日のイベント

今日は1時間半の枠で3人ごとにチーム分けでイベントが開催されました。
AWS Summit Tokyo 2023とは違い、hardの課題はありませんでした。
それでも普段あまり触ったことのないサービスがありましたので、課題を解くのに時間がかかりました。（security groupとか、load balancerとか）
結局自分のチームはあまり点が取れず、且つすべての課題を終わらせることができませんでしたが、チームで一緒に課題に取り込み且つ色々勉強になりましたので、なかなか楽しかったです。
内容が面白いし、且つ20時まで使えるのもあって、それまでに残りの課題を全部やりました。

# 感想

* 自分はAWSの資格を何個か取っていますが、業務で実際にAWSのサービスを触るチャンスが少ないですので、実際にAWSのサービスが触れるこのイベントは自分にとって結構有意義でした。
* 具体的な業務シナリオがあって、その中で発生した問題をトラブルシューティングする課題がありますので、結構勉強になりました。
* 後、課題の中AWS Lake Formationという自分の知らなかったサービスがありました。
  AWSでのデータ分析に興味があり、且つAWS Data Analystの資格をいつか取りたいと思いますので、もっと詳しくなりたいと思います。
* チームで一緒に取り組む形でしたので、コミュニケーション促進の意味でもなかなかいいイベントだと思います。

# 最後に

今日のイベントはAWS Skill Builderに参加している方に限定するイベントでした。
全社に範囲を広がって盛り上がるのもよさそうですね。
AWS JAMイベントはお勧めです！
天才エンジニアになった気分になれる音楽

# 突然ですが
皆さん、仕事中に音楽は聴きますか？
音楽といえば、歌詞を聞いて共感することで、元気を出したり悲しんだりするだけのモノだと思っていませんか？

否！
音楽というのは**仕事の効率化**にも役立つのです。
仕事中にゾーンに入ったことはありませんか？
適切な音楽を聴くことで意図的にゾーンに入れます。

これからわたくしがおすすめする音楽を聴くことで、
あなたの両の手がキーボード上で**ワルツを踊る**でしょう。
エンターキーを押すさまは老婆が子を寝かしつけるように**エレガントで繊細**。
何でもないif文は**天国と地獄を分かつ扉**の様。
そしてfor文は**輪廻転生の神秘**を表すのです。


# さっそく音楽紹介

## Jean-Michel Jarre-Équinoxe (1978)
![R-105388-1238292437.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3523264/6e639cfa-c84c-2c41-9afc-f745d2413b33.jpeg)

フランスの天才ジャン・ミッシェル・ジャールのキャリアハイとも言われる邦題「軌跡」です。ジャケットのセンスがたまらないですね。
かなり時代を感じさせるインストゥルメンタルのアナログ電子音楽です。ですがこの程よいレトロ感はきっとエンジニアの心をくすぐることでしょう。神秘的で適度な高揚を感じさせるこのアルバムは貴方を天才エンジニアに変貌させること間違いなし。たちまち**フランス映画のように難解なコード**を書きあげてしまうでしょう。

おすすめ曲：「Équinoxe Pt.3」


## Aphex Twin-Selected Ambient Works VollumⅡ(1994)
![81lrYSLBjiL._UF1000,1000_QL80_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3523264/77dc8a7b-5a0b-8485-a70b-dd9cccdb799c.jpeg)

こちらはテクノモーツァルトとも言われる天才エイフェックスツインの2時間半という大ボリュームの名盤です。某海外辛口音楽評論サイトでは満点を記録しています。
紹介しておいて何ですが、このアルバムは好みが別れるかもしれません。曲によっては不気味で悪夢のような雰囲気があります。ですが、それはエンジニアにとっては好都合。このアルバムはたちまち貴方をコードと数字のみが漂う精神世界に閉じ込めてしまうでしょう。その世界に誘われた貴方は、**誰も思いつかない、あっと驚くコード**をものの数秒で書きあげてしまうのです。

おすすめ曲：「#3」

## Radiohead-Kid A(2000)
![R-3165-1461363651-6420.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3523264/524e8bb8-6750-905b-38eb-192017d5a49a.jpeg)

皆大好きレディオヘッドのKid Aです。
レディオヘッドはUKロックのアーティストなのですが、電子音楽黎明期にたちまちロックと電子音楽の融合を果たしてしまいました。
計算されつくした緻密な音は、コーディングに最適。このアルバムが音楽の歴史を塗り替えた様に、このアルバムを聞いた貴方は時代を変えるコードを書いてしまうでしょう。もはやそれは**コードではない何か**なのかもしれませんね。

おすすめ曲：「Treefingers」

# さて
ここまで書いて途中から執筆の気力が失せてしまいました。
とりあえずほかに紹介しようと思っていた音楽以下にまとめておきます。

board of canada -Geogaddi
GAS- Pop
Heroku デザインパターン・アンチパターン

# はじめに
自分が作ったアプリをリリースしました！公開するときはAWSではなく、Herokuで公開しました！今回は、Herokuで公開してみて、これやってよかったなと思うもの（デザインパターン）とこれはしちゃだめだな（アンチパターン）ターンに分けて共有したいと思います。

作ってみたアプリケーションURL
+ [脈あり診断アプリ（男性用）](https://loveprovabirity-06c38203485f.herokuapp.com/
)

個人で開発していてただ公開したいだけならHerokuがおすすめ。
めっちゃくちゃ設定が簡単。AWSとかに比べたらッてことですが。

めちゃくちゃ、いい。

## デザインパターン
### Herokuを使う

まず、Herokuを使うのがとってもおすすめです。**Herokuじゃなかったら設定がめちゃくちゃめんどくさかった。** AWSを使おうと思ったんですけど、途中で挫折しちゃいました。
例えば、AWSだと、ルーティングしたりとか、どのインスタンスを使うのか？画像などのファイルはどうするのか？などなど、考えることがたくさんあって、たいへんです。

### 公式が用意してくれているプロジェクトとファイル構造を一緒にしよう

Getting Startedで公開されているやつと一緒のファイル構造にしてください。[こちらのURLをクリック](https://devcenter.heroku.com/start)。こちらからそれぞれの言語をクリックしたのちに、2から3ステップ目でGithubのページに飛ぶURLが分かるようになっています。

注意点：GitHubのページを参考にしてください。それぞれの言語ごとに異なります。ex.) python, go, node.js etc
+ https://github.com/heroku/node-js-getting-started.git
+ https://github.com/heroku/python-getting-started.git

Djangoの場合だと、
+ pythonをクリック
+ Clone Appのステップまで進める
+ クローンするリポジトリーのURLを選択

じゃないといろいろ読み込んでくれません。それぞれの言語によって少し違うのでそこは要注意でお願いします。

最初ちょっと違うファイル構造で出したら、「なんのアプリ？なんのフレームワーク使ってんの？」っていうエラーが出ちゃいます。。

### setting.pyの中身は公式が用意してくれているものを真似しよう

ちょっとここは設定がめんどくさかったです。
でも、大体はGetting Startedにあるsetting.pyをだいたいコピペしてれば大丈夫です。でも、名前とか必要なパッケージとかは残すようにしてsetting.pyを書こう。

### 公式ドキュメントをまずは読む

やっぱり、公式ドキュメントが最強です。最新で、正しい情報が記載されているので、、。何で、まずわからなかったら公式ドキュメントを見る。これが大切です。検索で「heroku doc デプロイ」みたいな感じで検索すれば、該当する公式ドキュメントが出てくると思います。それでも出てこなかったら、ブログを見たりとか、Stack Overflowを見るといいと思います！

### 詰まったらマウスに説明する

開発していながら「プリンシプル オブ プログラミング」という本を読んでいました。そこで、この詰まったら無機物に説明するというアドバイスがされています。どういうことかというと悩みとかを相談すると、なんか勝手に自己解決しちゃうみたいな。そんな感じに近いです。これはプログラムも一緒で、僕はマウスに説明していたのですが、 **1時間くらい悩んでいたエラーが、話し始めて1分くらいで解決しちゃったのを覚えています。**


## アンチパターン
### GitとGitHubを使用していない

Gitを使えるようになるまで大変だと思います。なんで困難使うねん、いらんやろって思いながら勉強していたのを昨日のことのように覚えています。でも、一度慣れてしまうと戻れないものですね。めちゃくちゃ便利です。どういうことかというと、**戻せるんですよ、それにチームでの開発もめちゃくちゃやりやすいんですよ。**
戻せるというのは、最悪、エラーがなかったその時に戻せるっていう意味です。もう、何が何だかわからなくなっちゃったって時に、、、、。やらないといけないという状況にならないのが一番ですが、、、、、。

### 仮想環境を作っていない。

仮想環境を作りましょう。pythonで開発してたんですけど、結構簡単に仮想環境って作ることできます。仮想環境っていうのは何かと申し上げますと、仮想の環境のことですね。今入れているアプリやパッケージ、ソフトウェアに影響されない環境を作ることができます。これの何がいいかっていうと、アプリごとに環境を作ることができるし、**余分なものが影響してこないっていうのがいいですね。** 自分が機械学習で入れているパッケージがちょっと悪さしていて動作しないとか、バージョンが違うからちょっと動作しないとか、そんなエラーが起きにくいのでぜひ仮想環境を作るようにしましょう。

### テストしていないのにコミットしちゃう

ほんとに、にこれやっちゃいましたね。コミットしたのにエラーがあって、何か知らんけど、クラッシュするみたいな。そして、それに気づかずに開発を続けっちゃっていつどこでエラーが発生したかがわからないなんてことが怒っちゃいます。テストしていないのにコミットしちゃうと。そんなことが起こらないためにも、**自動テストを走らせること　+ 自分が変更した箇所のテスト（手動で、できれば本番環境に近い状態で）軽くやるのがおすすめです。**


# おわりに
今回は最後まで読んでくれてありがとうございました。まとめると次のようになります。
+ Herokuを使う
+ 公式が用意してくれているプロジェクトとファイル構造を一緒にしよう
+ setting.pyの中身は公式が用意してくれているものを真似しよう
+ 公式ドキュメントをまずは読む
+ 詰まったらマウスに説明する
+ GitとGitHubを使用していない
+ 仮想環境を作っていない。
+ テストしていないのにコミットしちゃう

アプリ開発のコツやHerokuのデザインパターン、アンチパターンたくさんあると思いますが、個人的に思うのはこんな感じです。
では、楽しいひと時を。ハッピープログラミング！
【AWS x Github】エラー「Either the GitHub repository "xxx" does not exist」の原因とは？

# 概要
AWS CodepipelineでGithubの指定リポジトリの指定ブランチにマージがあった場合に、自動で実行される設定にしていたものが、突然「`Either the GitHub repository "xxx" does not exist`」のエラーで失敗してしまいました。

# エラー概要

エラー全文は以下の通りです。
Codepipelineでは、OAuth承認でGithub Webhookを連携させています。
(バージョン１は古いので推奨されていません...バージョン２にしないとですが)


```
Either the GitHub repository "xxx" does not exist, or the GitHub access token provided has insufficient permissions to access the repository. Verify that the repository exists and edit the pipeline to reconnect the action to GitHub.
```

## 原因
原因は、最近オーナーアカウントのメールアドレスを変更したことでした。
オーナーアカウントのメールアドレスを変更した場合、GitHubはアクセス権限に影響を及ぼす変更があったとみなし、既存のアクセストークンを無効にしてしまうことがあるようです。

## 解決策
以前のアクセストークンが無効になってしまったので、再度認証を行って新しいアクセストークンを取得する必要があります。
OAuth承認をもう一度実施するには、Pipelineの画面から「Githubに接続する」をもう一度実行してあげれば良いです。以下の「OAuth　リクエストを処理しています」という画面に飛ぶので、「確認」をクリックすると無事にパイプラインが走りました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710373/3a16eb81-bf34-cedb-3f9a-a8906f913d6b.png)

### OAuthとは？
OAuth（オーオース）は、Webサービスやアプリケーションに対して、ユーザーの認証と権限委任を行うためのオープンスタンダードな認証プロトコルです。

これにより、AWS CodePipelineがGitHubリポジトリにアクセスし、ソースコードを取得したりアクションをトリガーしたりする際に、ユーザーのGitHubの認証情報を直接提供せずに済むようになります。

利用する場合は、GitHubのOAuthトークンというアクセストークン（CodePipelineがGitHub APIにアクセスするために必要な認証情報）が必要です。AWS CloudFormationを使用して設定することが多いと思いますが、その際はSecretManagerから取得するなどした方が良いでしょう。
PlayCanvasで「遊べるMV」をつくった話

# 前置き
みなさま、PlayCanvasをご存知でしょうか？

WebGLで3Dコンテンツを作るためのブラウザベースのツールです。


UnityでWebGLコンテンツを吐き出すこともできるけど、色々としんどいじゃないですか……スマホ挙動とかデバッグとか…
それをぜーーーーーんぶ解消してJavaScriptベースで制作できる、バージョン管理システムまでついてる超・優れものです。

今回はそのPlayCanvasで自作音楽アルバムの「遊べるMV」バーチャル動物園コンテンツを作った話をします。

## そもそもなんですか遊べるMVって
わたくし、ミュージシャンとして活動しております。

これは宣伝なんですけど、今年2月に動物の鳴き声をフィーチャーしたアルバム「ZOO-ZOO-SEA」をリリースしました。

で、どうせなら「遊べるMV」を作りたいなと思ったのです。

クリックできる、360°ぐりぐり見れる。
で、動物がテーマなので動物園を作ろう。
ということで、これが完成品です。

https://geeker-natsumi.com/zoo/

ロードが重いのは後々改善したい。
重すぎて諦めちゃった方はこちらの動画で雰囲気を味わってくれ。

https://youtu.be/oOuk6F5n-jM

ではそれぞれの機能について紐解いていきます。

# 各機能

## カメラ操作
最初は何も知らずに自前実装しようとして四苦八苦していたのですが、公式exampleのソースコードを使ったらあっさり理想の挙動になりました。

https://developer.playcanvas.com/ja/tutorials/information-hotspots/

https://playcanvas.github.io/#/camera/orbit

ありがとう公式example。

## ビデオ再生
こちらの記事を参考にしました。

https://qiita.com/yushimatenjin/items/4c3a3839bffdd8859a6f


HLSというストリーミング形式でビデオを貼っています。

premireで制作したmp4を.mu8uという形式に書き出し直す必要があります。エンジニアならfffmpegなどを使って変換するのが一般的かと思いますが、わたしはものぐさがってこちらのブラウザ上での変換ツールを使いました。

https://mp4.to


## 音楽と同期して動物オブジェクトを動かす
音楽自動解析サービス「Songle」というものを利用しました。

https://songle.jp

YouTubeやmp3の楽曲を登録すると、BPMや曲のセクションなどを解析してくれ、いま何拍めが再生中なのかといった情報を受け取ることができます。

当初はmp3で試しましたが、埋め込み再生がなぜかうまくいかなかったのでYouTube経由で楽曲を登録しました。

これで再生中の楽曲のリズムにあわせて動物たちをTweenさせています。

## 音楽と映像を同期させる

動物と音楽を同期させるのは上記でクリアしましたが、では背景の映像との同期は……？

動画は環境によって度々ロードが走るので、単純に音楽と同時に再生開始するだけではズレが生じます。

動画の再生状態を見て、音楽もそれに合わせて一時停止したり再開したりといければよかったのですが、モバイルブラウザ仕様の壁が立ちはだかります。

ユーザーのアクションなしに音声付きのコンテンツの再生を開始することはできません。

ここで採用したのが下記の力技です。


「音声付きの動画を再生する。
Songleの埋め込みはiframeのDOMをほじくり、JavaScriptで無音にして任意のタイミングで再生停止できるようにする。」

無音コンテンツなら任意のタイミングで再生停止できます。
songleは無音で再生しても拍や楽曲情報を得ることが可能です。

## シークバー
シークバー実装はsongleにお世話になりました。

ドラッグでシークはできないですが、タップでのシークを実装しています。

再生中のsongle楽曲の長さと現在位置を取得し、バーの長さを決めています。

## ダブルタップで動物に関連するオブジェクトを投げる
それぞれのエリアの空間をダブルタップすると、その動物に関連するオブジェクトを投げることができます。

遊べるMVのアイデアとして、360°ぐりぐり見れる、動物をつんつんできる他だと実装できそうなのがこれだったのです…

これは、それぞれのエリアに透明な壁を立てて、その壁で当たり判定(Ray)をとっています。

その壁に動物に応じたタグを設定しておき、当たった壁を判別、オブジェクトを生成し落とす、という仕組みです。

# 作ってみて
初めは3DコンテンツならUnityかな？ってことでUnityで制作していましたが、モルモットとイルカを実装したあたりでUnityはWEBには絶望的に向いていないことを目の当たりにし挫折しました。

そこでPlayCanvasを見つけたのです。

Unityはもともと初学者に優しいツールだと思っているのですが、Unityで得た勘所があればPlayCanvasもわりといけます。

ふだんゲームや3Dコンテンツといったものにはあまり触れて来なかったのですが、「自分だけの壮大な箱庭を作っていく」感覚がとてもワクワしました。

わたしはモデリングができないので、各オブジェクトは全てロイヤリティフリーの3D素材サイトから買ったり落としたものです。

このへんから

https://free3d.com

https://www.cgtrader.com

寄せ集めの素材でもこんなに愛おしくなってしまうんだから、自分でモデリングからできたらどうなってしまうのでしょう……

肝心のアルバムのプロモーションとしては1mmもおバズりいたさずですが、インディアーティストがこんなもん作ったよ！ということで自慢半分、忘備録半分でした。

よかったらアルバムもきいてね！！！

https://linkco.re/ECpag29t
言語プロセッサ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457284/87476802-bb1c-f8cc-672f-89001622ae18.png)
１：言語プロセッサ
　言語プロセッサには、アセンブラ、コンパイラ、インタプリタがあります。
　アセンブラは、ニモニック表記の機械語プログラムをバイナリコードの機械語プログラム変換するプログラムです。
　コンパイラは、C,Javaといった高級言語のプログラムを、機械語プログラムに変換するプログラムです。コンパイラは、プログラム全体をまとめて機械語に変換してから実行します。

　一方で、インタプリタは、プログラムを１行ずつ解釈しなら実行します。１行解釈しては実行するという流れになりますから、プログラムの実行速度は遅くなりがちです。しかし、プログラムが途中までしか出来上がっていなくても、出来上がっているところまでは実行できるという点や、プログラムを途中で止めて、変数の内容をチェックしたり、プログラムを変更したのちに、続きをそのまま実行できる点などがコンパイラ方式葉理も優れています。
New Relicのアラートで指定したタイムゾーンの時刻を通知してみる

# 概要
稼働中のシステムにおいて何らかの問題やその兆候が発生した場合にアラートを受け取ることは運用監視においては一般的です。New Relicでも当然アラートの通知は可能ですが、通知する内容は要件に応じて柔軟にカスタマイズすることが可能になっています。今回、<font color="Red">**通知に含まれる時刻のタイムゾーンを自由に変更**</font>できるようになりました。

これにより、例えば、24時間体制でグローバルの拠点のメンバーと輪番体制をとっている場合にはローカルのタイムゾーンに合わせた通知など行うことができます。

:::note info
このアップデートの詳細はこちら
[New Relic アップデート(2023年6月)](https://newrelic.com/jp/blog/nerdlog/new-relic-update-202306)
[New Relic アップデート一覧](https://newrelic.com/jp/blog/nerdlog/new-relic-update)
:::

:::note info
無料のアカウントで試してみよう！
[New Relic フリープランで始めるオブザーバビリティ！
](https://qiita.com/ktst79/items/5ee74b34e6adb8a7a6fa)
:::

それでは早速やってみましょう。

# 手順
手順は非常に簡単です。
まず、New Relicログイン後に表示される「Alerts & AI」メニューにある「Workflow」にて通知内容の設定をします。
![AlertsAI-Menu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535230/a27e7ecd-7054-67e8-24f0-a4f692742a59.png)



通知内容には、テキストなどをハードコードで指定できる以外に、インシデントが発生した日時や監視対象など状況によって動的に変わるものを変数として指定することができます。
タイムゾーンを指定した日時を出力するためには以下のフォーマットを使います。

`{{#timezone <変数名> <タイムゾーン>'}}{{/timezone}}`

フォーマットの詳細は、以下の公式ドキュメントを参照ください。
https://docs.newrelic.com/docs/alerts-applied-intelligence/notifications/message-templates/#timezone

通知の際に利用できる変数は以下のドキュメントを参照してください。日時に該当するものはいくつかありますが、例えば、`createdAt`という変数は、Issueが生成された日時を表します。
https://docs.newrelic.com/docs/alerts-applied-intelligence/applied-intelligence/incident-workflows/custom-variables-incident-workflows/

また、指定できるタイムゾーンは以下に記載されています。
https://en.wikipedia.org/wiki/List_of_tz_database_time_zones


さて、実際に設定してみましょう。今回はタイムゾーンとしてAsia/TokyoとUTCの2つを指定してみます。必要あればそれ以上指定することも可能です。

```text:通知設定
Tokyo time:
{{#timezone createdAt 'Asia/Tokyo'}}{{/timezone}}
UTC time:
{{#timezone createdAt 'UTC'}}{{/timezone}}
```
![Slack-Config.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535230/14f7ea17-1498-2a0c-898a-8f4c022ec30e.png)




通知された内容を確認してみます。以下のスクリーンショットはSlack通知の一部です。確かに、それぞれ指定したタイムゾーンで出力されていることがわかります。
今回はSlack通知内容を確認しましたが、メールなどその他のチャネルへの通知も同様です。
![Slack-Notification.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535230/4098a497-92ed-eee7-383d-101ea13b57e0.png)



# まとめ
今回、指定したタイムゾーンに対応した時刻をアラート通知内容に含める方法をご紹介しました。デフォルトで通知されるタイムゾーンから変更したい場合、輪番体制などで複数のタイムゾーンにまたがる場合などは是非ご利用ください。

:::note info
このアップデートの詳細はこちら
[New Relic アップデート(2023年6月)](https://newrelic.com/jp/blog/nerdlog/new-relic-update-202306)
[New Relic アップデート一覧](https://newrelic.com/jp/blog/nerdlog/new-relic-update)
:::

:::note info
無料のアカウントで試してみよう！
[New Relic フリープランで始めるオブザーバビリティ！
](https://qiita.com/ktst79/items/5ee74b34e6adb8a7a6fa)
:::
GAS CDN 作り方(jqueryのCDNみたいなやつ)

ここではまって、誰もネットに公開してなかったみたいなので（簡単に調べた限り）公開します。  
ChatGPT4にはまったポイントをつたえて、アドバイスもらったら意外とあっさり？できました。

以下コピペ

HtmlServiceのcreateHtmlOutputFromFileメソッドは、スクリプトプロジェクトに含まれるHTMLファイルの内容をHTML出力として返します。しかし、JavaScriptファイル(.js)を読み込む際には適していません。

代わりに、ContentServiceを使用してJavaScriptファイルをテキストとして返すことができます。以下はそのためのサンプルコードです。

```javascript
function doGet(request) {
  var file = DriveApp.getFileById("YOUR-FILE-ID"); // あなたのファイルIDに置き換えてください
  var data = file.getBlob().getDataAsString();
  return ContentService.createTextOutput(data)
    .setMimeType(ContentService.MimeType.JAVASCRIPT);
}
```

このコードでは、指定されたIDのGoogle Drive上のファイルを取得し、その内容を文字列として読み取ります。その後、ContentServiceを使用してそのデータをテキスト出力として返し、そのMIMEタイプをJavaScriptに設定します。

このスクリプトをウェブアプリケーションとして公開したら、そのURLを使って他のウェブページからJavaScriptファイルを読み込むことができます。

なお、ファイルIDはGoogle Drive上でそのファイルを右クリックして「共有可能なリンクを取得」を選び、表示されたURLの末尾の部分です。

しかし、この方法もGASの制限（実行時間、URL Fetchコール数など）によって大量のリクエストや大規模なデータには向いていないことを覚えておいてください。


これを活用して、フレームワークを作りました。
https://fkeiwk.hateblo.jp/entry/2023/08/02/205815
式形式のメソッド定義は読みづらい[C#]

最近過去の自分のコードを見ていて少し思うところがあり，その中で気づいた点の1つです．新しく覚えた書き方の便利さに触れた時に陥りやすい罠かもしれないと思います．

C#で，メソッドの定義は通常このような形で行います．

```cs
public static bool IsElon(User user)
{
    return user.Id == "elonmusk";
}
```

ただ，このようなシンプルなメソッドの定義をこのように書くのは間延び感があります．そのようなケースのため，以下のような文法が用意されています．

```cs
public static bool IsElon(User user) => user.Id == "elonmusk";
```

このような形式を｢式形式｣と呼びます．

# 読みやすいパターン

タイトルでは｢読みづらい｣と言いましたが，シンプルで短いメソッドに対してはとても効果的な書き方です．

- ごく簡単な操作を行うメソッドに対して使う場合

    ```cs
    // public bool IsDirty { get; private set; }
    public void SetDirty() => IsDirty = true;
    ```

- getterやsetterを書く場合

    ```cs
    // private bool _isDirty;
    public bool IsDirty
    {
        get => _isDirty;
        private set => _isDirty = value;
    }
    ```

こういった場面では，書き手読み手双方にとって便利な書き方です．

# 読みづらいパターン

ではどのような場面で読みづらくなるかというと，メソッドの内容が単純ではない場合です．

```cs
public static bool CanMove(Player player, bool ignoreMenu) =>
    player != null &&
    player.AmOwner && (
        ignoreMenu || (
            !OptionsMenu.Instance.IsOpening &&
            !PopupManager.Instance.IsShown)) &&
    !player.Animator.IsAnimating;
```

見ているだけでうんざりしてきます．このような場合は無理して式形式を使わず，多少長くなっても素直にこう書くべきです．

```cs
public static bool CanMove(Player player, bool ignoreMenu)
{
    if (player == null)
    {
        logger.LogDebug("playerがnull");
        return false;
    }
    if (!player.AmOwner)
    {
        return false;
    }
    var isMenuOpening = OptionsMenu.Instance.IsOpening || PopupManager.Instance.IsShown;
    if (!ignoreMenu && isMenuOpening)
    {
        return false;
    }
    return !player.Animator.IsAnimating;
}
```

このように書く方が，行数の少なさにこだわるよりも遥かに利点が多いです．式形式では，1つの式に収めなければならないという制約がありますが，そういった制約を気にせず書けます．この例で示されただけでもざっと以下のようなメリットがあります．

- 途中でログの出力や例外の送出を行える
- 早期リターンを使える
  - 前提条件，このような場合は常にfalseになるよ，というような意図が汲み取りやすくなる
- 要約変数(`isMenuOpening`)を使える
  - ｢メニュー｣以外に様々な状態を考慮する必要があるような場合でも，どこからどこまでがメニューに関する判定をしているのか，といったことが読み取りやすくなる
  - 今後｢メニュー｣に該当するものが増えた際は`isMenuOpening`の右辺に追加されるため，メニュー開閉の条件を増やしたことがわかりやすい
    - メソッドの分割やメニューのリファクタを行うと尚良

# 結論

式形式の書き方は単純なメソッドに対しては強力ですが，濫用するとかえってコードを複雑に入り組んだ読みにくいものにしてしまい，バグの原因にもなります．
個人的な基準としては，式形式にしたときに2行以上にわたるようなメソッドや，複数の条件が絡み合うようなメソッドには使用を避けています．
プロジェクト内で明確に決められていない限り，使用は本当に単純なメソッドに限り，読みやすさに十分に気をつけて使うのが無難です．
JavaScriptの演算子優先順位とテンプレート文字列：バグの回避とコードの明確化


---

# 目次
1. [はじめに](#introduction)
2. [問題の発生](#problem)
3. [問題の理解](#understanding)
4. [解決策 1: 括弧の使用](#solution1)
5. [解決策 2: テンプレート文字列の使用](#solution2)
6. [まとめ](#conclusion)

---

<a name="introduction"></a>
## はじめに

JavaScriptは非常に便利な言語ですが、その柔軟性が時として混乱を招くこともあります。特に、演算子の優先順位についての理解が不十分な場合、思わぬバグを引き起こす可能性があります。

本記事では、Null 合体演算子(`??`)と文字列結合演算子(`+`)の間で発生する一般的な問題を取り上げ、その解決策を2つ（括弧の使用とテンプレート文字列の使用）提案します。

---

<a name="problem"></a>
## 問題の発生

以下のようなReactコンポーネントがあります。このコンポーネントは、プロファイルから姓（familyName）と名（givenName）を取得し、それらを結合して表示します。

```jsx
<DisplayProfileData
    label="名前"
    value={
        profile?.familyName ?? '' + profile?.givenName ?? ''
    }
/>
```

しかし、期待通りに動作しないことがあります。具体的には、`givenName`が表示されず、`familyName`のみが表示されることがあります。

---

<a name="understanding"></a>
## 問題の理解

この問題の原因はJavaScriptの演算子の優先順位にあります。JavaScriptでは、`??`（Null 合体演算子）は`+`（文字列結合演算子）よりも優先順位が低いです。したがって、`profile?.familyName ?? '' + profile?.givenName ?? ''`という表現は、`profile?.familyName`と`'' + profile?.givenName`の結果が`null`や`undefined`であれば`''`（空文字列）を返します。

したがって、`profile?.familyName`が`null`や`undefined`でなければ、`value`は`profile?.familyName`のみを表示します。その後、`+ profile?.givenName ?? ''`が評価されますが、`+ profile?.givenName`が`null`や`undefined`であれば結果は`''`となり、それ以外の場合は`NaN`（JavaScriptの"Not a Number"）となります。

---

<a name="solution1"></a>
## 解決策 1: 括弧の使用

この問題を解決するためには、`+`演算子が`??`演算子よりも先に評価されるように、括弧を使って演算子の優先順位を明示的に指定する必要があります。

以下のように修正しましょう：

```jsx
<DisplayProfileData
    label="名前"
    value={
        (profile?.familyName ?? '') + (profile?.givenName ?? '')
    }
/>
```

この修正により、`familyName`と`givenName`の両方が表示されるようになります。

---

<a name="solution2"></a>
## 解決策 2: テンプレート文字列の使用

もう一つの解決策は、JavaScriptのテンプレート文字列を使用することです。テンプレート文字列は、変数や式を埋め込むことができる文字列リテラルです。バッククォート（\`）で囲み、変数や式は\$\{ \}で囲んで埋め込みます。

以下のように修正しましょう：

```jsx
<DisplayProfileData
    label="名前"
    value={
        `${profile?.familyName ?? ''}${profile?.givenName ?? ''}`
    }
/>
```

テンプレート文字列を使用すると、演算子の優先順位について心配する必要がなくなります。テンプレート文字列はリテラルの値をそのまま文字列として扱うため、`+`演算子や`??`演算子の挙動について考える必要がなくなります。

---

<a name="conclusion"></a>
## まとめ

JavaScriptの演算子優先順位は、コードが思わぬ動作をする原因となることがあります。特に、`??`と`+`を組み合わせて使用する際は、その優先順位に注意を払う必要があります。しかし、括弧を使用して明示的に優先順位を指定したり、テンプレート文字列を使用して問題を回避することも可能です。

以上が、Nullish coalescingと文字列結合を混ぜた際に起こる一般的な問題とその解決策です。この記事があなたのJavaScriptプログラミングに少しでも役立つことを願っています。

---

いいね！やコメントをいただけると嬉しいです！また、何か質問があればお気軽にどうぞ。
JavaScriptで名前に数値が含まれるグローバル変数をループで動的に呼び出すコツ

# 背景
過去にJavaScriptを使って動的にグローバル変数を呼び出そうとした際、とある初歩的な内容で困ったことが印象的だったため、自分への備忘録を兼ねて記事に残すことにした。


# 例題
以下のようなコードを実装しようとしていた。

~~~
// 変数はグローバル変数とする。
var a1 ="aa1";
var a2 ="aa2";
var a3 ="aa3";
・
・
・
var a98 ="aa98";
var a99 ="aa99";
var a100 ="aa100";
var array = ["aa0"];
for (var x = 1; x <= 100; x++) {
	//変数xを使って、 array配列に変数a1~a100の値を順番に入れたい。
　　//最終結果：array = ["aa0","aa1","aa2","aa3",・・・,"aa98","aa99","aa100"]
　　//ただし、array.push(a1); ・・・array.push(a100); のように、
　　//a1~a100の変数を代入するコードを1行ずつ直接記載するのは無しとする。
}
~~~

# 困った理由
今までは「特定のタイミングで特定のグローバル変数を指定して呼び出す」ことが確定していたため、該当のグローバル変数を直接指定することで解決できていた。
しかし、今回のようにループ条件(変数xの値)のみで動的に特定のグローバル変数を呼び出す方法が不明だったため、とても困った。
※「array.push(a1);」 などを1つずつ書くのはメンテナンスが大変そうであり、可能な限り数行で抑えたかった。

# 解答例
以下のように記載することで対応可能。
~~~
// 変数はグローバル変数とする。
var a1 ="aa1";
var a2 ="aa2";
var a3 ="aa3";
・
・
・
var a98 ="aa98";
var a99 ="aa99";
var a100 ="aa100";
var array = ["aa0"];
for (var x = 1; x <= 100; x++) {
	//呼び出したい変数名を文字列で確保する変数を作成
	var variablename = "a" + x;
	//変数名から該当変数を呼び出す
	array.push(window[variablename]);
}
~~~

# 解説
「window[変数名]」で、「変数名」を持つ変数の値を参照しているが、これはJavaScriptのグローバル変数の仕組みがカギとなっている。

基本、グローバル変数を宣言する場合は、「var 変数名 = 値」のように宣言するのが一般的だが、この宣言方法は「var window.変数名 = 値」の短縮版となっている。
(この時の「window」は、「windowオブジェクト」と呼ぶ。)

短縮版(var 変数名 = 値)でグローバル変数を宣言した場合でも、本来の宣言方法(var window.変数名 = 値)で内部上処理されているため、解答例のように[]内に変数名の文字列を記載することで本件は解決できる。

# まとめ
結果論だが、1,2行のコードで解決できる問題だった。
しかし、Javascriptに初めて触れてから約4年以上経っており、グローバル変数に関しては一通り認識していたつもりだったが、意外と根本的なところでつまずく結果となった。
今回のように、「初歩的だが、内部の具体的な処理方法を理解しきれていない」ことが他でも当てはまりそうなため、他の課題にぶつかった際も、今回のように原点回帰して解決策を探してみようと思う。

# 参考文献
[グローバルオブジェクト | 現代の JavaScript チュートリアル](https://ja.javascript.info/global-object)
C#で簡単なステートマシンを作って使う

5年前に書いた記事 [Swiftで簡単なステートマシンを作って使う](https://qiita.com/herara_ofnir3/items/4d28bf2615bebcba9b13) のC#版です。

他の言語で実装したらどうなる？と聞かれたので、とりあえずC#でやってみます。

# 本体
イベント構文は便利ですね。

```csharp
class StateMachine<TState, TEvent>
{
	public StateMachine(TState initial, Func<TState, TEvent, TState?> routing)
	{
		Current = initial;
		this.routing = routing;
	}

	public TState Current { get; private set; }
	Func<TState, TEvent, TState?> routing;

	public event Action<StateChangeType, TState>? Changed;

	public void Transition(TEvent by)
	{
		var next = routing(Current, by);
		if (next == null)
		{
			return;
		}

		Changed?.Invoke(StateChangeType.OnExit, Current);
		Current = next;
		Changed?.Invoke(StateChangeType.OnEnter, Current);
	}
}

enum StateChangeType { OnEnter, OnExit }
```

# 定義
レコード型を使ってADTっぽく定義します。
できればシングルトンとかにしたほうが丁寧でいいですね。

```csharp
abstract record EditState();
sealed record Editing() : EditState;
sealed record Confirming() : EditState;
sealed record Saving() : EditState;
sealed record Saved(SaveResult SaveResult): EditState;

abstract record EditEvent();
sealed record Save() : EditEvent;
sealed record Confirm(bool IsOk) : EditEvent;
sealed record FinishSave(SaveResult SaveResult) : EditEvent;
sealed record ShownResult() : EditEvent;

abstract record SaveResult();
sealed record Success() : SaveResult;
sealed record Failure(SaveError Error) : SaveResult;
```

# 使い方


```csharp
class EditViewController
{
	public EditViewController()
	{
		stateMachine = new StateMachine<EditState, EditEvent>(new Editing(), (state, evt) => (state, evt) switch
		{
			(Editing, Save) => new Confirming(),
			(Confirming, Confirm { IsOk: true }) => new Saving(),
			(Confirming, Confirm { IsOk: false }) => new Editing(),
			(Saving, FinishSave finishSave) => new Saved(finishSave.SaveResult),
			(Saved, ShownResult) => new Editing(),
			_ => null,
		});

		stateMachine.Changed += OnStateChanged;
	}

	StateMachine<EditState, EditEvent> stateMachine;

	void OnStateChanged(StateChangeType type, EditState state)
	{
		switch (type, state)
		{
			case (StateChangeType.OnEnter, Confirming):
				OnEnterConfirming();
				break;
			case (StateChangeType.OnEnter, Saving):
				OnEnterSaving();
				break;
			case (StateChangeType.OnEnter, Saved saved):
				OnEnterSaved(saved.SaveResult);
				break;
		}
	}

	void OnEnterConfirming()
	{
		// 確認ダイアログを表示する
		// ...
		// ... OK/NGが選択されたら stateMachine.Transition(new Confirm(isOk)) を呼ぶ
	}

	void OnEnterSaving()
	{
		// 保存処理を開始する
		// ...
		// ... 保存処理が終わったら stateMachine.Transition(new FinishSave(saveResult)) を呼ぶ
	}

	void OnEnterSaved(SaveResult result)
	{
		switch (result)
		{
			case Success:
				// 保存に成功したことを表示する
				break;
			case Failure f:
				// 保存に失敗したことを表示する
				break;
		}

		stateMachine.Transition(new ShownResult());
	}
}
```

# 感想
最近のC#(9.0以降？)だとレコード型とパターンマッチが使えるので、Swiftと近い実装にできますね。

旧いバージョンの場合、この方針だと色々辛そうなので別のアプローチが必要です。
思いついたら書きます。もしいい方法があったら教えてほしいです。
[Oracle Cloud] OCIFS ユーティリティをつかってObject Storageのバケットをマウントしてみた。(2023/08/02)

# はじめに
OCI Object Storageバケットをファイルシステムとしてマウントが可能なOCIFSユーティリティが提供されました。
OCIFSを使用してObject Storageバケットをマウントした後、そのバケット内のオブジェクトに通常のファイルまたはディレクトリとしてアクセスできます。
インストールし使用してしてみました。

# OCIFSユーティリティの前提条件

- OCIFS ユーティリティ ( ocifs ) パッケージは、Oracle Linux 8 以降で使用可能
- OCI Object StorageのバケットにアクセスできるシステムまたはOCI コンピュートインスタンス
- Object Storageのバケットは事前に作成
- ローカル・ディスク領域
    - OCIFSは、Object Storageのオブジェクトをキャッシュするためにローカル・ディスク領域を消費する

# OCIFSユーティリティをインストール

1. 前提条件のクリア
1. ocifsパッケージを含むoci_includedリポジトリを有効化
   -   OCI プラットフォームイメージのOracle Linux 8 / Oracle Linux 9 では有効化済み
1. ocifsパッケージをインストール

```
$ sudo dnf install ocifs
```

# OCI認証の設定

OCIFSユーティリティは APIキーベースの認証（デフォルト）またはインスタンスプリンシパル認証で認証します。

### APIキーベースの認証

CLI 構成ファイル ( ~/.oci/config) に[DEFAULT]プロファイルと以下のエントリが必要です。( cli のインストールは 不要です )
- user
- tenancy
- region
- key_file
- finderprint

構成ファイルの例
 
```~/.oci/config
[DEFAULT]user=ocid1.user.oc1..aaaaaaaaXXXXX
fingerprint=fa:56:8a:e9:42:c8:8a:07:49:73:XX:XX:XX:XX
tenancy=ocid1.tenancy.oc1..aaaaaaaaXXXXX
region=ap-tokyo-1
key_file=/home/opc/.ssh/private.pem
```

### インスタンスプリンシパル認証

1. コンピュート・インスタンスに一致するルールを使用して、動的グループを作成
1. 動的グループにObject Storageの管理を許可するポリシーを作成
Allow dynamic-group <動的グループ名> to manage object-family in compartment <コンパートメント名>

# OCIFSでのマウント

$ ocifs <バケット名> <ディレクトリ名>

ocifs_bucket バケットを ./mydir にマウントする例
```
$ mkdir mydir
$ ocifs ocifs_bucket mydir
```

マウント後は 通常のファイルシステムディレクトリとしてファイル操作が可能

```
$ cd mydir
$ vi abc.txt
$ cp $HOME/a.csv .
$ ls -l
total 0
-rw-r--r--. 1 opc opc  168 Aug  2 00:00 aba.txt
-rw-r--r--. 1 opc opc    5 Aug  2 00:00 a.csv
```

OCI Webコンソールなどで Object Storage にアップロードしたファイルも確認可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108635/82e5e56d-534d-2271-9fd0-7b6311f07b38.png)

```
$ ls -l mydir
total 0
-rw-r--r--. 1 opc opc  595 Aug  2 00:00 2023.txt
-rw-r--r--. 1 opc opc  168 Aug  2 00:00 aba.txt
-rw-r--r--. 1 opc opc    5 Aug  2 00:00 a.csv
```


### インスタンスプリンシパルでの認証
インスタンスプリンシパルで認証する場合は --auth オプションを追加します。

```
$ mkdir mydir
$ ocifs --auth=instance_principal ocifs_bucket mydir
```

# OCIFS のアンマウント
fusermount コマンドで アンマウントします。

```
fusermount -u mydir
```



# 留意点

- OCIFS は共有ファイル システムではありません。
- オブジェクト・データの破損を避けるため、OCIFSを使用して同じオブジェクト・ストレージ・バケット(または重複するバケットのサブフォルダ)を同時にマウントしないでください。

# 補足
root ユーザでのマウント/アンマウントも可能

```
# mkdir /mnt
# mount -t fuse.ocifs ocifs_bucket /mnt
# umount /mnt
```

# おわりに

簡単に Object Storage バケットを ファイルシステムのように操作することができるようになりました。

# 参考情報

- [OCIFS Utility](https://docs.oracle.com/en-us/iaas/oracle-linux/ocifs/index.htm)
- [Introducing OCIFS](https://blogs.oracle.com/linux/post/introducing-ocifs)
- [Oracle Cloud(OCI)のoci cli設定ファイルの使い方をまとめてみた](https://qiita.com/feifo/items/29d842da0102379cf527)
- [[Oracle Cloud] インスタンスプリンシパル を OCI Go SDK で使ってみた](https://qiita.com/sugimount/items/159852749851282a33e6)
Gitブランチの一括削除! 煩雑な作業を一行で解決する方法



- 目次
    - [はじめに](#introduction)
    - [必要なもの](#requirements)
    - [ブランチの削除](#delete_branches)
    - [Zsh環境でのalias設定](#zsh_alias)
    - [注意事項](#caution)
    - [終わりに](#conclusion)

## <a name="introduction">はじめに</a>

Gitを使っていると、特にフィーチャーブランチを頻繁に作成する場合、ブランチの管理が複雑になりがちです。ブランチが増えてくると、それらを一つ一つ手動で削除するのは大変ですよね。今回は、マージ済みのGitブランチを一括で削除する方法と、Zsh環境でのalias設定方法について解説します。

## <a name="requirements">必要なもの</a>

- Gitがインストールされていること
- Zshがインストールされていること（alias設定の部分で必要）

## <a name="delete_branches">ブランチの削除</a>

まずは、マージ済みのブランチを表示するコマンドから始めましょう。

```bash
git branch --merged
```

このコマンドは、現在のブランチから見てマージ済みのブランチの一覧を表示します。

次に、このリストから `master` ブランチや他の保持したいブランチを除外し、残りのブランチを削除します。以下のコマンドは `master` と `develop` ブランチを除外し、残りのマージ済みブランチを削除します。

```bash
git branch --merged | egrep -v "(^\*|master|develop)" | xargs git branch -d
```

ここで、`egrep -v "(^\*|master|develop)"` の部分は、マージ済みブランチのリストから現在のブランチ（`*`で表示される）、`master` ブランチ、`develop` ブランチを除外します。保持したいブランチが他にもある場合は、この部分に名前を追加してください。

最後に、`xargs git branch -d` は、フィルタリングした各ブランチに対して `git branch -d` コマンド（ブランチの削除コマンド）を実行します。

## <a name="zsh_alias">Zsh環境でのalias設定</a>

この一連のコマンドをaliasとして設定すると、コマンドを一度打つだけでマージ済みのブランチを削除できます。これにより、コマンドの打ち間違いを防いだり、タイピングの手間を減らすことができます。

Zsh環境でaliasを設定するには、`~/.zshrc` ファイルに以下の行を追加します。

```bash
alias delete_merged_branches="git branch --merged | egrep -v \"(^\*|master|develop)\" | xargs git branch -d"
```

この設定を保存した後、新しいターミナルセッションを開始するか、以下のコマンドを実行して `.zshrc` ファイルの変更を反映させます。

```bash
source ~/.zshrc
```

これで、`delete_merged_branches` というコマンドをターミナルで実行すると、マージ済みのブランチが削除されます。

## <a name="caution">注意事項</a>

Gitでブランチを削除するときは注意が必要です。削除操作は取り消しできませんので、削除するブランチが本当に必要ないものであることを確認してから実行してください。また、このコマンドはローカルのブランチを削除します。リモートのブランチを削除するには、ブランチ名を指定して `git push origin --delete <branch_name>` を実行する必要があります。

## <a name="conclusion">終わりに</a>

今回は、マージ済みのGitブランチを一括で削除する方法と、Zsh環境でのalias設定方法について解説しました。これにより、ブランチの管理がより楽になり、効率的な開発作業が可能になることでしょう。それでは、Happy Git-ing!
2つの封筒問題（金額仮定版）を現実的に解いたら驚愕の結果になった

## 前書き

数学的に解いた記事はこちら

https://qiita.com/mogamoga1337/items/be9c610f778dda223138

今回は現実世界で実際に行われると仮定して解きます。

## 数学的と現実的では何が異なるのか

数学的に考えると2つの封筒の金額の組み合わせは無限に考えられます。
例えば、100那由他円と200那由他円だとしても何ら問題ないわけです。
ですが、現実的に考えるとこういった天文学的金額が入っているとは考えられません。
つまりなんらかの上限があると考えるのが現実的です。

## 解く

解くと言っても数学的に解きません。
プログラムでシミュレーションして交換前と交換後の平均値をとり考察していきます。

また封筒を開けて奇数円の場合、明らかに交換有利なため、
封筒を開けて偶数の場合のみをシミュレーションします。

### プログラム

```js
const 最大金額 = 1000000;
const 半額最小金額 = 1;
const 半額最大金額 = 最大金額 / 2;
let 試行回数 = 0;
const 最大試行回数 = 10000000;

let 交換前金額合計 = 0;
let 交換後金額合計 = 0;

function 乱数生成(min, max) {
	return Math.floor(Math.random() * (max - min + 1)) + min;
};

function にぶいち(a, b) {
	return Math.random() < 0.5 ? a : b;
};

for (let i = 0; i < 最大試行回数; i++) {
	const 封筒1 = 乱数生成(半額最小金額, 半額最大金額);
	const 封筒2 = 封筒1 * 2;
	const 選択した封筒 = にぶいち(封筒1, 封筒2);
	if (選択した封筒 % 2 === 1) {
		continue;
	}
	const 選択していない封筒 = 選択した封筒 === 封筒1 ? 封筒2 : 封筒1;

	交換前金額合計 += 選択した封筒;
	交換後金額合計 += 選択していない封筒;

	試行回数++;
}

const 交換前平均 = 交換前金額合計 / 試行回数;
const 交換後平均 = 交換後金額合計 / 試行回数;
console.log(`交換前平均：${交換前平均}`);
console.log(`交換後平均：${交換後平均}`);
console.log(`交換後平均 - 交換前平均：${交換後平均 - 交換前平均}`);
```

実行結果

1回目

```shell
交換前平均：416695.6769510277
交換後平均：333358.8286292419
交換後平均 - 交換前平均：-83336.8483217858
```

2回目

```shell
交換前平均：416606.64031773026
交換後平均：333295.18355957104
交換後平均 - 交換前平均：-83311.45675815921
```

3回目

```shell
交換前平均：416735.328635139
交換後平均：333457.8777614282
交換後平均 - 交換前平均：-83277.4508737108
```

4回目

```shell
交換前平均：416678.64896057214
交換後平均：333388.62810229266
交換後平均 - 交換前平均：-83290.02085827949
```

5回目

```shell
交換前平均：416716.12026615045
交換後平均：333341.75925688125
交換後平均 - 交換前平均：-83374.3610092692
```

交換前と交換後で平均値がそれぞれ約417000と約333000となり、交換しないほうが有利という結果になりました。正直予想外です。

また最大金額を10000000や100000000にして試してみましたが、
同様の結論が導き出されました。

## 結論

現実的に金額に上限があると仮定し、選択した封筒の金額を見た場合
交換しないほうが有利だと分かりました。
もちろんこれは観測した値が偶数の場合の話です。
奇数の場合は100％交換有利なので以下のような戦略をとるとよいでしょう。

選択した封筒の金額が奇数 → 交換する
選択した封筒の金額が偶数 → 交換しない

終わり。

間違いがあれば教えてください。
Reactパフォーマンスを最大70%向上させる!? Million.js入門



# 目次
1. [Million.jsとは](#what-is-millionjs)
2. [Million.jsのインストール方法](#how-to-install-millionjs)
3. [Million.jsの基本的な使い方](#how-to-use-millionjs)
4. [Million.jsでのパフォーマンス向上](#performance-improvement-with-millionjs)
5. [まとめ](#conclusion)

## <a name="what-is-millionjs"></a>1. Million.jsとは

Million.jsは、Reactのコンポーネントを高速化するライブラリです。これにより、Reactコンポーネントのパフォーマンスが最大70%向上するとされています[^1^]。

## <a name="how-to-install-millionjs"></a>2. Million.jsのインストール方法

Million.jsはnpmを通じて簡単にインストールできます。以下のコマンドを実行してください。

```
npm install million
```

## <a name="how-to-use-millionjs"></a>3. Million.jsの基本的な使い方

Million.jsの基本的な使用方法は、Reactのコンポーネントを`block`という関数で包むだけです。以下に例を示します。

```jsx
import { block } from "million";

function Lion() {
  return (
    <img src="https://million.dev/lion.svg" />
  );
}

const LionBlock = block(Lion);
```

上記のように、Million.jsを使用すると、Reactのコンポーネントを高速化できます。

ただし、現時点ではUIコンポーネントライブラリと一緒に使うことはできず、またコンポーネントにpropsを渡す際にスプレッド構文が使えないなど、まだいくつかの制約が存在します[^1^]。

## <a name="performance-improvement-with-millionjs"></a>4. Million.jsでのパフォーマンス向上

Million.jsはReactの代替品ではなく、Reactとともに働き、Reactのパフォーマンスを向上させるツールです。独自の仮想DOMを使用してレンダリング速度を上げ、再レンダリングを最適化します。

再レンダリングの最適化は、ブロック仮想DOMという仕組みによって実現されています。これは、仮想DOMを解析し、動的な部分を抽出する「静的解析」、そして状態が変更された場合にDOMが直接更新される「ダーティーチェック」の2つの部分からなります[^1^]。

具体的なパフォーマンス向上の数値については、アプリケーションの種類や使用するReactコンポーネントの複雑さ、そしてMillion.jsの使用方法によって大きく変わる可能性があります。そのため、具体的な数値を得る最善の方法は、自身のアプリケーションでベンチマークテストを実施することです。

## <a name="conclusion"></a>5. まとめ

Million.jsは、Reactのコンポーネントを高速化するための強力なライブラリです。独自のブロック仮想DOMを使用してレンダリング速度を最適化し、再レンダリングを効率化します。今後の更新により、さらなるパフォーマンス向上や制約の緩和が期待されます。
What to do? What, todo?

最近の本で Rust を勉強中。

で、本で作るプロジェクトは良くあるような "To Do" アプリ。コードで ToDo という構造体や、todo_ で始まる関数などか定義されている。

そんな中に、todo!() と言った分が出てきたりする。

実はこれ、このアプリとは全く別で、Rust の std ライブラリが定義するマクロの名称。

https://doc.rust-lang.org/std/macro.todo.html

これはさすがに紛らわしいわ。
毎日のチェックリストをペーパレス化！～ノーコードでアプリを作る～



# 紙資料大好き
こんにちは。DXという言葉をよく聞くようになりましたが、いまだに紙資料が大好きなOLです。

私は、書類内容のチェックなど、いまだにPC画面上で見るより紙面で見る方が好きでつい印刷してしまいます。ですが、紙の無駄＆紙資料だからこそのめんどくさい作業もあったりしますよね。

# 困りごと
私は商業施設の運営管理の仕事を行っており、来店頂くお客さまの安全安心を守ることがとても大切な業務の一つです。

閉店時、各ショップさまが店内の施錠・消灯したか、電気や火を使う製品の電源をきちんと消しているいるか等、ショップスタッフさま自身でしっかり確認してもらい、事故が発生しないように指導したりもしています。

閉店時に施錠・消灯など漏れがないかショップスタッフさまに確認してもらうためにチェックリストを配布しており、毎日各ショップの閉店業務を担当するスタッフさまにリストを実際に見ながら施錠・消灯等してもらい、チェックリストに記入、最後に提出をして頂いています。そして、警備がそのリストに漏れがないか確認して翌朝私達運営スタッフがショップへ返却するという流れです。

事故を未然に防ぐためこのチェックリストを運用しているのですが、ショップさまのポストへ投函返却するため、時間がかかってしまいます。この返却作業の時間を短縮したら別の業務に時間をさくことや業務のクオリティを上げることができるかもしれない。

# じゃあデジタル化しちゃおうかな
`紙ではなくWEB上でチェックリストを提出してもらえば返却作業が不要になって手間が省けるのでは！`ということで作ってみたいと思います。

# 使用ツール
+ Google Sheets(スプレッドシート)
+ [Glide](https://www.glideapps.com/templates "Glide")

# 作成方法
 **①スプレッドシートに項目とチェック欄を作成** 
![コメント 2023-08-02 001111.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3474647/019f23c7-ab77-5139-61f4-7b36ca9a8b94.png)
 **②GlideでNew projectを選択** 
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3474647/bfca0da6-946e-1f17-bceb-b2e34a3dfcde.png)
 **③タイトルを入力し、Mobileを選択** 
![２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3474647/acab378b-f932-5778-1f52-f951e7a71e77.png)
 **④スプレッドシートを選択し、連動させるシートを選択**
 ![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3474647/1f34ecea-59b0-8252-a1c7-beb59e1ef086.png)
![コメント 2023-08-02 005706.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3474647/5cb677ef-bbe3-bc95-c752-558f37a89f8b.png)
 **⑤Glideと連携されたらSTYLEでChecklistを選択** 
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3474647/f28eed03-eca1-0fda-2332-d7a8c65fff01.png)
 **⑥ITEMS DATEの設定** 
![５.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3474647/02e940c0-4e6e-f40d-f5c2-d2e98a3942a6.png)

:::note info
 **Title：チェック項目が表示されるよう選択** 
 **Description：ショップさまでチェックをしたらスプレッドシートに☑が入るようにしたいので「ショップ確認」という欄を設けて設定** 
:::

# 実際にアプリを動かしてみた様子
https://twitter.com/iztm8111/status/1686411777033347072?s=20

# スタッフに実際に使ってみてもらった
直属の上司に試してもらいました。
意見として頂いたのは
 + メリット
①作業時間短縮(効率化)の観点からこういった発想は大切
②事務所スタッフ内、ショップ内全員で共有できる、どこでもいつでも見れるのは良い
③紙資源削減
 + デメリット
①いつでも、どこでも見れる便利さもあるが、セキュリティは問題ないのか
②一定期間保存が必要だが、1つのシートで全ショップ、日付ごとに保存できないのは不便
③誰がチェックリストを提出したのか分からないのは不便

# 反省
 **結論、導入できる出来栄えじゃない！** 約100ショップの退館時のチェックリストを日別で１つのエクセルで管理し、一定期間保存が必要であることを考えるとGlideではないツールの使用が望ましいと感じました。ただ、紙のチェックリストでの運用となると印刷や日々の返却の手間が発生しており、ショップさまが使用しているスマホで提出してもらうという発想はよかったと思います。

何も考えず「今までこのやり方でやっていたから」という理由で新しい方法やツールの導入を避けてしまうでのはなく、今までない観点から業務効率化をしていきたい！そういう意味では今回Glideを使用してチェックリストを作ってみてよかった！

 **これからもいろいろとチャレンジしていくぞ～！**
ソフトウェアテスト技法を学ぶ ～ 状態遷移テスト

:::note info
この記事は筆者の学習をまとめたものです。
:::

# ソフトウェアテストテストを学ぼう

- 開発者も積極的にテストをしよう
- テスト専門家とコミュニケーションできるようになろう

という考えでソフトウェアテスト技法について学んでいきます。

- [同値分割法と境界値分析](https://qiita.com/blue32a/items/0bd02910356144b63cc2)
- [デシジョンテーブル](https://qiita.com/blue32a/items/add0dfdc24c447a5c15c)
- 状態遷移テスト（本記事）
- [組み合わせテスト](https://qiita.com/blue32a/items/f6c4ee2db82be8ed8e5c)

# テスト技法：状態遷移テスト

状態遷移テストとは、ソフトウェアの状態に注目し、発生したイベントによって想定した状態に遷移することをテストします。
状態とイベントの組み合わせを状態遷移図や状態遷移表としてまとめ、テストケースを作成していきます。

# 状態遷移図

状態遷移図は、状態から状態への遷移を図として表現したもので、UMLではステートマシン図として標準化されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595926/f095a5d9-2c00-f427-5e3c-59b0dd77c1b0.png)

この図ではイベントであるスイッチのON/OFFにより、状態が運転中や停止中に遷移することが示されています。

# 状態遷移表

状態遷移表はイベントと状態の組み合わせを表形式にしたものです。ある状態でイベントが発生した時にどの状態に遷移するかがまとめられています。

|状態/イベント|スイッチON|スイッチOFF|
|--|--|--|
|停止中|運転中|-|
|運転中|-|停止中|

先程の状態遷移図を状態遷移表で表しました。例えば、状態が停止中の時にスイッチONイベントが発生すると運転中に遷移することが示されています。また、停止中にスイッチOFFイベントが発生しても、状態は遷移しません。

# Nスイッチカバレッジ

状態遷移の経路を網羅するテストで、スイッチとは「事前状態と事後状態の間にある状態」を示すようです。
例えば0スイッチだと間にある状態が0なのでA→Bのように1回のイベントで遷移する経路をテストし、1スイッチだとA→B→Cのように状態を１つ経由する経路を網羅します。

## 例）ストップウォッチ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595926/c2daf974-277c-c2ea-acc5-c1bedb1e1c14.png)

例えば上のようなストップウォッチの状態遷移図から0スイッチカバレッジの表を作成してみます。

### 0スイッチカバレッジ

|事前状態/事後状態|待機中|計測中|停止中|
|--|--|--|--|
|待機中|-|スタート|-|
|計測中|-|-|スタート|
|停止中|-|スタート|リセット|

１つの状態遷移（間の状態が無い＝0スイッチ）を網羅するので、左の事前状態からイベントが起きると上の事後状態になる、という形で表していきます。

### 1スイッチカバレッジ

次に1スイッチカバレッジの表を作成してみます。

|事前状態/事後状態|待機中|計測中|停止中|
|--|--|--|--|
|待機中|-|-|スタート、スタート|
|計測中|スタート、リセット|スタート、スタート|-|
|停止中|-|リセット、スタート|スタート、スタート|

こちらは間に状態が１つある遷移を網羅するので、イベントが２回起こります。例えば待機中からスタート、スタートとイベントが起きると停止中になります。
1スイッチは0スイッチに比べてテストケースが増えてしまいますが、「停止中からリセット、スタートとすると新しくカウントが開始される」のようなケースをテストしたい場合に使えそうです。

# まとめ

- 状態遷移テストとは、発生したイベントによる状態の遷移に注目したテスト
- 状態とイベントの関係は状態遷移図や状態遷移表で表すことができる
- スイッチカバレッジで状態遷移の経路を網羅したテストを行う
- 0スイッチではカバーできないケースもあるので、スイッチを増やしたテストも検討する

# 参考

https://gihyo.jp/book/2020/978-4-297-11061-1

https://www.shoeisha.co.jp/book/detail/9784798130606
フローやトリガーなどの実行順序

フローやトリガー、プロセスビルダー、入力規則などの項目制御が行われていますが、これらには実行順序があります。
--------------------------------------------------------------------------------

実行順序は次のようになっています！
1.元のレコードの読み込み,upsert用のレコードの初期化
2.新しいレコードの項目の値の読み込み及び上書き
3.レコードを保存する前に実行されるように設定したレコードトリガフローの実行
4.すべてのbeforeトリガの実行
5.必須項目・入力規則のチェック
6.重複ルールの実行
7.レコードのデータベースへの保存(確定はしていない)
8.すべてのafterトリガの実行
9.割り当てルールの実行
10.自動応答ルールの実行
11.ワークフロールールの実行
12.ワークフロー項目自動更新が存在する場合、レコードが再度更新
13.ワークフロー項目自動更新でレコードが更新された場合、before updateトリガとafter updateトリガをもう一度だけ実行
14.プロセス及びプロセスによって起動されたフローの実行(順番の保証はなし)
15.エスカレーションルールの実行
16.エンタイトルメントルールの実行
17.レコードの保存後に実行されるように設定したレコードトリガフローの実行
18.積み上げ集計項目の更新
19.条件に基づく共有の評価の実行
20.すべてのDML操作がデータベースで確定
21.メール送信など確定後のロジックが実行
--------------------------------------------------------------------------------
Windowsのhostsファイルで特定URLとの通信禁止

# やり方

『hosts』ファイルは下記にあります。

```
C:\Windows\System32\drivers\etc
```

『etc』フォルダーはシステムフォルダーなので、中のファイルを簡単に変更できないです。
なので『hosts』ファイルをダウンロードフォルダーなどの『ファイル編集ができる場所』にコピー。

コピーした『hosts』ファイルに対して、下記のように ```0.0.0.0 アクセス禁止にしたいサイトURL``` を追記。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/9e7e12ce-2d93-111e-0e26-1cfc3930e8e6.png)

変更した『hosts』ファイルを『etc』フォルダーに上書きで戻してあげます。
下記のような画面が出てきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/5e035de9-6c61-7298-a5a6-3ddc8f6868d6.png)

『hosts』ファイル変更後に再起動は不要です。
変更は即反映されます。

# ファイアウォールでも設定可

特定IPアドレスとの通信遮断はhostsファイルではなく、ファイアウォールでも設定可です。

https://qiita.com/waokitsune/items/13cae35a09c300c76f43

# 参考サイトさん

https://www.reneelab.jp/tokutei-site-akusesu-kinshi.html#hosts

# バージョン

Microsoft Windows [Version 10.0.19045.3271]
スッキリわかるJava入門 第３版を読んでみて- part３ -条件分岐と繰り返し

# はじめに
こんにちは・ω・）ﾉ
今回は条件分岐と繰り返しについて学びました！

## 第３章　条件分岐と繰り返し
### 1.プログラムの流れ
　__制御構造(制御フロー)__...文を実行させる順番

代表的なもの３つ
・順次　
　文　→　文
・分岐　
　　　　 →　A
　文　ー｜
　　　　 →　B
・繰り返し
　文　→　文
　↑______｜

:star2:構造化定理
　順次・分岐・繰り返しの３つの制御構造の組み合わせで
　どんな複雑なプログラムでも作成可能

制御構造を表す文ー __制御構文__
分岐ーif文
繰り返しーwhile文

制御構文の構成要素
・条件式ー分岐条件や繰り返しを続ける条件を示した式
・ブロックー分岐や繰り返しで実行する一連の文の集まり

### 2.ブロックの書き方
__ブロック__...複数の文をひとまとまりとして扱うもの

ルール1:波カッコの省略
　内容が1分しかなければ波カッコを省略可能
※プログラムのミスの防止として省略は非推奨
ルール2:ブロック内で宣言した変数の寿命
　　ブロック内で宣言した変数は、そのブロックが終わると同時に消滅する

__スコープ__...変数が利用可能な場所の範囲
### 3.条件式の書き方
条件式ー分岐条件や繰り返しを続ける条件を示した式

__関係演算子__
「==」...等しいを表現する

関係演算子は評価された時にtrueかfalseに変形する

<例>
算術演算子　3+5⇨8
関係演算子　age>18⇨true

if文
条件式の評価結果がtrue⇨第１ブロック、false⇨第２ブロックを実行する文
while文
条件式の評価結果がtrueなら、ブロックを繰り返し実行する文
と捉えることができる

:point_up:条件式のルール
　ifやwhileで用いる条件式は評価がtrueかfalseになる式

文字列の比較
文字列は「＝＝」で比較できない
　`文字列型の変数.equals(比較相手の文字列)`

論理演算子
　＆＆　かつ（両方の条件が満たされた時にtrue）
　｜｜　または（どちらかの条件が満たされた時にtrue）

否定演算子
「！」　条件式の前につける

### 4.分岐構文のバリュエーション
1.if-else構文
2.ifのみの構文
3.if-else if-else構文

:point_up:if-else if-else構文ルール
　複数記述できるが、ifブロックより後ろ、elseブロックより前にだけ記述可能

swith文
if文の同じような条件をシンプルにする

:point_up:置き換えられる条件
1.すべての条件が一致するかを比較する式
2.比較する値が整数、文字列、または文字
```
switch（条件式）{
case:
出力処理;
break;
}
```
### 5.繰り返し構文のバリュエーション
回数指定の繰り返し...for文
for文の構成
1.初期化処理
2.繰り返し条件
3.繰り返し時処理

ポイント1:ループ変数の名前は自由
ポイント2:ブロック内で利用可能
ポイント3:ブロック外では利用不可能
### 6.制御構文の応用
制御構造の中に別の制御構造という多重構造...__入れ子（ネスト）__

繰り返しの中断
break文...繰り返し自体を中断
continue文...同じ繰り返しの次の集会に進む

無限ループ
永久に繰り返しを続ける制御構造

## まとめ
だんだんとおほえる内容が多くなってきた気がします...(›´ω`‹ )
プログラムの基本的な流れ、特に分岐や繰り返しのifやwhileについて学ぶことができました。
分岐や繰り返しでも色々なバリュエーションがあるので使い分けるのが難しそうだと感じました。
関係演算子での等しいを表す時は気をつけたいなと思います！

今回もありがとうございました！
ではまた〜　＊˙︶˙＊)ﾉ"
【Rails超初心者が説明】ruby on railsとは

今回は、ruby on railsを始めて1か月の超初心者が
railsについて紹介していきたいと思います。

ruby on railsとはRubyのフレームワークです。
フレームワークとは何だろうという方もいるとは思いますが、
Rubyとはというところから順を追って説明していきたいと思います。
## Rubyとは


<dl>
  <dt>　1.簡単に使えるオブジェクト指向スクリプト言語</dt>
  <dd>
例えば、あなたが料理のレシピを書くようなイメージです。レシピには具体的な食材や手順が書かれていて、<br>
それを順番通りに実行することで美味しい料理が作れます。<br>
同様に、オブジェクト指向スクリプト言語では、プログラムを作る際に「もの」（オブジェクト）とその「動作」（メソッド）をまとめて定義し、<br>それを使ってコンピュータに特定のタスクを実行させることができます。</dd><dd>つまり、オブジェクト指向スクリプト言語を使うことで、<br>
プログラミングの難しい部分を気にすることなく、簡単な操作やタスクをコンピュータに指示することができます。</dd>
<br>
  <dt>　2.日本で開発された言語</dt>
  <dd>Rubyは日本で開発された言語であるため、日本語の解説サイトがたくさんあります。</dd>
</dl>


## ruby on railsとは
<dl>
  <dt>　1.フルスタックフレームワーク</dt>
  <dd>フルスタックフレームワークは、ウェブアプリケーションを作るために必要なさまざまな要素を一つにまとめたものです。<br>
これを料理に例えると、レシピ本のようなものと考えることができます。<br>
レシピ本には、料理の材料や手順が詳しく書かれていて、それに従って料理を作ることができます。<br>
フルスタックフレームワークも同様で、ウェブアプリケーションの材料や手順がまとめられています。
</dd>
<br>
  <dt>　2.設定よりも規約重視</dt>
  <dd>Railsは、開発者が特定の決まりごと（規約）に従ってコードを書くことを奨励します。<br>
そうすると、コードの一貫性が保たれ、効率的な開発が可能となります。</dd>
</dl>

## ruby on railsでできること
ruby on railsを使うと以下のようなものを効率的に作成することができます。

- オンラインショッピングサイト
- ソーシャルメディアプラットフォーム
- オンライン予約システム
- ブログプラットフォーム

ここで挙げたのは一部ですので他にもいろいろなものを作ることができます。


簡単にではありますが、ruby on railsについて紹介してみました。
ここまで読んでいただきありがとうございます。
ruby on railsについて少しでも知って興味を持っていただけると幸いです。
flutterで何ができるのか


## Flutterのメリット

Flutterとは2018年にGoogleが開発したフレームワークです。
Flutterを使うと1コードでアプリを作ることができるため、効率的な開発ができます。

## Flutterの将来性

FlutterはGoogleが提供し、将来性が高いといわれているフレームワークです。
FlutterはAndroidアプリとiOSアプリの両方を同時に開発できる画期的なフレームワークであるため、効率的なアプリ開発ができることを特徴としています。
Flutterでは、Googleが開発したプログラミング言語「Dart」を使っており、JavaScriptを意識した設計になっています。

このように将来性の高いFlutterについて、期待されている役割を見ていきましょう。


#### 効率的にアプリを開発することができる

##### 1\. 開発スピードが速いこと
Flutterにはアプリケーションを停止したり、再起動したりせずに修正を反映できる「Hot Reload」機能があります。コードをアプリにすぐに反映できるため、開発時間を大幅に削減できるのが特徴です。

従来は、コードを書いてアプリでテストし、コードにミスがあった場合、書き直さなくてはなりませんでした。

Flutterは、すぐにアプリに反映できるため、開発時間を減らすことができるのです。


##### 2\. 人件費と時間を削減できる
Flutterで開発するとAndroidとiOSを同じコードで開発できるため、本来二倍かかるはずだった人件費と時間を削減できるということです。

##### 3\. 学習する量が少ない
Flutterで使用している言語はDartです。

Dartは、JavaScriptに替わる言語だと期待され開発された背景があるため、文法が非常に似ています。

これにより、Flutterによる開発をする場合、JavaやJavaScriptを学んだ人にとっては、学習ハードルが低く、比較的理解しやすいのが特徴です。

JavaやJavaScriptを習得した経験のあるエンジニアは多いため、多くの人材が学習コストをあまりかけずに理解できるのが強みです。