OmniAICreator/Qiita-1.07M huggingface dataset:
統計的推定と検定をPythonで解く「母分散の推定（母平均未知）の場合」(2022.4.19)

# 背景
先日は、Pythonで「区間推定（一般母集団で大標本の場合）」を行いました。コード的には、stats.binom.interval 関数を用い母比率の信頼区間を求めるだけです。その引数として「信頼度：alpha」「標本数：n」「母比率：p」を必要としました。基本は標準化得点$Z$について、<br>$P(−1.64≤Z≤1.64)=0.90$<br>が成り立つため、母比率の信比率頼区間を求めるために上手い具合に式を変形して求められるのでした。

前回の記事
[統計的推定と検定をPythonで解く「区間推定（一般母集団で大標本の場合）」(2022.4.11)](https://qiita.com/tan0ry0shiny/items/5fe9d090676669adaf9a)

今回は、「区間推定（母分散の推定で母平均未知の場合）」について解いていこうと思います。今回も「[とけたろうさんのチートシート](https://toketarou.com/cheatsheet/#toc16)」を使わせて頂きます。

# 問題
あるメーカーが製造しているロープの破断荷重（ロープに物をつるしたときにロープが破損する重さ）を調べるために，６本のロープを無作為に抽出したところ，次のような結果になった。

5.1，4.7，5.3，5.2，5.5，4.8（トン）

このとき，母分散σ2の信頼度95％の信頼区間を求めなさい。ただし，メーカーが製造しているロープの破断荷重は正規分布に従うものとする。

# 解答
## どういう問題か（問題の分類）
今回も、母分散の区間推定です。確率分布としてはカイ二乗分布で、母分散は未知です。

## <h2>どのように解けるか（解法）</h2>
標本の大きさを $n$，不偏分散を$U^2$とすると，次の確率変数は自由度$(n-1)$の$\chi^２$分布に従います。
$$\frac{(n-1)U^2}{\sigma^2}$$
まず$\chi^2$（カイ二乗）値については次のようになります。
$$\chi^2=\frac{(n-1)U^2}{\sigma^2} ①$$

カイ２乗分布表から，自由度５のカイ２乗分布の下側2.5％点は0.831，上側2.5％点は12.833であるから，次の不等式が成り立ちます。

$$0.831\leq \chi^2\leq12.833$$
これに①を代入すると
$$0.831\leq \frac{(n-1)U^2}{\sigma^2}\leq12.833②$$

ここで不偏分散$U^2$の$(n-1)$倍を計算すると，次のようになります。
$5U^2$
$=(5.1-5.1)^2+(4.7-5.1)^2+(5.3-5.1)^2+(5.2-5.1)^2+(5.5-5.1)^2+(4.8-5.1)^2$
$=0.46$

②に$5U^2$を代入して、母分散について解くと次のようになります。

$$\frac{0.46}{12.833}\leq\alpha^2 \leq\frac{0.46}{0.831}$$

最左辺と最右辺を小数第４位を四捨五入して計算すると，母分散の信頼度95％の信頼区間は次のようになります。

$$0.036\leq \alpha^2 \leq 0.554$$

## <h2>どのように解けるか（Python）</h2>

```Python
import numpy as np
from scipy import stats
data=np.array([5.1,4.7,5.3,5.2,5.5,4.8])
df = len(data)-1 # 自由度n-1
U5 = np.var(data, ddof=1)*df #不偏分散の自由度倍
low, high = stats.chi2.interval(alpha=0.95, df=df)
print(f"不偏分散Uの自由度({df})倍は{U5:.2f}となります。これより、")
print(f"母分散の信頼度95％の信頼区間は{U5/high:.3f}≦σ^2≦{U5/low:.3f}となります")
```

母分散$\sigma^2$の信頼度95％の信頼区間は
$0.036\leq \sigma^2\leq 0.553$になります。

次に、このコードの解説をしていきます。前回は 二項分布ですので stats.binom.interval 関数を使いました。今回は $\chi^2$ 分布ですので stats.chi2.interval 関数を使います。これを使うためには、「信頼度：alpha」「自由度：df」が必要になります。また、不偏分散$U$はnp.var 関数を使って求めています。

# 可視化
この時想定する$\chi^2$分布は次の様になります。
```Python
from scipy import stats
import numpy as np
import matplotlib.pyplot as plt

rv=stats.chi2(df=5)
x=np.arange(0,28,1)
plt.plot(x, rv.pdf(x))
plt.title(f"有意水準{(1-0.95)*100}%の範囲")
plt.fill_between(x, rv.pdf(x), where=(x>=rv.ppf(0.975)), facecolor='blue', alpha=0.1)
plt.fill_between(x, rv.pdf(x), where=(x<=rv.ppf(0.025)), facecolor='blue', alpha=0.1)
plt.plot(rv.ppf(0.025),0,marker='x')
plt.plot(rv.ppf(0.975),0,marker='x')
plt.show()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2496939/ac3e9178-330e-7d83-80b4-26e704531e62.png)



# <h1>感想</h1>

1. この記事を作ってみて
今回は、統計的推定の簡単な問題3です。前回の「区間推定（正規母集団で母分散未知の場合）」でした。違いは「二項分布か$\chi^2$分布か」くらいです。私の表現の仕方に癖があり、受け入れられない方も多くいらっしゃると思いますが、そこは生暖かい目で見守って頂ければと思います。また、間違いの指摘やご意見などありましたら遠慮なく仰って下さい。
cscの作法 その130

# 概要
cscの作法、調べてみた。
managed directxやってみた。
シェーダー書いてみた。
shadertoyのglslを移植してみる。


# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/33221b9c-a318-1101-a586-8977afffbca3.png)

# hlsl

```
struct VS_IN {
	float4 Pos: POSITION;
	float4 color: COLOR;
};
struct VS_OUT {
	float4 Pos: POSITION;
	float4 color: COLOR;
	float2 coord: TEXCOORD;
};
VS_OUT VSmain(VS_IN In) {
	VS_OUT output = (VS_OUT) 0;
	output.Pos = In.Pos;
	output.color = In.color;
	output.coord = In.Pos.xy;
	return output;
}
float linearstep(float edge0, float edge1, float x) {
	float t = (x - edge0) / (edge1 - edge0);
	return clamp(t, 0.0, 1.0);
}
float smootherstep(float edge0, float edge1, float x) {
	float t = (x - edge0) / (edge1 - edge0);
	float t1 = t * t * t * (t * (t * 6. - 15.) + 10.);
	return clamp(t1, 0.0, 1.0);
}
void plot(float2 r, float y, float lineThickness, float3 color, inout float3 pixel) {
	if (abs(y - r.y) < lineThickness)
		pixel = color;
}
float4 PSmain(VS_OUT In): COLOR {
	float2 r = In.coord;
	float3 bgCol = float3(1.0, 1.0, 1.0);
	float3 axesCol = float3(0.0, 0.0, 1.0);
	float3 gridCol = float3(0.5, 0.5, 0.5);
	float3 col1 = float3(0.841, 0.582, 0.594);
	float3 col2 = float3(0.884, 0.850, 0.648);
	float3 col3 = float3(0.348, 0.555, 0.641);
	float3 pixel = bgCol;
	const float tickWidth = 0.1;
	float x = r.x;
	float y = r.y;
	if (abs(sin(PI * r.x) - y) < 0.02)
		pixel = col1;
	if (abs(0.25 * linearstep(-0.5, 0.5, x) + 0.1 - y) < 0.01)
		pixel = col3;
	if (abs(0.25 * smootherstep(-0.5, 0.5, x) - 0.9 - y) < 0.01)
		pixel = col3;
	plot(r, 0.5 * clamp(sin(TWOPI * x), 0.0, 1.0) - 0.7, 0.015, col2, pixel);
	plot(r, 0.6 * exp(-10.0 * (x + 0.8) * (x + 0.8)) - 0.1, 0.015, col2, pixel);
	return float4(pixel, 1.0);
}
technique MyTechnique {
	pass MyPass {
		VertexShader = compile vs_2_0 VSmain();
		PixelShader = compile ps_2_0 PSmain();
	}
}


```

以上。
UbuntuのCUIでファイルサイズを大きい順に探す

ncdu を使うとよいです。

```bash
sudo apt-get install ncdu
ncdu
```

どうしてもncduが入れられない場合、以下のコマンドでも動きます。
ファイルサイズ昇順
```bash
while read file; do du -maxd 0 -h "${file}";  done < <(du -maxd 1 | sort -n | cut -f 2-2)
```

ファイルサイズ降順
```bash
while read file; do du -maxd 0 -h "${file}";  done < <(du -maxd 1 | sort -nr | cut -f 2-2)
```
重度のMac使いのWebエンジニアがUbuntuにデスクトップ環境を変えた。メリット、デメリット

約20年間、OSXの10.0からMacを使っていた私が、コロナ禍に伴い個人デスクトップ環境をUbuntuに変えて1年以上、2年近く経ちました。改めて、環境を変えた理由なども含めていくつか紹介していきます。

## 環境の概要
以前使っていたMac(ノート) MacBookPro(2017年モデル 13inch　メモリ16G)
今使っているPC(デスクトップ)　第9世代corei7 9700k メモリ32G

## 環境を変えた理由
- コロナ禍で移動して仕事をすることがなく、デスクトップで快適に作業をしたくなった為
- Mac版のDockerが重たくてかなり不快感があった為
- DeepLearning系のコードを触って色々遊んでみたかった為(MacはGeForce使えない)
- 最近のAppleの製品に全く魅力を感じなくなってきている為(Surfaceの方がデバイスとしてCoolだよね？)

## ココが良かったUbuntuデスクトップ(メリット)
- 仕事面
    - VSCode、intelliJ等、開発環境は一通り揃っている
        - ただ、intelliJのLinux版はちょっと不安定かも？メモリを結構食べる
    - 変えた理由はすべて達成出来ている
    - プログラマーとしての日常業務はほぼ問題ない。作業効率はむしろ高い
    - LiberaOfficeがあればMS Officeマジで要らない
        - なんならGoogleDocsでもだいたい動く
    - 複数デスクトップの切り替え等、割と痒い所に手が届く
    - Zoom、Slack、Discord、Google Meet、Skypeといったリモート会議系のツールも何ら問題ない
    - ディレクトリ構造が一般的なので、特にCUI関連は移行にあたって違和感はなかった
    - Mac時代に作った自分用の便利コマンドラインツールはだいたい動く
- プライベート面
    - 周辺機器はほぼ問題なく使えた
        - キャプチャボード、Bluetoothアダプタ、音声出力デバイス、Webカメラなどなど
        - Apple Wirelessキーボードを上手く使えなかったくらい？
    - 周辺機器を使う上で、CUI上でいろいろやらなくちゃいけない等もなかった
    - 意外とデフォルトのフォントが綺麗で画面が見やすい
    - Macは表示が綺麗というが、Ubuntuも負けていないと思う

## ココが微妙だUbuntuデスクトップ(デメリット)
- 仕事面
    - ~~デスクトップで変なバグを踏み、操作不能になることが頻発する~~
        - ~~例：何かセレクトメニューひらいたまま、範囲選択画面キャプチャをしようとするとクリックが不能になる~~
        - ~~例：全画面表示を続けていると、何故か時計等のシステムの文字が消える~~
        - ~~その度にPCの再起動が必要になる~~
            - Ubuntu22.04にアップデートしてからは安定している
    - LiberaOfficeのウィンドウをリサイズすると、数ピクセルの細いウィンドウになって行方不明になった
        - 最小ウィンドウサイズが無いのか？
    - Chromeがたまに不安定
        - ~~自動アップデートが何故か対応してくれなかったり、面倒~~
            - こちらも解決
    - ターミナルのコピペはShift+Ctrl+C(Ctrl+Cはキル)でしか対応しないが、通常のエディタ等はCtrl+Cでコピーになるの面倒
    - Mac時代にはあった便利なGUI機能が無い。Finderはマジで最強だった
        - フォルダアイコンの上にドラッグし続けると、そのフォルダのウィンドウが開く
        - QuickLook系
    - ~~デスクトップのカスタマイズが殆ど出来ない~~
        - ~~所謂Dock~~
            - めんどくさいけど結構出来た
    - OSのバージョンアップがたまに転ける
        - Python周りとかいろいろ
    - iOS系の開発
    - デスクトップPCにしたので、たまに出社したときやがキツい
        - レンタルオフィスとか、コワーキングスペースの利用が困難
- プライベート面
    - iPhoneとの同期問題
        - iTunesが無いことから、昔から取り込んできたCD音源の数々が微妙に使えていない
        - 結果、音楽を聴くことがめっきり減った
    - ゲーム系はやはりWindowsが良い
        - 子供がマイクラしたいと言った時にデュアルブートWindowsを毎度立ち上げている
        - ゲームの配信などしたい時、OBS系のチューニングに適した外部アプリがほぼwindows
    - Yahooニュースの動画が何故かLinux版のChromeに対応していない
        - UA偽装したら見えるけど、AWSコンソールでLambda関数いじる時に怒られたりしたので辞めた


## 総評

ぶっちゃけほぼ不満は無いです。
基本的なhamlの書き方

# はじめに
仕事でhtmlではなくhamlを使うと言うので急いでドットインストールで学習しました。備忘録として残します。
# 基本的な書き方
hamlを使う場合、基本的には頭に%をつけます。そうすることで下記のようにhtmlへ変換されます。
```test.haml
!!!
%html
  %body
    hello world!
```
```test.html
<!DOCTYPE html>
<html> 
  <body>
    hello world!
  </body>
</html>
```
とても便利！
# 属性の書き方
属性を書く場合は２パターンあります。{}を使う場合と()を使う場合です。
```test.haml
!!!
%html{:lang => "ja"}
  %head
    %meta(charset="UTF=8")
```
```test.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF=8">
  </head>
</html>
```
{}の場合はシンボルと=>、()の場合は=を使って表します。
# コメントアウト
/ コメント　　htmlにも反映される。 
-#　　コメント　htmlに反映されない
# 改行のコントロール
hamlの見た目を意識して次のように記述するとhtmlにはバランスが悪く表示されてしまします。
```test.haml
%div
  %ul
    %li
      test
```
```test.html
<div>
  <ul>
    <li>
      test
    </li>
  </ul>
</div>
```
そこで<>を使います。li要素の末尾に<を記入すると文字列が<li>内１行で表示されます。
```test.haml
%div
  %ul
    %li<
      test
```
```test.html
<div>
  <ul>
    <li>test</li>
  </ul>
</div>
```
さらに子要素の末尾に>を記入すると親要素内１行で表示されます。
```test.haml
%div
  %ul
    %li<>
      test
```
```test.html
<div>
  <ul><li>test</li></ul>
</div>
```
# 属性の記述
属性を記述するには２通りの記法があることは先でも述べました。
{}を使用する場合では　{:属性　=> 属性値}となります。()を使用する場合は(属性="属性値")となります。
```test.haml
%div{:id => "main"}
%div(id="main")
```
どちらで書いても下のようになります。
```test.html
<div id="main">
</div>
```
また、divはよく使用されるものなので、次のように記入しても同じです。
```test.haml
%div{:id => "main", :class => "myClass"}
%div(id="main" class="myClass")
%div#main.myClass
#main.myClass
```
全て下と同じです。
```test.html
<div id="main" class="myClass>
</div>
```
最後の行はすでに%divまで省略しています。
# フィルター
hamlにはフィルターを設けることができます。以下css,script,escapeなど使えます。
```test.haml
:css
　　　　.myStyle {
 　　　　　　color: red;
  }

:javascript
  alert(1);
  if (1) {
  　　　　alert(2);
  }

%div
　　　　:escaped
 　　　　 <html>
    </html>
```
全て下と同じです。
```test.html
<style>
  .myStyle {
    color: red;
  }
</style>

<script>
  alert(1);
  if (1) {
    alert(2);
  }
</script>

<div>
　　　　&lt;html&gt;
　　　　&lt;/html&gt;
</div>
```
以上

# 参考
ドットインストール
https://dotinstall.com/
Java: WebSphereトラブルシューティング三種の神器(HeapAnalyzer, TMDA, PMAT)

IBM WebSphere(IBM Java)には、Javaのトラブルシューティングに利用できる、いくつかのツールがあります。本記事では、それらのツールを3つ紹介します。

# HeapAnalyzer

ヒープダンプを解析し、OutOfMemoryErrorなどのJavaメモリ上の問題を調査するためのツールです。ヒープダンプの解析結果をグラフィカルに表示することができ、ヒープを占めているオブジェクトを特定することなどができます。

https://www.ibm.com/support/pages/ibm-heapanalyzer

ただし、上記のURLに記載されている通り、現在は新機能の開発を終了してしまっているようです。このため、Java 8以降の実行環境では、現在も開発が続けられているEclipse Memory Analyzer Toolを利用していくべきかもしれません。

https://eclipse.dev/mat/

# Thread and Monitor Dump Analyzer for Java (TMDA)

スレッドダンプ(javacore)を解析し、ハングの可能性のあるスレッドやデッドロックなどの問題を調査するためのツールです。ある時点で実行中のロジックを特定することなどができます。

https://www.ibm.com/support/pages/ibm-thread-and-monitor-dump-analyzer-java-tmda

使い方については、以下の記事に詳しく解説されています。

https://qiita.com/charon/items/23bc3d04f28f3a15578a

# Pattern Modeling and Analysis Tool for Java Garbage Collector (PMAT)

GC(ガベージコレクタ)トレースを解析し、Javaヒープの使用状況を調査するためのツールです。CPU使用率が高止まりしている場合などにおいて、GCの実行頻度などを調査することができます。

https://www.ibm.com/support/pages/ibm-pattern-modeling-and-analysis-tool-java-garbage-collector-pmat

こちらのツールも、現状は開発を停止してしまっているようです。このため、後継のGarbage Collection and Memory Visualizerの利用が案内されています。ただし、デフォルトでは起動にIBM Java 8またはIBM Semeru 8を必要とするため、やや注意が必要です。

https://www.ibm.com/support/pages/garbage-collection-and-memory-visualizer
no_proxyに連続した複数IPアドレスを指定する方法

`no_proxy`にはサブネットを指定できないため、IPアドレスを一つずつ指定する必要がある。
連続した複数のIPアドレスを指定する場合、以下のようにすればIPアドレスを一つずつ指定せずに済む。

* `172.16.10.5` ~ `172.16.10.24`のIPアドレスをno_proxyに指定する場合

`/etc/profile.d/proxy.sh`に以下を指定

```bash
export http_proxy=<proxyのURL>
export https_proxy=${http_proxy}
export HTTP_PROXY=${http_proxy}
export HTTPS_PROXY=${http_proxy}

export no_proxy=localhost,127.0.0.1
export no_proxy=${no_proxy},.example.com,.localdomain
for i in $(seq 5 24); do export no_proxy=${no_proxy},172.16.10.${i}; done

export NO_PROXY=${no_proxy}
```
Photoshopのフレームアニメーションを使って動画を作ろう

### 対象読者
- フォトショで動画作ろうっていうニッチな方
- フレームアニメーション、トゥイーンという用語だけは聞いたことあるよ、という方

### 今回作る動画の完成図

![sample.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694513/0176ba1e-5705-46c5-f03c-27667349d91b.gif)
このご時世なのでなかなか日本へ来てくださる方も少ないですが、このような動画をPhotoshopで作ってみましょう。
※素材は[いらすとや](https://www.irasutoya.com/)さんから

### 作業環境
- Photoshop 2022 23.0.1(←このバージョンである必要はないです)

### 作成手順
冒頭のgifは「日本列島を表示→桜吹雪が左から右へ→扇子の表示」というのが一連の流れとなっています。

1. 素材を読み込み、ウィンドウ > タイムラインを選択し、「フレームアニメーションを作成」を押下
![01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694513/8da9041c-5e00-1d1d-1973-9c42385ab777.jpeg)
1. 動画の開始部分を作成します。日本列島と桜吹雪を表示状態にし、桜吹雪を左端へ移動
![02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694513/7065c3cb-76a8-909a-9743-1f35736913e9.jpeg)
1. フレームの複製をします。タイムライン上で「選択したフレームを複製」を押す
![03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694513/17943219-4d8e-a5d6-03a2-a9c4391408f7.jpeg)
1. 桜吹雪の移動後の状態を作成します。複製したフレームを選択して桜吹雪を右側へ移動します
![04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694513/e271104d-7799-4f66-8a50-c5903df58817.jpeg)
1. 中間フレームの作成をします。タイムライン上の1と2のフレームを選択し、トゥイーンを押す
![05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694513/1f659928-9ec9-a343-cfb4-b43ff621f82b.jpeg)
追加したいフレーム数を入力します（今回は5）
![05_02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694513/669be54b-e65c-fc62-fad8-815877ca284f.jpeg)
すると、間のフレームを自動補完してくれます。便利。
![06.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694513/14860a9b-e05d-d7b1-e35d-ca1297b2e273.jpeg)
![sample-1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694513/267fd892-af1b-f217-b3a7-5309c50dc900.gif)
6. 2～5の手順と同じ要領で、扇子も同様に作成ができます。フレームを複製してから扇子を表示し、不透明度をつけます
![07.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694513/99a7fadb-60e8-0588-76a0-f0db09c06623.jpeg)
7. 扇子の不透明度100%状態のフレームを作成し、トゥイーンで間を補完すると、冒頭のgifのようになります

### 補足
トゥイーンですが、拡縮には対応していません。よって「徐々に大きくする」などの補完はできないので注意が必要です
※誰か方法ご存知でしたら教えて頂きたいです

### より複雑な動画を作りたい場合は、、
フレームをレイヤーに吐き出して、1枚ずつ調整することも可能です。
タイムライン上のハンバーガーメニュー > フレームをレイヤーに統合　をすることでレイヤーに各フレームの情報が転記されるので、そちらで調整を行うことができます。
![08.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694513/c1ff64c4-9d7e-0a54-bfdf-30790d9002de.jpeg)

### 書き出しについて
ファイル > 書き出し > ビデオをレンダリング　で書き出しが可能です。
連番pngで書き出す場合は「Photoshop画像シーケンス」を選択した上で書き出すと、名前も指定しやすくてとても便利です。
![render.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694513/7c092e88-bcca-764b-cf41-0336bf1def31.png)

### さいごに。参考URL情報
Photoshopだけで動画を作ろう！と思い立つ方は少ないと思いますが、今回の動画なら15分程度で作成可能です。特にトゥイーン機能がとても便利で、そこだけ作って連番pngで書き出すだけで時短できることもあるので、試してみてください。

本件調査＋記事を書くにあたり参考にした情報を掲載して終わりにしたいと思います。ありがとうございました。

[M-HAND「【Photoshop】トゥイーン機能を使って滑らかなGIFアニメを作る方法」](https://www.m-hand.co.jp/design/6462/#:~:text=%E3%83%88%E3%82%A5%E3%82%A4%E3%83%BC%E3%83%B3%E3%81%AF%E7%A7%BB%E5%8B%95%E3%81%A0%E3%81%91%E3%81%A7%E3%81%AF,%E3%81%AA%E8%A1%A8%E7%8F%BE%E3%81%8C%E5%8F%AF%E8%83%BD%E3%81%A7%E3%81%99%E3%80%82)
[日曜アーティストの工房「Photoshopのレイヤーを連番画像として一気に書き出す方法」](https://tomaki.exblog.jp/15857408/)
UITextFieldの中の文字をサイズによって可変にする

# 前提条件
UITextFieldが左右の制約により適切に突っ張っていること。

# バージョンによってやり方が異なる
## iOS13より前のバージョン
`_placeholder.adjustsFontSizeToFitWidth`をUITextFieldに以下のように設定するとプレイスホルダーを含めた文字が小さく表示されます。
![スクリーンショット 2020-11-11 17.29.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171702/5cb0a317-f30a-e676-d245-bcd2fecfe3d5.png)

Min Font Sizeを設定
![スクリーンショット 2020-11-11 17.39.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171702/bda7d072-e845-6304-f7c2-ce80d1a59044.png)

## iOS13移行
https://developer.apple.com/documentation/uikit/uitextfield/1619625-adjustsfontsizetofitwidth
UITextFieldのminimumFontSizeを設定し、`adjustsFontSizeToFitWidth `をtrueにします。

```swift
    @IBOutlet weak var textField: UITextField! {
        didSet {
            textField.minimumFontSize = 10
            textField.adjustsFontSizeToFitWidth = true
        }
    }
```
cscの作法 その129

# 概要
cscの作法、調べてみた。
managed directxやってみた。
シェーダー書いてみた。
glslをhlslに書き換えてみる。

# glsl→hlsl書き換え手順

## 置き換え

| glsl | hlsl |
|:--|:--|
|vec4|float4|
|vec3| float3|
|vec2	|  float2		|
|mat3|float3x3|
| mat4|float4x4|
| mat3x4	|  float3x4|
|fract|			frac|
|mod|				fmod|
|atan|		atan2|
|mix|		lerp|
|texture2D|	tex2D|
|*= | mul|
|signed integer|int2|
| vector|int2|
| ive2|int2|
| ivec3|int3|
| ivec4|int4| 
|dFdx| ddx|
|dfdy | ddy|

## テンプレート

```
struct VS_IN {
	float4 Pos: POSITION;
	float4 color: COLOR;
};
struct VS_OUT {
	float4 Pos: POSITION;
	float4 color: COLOR;
	float2 coord: TEXCOORD;
};
VS_OUT VSmain(VS_IN In) {
	VS_OUT output = (VS_OUT) 0;
	output.Pos = In.Pos;
	output.color = In.color;
	output.coord = In.Pos.xy;
	return output;
}
float4 PSmain(VS_OUT In): COLOR {
	float4 color = float4(1.0, 1.0, 1.0, 1.0);




	return color;
}
technique MyTechnique {
	pass MyPass {
		VertexShader = compile vs_3_0 VSmain();
		PixelShader = compile ps_3_0 PSmain();
	}
}


```

以上。
API('ω')？

# [<font color="#333">APIとは</font>](#-APIとは)
調べるとだいたい「アプリケーションなんたらかんたら」の略で～と出てきますが、おそらく私レベルの初学者が知りたいのはそこじゃない。
正式名を知りたくて調べたのではない。
APIを使って何が出来るかイメージが付かない。


# [<font color="#333">両想いってこと</font>](#-両想いってこと)
|　　　　　　　　  　　　　　　　　   　　　　　　　　　　　　　　　　　　　　　　　　　
|:-:|
|<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/920917/e1ab40cb-470f-d3ce-2dee-1823b297bb5a.png" >|

要するにサービスを使いたい側居て、そしてサービスを使って欲しい側が居て成り立っている。
ではどのようにしてそれが成立しているのか？


基本的にAPIは「リクエスト（要求）」と「レスポンス（応答）」で構成されます。
という事はURLが関係してきますね。

どのようなリクエストをすればどのようなレスポンスを返すかはAPIのサービスの提供者側が設計段階で決定します。
なので一概に「APIを利用すればこれが出来る！」というものでもありません。


# [<font color="#333">具体例</font>](#-具体例)
例えばよく見るGoogleアカウントでログイン等のソーシャル認証機能を実装したい時は
[Google API Console](https://console.cloud.google.com/)
にアクセスしてAPIを使用する為のURLを登録します。
![スクリーンショット (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/920917/e3fda13b-f7d5-3363-0ac1-aaf0a34e28da.png)
ここで設定したURLに対しての処理をLaravel側で行うとGoogleが提供しているAPIであるソーシャルログイン機能が実装できるわけです。

あとは例えば楽天レシピAPIと連携する場合もこの様にURLを設定して提供されたIDなどをLaravelに設定する事で楽天レシピの情報がJSON形式で取得できます。JSON形式とは簡単に言えば配列ですね。あとはその配列からレシピ名や画像やリンクを取得してブラウザに表示します。

![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3932303931372f31343063333531612d633733312d333662382d666133332d3761613031316436646461382e706e.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/920917/5c69ab0f-320f-3cba-2815-7841fde61fe2.png)

こんな感じですね。画像もコメントも楽天APIから取得しています。
![スクリーンショット (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/920917/f82f60f6-3978-68b5-446f-6046e1692019.png)
この様に開発側の「レシピサイト使いたいなぁ」に対して
レシピサイト側は「レシピサイト使って欲しいなぁ」と思っていてまさに相思相愛状態がAPI。
# [<font color="#333">「API叩け・・・？」</font>](#-「API叩け・・・？」)

それとは別に「APIを叩く」ってのも聞きます。
これも本質は一緒でリクエスト（要求）に対して何かしらのレスポンス（応答）を意図的に返す事。
例えばこの様にルーティングを設定して
```web.php
Route::post('/signup', 'RegisterController@register')->name('register');
```

それに対する処理を書く。
```SignUpController.php
 public function register(MyVaridation $request)
  {

    $store = new Store;

    $store->fill([
      'store_name' => $request->store_name,
      'email' => $request->email,
      'password' => Hash::make($request['password']),
    ])->save();
   
    return redirect()->route('mypage', $store->id);
  }
```
これは「/signup」というURLにPOSTする事であらかじめ実装した機能（今回は新規登録）にしたがって処理を行うという事。
これで胸張って「API叩きました！」と言っていいはず。
APIとはこの様に何かしらのリクエストを要求してレスポンスを返す事。
***何も外部のサービスを利用する事だけがAPIという訳ではない***
Windowsターミナルでコマンドラインの変数を定義する方法

# Windowsでコマンドラインの変数を定義する。
こんにちは、k_uki512です。
現在は、「AWSで始めるクラウド開発入門」という書籍でAWSの勉強をしています。
この中で、コマンドライン変数を定義する箇所が出てきたのですが、本通りではエラーが出てしまったのでその解決法をまとめていきます。

## Linuxの変数定義の仕方
Linux(Ubuntu)では以下のような書き方で変数を定義します。
```
content="hogehoge" //変数名=文字列
```
また、変数の出力は以下のように行います。
```
echo $content
```
書籍ではLinuxのコマンドが記載されていたため、このまま入力してもwindowsのターミナルではエラーが出てきてしまいます。
## Windowsで変数定義をする。
Windowsでの変数定義の仕方を調べているうちに<b>setコマンド</b>というコマンドがあることを知りました。今回はそれを使用すればよさそうです。

そのため、windowsでの変数定義は以下のようにコマンドを入力します。
```
set content=hogehoge
```
また、入力は以下のようなコマンドになります。
```
echo %content%
```

同じ書籍を使っていて、変数定義に詰まっている方、windowsでの変数定義に困っている方に届けばと思います。
文字コードと文字符号化方式について

## 勉強前イメージ

符号化方式ってのがいまいちこう！ってのがまだ掴めてない

## 調査

### 文字コード(CSS) とは

文字コードとはコンピュータ上で文字や記号をデータとして扱うために
一文字に固有の識別番号を割り振って区別できるようにしたものを言います。

コンピュータは0と1の組み合わせで、文字をデータ化したものはデータ量が多い。
そのため識別番号を割り振って0と1で文字列を表現、この対応関係を文字コードという。

詳細は [こちら](https://qiita.com/miyuki_samitani/items/59b8285d514d8786257d) をごらんください。

文字コードの規格には ASCII や JIS X 0208、 Unicode がある。

- ASCII

American Standard Code for Information Interchange の略で、
最初に標準化された文字コードです。
英語に使われる文字しか入ってなかった。

- JIS X 0208

今でも使用されている日本語の文字コード(JISコード)。
現在までに何度か改定が行われています。
ASCIIと工法互換性があります。

- Unicode

文字コードの国際的な業界標準の一つ。
Unicodeができる前は、各国別々に標準化された文字コードが使われてたが
テキストの処理を地域毎に変更しないといけなく
それを解消するためにUnicodeが開発され世界中の文字コードを統一して使えるようにした。

### 文字符号化方式(CES) とは

文字コードで定義された文字をコンピュータで使えるように変換する符号化方式のこと。
言語や環境によって符号化方式があって、一般的に文字コードと呼ばれることが多い。
UTF-8やShift_JiSはここで言う符号化方式と呼ばれています。
文字コードのビットの組み合わせに対してビット値を与えます。

- Shift_JIS ← JIS X 0208

JIS X 0208の文字コードのビット値を計算する方式でShift_JISという文字符号化方式が使われています。

- UTF-8 ← Unicode

Unicodeの文字コードのビット値を計算する方式でUTF-8という文字符号化方式が使われています。
他にもUTF-16,UTF-32

## 勉強後イメージ

めちゃくちゃややこしくなったけど、まとめたら↓かな？

- ASCII や JIS X 0208、 Unicode → 文字コード,文字集合(CSS) : 文字と番号の対応表
- Shift_JIS、UTF-8やUTF-16,UTF-32 → 文字符号化方式(CES) : 符号化してコンピュータで扱えるようにしたもの

辞書(CSS)とそれを読む方法(CES)みたいな解釈してる、ちょっと違うかもやけど。
難しい。

## 参考

- [Unicodeとは？ その歴史と進化、開発者向け基礎知識](https://www.buildinsider.net/language/csharpunicode/01)
- [UnicodeとかUTF-8とかShift_JISとか色々複雑なので自メモ](https://appakumaturi.hatenablog.com/entry/20120414/1334334986)
- [文字コードを整理する](https://seiai.ed.jp/sys/text/cs/chp02/c02a040.html)
- [文字集合(CCS)と符号化方式(CES)とは](http://office-qa.com/win/win243.htm)
cscの作法 その128

# 概要
cscの作法、調べてみた。
managed directxやってみた。
シェーダー書いてみた。
テクスチャー使ってみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/e87ef991-e88a-10a3-7d7d-d6b7c4761994.png)

# hlsl


```

texture banana;
sampler bananasamp = sampler_state {
	Texture = (banana);
	MinFilter = LINEAR;
	MagFilter = LINEAR;
	MipFilter = Linear;
};
struct VS_IN {
	float4 Pos: POSITION;
	float4 color: COLOR;
};
struct VS_OUT {
	float4 Pos: POSITION;
	float4 color: COLOR;
	float2 coord: TEXCOORD;
};
VS_OUT VSmain(VS_IN In) {
	VS_OUT output = (VS_OUT) 0;
	output.Pos = In.Pos;
	output.color = In.color;
	output.coord = In.Pos.xy;
	return output;
}
float4 PSmain(VS_OUT In): COLOR {
	float4 color = float4(1.0, 1.0, 1.0, 1.0);
	color = tex2D(bananasamp, In.coord);
	return color;
}
technique MyTechnique {
	pass MyPass {
		VertexShader = compile vs_3_0 VSmain();
		PixelShader = compile ps_3_0 PSmain();
	}
}





```

# サンプルコード

```

using System;
using System.Drawing;
using System.Windows.Forms;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;

namespace mdx
{
	public partial class Form1 : Form {
		Device device = null;
		Effect effect;
		Mesh m;
		private Texture _texture;
		public Form1() {
			Text = "Form1";
			this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);
			PresentParameters pp = new PresentParameters();
			pp.Windowed = true;
			pp.SwapEffect = SwapEffect.Discard;
			device = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, pp);
			m = Mesh.Box(device, 2.0f, 2.0f, 2.0f);
			_texture = TextureLoader.FromFile(device, Application.StartupPath + @"\sprite-animation4.jpg");
			try
			{
				string a;
				effect = Effect.FromFile(device, "t0.fx", null, null, ShaderFlags.None, null, out a);
			}
			catch
			{
				MessageBox.Show("ng1");
			}
			this.Paint += Form1_Paint;
		}
		private void Form1_Paint(object sender, PaintEventArgs e) {
			device.BeginScene();
			device.RenderState.CullMode = Cull.None;
			device.RenderState.ZBufferEnable = true;
			device.Clear(ClearFlags.Target, Color.DarkBlue, 1f, 0);
			effect.Begin(FX.None);
			effect.BeginPass(0);
			effect.SetValue("banana", _texture);
			m.DrawSubset(0);
			effect.EndPass();
			effect.End();
			device.EndScene();
			device.Present();
			this.Invalidate();
		}
		[STAThread]
		public static void Main() {
			Application.Run(new Form1());
		}
	}
}


```

以上。
Oracle Analytics Cloud：Javaキーストアのパスワード変更方法

# はじめに
Oracle Analytics Cloud（**OAC**）のリポジトリはClient Tool (Oracle BI管理ツール）で読み込むことができます。
Oracle BI管理ツールではリポジトリの高度な編集をサポートしているため、例えばデータレベルセキュリティ等を実装するためには不可欠のツールとなっています。
ただし、一度Oracle BI管理ツールで編集したリポジトリは、Webベースのデータ・モデラーで開くことができなくなるので注意してください。

# リポジトリを読み込む
Oracle BI管理ツールをダウンロードし、インストールします。
[Oracle Analytics Client Toolsのダウンロード・ページ](https://www.oracle.com/middleware/technologies/oac-tools-downloads.html)

:::note
OACのバージョンにあったClient Toolをインストールしてください。
:::

Oracle BI管理ツールを起動し、OACのリポジトリを読み込みます。
「ファイル」－「開く」－「クラウド...」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/7be24431-93e2-06ca-0ca7-2bfd9c0ee395.png)

# パラメータを入力する
| パラメータ | 値（例） |
|:-|:-|
| ユーザー  | IDCSまたはIdentity Domainに登録されているOACの管理者ユーザー  |
| パスワード  | OAC管理者のパスワード  |
| クラウド  | bootstrap（変更しない）  |
| ホスト名  | OACのホスト名  |
| ポート番号  | 443（変更しない）  |
| SSL  | チェックする  |
| トラスト・ストア  | （変更しない）  |
| パスワード  | changeit（デフォルト値）  |
| プロキシ  | 必要に応じて設定  |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/bbc17dc8-9fba-d23a-c2e4-6332e3b68bf2.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/aeb74bbd-8e4c-36d5-bf31-8ffe6018ec23.png)

# Javaキーストアのパスワードを変更
トラスト・ストアのデフォルトのパスワードは「changeit」ですが、これを変更してみたいと思います。
コマンドプロンプトを開き、次のディレクトリに移動します。
\<Oracle Analytics Client Toolsのインストール先\>\oracle_common\jdk\jre\lib\security
例：C:\oracle\BIAdmin\oracle_common\jdk\jre\lib\security

```
C:\>cd C:\oracle\BIAdmin\oracle_common\jdk\jre\lib\security
C:\oracle\BIAdmin\oracle_common\jdk\jre\lib\security>
```

keytoolコマンドでパスワードを変更します。

:::note
パスワードを変更する前に、必要に応じて cacerts のバックアップを取得してください。
:::

```
C:\oracle\BIAdmin\oracle_common\jdk\jre\lib\security>keytool -storepasswd -keystore cacerts
キーストアのパスワードを入力してください: <現在のパスワード、すなわちchangeit>
新規keystore password: <新しいパスワード>
新規keystore passwordを再入力してください: <もう一度、新しいパスワード>

C:\oracle\BIAdmin\oracle_common\jdk\jre\lib\security>
```

これでパスワード変更完了です。
次回から、Oracle BI管理ツールでOACのリポジトリを読み込む際のトラスト・ストアのパスワードは、changeitの代わりに新しく設定したパスワードを使用します。
cscの作法 その127

# 概要
cscの作法、調べてみた。
managed directxやってみた。
シェーダー書いてみた。
SetValue使ってみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/a433c40d-f69f-ef18-62d0-3878f7eb3fbd.png)


# hlsl

```
float p;
struct VS_IN {
	float4 Pos: POSITION;
	float4 color: COLOR;
};
struct VS_OUT {
	float4 Pos: POSITION;
	float4 color: COLOR;
	float2 coord: TEXCOORD;
};
VS_OUT VSmain(VS_IN In) {
	VS_OUT output = (VS_OUT) 0;
	output.Pos = In.Pos;
	output.color = In.color;
	output.coord = In.Pos.xy;
	return output;
}
float4 PSmain(VS_OUT In): COLOR {
	float4 color = float4(1.0, 1.0, 1.0, 1.0);
	if (p == 1.0)
		color = float4(1.0, 0.0, 0.0, 1.0);
	return color;
}
technique MyTechnique {
	pass MyPass {
		VertexShader = compile vs_3_0 VSmain();
		PixelShader = compile ps_3_0 PSmain();
	}
}

```

# サンプルコード



```
using System;
using System.Drawing;
using System.Windows.Forms;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;

namespace mdx
{
	public partial class Form1 : Form {
		Device device = null;
		Effect effect;
		Mesh m;
		public Form1() {
			Text = "Form1";
			this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);
			PresentParameters pp = new PresentParameters();
			pp.Windowed = true;
			pp.SwapEffect = SwapEffect.Discard;
			device = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, pp);
			m = Mesh.Box(device, 2.0f, 2.0f, 2.0f);
			try
			{
				string a;
				effect = Effect.FromFile(device, "f0.fx", null, null, ShaderFlags.None, null, out a);
			}
			catch
			{
				MessageBox.Show("ng1");
			}
			this.Paint += Form1_Paint;
		}
		private void Form1_Paint(object sender, PaintEventArgs e) {
			device.BeginScene();
			device.RenderState.CullMode = Cull.None;
			device.RenderState.ZBufferEnable = true;
			device.Clear(ClearFlags.Target, Color.DarkBlue, 1f, 0);
			effect.Begin(FX.None);
			effect.BeginPass(0);
			effect.SetValue("p", 1.0f);
			m.DrawSubset(0);
			effect.EndPass();
			effect.End();
			device.EndScene();
			device.Present();
			this.Invalidate();
		}
		[STAThread]
		public static void Main() {
			Application.Run(new Form1());
		}
	}
}





```

以上。
cscの作法 その126

# 概要
cscの作法、調べてみた。
managed directxやってみた。
シェーダー書いてみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/69224f93-a91f-1daa-e2bd-d4dfc28814c7.png)


# hlsl

```
struct VS_IN {
	float4 Pos: POSITION;
	float4 color: COLOR;
};
struct VS_OUT {
	float4 Pos: POSITION;
	float4 color: COLOR;
	float2 coord: TEXCOORD;
};
VS_OUT VSmain(VS_IN In) {
	VS_OUT output = (VS_OUT) 0;
	output.Pos = In.Pos;
	output.color = In.color;
	output.coord = In.Pos.xy;
	return output;
}
float4 PSmain(VS_OUT In): COLOR {
	float4 color = float4(1.0, 1.0, 1.0, 1.0);
	float2 coord = In.coord;
	float2 center = float2(0.0, 0.0);
	float dist = distance(coord, center);
	if (dist < 0.5)
		color = float4(1.0, 0.0, 0.0, 1.0);
	else
		color = color;
	return color;
}
technique MyTechnique {
	pass MyPass {
		VertexShader = compile vs_3_0 VSmain();
		PixelShader = compile ps_3_0 PSmain();
	}
}
```

# サンプルコード

```

using System;
using System.Drawing;
using System.Windows.Forms;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;

namespace mdx
{
	public partial class Form1 : Form {
		Device device = null;
		Effect effect;
		Mesh m;
		public Form1() {
			Text = "Form1";
			this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);
			PresentParameters pp = new PresentParameters();
			pp.Windowed = true;
			pp.SwapEffect = SwapEffect.Discard;
			device = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, pp);
			m = Mesh.Box(device, 2.0f, 2.0f, 2.0f);
			try
			{
				string a;
				effect = Effect.FromFile(device, "my0.fx", null, null, ShaderFlags.None, null, out a);
			}
			catch
			{
				MessageBox.Show("ng1");
			}
			this.Paint += Form1_Paint;
		}
		private void Form1_Paint(object sender, PaintEventArgs e) {
			device.BeginScene();
			device.RenderState.CullMode = Cull.None;
			device.RenderState.ZBufferEnable = true;
			device.Clear(ClearFlags.Target, Color.DarkBlue, 1f, 0);
			effect.Begin(FX.None);
			effect.BeginPass(0);
			m.DrawSubset(0);
			effect.EndPass();
			effect.End();
			device.EndScene();
			device.Present();
			this.Invalidate();
		}
		[STAThread]
		public static void Main() {
			Application.Run(new Form1());
		}
	}
}





```

以上。
laravelでmigrationが通らなかった時に対応したこと(Illuminate\Database\QueryException )


# エラーの背景
以下のようなエラーが出ました。

```
$ php artisan migrate
```
```
Illuminate\Database\QueryException 

  SQLSTATE[HY000] [1049] Unknown database 'laravel-todo_db' (SQL: select * from information_schema.tables where table_schema = laravel-todo_db and table_name = migrations and table_type = 'BASE TABLE')

  at vendor/laravel/framework/src/Illuminate/Database/Connection.php:745
    741▕         // If an exception occurs when attempting to run a query, we'll format the error
    742▕         // message to include the bindings with SQL, which will make this exception a
    743▕         // lot more helpful to the developer instead of just the database's errors.
    744▕         catch (Exception $e) {
  ➜ 745▕             throw new QueryException(
    746▕                 $query, $this->prepareBindings($bindings), $e
    747▕             );
    748▕         }
    749▕     }

      +33 vendor frames 
  34  artisan:37
      Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
```
mysqlが接続されていないことが原因でした。

# 有益な記事
基本mysql接続はこの記事で接続ができてエラーが解決しました。
https://yaba-blog.com/laravel-db/


このエラーが出たらこの記事も参考にする

https://onoredekaiketsu.com/can-not-root-login-to-mysql-with-error-1045-28000/


https://yaba-blog.com/laravel-db/


# MySQL　Workbenchを入れておく
phpadminは基本実務で使わないので、MySQL　Workbenchをダウンロードします。

https://www.mysql.com/jp/products/workbench/

# 上の方法以外で解決した方法

```.example.env
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost

LOG_CHANNEL=stack

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laraveldb
DB_USERNAME=dbuser
```

```.example.env
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost8080

LOG_CHANNEL=stack

DB_CONNECTION=laravel_db
DB_HOST=laravel_db
DB_PORT=3306
DB_DATABASE=laraveldb
DB_USERNAME=dbuser
```
に修正したら、解決して、Adminerに入ることができて、マイグレーションも通りました。

https://qiita.com/isaatsu0131/items/50f8dca389b60a1fd5b5
Safariでの問題


[まとめページに戻る](https://qiita.com/Keiji_otsubo/items/60afc2a8d211b6f7d89f)

+ [ロールの新規追加ができない](https://qiita.com/Keiji_otsubo/items/3f6d6381cb4683e5c36f)

+ [未解決：Data Security - Role Hierarchy missing banner](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007PzDOz)

------------------------

+ [エラーメッセージ「ブラウザがクロスドメインCookieをブロックしているため、このページを表示できませんが、SalesforceClassicでこのページを表示できます。](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000G66hf)

Safariの設定で[サイト間の追跡を防ぐ]をオフにします。

+ [Troubleshoot issues with Safari](https://help.salesforce.com/s/articleView?id=000312840&type=1)

+ [Customize Your Site : ガイダンスに従ってアクションを実行するためのオプションが提供されません](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000G4jEHSAZ)
サブネットマスク なんやそれ?(基本情報技術者試験)

今回はサブネットマスクについて書いていきたいと思います。

前回の記事タイトルであるIPアドレスと今回のサブネットマスクは密接な関係である為、
「IPアドレス?全くわからんぜ！」の方はこちらの記事もご覧になってみてください。

https://qiita.com/Haruki-Sakamoto/items/6bdf99f135d37043879a

# サブネットマスク
IPアドレスのネットワークアドレス部とホストアドレス部を識別する為のもの。
２進数の各ビットの値が1の場合は<font color="red">ネットワークアドレス部</font>、0の場合<font color="blue">ホストアドレス部</font>を示す。

ネットワーク規模で一番小さいクラスCでも254台のホストを扱えるが、そこまでホスト数は要らないという時にサブネットマスクを用いて必要な分のネットワークを振り分けることができる。

## サブネットマスクの一例
<font color="red">11111111.11111111.11111111.11</font><font color="blue">000000</font> → 10進数表記だと255.255.255.192


この例だと左から数えて26桁目までが<font color="red">ネットワークアドレス部</font>、27桁目から32桁目が<font color="blue">ホストアドレス部</font>だということがわかる。

クラスCのネットワークに該当するIPアドレス(192.0.0.1)に先程のサブネットマスクの例を当てはめると、
 ブロードキャストアドレスとネットワークアドレスを除いた192.0.0.1 ~ 192.0.0.62 までのネットワークが割り当てられている事がわかる。

「ブロードキャストアドレス、ネットワークアドレス、ネットワークのクラスの種類？聞いた事ないぜ！」という方はこちらも是非ご覧ください。

https://qiita.com/Haruki-Sakamoto/items/0595888ce7de17040389

# まとめ
サブネットマスクはどこからどこまでがネットワークアドレス部でホストアドレス部に値するかを識別するもので、ホストの管理数を増減したり、ネットワークを分割したい際に使われる。
# 参照
https://www.cman.jp/network/term/subnet/
https://note.cman.jp/network/subnetmask.cgi
配列の最後の要素を取得する方法【JavaScript】

JavaScriptで配列の最後の要素を取得する方法をまとめます。

# lengthプロパティを使う方法

```javascript
const array = ["りんご", "みかん", "ぶどう"];

const last1 = array[array.length - 1];

console.log(array, last1);

// 結果
// ["りんご", "みかん", "ぶどう"]"ぶどう" 
```

１つ目はlengthプロパティを使う方法です。

`array.length - 1`を指定することで、最後の要素を取得します。

シンプルですが、記述が長くなりがちです。

# pop()を使う方法

```javascript
const array = ["りんご", "みかん", "ぶどう"];

const last2 = array.pop();

console.log(array, last2);

// 結果
// ["りんご", "みかん"]"ぶどう" 
```

2つ目はpop()メソッドを使う方法です。

pop()メソッドは配列の最後の要素を取り除きます。

lengthプロパティを使う方法より短い記述で済みますが、元の配列を直接操作するので注意が必要です。

参考：https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/pop

:::note info
JavaScriptの配列を操作するメソッドには、「破壊的」なメソッドが存在します。
「破壊的」なメソッドは、元の配列を直接操作（破壊）します。
一方「非破壊的」なメソッドは、元の配列を直接操作せず、配列をコピーしたものに対して操作します。
:::

# slice()を使う方法

```javascript
const array = ["りんご", "みかん", "ぶどう"];

const last3 = array.slice(-1)[0];

console.log(array, last3);

// 結果
// ["りんご", "みかん", "ぶどう"]"ぶどう" 
```

3つ目はslice()メソッドを使う方法です。

slice()メソッドは配列の一部をコピーし、新しい配列を返します。

マイナスのインデックスを指定した場合は末尾からコピーするため、`array.slice(-1)`は「最後の要素をコピーした配列」となります。
（配列なので最後に`[0]`を付け足すことで、要素を取得できます）

元の配列を直接操作せず、記述もそこそこわかりやすく書くことができます。

参考：https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/slice

# at()を使う方法

```javascript
const array = ["りんご", "みかん", "ぶどう"];

const last4 = array.at(-1);

console.log(array, last4);

// 結果
// ["りんご", "みかん", "ぶどう"]"ぶどう" 
```

最後はat()メソッドを使う方法です。

at()メソッドはECMAScript2022から導入されました。

マイナスのインデックスを指定することで、末尾の要素を取得できます。

元の配列を破壊せず、記述も短くわかりやすいです。

参考：https://github.com/tc39/proposal-relative-indexing-method
Process.Startでexeファイルを起動したときProcess.MainModule プロパティでWin32Exceptionが発生する。

webで調べたところあまり情報がなかったので記載しておきます。
# 前提
フレームワーク：ASP.NET (C#)
webサーバ：IIS
exeファイル：C#で作成
やりたいこと：ブラウザでボタンを押したときにサーバ側のexeファイルを起動して処理を行いたい。
問題：サーバ側でProcess.Startでexeを起動しているが起動できず、デバッグで確認すると戻り値のProcessのMainModule プロパティでWin32Exceptionが発生している。

# 原因
Win32Exceptionについて調べると
・32ビットアプリケーションで64ビットのexeを起動している
・exeファイルが指定のパスに存在しない
等の情報が出てきたのですが、パスは問題なく、呼び出し元もexeも64ビットなのでこれらは当てはまらず。

exeが起動できてないので、起動ユーザーの問題かと考え、IISのDefaultAppPoolのプロセスモデルのIDをLocalUserにしたら起動できました。
（NetworkService等の他のユーザーでは無理なようなです）
【React Native】コールバック化したchildrenにパラメータを渡す

# はじめに
シャドウのスタイルをつけたコンポーネントでバナー画像をラップすると、そのままでは高さが設定されず、上下に余計なマージンが入ってしまう感じになってしまいました。

その解決策として、シャドウのコンポーネントで高さ(height)を設定した後に、コールバック化したchildrenにheightをパラメータとして渡してあげるようにしました。

childrenにパラメータを渡す方法をお探しの方には参考となる内容だと思います。

# 実装
いらすとやからとってきたバナー画像に、以下のようなシャドウをつけます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/d6176b07-1784-b6c6-35d8-184872467803.png" width="500">

まず、シャドウのスタイルをつけるコンポーネント`ShadowStyledView`を作成します。
`onLayout`で`View`の　`width`を取得し、この`width`にアスペクト比をかけて`height`を算出します。
そして、`children`が`function`のときの場合のみ、`width`と`height`を渡してあげるようにします。

また、`imageWidth`と`imageHeight`をpropsに置くことで、アスペクト比を可変させることもできます。

```tsx:ShadowStyledView.tsx
type ResizedProps = {
  width: number;
  height: number;
};

type ShadowStyledViewProps = {
  containerStyle?: StyleProp<ViewStyle>;
  imageWidth?: number;
  imageHeight?: number;
  children: ReactNode | ((resizedProps: ResizedProps) => ReactNode);
};

export const ShadowStyledView: React.FC<ShadowStyledViewProps> = React.memo(
  ({ containerStyle, imageWidth = 800, imageHeight = 287, children }) => {
    const { onLayout, width } = useLayout();
    const height = (width * imageHeight) / imageWidth;

    return (
      <View onLayout={onLayout} style={[styles.container, containerStyle]}>
        {typeof children === "function" ? children({ width, height }) : children}
      </View>
    );
  },
);

ShadowStyledView.displayName = "ShadowStyledView";

const styles = StyleSheet.create({
  container: {
    ...Platform.select({
      ios: {
        shadowColor: "rgba(0,0,0,0.15)",
        shadowOffset: { width: 0, height: 5 },
        shadowRadius: 1,
        shadowOpacity: 1,
      },
      android: { elevation: 5 },
    }),
  },
});
```
なお、`onLayout`と`width`については、カスタムフック`useLayout()`　にまとめます。

```ts:useLayout.ts
export function useLayout() {
  const [layout, setLayout] = useState({
    x: 0,
    y: 0,
    width: 0,
    height: 0,
  });

  const onLayout = useCallback(
    ({ nativeEvent }: LayoutChangeEvent) => setLayout(nativeEvent.layout),
    [],
  );

  return {
    onLayout,
    ...layout,
  };
}
```

バナーのコンポーネント`QuestionBanner`は以下のようになります。
`ShadowStyledView`の中身で`Image`をコールバックで呼び、`height`をパラメータとして渡しています。
これで指定したアスペクト比でシャドウをつけたバナーを表示させることができます。

```tsx:QuestionBanner.tsx
type QuestionBannerProps = {
  containerStyle?: StyleProp<ViewStyle>;
  children?: never;
};

export const QuestionBanner: React.FC<QuestionBannerProps> = React.memo(({ containerStyle }) => {
  return (
    <ShadowStyledView containerStyle={[containerStyle]}>
      {({ height }) => (
        <Image
          source={QuestionBannerImage}
          style={{
            height,
            resizeMode: "contain",
            borderRadius: 5,
            width: "100%",
          }}
        />
      )}
    </ShadowStyledView>
  );
});

QuestionBanner.displayName = "QuestionBanner";
```

# 参考資料

https://github.com/facebook/react-native/blob/7b05b091fd97f95b778369277ac2147730abc7b8/Libraries/Components/Pressable/Pressable.js
パッケージ管理システムとは【npm】

# 概要
パッケージ管理システムとは、パッケージの導入や削除、パッケージ間の依存関係などを管理するシステムのことです。

パッケージ管理システムを利用することで、パッケージの導入や削除をコマンド1つで実現できます。

また、パッケージ間の依存関係も解決してくれます。

:::note info
パッケージとは、あるプログラムとそれを利用するのに必要なものをひとまとめにしたものです。
これらのパッケージには依存関係があります。
パッケージAを使うにはパッケージBが必要、さらにパッケージBを使うにはパッケージCが必要、といったイメージです。
:::

フロントエンド開発においては、「npm」や「yarn」というパッケージ管理システムを利用することが一般的です。

# npm
npmは「Node Package Manager」の略称で、JavaScript開発者向けのパッケージ管理システムです。

「Node」とありますが、Node.js専用のパッケージ管理システム、というわけではありません

フロントエンド開発で使用するパッケージの導入や削除、依存関係の管理もできます。

[こちら](https://www.npmjs.com/)からどんなパッケージがあるか確認できます。

npmコマンドの一例

| コマンド | 実行内容 |
|:-----------|:-----------|
| npm install | package.json（後述）に記載されているパッケージをインストール |
| npm install --save-dev {package} | package.jsonのdevDependenciesにパッケージをインストール |
| npm uninstall --save-dev {package} | package.jsonのdevDependenciesからパッケージをアンインストール |

# package.json
package.jsonとは、パッケージの情報を記載するためのJSONファイルです。

必要なパッケージ名とバージョンを記載していきます。

手動で編集できますし、コマンドでパッケージを追加した場合は自動で更新されます。

例えば、`npm install --save-dev sass`を実行すると、package.jsonは以下のように更新されます。

```json:package.json
{
    "devDependencies": {
        "sass": "^1.49.11",
    }
}
```

`devDependencies`属性には開発時に使用するパッケージを記載します。

その他にも様々な属性を記載できます。

属性の一例

| 属性名 | 役割 |
|:-----------|:-----------|
| name | アプリケーションの名前を記載 |
| description | アプリケーションの説明を記載 |
| dependencies | 本番環境で使用するパッケージを記載 |
| devDependencies | 開発環境で使用するパッケージを記載 |

# node_modules
node_modulesとは、package.jsonを元にインストールされたパッケージの、インストール先ディレクトリのことです。

package.jsonがあれば`npm install`を実行することで、自動で作成、更新されます。
（手動で編集してはいけません。）

また先述したようにパッケージ間には依存関係があり、npmはそれを自動で解決してくれます。

そのため、node_modulesは膨大な量になります。

これらの理由から通常は.gitignoreに指定します。

# 開発時の具体例
以下は開発時に使いそうな場面についてです。

## プロジェクトに参加
package.jsonがあれば`npm install`を実行するだけで、他のメンバーと同じパッケージをインストールすることができます。

## パッケージを追加
例えば`npm install --save-dev {package}`でパッケージをインストールします。（package.jsonが更新される）
問題なければ、更新されたpackage.jsonをpushします。（node_modulesは.gitignoreに指定）
他のメンバーにもpackage.jsonを共有し、`npm install`してもらうことで、同じパッケージを追加できます。

# まとめ
パッケージ管理システム→パッケージの導入や削除、パッケージ間の依存関係などを管理するシステム
npm→JavaScript開発者向けのパッケージ管理システム
package.json→パッケージの情報を記載するためのJSONファイル
node_modules→package.jsonを元にインストールされたパッケージのインストール先ディレクトリ
Webサイトの速度改善による収益増を事前に見積もるには

Webサイトの速度改善に例えば100万円という見積りが出たとき、それが妥当かどう判断したらよいでしょうか？

一番わかりやすいのは、**100万円以上収益が上がるなら妥当**という根拠でしょう。

しかし「費用をかけて速くして、結局いくら儲かるの？」という疑問には「やってみないとわからない」が暗黙の了解になっているように思えます。正面から答えた例を私は見たことがありません。

なんだか幻を追うような提案になりがちでした。

そこで、**速度と収益に特化した無料アクセス解析サービス**を作ってみました。ずばり「速度は金なり」です！

[Speed Is Money](https://speedis.money/)

こちらでは [弊社のブログサイト](https://blog.ideamans.com/) の計測結果をサンプルレポートとしてご覧になれますし、条件に承諾いただけたら**みなさんのサイトも無料で計測**します。

それを例に、**速度改善による収益増の見積り方**をひとつ紹介します。

なお、集計結果は2022年4月13日〜19日の約1週間。この記事ではLCP(Largest Contentful Paint)をもって体感速度を代表します。

## 体感速度は自然にばらつく

まず認識いただきたいのが、**体感速度はさまざまな要因により自然とばらつきが生じる**ことです。以下はユーザー平均LCPのヒストグラムです(横軸は階級値。詳細はリンク先をご覧ください)。

![speedis.money_reports_web-vital-and-pvs.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35178/724f6130-18a1-4016-594d-7e320288b8fa.png)
[SpeedIsMoney | Web Vital と PV・直帰の関係](https://speedis.money/reports/web-vital-and-pvs)

弊社のブログサイトはシンプルで、ほとんどがPCによる閲覧です。速度の違いが出るように思えません。

![blog.ideamans.com_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35178/9f5ba111-d7bf-40a2-378f-a55ee80cf33a.png)


実際、ほとんどはLCPが2秒以内なのですが、**最大LCPは10.13秒と裾野は広い**です。

このように実はWebサイトでは、意図したわけではないけど**体感速度に差をつけたA/Bテストが常に行われている**と考えることができ、観察すると面白い傾向が見えてきます。


# 体感速度とユーザー平均PVを比較

Webサイトの目的はいろいろありますが、一般的にPV数と収益が比例することが多いでしょう。ここではその前提で進めます。

次にユーザーを**平均LCPのよい順に並べ、5つのセグメント(A〜Eクラス)に等分**します。それぞれのクラスのユーザー平均PVが次のグラフです。

![speedis.money_reports_web-vital-and-pvs (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35178/7ec678be-7e25-af60-2737-7485921d9f43.png)

**体感速度が速いほど平均PV数が多い**傾向が、とてもわかりやすく現れました！ **Aクラスは平均PVが1.48、Eクラスは平均PVが1.09**でした。

# 体感速度の改善によるPV増の見積り

この間の全体のPVは、Aクラス(0.03~0.68秒)のユーザー数×1.49、Bクラス(0.68~0.96秒)のユーザー数×1.26、…の合計で成り立っていたと考えることができます。

![speedis.money_reports_web-vital-and-pvs (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35178/d956c85e-a117-ac11-ec93-148d058a6db7.png)


もしここから体感速度が速くなれば、**平均PVの多い上位クラスの人数が増加し、逆に下位クラスの人数が減少**します。それによって全体のPV増を見積もるという理屈です。

もしLCPが一律**20%改善されたら、PVは全体で +4.11% 増加**します。

![speedis.money_reports_web-vital-and-pvs (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35178/736b5044-4632-6a2f-06c2-9b21ebaa373a.png)
[SpeedIsMoney | 改善による PV 増加予測](https://speedis.money/reports/pv-forecast)

要は1週間前に戻って体感速度を20%改善したらPVは4.11%多かったはず、という話です。

さらに頑張って体感速度を**50%改善、つまり2倍高速化できたらPVは全体で +12.32% 増加**します。

![speedis.money_reports_web-vital-and-pvs (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35178/c4ad996a-29b9-6a30-2e2e-22dfe067eff2.png)

もちろんこれは100%正確な予測ではありません。しかし、傾向そのものから極端に変動することも考えにくく、何より **「やってみなければわからない」に比べたらはるかにマシ** だと思いますが、いかがでしょうか。

# 速度改善は長期投資

「体感速度を20%改善しても収益は4%増か〜」と地味でガッカリしたかもしれません。

弊社のブログサイトは速度改善の伸び代が小さく、他のサイトではもう少し大きな増収を期待できると思います。

また、この4%増は追加の費用や労力を必要とせず変動も小さいと期待できます。**時間さえ経てば回収できる長期投資のようなもの**で、例えば冒頭の100万円の費用を「6ヶ月で回収できるならOK」といった判断はあり得ます。

加えてこのような短期的な収益の視点だけでなく、顧客ロイヤルティを維持し、太客を繋ぎ止めるためにも体感速度は重要です。やはり「速度は金なり」です。
エクセルで1個のセルに何か入力があれば、他のセルに文字を表示する関数の例

# 例

「A1セルに入力があった時に、B1セルに表示したい」場合は、

B1セルで次のような式を利用する

```
=IF(A1<>"","入力されています","入力されていません")
```

`A1<>""` は「もしA1セルの値が空ではない場合」という意味だ。

# 出力例

文字が入力として扱われる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89618/e6db337b-8765-6fca-7d7e-38fbfa3fc5fd.png)


数字も入力として扱われる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89618/c046ab2e-c2ff-c2f8-159b-2a5134a3c136.png)

何も入力がないことも検知する


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89618/c04840fe-0a6a-fe26-df47-5dec0bb07739.png)


# 複数行で利用する場合の例

B1の式

```
=IF(A1<>"","入力されています","入力されていません")
```

B2の式

```
=IF(A2<>"","入力されています","入力されていません")
```

B3の式

```
=IF(A3<>"","入力されています","入力されていません")
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89618/f97720ab-8072-ded8-46a3-c1d31216bd38.png)











<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
GitHubでウェブサイト開発のコーディングワークフローを見直した話。

今回は、弊社デザイナーとお仕事をする中で、数年前から課題となっていたウェブサイト開発のワークフローを、GitHubを活用して業務改善してみました。

## なかなか踏み切れなかった現状
ウェブサイトのデザイン業務は、大きく分けると

- デザイン作業
- HTMLコーディング作業

この２つになります。

ベクターデータや画像処理などを行うデザイン作業と、テキストベースのHTMLコーディングは、性質の違うファイルを管理するというのが、そもそも非常に難しいと思っています。
また、デザイナーにすると更新作業は一手間増えるし、直感的ではないので運用上でハードルが高かったりしました。

## デザイン作業について
調べてみると、デザインファイルはPhotoshopやIllustrator、Adobe XDの主要なツールがGitへ未対応の状況でした。バージョン管理というのであれば、単なるバックアップではなく、デザインファイルのどこを修正したのかビジュアルで見比べたいのですが、なかなか良いツールがありません。バイナリのファイルをバージョン管理すると容量の問題もついてきそうです。

Sketchを利用するとGitでのバージョン管理が出来て幸せになれそうですが、主要ツールを変えてまで制作フローを刷新するほどのメリットが現状では期待できないので、ここは一旦クラウドドキュメントを利用してバージョン管理することにしました。（PhotoshopやIllustrator、XDは対応しています）
https://helpx.adobe.com/jp/creative-cloud/help/versioning-faq.html

## HTMLコーディング作業について
現状弊社デザイン部門では、HTMLのコーディングの際には、社内のHyper-Vで起動したウェブサーバーのDocument Rootを共有フォルダーとしてPCにマウントし、ファイルを直接書き換えるワークフローとなっていました。

これは、各クライアントPCのローカル環境にウェブサービスを構築していくと、セッティング違いによる開発への影響など環境依存を防ぐことも出来ていたので、一定のメリットはありましたが、以下の様な課題点もありました。

- バージョン管理は、サーバーのデイリーで行われるファイルバックアップだったので、出来なくはないが簡単ではなかった。
- 公開サーバーへのリリース時に、FTPを必要と利用するケースがあり、更新ファイルの把握が大変だった。
- バリデーションチェックや、アクセシビリティチェックが、担当者任せになっていた。
- リモートワークが中心となり、VPN接続では同様の作業方法ではスピードが出なかった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140547/af8ed50b-f17f-4f9f-6408-0e399ca2c283.png)


## コーディングのワークフローだけを改善してみる
見直すときには、全部完璧に良くしたい欲に駆られますが、限られた時間で結果を出すには、まずは小さく出来るところから改善です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140547/2614870e-eddf-065c-cabc-a1ef7d70c4f0.png)

今回の制作フローでは、Dreamweaverで行ったコーディング作業をDevelopブランチへPushすると、GitHub Actionsで、毎回自動的にHTML5 ValidatorとLighthouse CIがコーディングとアクセシビリティーなどのチェックをしてくれ、テストサーバー代わりのGitHub Pagesへファイルを更新し、Teamsへその結果を通知してくれます。
ややGitHub Pagesへのデプロイには時間がかかるので、実際のコーディング時はDreamweaverのプレビューで行い、主にクライアントへの確認に使用する予定です。

コーディングが完了したら、Pull RequestをMainに出すと、GitHub Actionsに設定したrsyncコマンドで公開サイトのレンタルサーバへSSHでセキュアにデプロイされます。


## [最後に]まだまだ自動化を実現出来る！
ここまでだと普通に作業フローだけを見直した話ですが、普段から活用している、Microsoft365に付帯するPower Automateを利用することで、

- 公開サイトへデプロイしたらクライアントへメールでURLをお知らせする
- メンテナンスの作業記録をSharePointリストやエクセルに転記して作業明細にする

など、後工程の作業も楽にできそうです。

やりたいことは色々ありますが、前述の通り改善は小さくやるべきで、今回の設定や作業方法は、何度かに分けてブログにまとめていきます。

リポジトリはこちらです。
https://github.com/frogkoby/rsync-deploy-for-lolipop