OmniAICreator/Qiita-1.07M huggingface dataset:
ストワで始めるLua　第12回　物理センサー

https://www.nicovideo.jp/watch/sm42861894

https://www.nicovideo.jp/watch/sm42861907

outputは適当に追加してください

```lua

pi=math.pi
pi2=2*pi

--multiplier matrix
function multiplier(A, B)
	if #A[1] ~= #B then return nil end
	local r = {}
	for i = 1, #A do r[i] = {} end
	for i = 1, #A do
		for j = 1, #B[1] do
			local s = 0
			for k = 1, #B do s = s + A[i][k] * B[k][j] end
			r[i][j] = s
		end
	end
	return r
end

--transporse matrix
function transpose(M)
	local r = {}
	for i = 1, #M[1] do
		r[i] = {}
		for j = 1, #M do r[i][j] = M[j][i] end
	end
	return r
end

--rotation matrix
function rotation(T)
	local RX, RY, RZ, qx, qy, qz
	qx, qy, qz = T[1], T[2], T[3]
	RX = { { 1, 0, 0 }, { 0, math.cos(qx), -math.sin(qx) }, { 0, math.sin(qx), math.cos(qx) } }
	RY = { { math.cos(qy), 0, math.sin(qy) }, { 0, 1, 0 }, { -math.sin(qy), 0, math.cos(qy) } }
	RZ = { { math.cos(qz), -math.sin(qz), 0 }, { math.sin(qz), math.cos(qz), 0 }, { 0, 0, 1 } }
	return multiplier(RZ, multiplier(RY, RX))
end

function onTick()

	--gps position (m)
	gps={}
	gps.x=input.getNumber(1)
	gps.y=input.getNumber(3)
	gps.z=input.getNumber(2)--height
	
	--liner speed (m/s)
	liner={}
	liner.x=input.getNumber(7)
	liner.y=input.getNumber(9)
	liner.z=input.getNumber(8)--height

	--tilt angle (rotation)
	tilt={}
	tilt.x=input.getNumber(15)--pitch
	tilt.y=-input.getNumber(16)--roll
	tilt.z=input.getNumber(17)--yaw(compass)


	--angular
	local euler = { -input.getNumber(4), -input.getNumber(5), -input.getNumber(6) }
	local rT = rotation(euler)
	--local rT = transpose(r)
	
	globalAngular={ { input.getNumber(10) }, { input.getNumber(11) }, { input.getNumber(12) } }
	local angular = multiplier(rT, globalAngular)
	angularVelocity={ x=angular[1][1], y=angular[3][1], z=angular[2][1] }

end
function onDraw()
	w=screen.getWidth()
	h=screen.getHeight()
	
end
```
AWS Directory Service比較

|サービス名|特徴|最大ユーザ数|他ドメインとの信頼関係|MFA|
|:-:|:-:|:-:|:-:|:-:|
|AD Connector|オンプレADの認証機能をそのまま使える|オンプレAD次第|   |   |
|AWS Managed Microsoft AD|大規模向け|制限なし|可能|可能   |
|SimpleAD|小規模向け|5000|×   |×|
PHP Conference Japan 2023に登壇しました。

## はじめに

[PHP Conference Japan 2023](https://phpcon.php.gr.jp/2023/)に参加・登壇してきました！
私が所属している[NE株式会社](https://ne-inc.jp/)は本イベントのシルバースポンサーでした。
（温泉の素を配っていた会社です！）

## 登壇

発表概要と資料はこちらです。

https://fortee.jp/phpcon-2023/proposal/383e4223-02f0-4229-93b4-ccae3247527a

https://speakerdeck.com/yamamotohiroya/pururikusaizugada-kiitojing-gao-sitekurerujun-wozuo-rimasita

社内外で登壇する機会はまぁまぁあるので直前まではあまり緊張しませんでしたが、やはりLTの待機列で待ってる間に徐々に緊張してましたね。
LTって他の講演と違って並列の講演がないので参加者ほぼ全員が聞きに来るんですよね。
今回のぺちこんは大体1000人くらいの参加だと聞いているので、私の中では過去最大の人数の前での登壇になったかな？と思います。
最近はオンラインが主流だったのでリアル登壇は久しぶりでそれも緊張した要因の1つでした。
発表は緊張のせいかちょっと早口になっていて思っていたよりも30秒から1分くらい巻きで終わりました。
ちゃんと話したい内容が伝わっていればいいのですが…！

## 良かった点

* 久しぶりのリアル開催
    * めっちゃ個人的に「オフライン」って言葉が馴染まず、「ん？オン？オフ？どっちだ？」ってなる。
    * 「オンライン」って言葉出てきたから「オフライン」って言葉があるわけで、レトロニム感。
    * 「オンライン」⇔「リアル」で分けていきたい。
    * 懇親会コミュニケーションがあり、これはリアルならではだなと思いました。
* 登壇できた！
    * マネージャーになり、コードを書く時間がめっきり減っている私ですが、まだ話せる内容があった！
    * まだ登壇する側でいられることで自信には繋がりました。
* 熱を感じられた
    * レイブビューイングと現地ライブの差、みたいなところで、やっぱり現地の熱っていうのはあるよなーっていうのを強く感じました。

## ちょっと残念だった点

* リアルちょっとだけ大変
    * 現地まで行くために朝ちょっと早く起きないといけないし、普通に電車移動あるしで、そこはやはりオンラインの方が楽だよなーって感じました。
* スピーカーに優しくない…？
    * まず受付が分からず、結局朝からいましたけど昼過ぎに受付しました。
    * 当日まで何の連絡もなかったし「私本当に採択されてるよな…？」と不安になってましたｗ
    * また、登壇位置からスライドが見えないため何が映っているか分からず話しづらい、というのもあり、このあたりが残念要素でした。
* 寒かった。
* パイプ椅子お尻痛かった。
* BGM等なくてちょっと物足りなさを感じた。
    * PHPerKaigiのお祭り感が好きなだけかも。

## まとめ

2年前のぺちこん2021のブログがこちら

https://qiita.com/yamamoto_hiroya/items/a2063150f37ac96aaa98

初めてプロポーザル採択での登壇でウキウキしているのが分かります。
今はプロポーザル採択で話すのも慣れてきて、自身の成長を感じます。（それでもまだまだですが）
強くなったなー自分。
私は家庭があるので地方の勉強会に足を運ぶのはなかなか難しいのですが、せめて関東圏でやってるやつはこれからも参加できるように頑張ろうと思います。
次は[PHPerKaigi 2024](https://phperkaigi.jp/2024/)でお会いしましょー！

NEブースで記念撮影している様子。
![IMG_3816.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67471/c1f79a1d-745e-d985-a972-4b099fc2a8b5.jpeg)
Swift 08 Switch Syntax 

# 八・壱 　なぜswitchSyntaxを使うのか
多い数の条件を処理する時使います。
でも、他の言語のswitchと違う事があります。

# 八・弍　switchSyntax使うする
> Switch : verb; change the position, direction, or focus of.
origin ~ late 16th century (denoting a thin tapering riding whip)

> Case : an instance of a particular situation(a disease, injury, legal action); an example of something occurring. 
origin ~ Latin casus ‘fall’, related to cadere ‘to fall’;

>default :  1 failure to fulfil an obligation (especially to repay)
> 2. A preselected option, no alternative is specified by the user
>origin ~ from defaillir ‘to fail’, based on Latin fallere ‘disappoint, deceive’.
```swift
switch 表現式{
    case 一致する値 1:

    case 一致する値 2:

    case 一致する値 3, 一致する値 4:

    default:

```
表現式はvalueを現はれるとか、値をreturnする表現式です。
また、switchSyntaxが動かせる値です。
それぞれの一致する値は「表現式」と同じtypeで無ければ成らない。

# 八・参　caseSyntax結合する, 範囲マッチング
> syntax : the arrangement of words and phrases to create well-formed sentences in a language.
> origin ~ Latin from Greek suntaxis, from sun- ‘together’ + tassein ‘arrange’.
## 参・甲 caseSyntax結合する
![Screenshot 2023-10-08 at 6.08.43 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513806/a52d70f4-f2fa-f15b-91f7-5ae4e68c6b8e.png)

## 参・乙 範囲マッチング
![Screenshot 2023-10-08 at 7.55.06 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513806/10d3e570-56c4-998c-f0a4-39a5113fed31.png)

## 参・丙 whereSyntax 
![Screenshot 2023-10-08 at 11.24.34 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513806/83af6a8a-9d01-9968-6553-1e9717600dec.png)


# 八・肆 fallthrough
![Screenshot 2023-10-09 at 12.53.37 AM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513806/9d425146-720e-79b5-4370-3be4bbd1f5e0.png)

 > fallthrough : to not work or happen as intended.

swiftには構文にはcaseの構文の末尾には`break`を使う必要がないことです。
他の言語に比べてSwiftは`case`条件に一致すれば自動的にsyntaxの外で抜け出る。
でも、`fallthrough`syntaxを使うと例外状況を作って、その後のcaseSyntaxに続けさせることができます。
![Screenshot 2023-10-09 at 2.53.40 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513806/87829448-d8ff-abbc-ecdb-193733cdec3c.png)

Swiftの　`switch`構文に`break`はよく使わないんですけど、`deafault`で何の作業が必要ない時に有用です。
```swift
.
.
.
    default:
        break
}
```

# 八・要約
多い数の条件を処理するときにはif...、else...が適合では無い。
特に、評価結果が多い出る時にはswitchを使え
他の言語のSwitchとSwiftのSwitchは一寸違う。
初心者が初心者に教える初心者のためのGit&GitHub 2

## はじめに
二回目の投稿です。だいぶ間空いてたのですがサボってました()新卒にして半年で転職したので色々いそがしかったんです(言い訳するな)
今回も自分が勉強していたところをまとめたいと思います

## コミット前の変更の取り消し
リポジトリ内のファイルを間違えて消してしまった場合はcheckoutコマンドを利用します。試しに前回の復習も兼ねてコミット⇒プッシュしたものを削除して取り消すところまでやります。
~~~
$ touch git.py
$ git add git.py
$ git commit -m "どうせ削除される"
$ git push origin main
~~~
これでgit.pyファイルがリモートリポジトリにも反映されました。次にリポジトリからファイルを削除してみます。
~~~
$ rm git.py
$ git chekuout git.py
~~~
こうすると消したはずのgit.pyが元に戻ってきます。
git checkout .と入力すると、すべて変更前に戻すことができます。
それでは、コミットしてしまった場合も見てみましょう。変更をリセットする場合はresetコマンドを使って取り消しを行います。
~~~
$ rm git.py
$ git add .
$ git commit -m "削除しました"
$ ls
README.md
~~~
これで削除した変更をコミットしました。ここから削除したファイルを取り出していきます。
~~~
$ git  git reset HEAD^ --hard
HEAD is now at 5ffd472 どうせ削除される
$ ls
README.md  git.py
~~~
これで削除してコミットまでしてしまったファイルを取り戻すことができました。
HEADというのが一番先頭のコミットを示しています。^の記号が一つ手前。つまり最後のコミットの前に戻しています。
git logでコミットIDを確認してIDを指定するとそのコミットの手前まで戻ることが可能です。
--hardはリセットモードのコマンドだそうです。種類としては、
1. Soft・・・「変更」⇒「ステージング」⇒「コミット」のうち、最後の「コミット」だけをリセットします。
1. Mixed・・・「ステージング」までを取り消します。
1. Hard・・・すべての手順を破棄します。これはファイルの変更などもすべて破棄してしまい、やり直しがきかないので、間違えてファイルを消してしまった時などに使います。


## 感想
Gitの使い方もMarkDown式の文章作りも全然慣れていないので、会社も変わったので心機一転コツコツ勉強していきたいと思います。
[初心者投稿][開発環境構築]VisualBox+Vagrant+CentOS7+fuelPHP

■目標
ローカル環境にて、fuelPHPの検証環境を作成したい。
↓のように、fuelPHPの初期画面表示を目標とする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3288561/fe3afc07-5eca-fb4d-8ae7-243b9e7c10a9.png)
■前提条件
・VisualBox
・Vagrant
これらに関してはインストールするのみのため、特筆せずに次へ進む。

■仮想環境作成
①Boxファイルインストール
以下コマンドでCentOS7のboxファイルをインストールする。
$ vagrant box add centos/7
プロバイターを選択を求められるため、virtualboxを選択する。

②Box確認
以下コマンドで、インストールされたboxが確認できる。
$vagrant box list

③Vagrantファイル作成
任意のファイルパスに仮想環境の設定ファイルを作成する。任意のパスにcdで移動後、以下コマンドを実行する。
$ vagrant init centos/7

④Vagrantファイル調整
initコマンド実行後、Vagrantfileを開き、以下のコメントを解除する。
#config.vm.network "private_network", ip: "192.168.33.10"

⑤仮想環境立ち上げ
③で作成したファイルパスにcdで移動し、仮想環境を立ち上げる。
$ vagrant up

⑥仮想環境にSSH接続する
$ vagrant ssh

⑦仮想サーバーにアパッチとPHPをインストールする。(SSH接続状態で作業すること。以降※1とする)
$ sudo yum install php
$ sudo yum install httpd

⑧検証環境には不要なため、ファイアウォールとSELinuxを無効化する。(※1)
ファイアウォール無効化。
$ sudo systemctl stop firewalld
SELinux無効化。SELINUX=enforcingをSELINUX=disabledに変更する。
$ sudo vi /etc/selinux/config

⑨設定を変更したので再起動する。
webサーバーを再起動し、コントロール+DでSSH接続を解除しvagrantを再起動する。
サーバー再起動
$ sudo service httpd restart
SSH接続解除
コントロール + D
vagrant再起動
cdで③のパスに移動し、$ vagrant reload 。

➉仮想OS内にコンポーザーをインストールする。(※1)
$ curl -sS https://getcomposer.org/installer | php
どのパスでもコンポーザーコマンドが利用できるようにするために、移動させる。
$ mv composer.phar /usr/local/bin/composer
念のため⑨の手順をもう一度実行。

⑪任意のパスにfuelphpのプロジェクトを作成する。(※1)
任意のパスにcd移動後に実行。
$ composer create-project fuel/fuel:dev-1.7/master hogehoge
GitHubトークンを要求されるため入力する。
トークンを保持していない場合は⑫手順。トークン入力が成功した場合は⑬手順へ進む。

⑫GitHubトークン発行
GitHubにログインし、トークン発行を行う。
トークン発行設定は、repo,gist,userにチェックを入れて発行すること。

⑬webサーバーのドキュメントルート設定(※1)
httpd.confの内容を書き換える。
$ vi /etc/httpd/conf/httpd.conf
⑪で作成したfuelphpプロジェクトのpublicフォルダパスを設定する。
DocumentRoot hogehoge
Directory "hogehoge"
権限レベルの関係でhttpd.confの書き込みができなかった場合、以下で権限レベルを変更する。
$ chmod 777 httpd.conf

⑭タイムゾーン設定(※1)
$ vi /etc/php.ini
date.timezone = 'Asia/Tokyo'に書き換える。
理由はタイムゾーン設定を明示することが必須であるため。

⑮ログフォルダ権限調整(※1)
⑪で作成したfuelphpプロジェクト内の、fuel/app/logsフォルダへの書き込み権限を設定する。
$ chmod 777 fuel/app/logs
理由はログを出力できるようにするため。

⑯動作確認
⑨の手順を実行。
④の手順で設定したIPアドレスをブラウザに入力して冒頭の画面が表示されれば成功。

■最後に
いかがでしたでしょうか。以上です。
CSSでボーダーアニメーション - 四隅の空白を埋める


## はじめに

以下のようなアニメーションを実装する機会があったので、備忘録かねてシェアしようかと思います。
ホバーした時に枠線が伸びて四隅の隙間が埋まるエフェクトです。
誰かの役に立てれば。

**【サンプル】**

![ezgif.com-resize.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906859/15365bc6-361b-8ea8-10d4-b37933ff64f6.gif)


## 仕組み

borderプロパティを使用した線は太さを変えることはできますが、長さは中身の要素に依存するので自在に変更することができません。
よって今回は疑似要素を使用してborderの線に見立てた要素を作成して実現しています。

疑似要素は一つの要素につき２つしか作成できないので、ホバーする要素とその内側にタグを追加して、二つのタグの`::before`と`::after`を使用することにします。

それぞれの疑似要素の幅1pxにして、線を再現します。
長さはレスポンシブ対応を考えて80%と90%に指定しています。
※これらの数値はデザインに合わせて調整可能

ホバー時に四隅の隙間が埋まるように、通常時は上下の線を水平方向中央、左右の線を垂直方向中央にそれぞれ配置して四隅に隙間ができるような配置にしています。

あとはホバー時に線の長さを100%にして四隅が埋まるようにしています。


## コード

```html:html
<section class="border-animation">
        <div class="border-container">
            <div class="border-inner-container">
                <div class="text-container">
                    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. <br>A veritatis error, odio libero quis fugiat ex rerum quisquam? </p>
                </div>
            </div>
        </div>
    </section>
```


```css:css
/* 見た目を整える用 */
.border-animation {
    margin-top: 10%;
}
.border-container {
    width: 60%;
    margin: 0 auto;
    padding: 5%;
}

.border-container {
    position: relative;
}

/* 線になる疑似要素の共通設定 */
.border-inner-container::before,
.border-inner-container::after,
.border-container::before,
.border-container::after {
  background-color: #3498db;
  content: '';
  display: block;
  position: absolute;
  transition: all .3s ease;
}

/* 上下の線のサイズと配置の指定 */
.border-container::before,
.border-container::after {
    width: 90%;
    transform: translateX(-50%);
    height: 1px;
}
.border-container::before{
    top: 0;
    left: 50%;
}
.border-container::after {
    bottom: 0;
    left: 50%;
}

/* 左右の線のサイズと配置の指定 */
.border-inner-container::before,
.border-inner-container::after {
    width: 1px;
    height: 80%;
    transform: translateY(-50%);
}
.border-inner-container::before {
    top: 50%;
    left: 0;
}
.border-inner-container::after {
    top: 50%;
    right: 0;
}

/* ホバー時に線の長さを100%に */
.border-container:hover::after,
.border-container:hover::before {
  width: 100%;
}
.border-container:hover .border-inner-container::after,
.border-container:hover .border-inner-container::before {
    height: 100%;
}

```


## ポイント

- 線の色はbackground-colorで指定
- 線の太さはそれぞれのwidthとheightで調整
- それぞれtop, leftを50%にし、transformで中央寄せ
Stable Diffusion Web UI導入でつまずいたところ

昨今熱いAI業界にて、Stable DiffusionのWebUIがあると聞いたので導入を試みてみたが、詰まったところがあったので記録

# TL;DR
- 初手導入時にPythonバージョンが違うと、入れ直してもダメ
- Pythonインストール後に一から改めて、.bat（Macなら.sh）の実行をやり直す必要がある


# 導入に際して
基本に関してはググれば出てくるのが割愛
自分も見つけた数点の記事を参考に実行していった

やることとしては、基本的には

- Python3.10.6のインストール（済んでいればスキップ）
- 設置用ディレクトリを用意する
- stable-duffusion-webuiの[GitLab](https://github.com/AUTOMATIC1111/stable-diffusion-webui)から `git clone` する
- cloneしたディレクトリのstable-diffusion-webuiディレクトリに入りwebui-user.bat（Macならwebui.sh）ファイルを実行


これだけで完了である（時間はある程度かかる）
ただ、自分がやった際には.batファイルの実行時に詰まってしまった

# TypeErrorの発生

```
TypeError: __init__() got an unexpected keyword argument 'socket_options'　Stable Diffusion
```

最後に吐かれるエラーとしてはこのようなメッセージが出てしまった
調べる感じでは、どうやら使用サービスのバージョン違いとかが起こってるものらしく、 `package.json` 調べてみたり、pip3調べてみたりしたが、「現状Python3.10.6が必要である」ということを思い出し、単純に「Pythonのバージョンがあってないのでは？」ということに思い当たった

とはいえ、必要になっているPython3.10.6はちゃんとインストールしたしな…と思いつつ `python -V` してみると出てきた数字は↓

```
3.7.0
```

なんだこれは

自分はちゃんと3.10.6をインストールした覚えもあるしその時のインストーラもまだ残っている（「ゴミ箱を空にする」実行前）
なのにこんなでたらめなバージョン番号が出てくるはずはないと考え、再度3.10.6をインストール
でも `python -V` で出てくる数字は「3.7.0」のまま
Python2と3との切り替えで困った経験はないこともないが、3内部の切り替えでも悩むとは…

とはいえ、単に今ある3.7.0が邪魔になってるだけなら、今後使う予定はない（自分には）のでアンインストールすればいいだけでは？と調べてるうちに思い至り、3.7.0のインストーラを落としてきて「Uninstall」実行した

あらためて `python -V` してみると出てきた数字は↓

```
3.10.6
```

となり、これで正常にPython3.10.6が使えるようになった
さてこれで万事OKだわ、と改めてwebui-user.batを実行した、が…

# まだまだバージョン番号違い

出てくるのはだいたい同じエラーメッセージ

確認のためにまた `python -V` したが、やはり使われるバージョンは3.10.6で合ってるはず
まだ足りないものがあるのか、と改めてエラーメッセージを見返すと、その中に気になる文言が混じってる

```
This program is tested with 3.10.6 Python, but you have 3.8.5.
```

なんだこれは

やはり原因としてはPythonのバージョン違いであり、「3.10.6でないと動けへんねん。せやけど自分の持ってきてるPythonは3.8.5やないかーい」と答えてるようだ

だがこれはおかしい
このPCには一度たりともPython3.8を入れた覚えはない

3.7.0と同様、Python3.8.5のインストーラでアンインストールできるかと思い落としてきたが、「Uninstall」の項目はなく、やはりこのPCにはPython3.8.5は入っていない様子

だがStable Diffusion Web UIは「お前は3.8.5だ」と言ってくる

この不整合に対してはChatGPTが答えをくれた

```
このエラーメッセージは、StableDiffusionUIがPythonのバージョン3.10.6を要求しているにも関わらず、実際にはバージョン3.8.5がインストールされているために発生しています。

この問題を解決するためには、以下の手順を試してみてください：

Pythonの再インストール:
まず、Pythonをバージョン3.10.6にアップデートする必要があります。以下の手順で行います：

Python 3.10.6のダウンロードページから、最新のPython 3.10.6インストーラーをダウンロードし、実行します。

インストーラーの指示に従ってPython 3.10.6をインストールします。

WebUIディレクトリのクリーンアップ:
インストールが完了したら、StableDiffusionUIのディレクトリ内にある古いPythonの残骸やvenvフォルダを削除します。これによって、古いPythonの影響が排除されます。

再起動:
Pythonの再インストールが完了したら、コンピューターを再起動します。

StableDiffusionUIの実行:
再起動後、コマンドラインで .\webui-user.bat を実行してみてください。

これによって問題が解決するはずです。もしまだ問題が続く場合は、開発者やコミュニティに問題を報告するための方法を探すことをお勧めします。
```

:robot:「ぜんぶ燃やしてしまえばかたづく。」

なるほどですね

3.7.0が使われる状況（3.10.6もインストール済み）でwebui-user.bat実行しちゃったから変に設定されてるわけなので、3.10.6が使われる状況で.batの初回実行をし直しすれば、設定もうまくなされて解決すると

# 再起動は偉大

AI様の言う通りに、まずは `git clone` したstable-diffusion-webuiディレクトリを削除、その上で改めて `git clone` し直し、 `python -V` するとちゃんと `3.10.6` と返ってくる状態であることを確認してからwebui-user.batを実行

![SDWU.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700474/acb58214-b259-d1d7-b137-700e41a955bc.png)

今度はちゃんと成功した（Edgeで見ています）


今後やる人としては、ちゃんと `python -V` するとちゃんと `3.10.6` と返ってくることを確認してから.bat（Macなら.sh）実行してくださいね、という話でした
【ReactNative】入力エリアのバリデーションを実装してみた

# はじめに
こんにちは。
本日はReactNativeでの入力エリアのバリデーションについて記事にしていきます。
今回はhooksを使用してのバリデーションについてです。
いろいろとライブラリもあるようですが、今回は触れません。

# 今回のアプリの説明
入力エリアは"99999999"まで入力することができる。
それ以上入力するとバックグラウンドが赤くなり「金額以上に達しました。」という文言が表示される。
数値以外の文字を入力するとエラーダイアログを表示する。（コピペ対策）
キーボードは数値入力キーボード
以下が画像になります。

入力前
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3117699/5c44707d-d9b9-8f02-a8c4-847fb06ebf22.jpeg" width="400px">

"99999999"以上入力した時
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3117699/a12031f6-96bf-00f6-09ba-2dea20eb1b5b.jpeg" width="400px">

数値以外の時
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3117699/2f2eb567-a3c4-8ce2-5774-d376c47f4924.jpeg" width="400px">

# コードの確認
実際にコードを見てみましょう。
コードの前に処理の流れについて少し話します。
今回のバリデーションは以下の流れでチェックしています。

* 数字かどうかをチェック
　　1.　数値を入力する
　　2. onChangeTextに定義しているamountTextChangeを実行　
　　3. 数値以外だった場合はダイアログを実行
* 文字数チェック
　　1.　数値を入力する
　　2. onChangeTextに定義しているamountTextChangeを実行
　　3. stateに数値をsetする
　　4. useEffectが実行される（1文字数値が入力されるたびに実行しチェックする）
　　5. 8文字以上入力された場合は以下になる<br>①maxLengthにより入力されないようになる<br>②useEffectに定義されている、setBackgroundColorがredに切り替わることにより赤色になる<br>③lengthをチェックして、Textタグが追加される

では流れがわかったところで実際にコードを見てください。
```tsx: app.tsx
  // Stateを定義
  const [text, setText] = useState<string>(value);
  const [backgroundColor, setBackgroundColor] = useState<string>('#CCFFFF');

  // 入力欄の数値が変わるごとに実行される
  useEffect(() => {
    // 文字数が8文字以上なら背景色を赤にする
    setBackgroundColor(text.length >= 8 ? 'red' : '#CCFFFF');
  }, [text]);

  const amountTextChange = (value: string) => {
    // 数値のみで構成されているか確認
    if (/^\d*$/.test(value)) {
      // stateにセットする
      setText(value);
    } else {
      // ダイアログを表示する
      Alert.alert('エラー', '数値のみを入力してください。');
    }
  }

  return (
    <View style={[styles.container, {backgroundColor}]}>
      <Text style={styles.label}>金額 :</Text>
      {/* 入力エリア */}
      <TextInput 
      maxLength={8}
      value={text} 
      style={styles.input} 
      onChangeText={amountTextChange}
      placeholder="金額を入力（最大9999999円）"
      keyboardType="numeric"/>
      <Text style={[styles.label,{padding:10}]}>円</Text>
      {/* 入力欄が8文字以上になった場合テキストを表示する */}
      {text.length >= 8 && <Text style={{color: '#ffffff'}}> 金額以上に達しました。</Text>}
    </View>
  );
};

// css
const styles = StyleSheet.create({
  container: {
    flexDirection: 'row',
    alignItems: 'center',
    margin: 6,
    padding: 10,
    borderRadius: 5
  },
  label: {
    fontSize: 14,
    fontWeight: 'bold',
    marginRight: 10,
  },
  input: {
    flex: 1,
    fontSize: 12,
    padding: 5,
    borderColor: '#000080',
    borderWidth: 1,
    borderRadius: 5,
  },
});
```

# 最後に
いかがでしたでしょうか？
あまりReactNativeに慣れていないこともありバリデーションを実装するのにどうやってやるのだろうと悩んでいました。
ただhooksの勉強にもなったので良かったです。
みなさんもいきなりライブラリを使用しないで実装してみるのもいいと思いました。結構勉強になります。
ということでこの記事が参考になれば嬉しいです。
最後までご覧いただきありがとうございました。
[用語]RFCにおいて要請の程度を示すために用いるキーワード(RFC2119)

:::note info
　ここで記載した情報はWebページを参照してまとめたものなので、
　確実性は保証できません。
:::

## 1.RFC2119
RFC等の使用記載で使用する場合に利用する要求の強度はRFC2119を利用することがある。
参考に利用する際のmust/shall/should/mayについて記載する。

| No. | 強度 | 内容 | 備考 |
|:---:|:----|:-----|:-----|
|1 |MUST|当該仕様「要求さえている(REQUIRED)」および「することになる(SHALL)」の絶対的な要請事項であることを意味します。|－|
|2 |MUST NOT|当該仕様は、「することはない(SHALL NOT)」と同様に絶対的な禁止事項であることを意味します。|－|
|3 |SHOULD|特定の状況下では、 特定の項目を無視する正当な理由が存在するかもしれませんが、 異なる選択をする前に、当該項目の示唆するところを十分に理解し、 慎重に重要性を判断しなければならない、ということを意味します。|－|
|4 |SHOULD NOT|特定の動作が容認できる、ないし、非常に有用である、 というような特定の状況下では、正当な理由が存在するかもしれませんが、 このレベルの動作を実装する前に、 当該項目の示唆するところを十分に理解し、 慎重に重要性を判断しなければならない、ということを意味します。|－|
|5 |MAY|ある要素が、まさに選択的であることを意味します。|－|


# Z1.参考にさせて頂いたリンク

| No.| 区分 | サイト名 | タイトル名 |
|:--:|:--|:--|:--|
|x|RFC2119|JPNIC|[RFCにおいて要請の程度を示すために用いるキーワード](https://www.nic.ad.jp/ja/tech/ipa/RFC2119JA.html "RFCにおいて要請の程度を示すために用いるキーワード")|
|x|RFC2119|RFCの部屋|[必要条件レベルを示すRFCの中の使用のためのキーワード](http://www.t-net.ne.jp/~cyfis/rfc/format/rfc2119_ja.html "必要条件レベルを示すRFCの中の使用のためのキーワード")|
|x|RFC2119|うぃるどん ぶろぐだどん|[RFC2119を斜め読みしてみる](https://blog.wyrd.co.jp/2023/04/10/rfc2119%E3%82%92%E6%96%9C%E3%82%81%E8%AA%AD%E3%81%BF%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B/ "RFC2119を斜め読みしてみる")|
|x|RFC2119|RFC-j内田訳一覧|[RFC文書中で要求レベルを表現するために用いられるキーワードの使用法について](http://www.asahi-net.or.jp/~sd5a-ucd/rfc-j/rfc-2119j.html "RFC文書中で要求レベルを表現するために用いられるキーワードの使用法について")|
【Windows11】レジストリをいじってJIS配列とUS配列を共存させる

## やりたいこと
日本語JIS配列のノートパソコンにUS配列の外付けキーボードをつけたときにそれぞれの配列で入力したいいいい

## 参考にした先駆者様
https://zenn.dev/gn5r/articles/coexistence-jis-and-us

今回の執筆にあたり、大変参考にさせていただきました。
情報を共有いただきました先駆者様に感謝いたします。
というかほとんどやってることが一緒です。

## 環境
- PC側
  - Dell Inspirion 3501
  - Windows 11 22H2
  - JIS配列
- 外付けキーボード側
  - E-YOOSO 赤軸
  - US配列

## 大まかな手順
大まかな流れは以下の通り
1. システムキーボードレイアウトを変更する
1. レジストリを書き換える
1. 完了!

今回は先駆者様の記事にもある`.reg`ファイルを作成し簡単にレジストリ値を書き換えたいと思います。

:::note warn
レジストリの編集はシステムに大きな影響を与えます。
実行は自己責任で行い、バックアップを取ってから実行するようにしましょう。
:::

## システムキーボードレイアウトを変更する
まずシステム側のキーボードレイアウトを`接続済みキーボードレイアウトを使用する`にします。
これにより、キーボードレイアウトの強制設定を解除できます。

1. `Win + I` で設定を開く
1. 左メニューから`時刻と言語`をクリック
1. `言語と地域` をクリック
1. `日本語` の \[...\](三点リーダー)をクリックし、`言語のオプション` をクリック
1. 少し下にある `キーボードレイアウト`の設定の `レイアウトを変更する` をクリック
1. レイアウト変更のウィンドウが出てくるのでリストから `接続済みキーボードレイアウトを使用する` を選択 
1. `今すぐ再起動` をクリックし設定を反映する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821686/06d1cdf6-641a-a232-2262-b7bc98d0c32e.png)

## レジストリを書き換える
ここまま自動で識別してくれるわけではありません。
(マイクロソフトが自動でキーボードの入力レイアウトを識別する機能追加してくれないから悪いんだ)
なのでレジストリを書き換えて配列の情報を変更します。

### 下準備
`デバイスインスタンスパス`というデバイスごとに付与されるIDのようなものが必要になります。
1. `Win + X` -> `M` でデバイスマネージャーを開く
1. `キーボード`のセクションを展開し、内蔵キーボード(と思われるデバイス)をクリックしプロパティを表示
1. 詳細タブの`デバイスインスタンスパス`をコピーしておく

### .regファイルを作る
`.reg`ファイルはレジストリを簡単に書き換えられる`.bat`ファイルのようなものです。

``` us_to_jis.reg
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\@@@\Device Parameters]
"OverrideKeyboardType"=dword:00000007
"OverrideKeyboardSubtype"=dword:00000002
```

`@@@`に先程コピーした`デバイスインスタンスパス`を置き換えてください。

### 実行する
ファイルを`UTF-16 LE`で保存をしてください。
エクスプローラーなどからファイルをダブルクリックし実行してください。
先述の通りレジストリの書き換えは自己責任でお願いします。

レジストリの変更を反映するため再起動します。

# ugoitaaaaaaaaaaaaaaaaaaaa!!!!!!!!!!!!!
内蔵キーボードと外付けキーボードの配列を別で扱うことに成功しました。
WSL 2.0.0 で導入されたDNS参照方法/dnsTunneling

WSLパッケージの2.0.0にて追加された機能の一つにdnsTunnelingがあります。DNSもWSLの中でトラブルの多い機能の一つでしたからこの機能に救われる方は多いと思います。

### dnsTunneling

https://devblogs.microsoft.com/commandline/windows-subsystem-for-linux-september-2023-update/

[公式案内](https://devblogs.microsoft.com/commandline/windows-subsystem-for-linux-september-2023-update/)に詳しく説明されていますが、これまでのDNS参照にあった課題を解決するためにWindows自身のDNS参照機能に結果を教えてもらう手法が導入されました。まだ使い込めてはいませんが良好に機能しているように思えます。

使用するには .wslconfig に以下の記述を追加します。
```
[experimental]
dnsTunneling=true
```

### これまでの問題点

WSL2でのトラブルとして**ネットワークに繋がらない**は比較的多く報告されています。もちろん、トラブルには様々なパターンがあるのですが、比較的多いのがDNS名前参照に失敗するケースです。

#### case1. DNS通信がブロックされる

Windowsのファイヤーウオールや経路の混乱(IPアドレスの重複等)によりDNSサーバーとやり取りできないことがありました。dnsTunnelingを使うと、非IP通信でWindowsから情報を貰うのでこの種のトラブルは発生しづらくなります。

#### case2. DNSサーバーが貧弱

WSL2では仮想ネットワーク上にDNS中継サーバーが提供されます。しかし、このサーバーは簡易的なものでTCPフォールバックやEDSN0という大きなレスポ ンスを処理する仕組みがありません。この為、DNS問い合わせによって失敗するパターンがありました。dnsTunnelingを使うと、Windowsが参照した情報を貰えるのでこの種のトラブルは発生しづらくなります。


### dnsTunnelingの仕組み

では、どういう仕組みでどの程度の互換性が向上するのか眺めてみた範囲で考察します。

/etc/resolv.confは標準状態と同様に自動作成されます。
ただし、DNSサーバーは`127.0.0.42`を指します。DNSサーバーですからUDP及びTCPのport53でサービスが提供されているのですが、おそらく /init からハイパーバイザーを介してWindowsのDNSレゾルバを参照します。

この利点はWindowsのルールに従って名前解決を行えることです。具体的には、VPN接続するとVPNで使われるDNSサーバーへの問い合わせがWindows同様に行えます。他にもWindowsにDNSサーバーへの参照ルールが設定されている場合にはそのルールに従って適切なサーバーへ問い合わせることが可能となります。

ただし、微妙に挙動が異なるのはWindowsだと最優先のDNSサーバーにアクセスできなくても別のサーバーから情報を取得してくるのですが、この機能ではタイムアウトまで待ってエラーとなります。こうした挙動は異常時のみなので特に気にはならないはずですが、全く同じというわけでもないようです。


### 特にNATネットワークでの課題を解決してくれる

この機能で一番メリットがあるのは標準のNATモードで利用しているケースです。これまで提供されていたDNS中継サーバーでは何かと発生していたトラブルが解消しますので大いに期待できます。ミラーモードでもVPN接続時の追従など利便性が高いので用途に応じて使用するとよさそうです。ブリッジモードの場合は、Windowsを参照する意義はあまりないでしょうからDHCPで配布されたDNSサーバーを使うのがよさそうですね。
【TypeScript】国土地理院APIを使用して緯度・経度から都道府県を判定する

## 概要
緯度・経度を元にどこの都道府県かを判定する方法はいくつか挙げられますが、無料で手軽にできる方法はないかと探していたところ、国土地理院APIなるものを見つけました。
今回は国土地理院APIを使用して、タイトルにある処理を実装してみたので紹介します。

## 実装方針や前提など
* 国土地理院APIの詳細については、[国土地理院APIでお手軽ジオコーディング＆逆ジオコーディング](https://memo.appri.me/programming/gsi-geocoding-api)の記事を参照ください。
* 今回は緯度・経度から住所を判定するので、上記の記事で紹介されている逆ジオコーディングの機能を使用します。逆ジオコーディングで取得したコード（muniCd）を、[muni.js](https://maps.gsi.go.jp/js/muni.js)という変換表を使って都道府県コードを取得します。
* 今回はTypeScriptで実装していますが、JavaScriptでも同様の内容で実装できると思います。

## 実装サンプル
緯度・経度を入力して、都道府県コードを取得する実装サンプルを以下に記載します。

```ts
export const useGeolocationService = () => {
  // 緯度・経度を項目として持つ型を受け取る
  const getPrefectureCodeFromLatLon = async (latLon: LatLon) => {
    const muniCd = await getMuniCdFromLatLon(latLon);
    if (!muniCd) {
      return undefined;
    }

    return getPrefectureCodeFromMuniCd(muniCd);
  };

  // 緯度・経度からmuniCdを取得
  const getMuniCdFromLatLon = async (latLon: LatLon) => {
    type LonLatToAddress = {
      results?: {
        muniCd: string;
        lv01Nm: string;
      };
    };

    const response = await fetch(
      `https://mreversegeocoder.gsi.go.jp/reverse-geocoder/LonLatToAddress?lat=${latLon.lat}&lon=${latLon.lon}`
    );
    if (!response.ok) {
      return undefined;
    }

    const lonLatToAddress: LonLatToAddress = await response.json();
    return lonLatToAddress.results?.muniCd;
  };

  // muniCdから都道府県コードを取得
  const getPrefectureCodeFromMuniCd = (muniCdInput: string) => {
    // 先頭が0の場合は除去
    const muniCd =
      muniCdInput.substring(0, 1) === "0" ? muniCdInput.slice(1) : muniCdInput;
    // muni.jsの一覧を元にしたリストから中身を取得
    const muniContents = MUNI_LIST.MUNI_ARRAY[muniCd];
    if (!muniContents) {
      return undefined;
    }

    // カンマ区切りの一番最初の値が都道府県コード
    return muniContents.split(",")[0];
  };

  return { getPrefectureCodeFromLatLon };
};
```
VS Code 1.83の新機能 - ピン留めされたタブを別行に表示する機能の追加

https://code.visualstudio.com/updates/v1_83#_pinned-editor-tabs-on-separate-row

ピン留めされたタブを別行に表示する機能が追加された。
設定 `Workbench > Editor: Pinned Tabs On Separate Row` をONにすると、ピン留めされたタブが最上段に、それ以外のタブが2段目以降に表示されるようになる。
また、タブをドラッグ＆ドロップすることで最上段と2段目以降を移動させることもできる（つまりピン留めの設定/解除）。

![separate_pinned_tab.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181011/7c0dbcc5-04ba-9519-189b-397980fd71f9.gif)

タブのピン留め機能はイマイチ良い使い方が思いつかず今までほぼ使ってこなかったが、この機能を使えばメインで表示するファイルのタブを最上段(ピン留め)に配置し、一時的に表示するファイルのタブを2段目以降(ピン留めなし)に表示する、みたいな使い方ができて便利そう。
不用意に edge://mam-enrollment-page にアクセスをしてはいけない。

# これは何？
Microsoft Edge で不用意に edge://mam-enrollment-page にアクセスして酷い目に合った話です。
なお、後述の事由との兼ね合いでキャプチャは無いです。

# そもそも edge://mam-enrollment-page とは？
Microsoft Edge は v116 から企業向けに Microsoft Edge For Business に切り替わるよう機能拡張されました。
具体的には企業用アカウントでのプロファイル利用の際、上記に切り替わります。
本 URL はプロファイル用アカウントの MAM 管理を行うページのようです。

# アクセスしちゃダメな条件
・ Microsoft Edge にて既に企業用アカウントで利用中のプロファイル
・ 同期設定を施してないプロファイル

# どうなる？
画面アクセス時で自動で実行される MAM (?) の処理をキャンセルした際に、
そのタイミングで利用中のプロファイルを破棄するようです。
つまり、アクセス後、表示されるダイアログでキャンセル行為を行うと**プロファイルが飛びます。**

これが想定された動作かはわかりません。(1回しか試してないので
そして、同期してなければ**復元方法はありません。**

不用意にアクセスしないようしましょう (1敗)。
B2C CommerceのBusiness Managerでの開発環境セットアップ

# はじめに
新たにB2C CommerceでECサイトの構築をすることになった。
作業環境用のサンドボックスを用意したので、そこで初期設定をしていく。

# 1. デモサイトのインストール
B2Cが用意しているデモサイト(RefArch)をインストールする。

Administration > Site Development > Site import&Export
![Screenshot 2023-10-05 at 19.03.16 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/ae9253bf-bdc6-a44b-326c-7967b2900ee1.png)

Storefront Reference Architecture Demo Sitesにチェック > import

![Screenshot 2023-10-05 at 19.05.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/a8769b51-07b8-e920-d921-555456e43df2.png)

Storefront Reference Architecture base + All Optional Featuresにチェック > Deploy
Statusが RunnningからSuccessに変わればOK（数十分かかる）

![Screenshot 2023-10-05 at 19.06.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/d9288fc4-11ed-171c-9849-79c40a175bea.png)

左上でImportしたサイトを選択できるようになる
![Screenshot 2023-10-09 at 13.44.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/e2a33cac-29c6-c479-e21e-148cdea98ae6.png)


# 2. サイトキャッシュの無効化
サイトのキャッシュを無効化することで、変更を即座に反映させる。

Administration > Sites > Manage Sites
![Screenshot 2023-10-09 at 13.36.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/6cb5454f-0bd5-a551-e1c6-f8060fa11f0d.png)

（作業対象のサイト）をクリック
![Screenshot 2023-10-09 at 13.39.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/48bcd6be-f60b-40bc-701f-d1ad40044ad6.png)

Cacheタブ > Enable Page Cachingのチェックを外す > Apply
![Screenshot 2023-10-09 at 13.41.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/1942a6d3-a0d7-6089-e41d-1f92d14213ba.png)

追加で、キャッシュ削除には以下の設定も必要
- サイトの静的コンテンツキャッシュとページ全体のキャッシュ
- サイトのページ全体キャッシュ
- 静的コンテンツのTTL 0

![スクリーンショット 2023-10-20 17.02.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/088aeb66-eb19-c46c-abe8-26649b3f7210.png)

# 3. ストアフロントのURLにコントローラとメソッド名を表示
デフォルトは以下のように、コントローラとメソッド名が表示されていない

![Screenshot 2023-10-09 at 14.08.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/1ec2b951-b899-be0c-312a-7716c9f0c21f.png)

Merchant Tools >  Site Preferences >  Storefront URL
Enable Storefront URLs:のチェックを外す > Apply

![Screenshot 2023-10-09 at 14.08.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/da2bf50d-5a4b-d98a-6176-721f8fe35c0f.png)

以下のように、コントローラとメソッド名（Search-Show）が表示されるようになった

![Screenshot 2023-10-09 at 14.08.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/3b738ff5-3ebc-e020-360d-a79e81f6b871.png)


# メタデータ（作成中）
## エクスポート
![Screenshot 2023-10-06 at 8.47.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/1b83dc6a-19cd-68dd-7133-f2461d91a2f1.png)

## インポート
![Screenshot 2023-10-06 at 8.48.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/01ce0c3d-cad3-d9fc-391b-41dac8d79335.png)
VS Code 1.83の新機能 - エディタタブの高さを低くする機能の追加 

https://code.visualstudio.com/updates/v1_83#_editor-tab-height-density

エディタタブの高さを低くする機能が追加された。
設定 `Window > Dentisy: Editor Tab Height` で `Compact` を指定するとエディタタブの高さが低くなるようになった。

![tab_height.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181011/706ec59b-22b7-49ab-a28a-7e6e6d730dac.gif)

タブを1段で使っているとタブの高さが変わってもあまりピンとこないが、複数段の時は確かにこのほうがスッキリして良さげ。

同じリリースタイミングで[ピン留めされたタブを別行に表示する機能](https://qiita.com/12345/items/844082add474af68d9fa)が追加されたので、これと組み合わせて使うのも良いかも。
せんせー、光場ディスプレイってなに？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/2c47de5a-d81a-78f9-53c1-4d31d8398c36.png)

キーンコーンカーンコーン...
授業が始まります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/be1492ca-910f-2708-d0fa-8fcfcf14af73.png)

せんせー、光場ディスプレイってなに？

# 光場ディスプレイとは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/da229491-9c49-fb7a-a542-417180e256a7.png)

## 光場ディスプレイって何？

みんな、3D映画を見たことがあるかな？特別なメガネをかけると、画面から物が飛び出してくるみたいに見えるよね。光場ディスプレイは、その特別なメガネなしで、物が飛び出してくるように見える魔法のテレビやモニターだよ。

## どういうこと？

光場ディスプレイは、光の方向や強さをちょうどいい感じに変えることで、3Dのように物が飛び出して見える映像を作る技術なんだ。だから、メガネなしで立体的に物が見えるんだよ。

## どうしてそれがすごいの？

普通のテレビやモニターでは、画面が平らなので、立体的に物が見えることはないんだ。でも、光場ディスプレイを使うと、本当に物が飛び出してきているみたいに見えるから、とても不思議で楽しいんだよ。

## だから、光場ディスプレイってなに？

光場ディスプレイは、特別な技術を使って、物が飛び出してくるように見える魔法のテレビやモニターなんだよ。

# まとめ

このように、光場ディスプレイは、私たちがまるで本物の物が飛び出してくるような映像を楽しむことができるすごい技術なんだよ。これで、もっと楽しい映画やゲームの世界を体験することができるね。
KubernetesにおけるCNIとLinuxカーネルを通じたコンテナネットワーク

# KubernetesにおけるCNIとLinuxカーネルを通じたコンテナネットワークの流れ

#### 1. はじめに

##### 1.1 記事の目的とスコープ
この記事では、コンテナオーケストレーションプラットフォームであるKubernetesのネットワーキングに焦点を当てます。特に、Container Network Interface (CNI)とLinuxカーネルがどのように連携してコンテナネットワークを実現しているのかに焦点を当てます。

##### 1.2 コンテナ技術とKubernetesの基礎
コンテナ技術は、アプリケーションとその依存関係を包括し、軽量で移植可能なパッケージを提供します。Kubernetesは、これらのコンテナを効率的にスケジューリングし、管理するためのプラットフォームを提供します。

##### 1.3 Linuxカーネルとネットワーキングの基本
Linuxカーネルは、ネットワークネームスペースやvethペアなど、コンテナネットワークをサポートする多くの機能を提供します。これらの機能がどのように動作し、コンテナ間の通信を可能にするのかを探ります。

#### 2. KubernetesのネットワークアーキテクチャとCNI

##### 2.1 Kubernetesネットワークの概要
Kubernetesは、ポッド内のコンテナ間、ポッド間、ユーザーとポッド間の通信をサポートします。これは複雑なネットワークのルーティングと制御を必要とします。

##### 2.2 CNIの役割と基本的な機能
CNIは、Kubernetesのコンテナがネットワークに接続する際のインターフェースを提供します。異なるCNIプラグインは、異なるネットワーク実装を提供し、ポッドのネットワーク接続を担います。

##### 2.3 CNIプラグインの動作メカニズム
CNIプラグインは、ポッドを作成または削除する際にKubeletによって呼び出され、ネットワークインターフェースをセットアップし、ネットワークトラフィックを適切にルートします。

#### 3. Linuxカーネルのネットワーキング機能

##### 3.1 Linuxネットワークネームスペースの概要
ネットワークネームスペースは、プロセスがネットワークリソースを分離された視点から見ることを可能にします。これにより、コンテナがそれぞれのネットワークスタックを持つことができます。

##### 3.2 vethペアとネットワークの接続
vethペアは、2つのネットワークネームスペースを接続するのに使用されます。通常、1つはホストのネームスペース、もう1つはコンテナのネームスペースです。

##### 3.3 Linuxネットワークブリッジと通信の流れ
Linuxブリッジは、同じホスト上の異なるネットワークネームスペース（コンテナ）間でトラフィックを転送するのに使用されます。

#### 4. コンテナネットワークのトラフィックフローの解析

##### 4.1 コンテナ内部のトラフィックフロー
コンテナ内部のトラフィックは、通常、ローカルホストアドレスを介してルーティングされます。

##### 4.2 コンテナからホストへのトラフィックフロー
コンテナからホストへのトラフィックは、vethペアを経由してルーティングされます。

##### 4.3 ノード内外のコンテナ間でのトラフィックフロー
ノード内外のコンテナ間でのトラフィックは、CNIとLinuxカーネルネットワーキング機能を使用してルーティングされます。
【Rails】実務でのsaveとcreate、create（save）とcreate!（save!）の使い分け

こんにちは。プログラミングスクール[Happiness Chain](https://happiness-chain.com/)でメンターをしているryoです。

今回はスクールでsaveとcreate、create（save）とcreate!（save!)をどのように使い分けるのか、質問があったので、実際に実務でどのように使い分けているかお話しします。

## saveとcreateの違いと、エラーハンドリングの方法

saveとcraeteの違いは、以下になります。
- save
    - newで作成したインスタンスを、DBに保存する
    - 返り値として、`true`（DB保存成功）or`false`（DB保存失敗）を返す
- create
    - インスタンス生成 + DB保存を一括で行う
    - 返り値として、DB保存成功・失敗に関わらず、インスタンスを返す（違いとして、IDの有無）

- 共通点
    - インスタンスのerrorsに、ActiveModel::Errorインスタンスが配列に格納される

上記を考慮すると、エラーハンドリングは以下になります。

- saveの場合
```rb
def create
  @user = User.new(user_params)
  if @user.save
    # 成功の処理
  else
    flash[:alert] = @user.errors.full_messages.join("\n")
    render :new
  end
end

```

- createの場合
```rb
def create
  @user = User.create(user_params)
  if @user.id.present?
    # 成功の処理
  else
    flash[:alert] = @user.errors.full_messages.join("\n")
    render :new
  end
end
```

createの場合は、__idが存在するかどうかで__ 判断する必要があります。
個人的には、__saveの方が、エラーハンドリングをする際に分かりやすい__ かなと思います。

## create(save)とcreate!（save!)の違いと、エラーハンドリングの方法
実務では、create!をよく使うので、create!の方で説明します。

「!」を付ける場合と付けない場合の違いは、
__失敗した場合に、例外処理を発生させるかどうか__ になります。

上記で記載したcreateの場合を、create!に書き直すと以下になります。
```rb
def create
  @user = User.create!(user_params)
  # 成功の処理
rescue => e
  flash[:alert] = e.messages
  render :new
end
```

ただ上記の場合だと、ちょっと分かりずらいと感じるかもしれないですし、
エラーが考えられる場合って、`@user = User.create!(user_params)`
の部分のみですので、
__1レコードの作成・更新の場合は、「!」を付けないで記載する__ 方が、どこでエラーが発生するのか明示的で良いかなと思います。

逆に、2レコード以上の作成・更新がある場合は、transactionを考慮する必要があり、
`ActiveRecord::Base.transaction`で括った処理で、例外処理が起こった場合に、　rollbackするので、
以下のように記載することができます。

```rb
def create
  ActiveRecord::Base.transaction do
    @user = User.create!(user_params)
    @profile = @user.profile.create!(profile_params)
  end
  # 成功の処理
rescue => e
  flash[:alert] = e.messages
  render :new
end
```

もし、上記をcreateで書こうとした場合は、以下のようになります。

```rb
def create
  ActiveRecord::Base.transaction do
    @user = User.create(user_params)
    raise @user.errors.full_messages.join("\n")  if user.id.nil?
    @profile = @user.profile.create(profile_params)
    raise @profile.errors.full_messages.join("\n")  if profile.id.nil?
  end
  # 成功の処理
rescue => e
  flash[:alert] = e.messages
  render :new
end
```

上記だと、成功したかどうかを条件分岐して、raiseを自分で書く必要があります。
ですので、__2レコード以上の作成・更新がある場合は、create!（save!)を使う__　方がすっきりします。


## まとめ
- 1レコードの作成・更新は、saveを使う
- 2レコード以上の作成・更新は、create!を使う
Composerについて

# Composer #

Composer（コンポーザー）は、PHPの依存関係管理ツールで、PHPプロジェクトで使用されるライブラリやパッケージを管理およびインストールするためのツールです。

## Composerの特徴 ##
1. **依存関係の管理**:
   - Composerは、PHPプロジェクトの外部依存関係（ライブラリ、フレームワーク、パッケージなど）を管理します。これにより、プロジェクトのコードベース内に必要なパッケージを簡単に追加、削除、アップデートできます。

2. **自動的な依存関係解決**:
   - Composerは、依存関係を解決する際に、各パッケージが必要とするバージョンを選択し、競合を解決します。これにより、依存関係が正確に管理され、バージョンの競合や互換性の問題が最小限に抑えられます。

3. **プロジェクトごとの設定**:
   - Composerは、プロジェクトごとに独自の`composer.json`ファイルを使用して依存関係を定義します。このファイルには、プロジェクトで使用するパッケージとそのバージョン情報が含まれます。

4. **パッケージのダウンロードとインストール**:
   - `composer.json`ファイルに依存関係を記述したら、Composerを使用してこれらのパッケージを自動的にダウンロードおよびインストールできます。これにより、開発者は手動でライブラリをダウンロードし、配置する手間が省けます。

5. **便利なコマンドラインツール**:
   - Composerはコマンドラインツールとして提供され、ターミナルから簡単に使用できます。例えば、新しい依存関係を追加する、依存関係を更新する、自動生成されたオートローダーを利用するなどの操作が可能です。

6. **グローバルインストールとプロジェクトローカルインストール**:
   - Composerをグローバルにインストールして、複数のプロジェクトで共有できます。また、プロジェクトごとにComposerをローカルにインストールすることもできます。プロジェクトローカルのインストールは、プロジェクトごとに異なる依存関係セットを管理する場合に便利です。

7. **オートローダーの生成**:
   - Composerは、依存関係のクラスを自動的にロードするオートローダーを生成します。これにより、手動でクラスファイルをインクルードする必要がなくなり、コードのメンテナンスが容易になります。

## MacOSへのcomposerのインストール方法 ##

MacOSへのcomposerのインストール方法は二つあります。

### 1.公式のインストーラーの利用 ###
公式のインストーラー（https://getcomposer.org/download/ ）を利用してComposerをインストール

```
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('sha384', 'composer-setup.php') === '906a84df04cea2aa72f40b5f787e49f22d4c2f19492ac310e8cba5b96ac8b64115ac402c8cd292b8a03482574915d1a8') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"
```

### 2.homebrewの利用 ###
1. **Homebrewをインストール（すでにインストール済みであればスキップ）**:

   Homebrewを使ってComposerをインストールする方法が最も簡単です。Homebrewがインストールされていない場合は、以下のコマンドを使ってインストールします。

   ```bash
   /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
   ```

   インストールが完了したら、ターミナルを再起動します。

2. **Composerをインストール**:

   Homebrewを使用してComposerをインストールします。以下のコマンドを実行します。

   ```bash
   brew install composer
   ```

   上記のコマンドを実行すると、Composerとその依存関係がインストールされます。

3. **Composerのバージョンを確認**:

   インストールが完了したら、Composerのバージョンを確認して、インストールが成功したかどうかを確認します。

   ```bash
   composer --version
   ```

   これでComposerがmacOSに正常にインストールされました。Composerを使用してPHPプロジェクトの依存関係を管理できるようになります。
HomebrewでMacにPHPをインストールする

# HomebrewでMacにPHPをインストールする #

## コマンド ##
下記コマンドを実行

```
brew install php
```

インストール後、下記コマンドでバージョンが表示されれば成功

```
php -v
```

## 公式ページ ##
https://www.php.net/manual/ja/install.macosx.packages.php
brewコマンド

# brewコマンドについて #

Homebrew (`brew`) を使用して、macOSにソフトウェアパッケージをインストール、アップデート、アンインストールするための基本的なコマンド例を説明します。

1. **パッケージの検索**:

   `brew search`コマンドを使用して、Homebrewのリポジトリから特定のパッケージを検索できます。

   ```bash
   brew search パッケージ名
   ```

   例えば、`curl`というパッケージを検索する場合：

   ```bash
   brew search curl
   ```

2. **パッケージのインストール**:

   `brew install`コマンドを使用して、ソフトウェアパッケージをインストールします。

   ```bash
   brew install パッケージ名
   ```

   例えば、`curl`をインストールする場合：

   ```bash
   brew install curl
   ```

3. **パッケージのアップデート**:

   `brew update`コマンドでHomebrew自体をアップデートし、`brew upgrade`コマンドを使用してインストール済みのすべてのパッケージをアップデートします。

   ```bash
   # Homebrew自体のアップデート
   brew update

   # インストール済みのすべてのパッケージをアップデート
   brew upgrade
   ```

4. **特定のパッケージのアップデート**:

   特定のパッケージをアップデートするには、`brew upgrade`コマンドとパッケージ名を指定します。

   ```bash
   brew upgrade パッケージ名
   ```

   例えば、`curl`をアップデートする場合：

   ```bash
   brew upgrade curl
   ```

5. **パッケージのアンインストール**:

   `brew uninstall`コマンドを使用して、特定のパッケージをアンインストールできます。

   ```bash
   brew uninstall パッケージ名
   ```

   例えば、`curl`をアンインストールする場合：

   ```bash
   brew uninstall curl
   ```

6. **Homebrewのバージョンを確認**;
    Homebrewのバージョンを確認するには、次のコマンドを使用します。

    ```bash
    brew --version
    ```
Vue.js 3 学習記録　チュートリアル編

# Vue.jsの概要学習　
https://www.youtube.com/watch?v=wlCwyouRbtE&t=157s
倍速で概要を確認した

# 公式HPで学習

## はじめに
https://ja.vuejs.org/guide/introduction.html

### Vue.jsの特徴 要点まとめ
​* 単一ファイルコンポーネント 一個のファイルでまとめて見た目、ロジック、スタイルを定義できる
HTML に似たファイル形式の Vue コンポーネント (*.vue ファイルとしても知られ、「SFC」と略されます)。
SFC は、その名前が示す通り、コンポーネントのロジック (JavaScript)、テンプレート (HTML)、およびスタイル (CSS) を単一のファイルに収めたもの

vueはHTMLの書き方とSFCの書き方がある

* 2 つの API スタイル​
Vue コンポーネントを作成する際は、Options API、そして Composition API と呼ばれる 2 種類
Composition APIの方が楽にかける

> Options API​
Options API では、data、methods、mounted といった数々のオプションからなる 1 つのオブジェクトを用いてコンポーネントのロジックを定義。定義されたプロパティには、コンポーネントのインスタンスを指す this を使って、関数内からアクセス

> Composition API​
Composition API では、インポートした各種 API 関数を使ってコンポーネントのロジックを定義していきます。SFC において、Composition API は通常、\<script setup>と組み合わせて使用し。setup という属性を付けることで、Vue にコンパイル時の変形操作を実行してほしいというヒントが伝えられます。これにより、定型的な書式の少ない Composition API を利用することができます。たとえば、\<script setup>のなかで宣言したインポート、トップレベルの変数、トップレベルの関数は、テンプレート内で直接使うことができます。



## チュートリアルで学習
CompositionとSFCの形態で学習
https://ja.vuejs.org/tutorial/#step-1

### 宣言的レンダリング
reactive() API 通常のオブジェクト
ref() API　任意の値の型

### 属性バインディング
```
<h1 v-bind:class="titleClass">{{titleClass}}</h1>
{{}} テキスト補間
v-bind:idはhtmlのid要素に割り当てる
v-bind:classはstyleの割り当て

```

### イベントリスナー
v-on ディレクティブを使うことで script内で宣言した関数を割り当てることができる
```
<script setup>
import { ref } from 'vue'

const count = ref(0)

function increment() {
  count.value++
}
</script>

<template>
  <!-- make this button work -->
  <button v-on:click="increment">count is: {{ count }}</button>
</template>
```

### フォームバインディング
input要素やラジオボタンに使えるやつ、v-model

### 条件付きレンダリング
if文 v-if,v-else

### リストレンダリング
v-for

### 算出プロパティー
computed() 
他のリアクティブなデータに基づいて .value を計算する算出 ref を作ることができる

### ライフサイクルとテンプレート参照
react hooksみたいな感じでレンダリング、マウントのタイミング重要、後で苦労しそう
```
<script setup>
import { ref, onMounted } from 'vue'

const p = ref(null)

onMounted(() => {
  p.value.textContent = 'mounted!'
})
</script>

<template>
  <p ref="p">hello</p>
//helloはマウント前の初期値、マウント後onMountedで実装した値が入る
</template>
```

### ウォッチャー
watch() は、直接 ref を監視することができ、 監視するrefの値が変化するたびにロジックを実行することができる

### コンポーネント、プロパティ
reactと一緒、コンポーネント(一塊)を定義し要素を渡すことができる

### イベントの発行
プロパティを受け取るだけでなく、子コンポーネントは親コンポーネントにイベントを発行することもできます、
要は子コンポーネントから親コンポーネントに値を渡す

### スロット
プロパティを経由したデータの受け渡しだけでなく、親コンポーネントはテンプレートフラグメントを スロット を経由して子コンポーネントへ渡すこともできる
reactではなかった、要確認

https://ja.vuejs.org/tutorial/#step-14




## 環境構築

yesにした項目、JSX reactで使っていたのでなんとなく入れた
ESLintとPrettierは整形のために入れた

* JSX 
*  Vue Router for Single Page Application development
*  Vitest for Unit testing
*  ESLint for code quality
*  Prettier for code formatting

https://ja.vuejs.org/guide/essentials/application.html#the-root-component

JSXって何だっけ
> JSXとは、「JavaScript XML」の略であり、HTMLと似たような記述をすることができる「Javascriptの拡張構文」

https://high-career.jp/2022/02/28/jsx/#:~:text=JSX%E3%81%A8%E3%81%AF%E3%80%81%E3%80%8CJavaScript%20XML,%E3%81%9F%E3%82%81%E3%81%AE%E6%A7%8B%E6%96%87%E3%80%8D%E3%81%A8%E3%81%AA%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82
デザインスキルに自信がなくても個人開発のUIUXに力を入れたい


# はじめに

個人開発をする際に、UIUXに力を入れたい！
ただプログラマーである以上、センスや知識がない中でUIUXをキレイに整えることはなかなか難しいと思います。
業務ではXDやFigmaでデザインが渡されているので、それを実装するのはできるけど自分で考えるのは難しい。。
そんな私と同じ思いを持っている方向けに、デザインツールを紹介します。

# レイアウト：UI Pocket

レイアウトは、以下の `UI Pocket`がとても素晴らしいサイトです。

https://ui-pocket.com/apps/

このサイトは、有名アプリのデザインがオンボーディングから退会まで全て掲載されています。
画面レイアウトに関してはとても参考になります。

### UI Pocketの素晴らしいところ
#### 1. カテゴリでまとまっている + アプリ検索ができる
アプリのサイドバーにはカテゴリボタンがあります。
自分が作りたいと思うアプリのカテゴリから似たようなカテゴリを探しましょう。

![Screenshot 2023-10-09 12.00.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/735195/4957e2d6-e4fb-84cb-5b30-075340706fcd.png)

#### 2. パーツ（コンポーネント）単位で検索できる

以下のscreen画面では、パーツ単位での検索ができるのも魅力的です。
Date PickerのいいUIはないか、おしゃれなグラフはないかなど調べるのにもってこいです。

https://ui-pocket.com/screens/

また、配色を真似したい場合は、 UI Pocketのスクリーンショットを撮って以下のサイトなどで色を取得するといいでしょう

https://lab.syncer.jp/Tool/Image-Color-Picker/

# レイアウト：Figr

Figrというサービスは、UI Pocketと似ていますが有名サービス等のFigmaデータの参照や取得ができるサービスのようです。その代わり、一部有料なので注意が必要です。

https://flash.figr.design/

ただし、UI Pocketの検索より豊富で、モバイル・Web別で検索できたりコンポーネント単位でも検索できるのでこちらも実装の参考になると思います。

### 検索画面

![スクリーンショット 2024-04-02 10.16.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/735195/f5077c5b-c714-93ce-6188-ce475e6dbb49.png)



# アイコン

アプリといえば、なんといってもアイコンです。
HTMLのheadだったり、モバイルのタブやアイコンだったりと必須ですよね。
アイコンをゼロイチで作るのはそれこそセンスが出てきて辛い...
その時には以下の2つがとてもおすすめです

## 1. Canva

Canvaではロゴ作成が簡単にできます。
その他のデザインも簡単に実装できるため

#### デザイン
デザイン検索では、元から完成したロゴを提供してくれます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/735195/7974fbb7-ba7e-e6cf-04a9-42e8a7443e15.png" width="280" >

#### 素材
素材検索では、写真やグラフィックの提供をしてくれます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/735195/c7a5f548-be7d-eccd-8a0a-6fe0a512219d.png" width="280" >

## 2. ChatGPT DALL-E 3

こちら、課金したGPT-4でしか使えませんが最近Beta版のDALL・E 3が使えるようになりました。

![Screenshot 2023-10-09 12.19.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/735195/c21cde2b-f2a9-a060-8704-677b16453e8d.png)

以下が、実際にアイコンを生成してみた例です。

#### Step1： お題を伝える

今回は、レシピ投稿アプリのアイコンを例に考えてもらいました。
ただ、左下以外はアイコンっぽくないですね。左下のようにしてもらいたい場合は、Vectorというキーワードを使って命令するといい感じになります。

![Screenshot 2023-10-09 12.22.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/735195/5f356fb4-cd46-8858-f15f-09e85f1cd43b.png)

#### Step2: Vector形式で出してもらい直す

どうでしょうか。結構アプリアイコンらしくなってきましたね。
ここから先は、自分の頭で描くアイディアだったり、もう少しこういう感じがいい、などのイメージをひたすら伝えていくことでブラッシュアップすることができます。

また、先ほどのCanvaを組み合わせてここで生成されたアイコンをCanvaで少し加工するとより良い結果になるでしょう。

![Screenshot 2023-10-09 12.23.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/735195/b118a5a8-8852-d398-df7f-4919300cda2a.png)


以上です！
これらのツールを使って個人開発でも素晴らしいUIUXを作り上げましょう！
プログラム初心者初日の出来事

フロントFWであるVue.jsの機能のうちの一つ「Vue-router」とバックエンド言語であるpythonのライブラリFlask-Loginを使用し、マルチログイン機能の実装をしようとした。

動き
1.ログイン→運営>メンバー
(管理者)(Vue.js+python)

2.ログイン→会員登録
(ユーザー側)(Vue.js+python)

2.で会員登録した内容をメンバーにて反映させる。

たたき台の作成
運営>メンバー部分を作成することとする。

よくあるものを作ることに。

AM～
バージョン関連の話は特に重要となってくるみたいで
Vueのバージョンをどう管理し、システム構築していくのをしっかりと決める必要がある。
どうやら、vue2が安定しているみたいなので今回はVue2でvue-routerを導入することにする。

プロジェクトを作成したが、このようなエラーが。

Skipped git commit due to missing username and email in git config, or failed to sign commit.
You will need to perform the initial commit yourself.

どうやら、Gitコミットなるものをしなくてはいけないらしい。
なので、ユーザー名、メールアドレスを設定することに

git config --global user.name "***"
git config --global user.email "***@***"

PM～
なぜかよくわからないが、vue-rouderはプロジェクト内作成不可とのこと。
ユーザーディレクトリにインストール後、先輩の記事をみて頑張ってみることに。
srcディレクトリ内にrouter.jsを作成。

エントリポイント？？main.jsに記述を追加。

...なんやかんや数時間後

どうやらCLIでプロジェクト作成した後にインストールする必要があるらしい。Chatgptが答えてくれた。
コマンド：vue add router
historyモードはYESで実行。

ルーティング機能実装完了。
これでSPAの入門編はとりあえず習得完了かな？(不安)

これがルーティングというものか？

次にログイン情報により、ページ分岐を制御する必要があるので、pythonのライブラリで動かすことに。
マルチログインとはどこまでのことを指すのかは不明だが、ログインID、パスワードごとにそれぞれのページの自動生成を可能としたい。

今日はここまで。
Macのパッケージ管理ツール（Homebrew）

# Homebrewとbrewの関係 #

Homebrewとbrewは、macOSおよびLinuxベースのシステムでソフトウェアのパッケージ管理を行うためのツールですが、異なるものです。

1. Homebrew:
   - Homebrewは、macOSおよびLinuxで利用できるオープンソースのパッケージ管理システムです。
   - Homebrewは、コマンドラインツールやGUIアプリケーションなどのソフトウェアパッケージを簡単にインストール、アップデート、削除することができます。
   - Homebrewは`brew`というコマンドを提供し、このコマンドを使ってパッケージの管理を行います。
   - Homebrewのパッケージリポジトリには、多くのオープンソースソフトウェアが含まれており、ユーザーは必要なソフトウェアを検索してインストールできます。

2. brew:
   - `brew`は、Homebrewのコマンドラインユーティリティです。macOSおよびLinuxシステムでHomebrewを使用する場合、`brew`コマンドを使用してソフトウェアのインストール、アップデート、アンインストールなどを行います。
   - `brew`コマンドは、ターミナルから直接実行されます。例えば、`brew install`コマンドを使用してソフトウェアをインストールできます。
   - `brew`コマンドは、パッケージの依存関係の解決やバージョン管理など、多くの便利な機能を提供します。

要するに、Homebrewはパッケージ管理システム全体を指し、`brew`はそのコマンドラインインターフェースを指します。Homebrewを使ってシステムにソフトウェアを簡単に追加したり更新したりすることができ、`brew`コマンドを通じてこれらの操作を行います。

## Homebrewのインストールの仕方 ##
- コマンド
    ```
    /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
    ```

- 公式ページ
    - https://brew.sh/

## Macで使用されている他のメジャーなパッケージ管理ツール ##

1. **MacPorts:** MacPortsは、macOS向けのオープンソースのパッケージ管理ツールで、UNIX系オペレーティングシステムのソフトウェアをmacOSにポートするために使用されます。MacPortsはHomebrewとは異なるアプローチを採用しており、ソフトウェアの依存関係を管理し、ソフトウェアをビルドおよびインストールします。

   - MacPortsのインストールは、公式ウェブサイト（https://www.macports.org/ ）からインストーラーパッケージをダウンロードして実行することができます。

2. **Fink:** FinkもmacOS向けのパッケージ管理システムで、UNIXアプリケーションをmacOSに移植するために使用されます。FinkはLinuxのAPT（Advanced Package Tool）に似たパッケージ管理システムを提供しています。
    - Finkのインストールについては、公式ウェブサイト（https://www.finkproject.org/ ）からインストーラーパッケージをダウンロードして実行します。
Androidアプリのproguardで画像が表示されなくなる件

# 問題
過去にリリースしたアプリに取り込んでいる各種ライブラリの最新化などメンテしていた際に
proguardまわりを見直していたら、突如画像が出力されなくなった。
![スクリーンショット 2023-10-09 11.47.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183689/7557ea95-6646-7d46-de38-8ed71f2befd7.png)
画像１．正しく表示されている例
![スクリーンショット 2023-10-09 11.47.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183689/875e097a-bcb4-6f47-73fd-f50389f04142.png)
画像２．正しく表示されていない例

# 原因・解決方法
build.gradle(:app)のbuildTypesに「shrinkResources true」を追加したことが原因。
これを削除したことで問題なく画像が出力されるようになった。
![スクリーンショット 2023-10-09 11.44.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183689/9faf2e71-e7d2-1d4f-affc-a13ae416f1e2.png)

# 分析とか
参考：https://developer.android.com/studio/build/shrink-code?hl=ja
「shrinkResources true」を追加すると
リソースの圧縮という機能が有効になるらしいのだが
プログラム的に参照されていないと判断されたリソースは削除されるらしい。

本アプリは、実行時に定義された画像ファイル名文字列を元に
リソースIDを取得して画像表示する実装となっているため
参照されていない画像として判断されてしまった模様（細かい動きはわからないけど……）

同様に別のアプリでもビルド時に「string.xml」で定義している文字列が削除されているっぽかったので
そちらもこの「shrinkResources true」が原因かも。。