OmniAICreator/Qiita-1.07M huggingface dataset:
Unity/C#のための「多分最速」のスクリプト言語作った。#2【Tween編?】


https://qiita.com/aakei/items/eb279ce7212b0dd6ac2e
これの続きというか更新記録というか。レポジトリはこれ
https://github.com/Akeit0/YukataScript
devのブランチを現在更新してます。(2/13)
# 新しいこと
エディタモードでイージング関数とアニメーションカーブでTweenできます。
![Async.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629974/c8f327b0-2053-1fb0-c75b-7b3082dc23c3.gif)


![スクリーンショット 2023-02-13 182646.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629974/b6a9dbc4-388f-836d-71a7-072c7245206f.png)

```C#
var timer=new YS.Timer(duration)
while not timer.IsExpired {
	await 16.ms()
	var current=timer.GetEasedElapsedRatio(easingType)
	transform.localScale=v3 * current
}
timer=new YS.Timer(duration)
while not timer.IsExpired {
	await 16.ms()
	var current=1f-timer.GetCurvedElapsedRatio(curve)
	transform.localScale=v3 * current
}
transform.localScale=default
```
経過時間を扱うTimerクラスとイージングを扱うEnumとクラスを作りました。
System.Timers.TimerではなくVisualScriptingのTimerを参考にしたものです。
エディタモードでもなめらかに動くようにしています。
まあそれは言語には関係ないんですけど、新たに実装したwhile文 と相性がとてもいいですよね。
while not timer.IsExpired{ }
書きやすいですね。
ここでの更新が必ずしも反映させてるとは限りませんが、遊んでみてほしいです。
時間を扱いましたが、細かい実装はほんとに時間が必要です。Document作りでもなんでも手伝ってほしいですね。
https://github.com/Akeit0/YukataScript
PowerAutomateからSharePointにHTTP要求を送信したところ不可解なエラーが起こる

今回はPowerAutomateに関するトラブルシューティングです。

PowerAutomateからSharePointに対して特殊な問い合わせをしたり、リスト項目を特定の列だけ指定して更新したりするとき、重宝するのが「SharePointにHTTP要求を送信します」（Send an HTTP request to SharePoint）アクションです：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/d880da08-b0bc-e56b-dcad-311695c6303c.png)

# Problem

このアクションを使用するフローを作成して動作確認をすると、時折不可解なエラーに遭遇します。

例1：
> プロパティ '__metadata' は型 'SP.Data.FooBarListItem' に存在しません。型で定義されているプロパティ名のみ使用してください。

例2：
> パラメーター __metadata はメソッド GetById に存在しません。

例3：
> 要求 ETag 値 '' がオブジェクトの ETag 値 '"xxxx6a6d-b66c-4f9d-8435-c664bbdxxxx,2"' と一致しません。

例4：
> 無効な JSON です。JSON コンテンツのトークンが認識されませんでした。

# Solution

以上は私が遭遇したバラエティに富んだエラーの数々ですが、総じてヘッダーやボディの入力値に半角空白文字やTAB文字なども含め制御文字が混入した結果でした。

こうした不可解なエラーに遭遇した場合は、エラーメッセージの意味解釈を始める前に、まずはヘッダーやボディのJSONをチェックし半角空白文字やTAB文字なども含め制御文字が混入していないか確認したほうがよいでしょう。

| # | エラー | 原因 |
|----:|:----|:----|
| 1 | `プロパティ '__metadata' は型 'SP.Data.FooBarListItem' に存在しません。型で定義されているプロパティ名のみ使用してください。` | ヘッダーの`Content-Type`の前後に制御文字が混入している可能性があります。 |
| 2 | `パラメーター __metadata はメソッド GetById に存在しません。` | ヘッダーの`X-HTTP-Method`の前後に制御文字が混入している可能性があります。 |
| 3 | `要求 ETag 値 '' がオブジェクトの ETag 値 '"xxxx6a6d-b66c-4f9d-8435-c664bbdxxxx,2"' と一致しません。` |ヘッダーの`If-Match`の前後に制御文字が混入している可能性があります。|
| 4 | `無効な JSON です。JSON コンテンツのトークンが認識されませんでした。` | ボディのJSONに制御文字が混入している可能性があります。 |
ionicをcapacitorで利用したりJavaのエラーに対応する


ionicでCapacitorを利用する場合の簡単な実行方法をメモします。

>あと、最新のJava環境でいろいろエラーでるのでその対応もメモ。

## 準備

もし、ionic-cliをインストールしてなければインストール。

```bash
npm install -g @ionic/cli
```

>追加でnpm install -g native-runとしておいてもいいかもしれません。

## プロジェクトの生成

プロジェクトを生成します。

```bash
ionic start ionic-website-cap blank --type=angular --capacitor
```

### Androidで動かす

まず、プラットフォームを追加。

>このときandroidフォルダが生成されます。

```bash
ionic capacitor add android
```

実行。

```bash
ionic capacitor run android
```

>実行するとどのエミュレータ（端末）で動かすか確認してきます。エミュレータは自動で起動してくるようです。便利。

### iOSで動かす

まず、プラットフォームを追加。

```bash
ionic capacitor add ios
```

>このときiosフォルダが生成されます。

実行。

```bash
ionic capacitor run ios
```


## Javaの環境調整

ionicのAndroid実行環境では、

* Cordova環境はJava8（1.8）
* Capacitor環境はJava11

が、標準となっているようです。
バージョンが合ってないとエラーがでることがあります。
そんなときは複数のJDKを切り替えながら利用する必要があります。

>私の環境ではJDK11だとCordovaでもCapacitorでもとりあえず動きました（ビルドできました）。

### JDKのインストールと切り替え（Mac）

Javaのバージョンの切り替えにはjenvなども使えますが、いちいちめんどいので、私は以下の方法で切り替えて利用しています。

#### インストールされているJDKの確認

```bash
/usr/libexec/java_home -V
```

私の環境の場合、下記のように表示されます。

```bash
    19.0.2 (x86_64) "Azul Systems, Inc." - "Zulu 19.32.13" /Library/Java/JavaVirtualMachines/zulu-19.jdk/Contents/Home
    17.0.3 (x86_64) "Oracle Corporation" - "Java SE 17.0.3" /Library/Java/JavaVirtualMachines/jdk-17.0.3.jdk/Contents/Home
    11.0.18 (x86_64) "Homebrew" - "OpenJDK 11.0.18" /usr/local/Cellar/openjdk@11/11.0.18/libexec/openjdk.jdk/Contents/Home
    1.8.331.09 (x86_64) "Oracle Corporation" - "Java" /Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home
    1.8.0_331 (x86_64) "Oracle Corporation" - "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_331.jdk/Contents/Home
```

#### 切り替え

.zshrcの中で、JAVA_HOMEを動的に指定し、バージョンを書き換えることで切り替えられるようにしています。

```bash
export JAVA_HOME=$(/usr/libexec/java_home -v 11)
```

>1.8の場合は1.8と記述。

切り替えたあとはたらしくコンソールを開くか、sourceコマンドで値を反映する必要があります。

```bash
source .zshrc
```

### 古いJavaのインストール

古いJavaは下記のようにすればインストールされます（11の例）。

```bash
brew install openjdk@11
```

ただ、認識させるためには下記のようにシンボリックリンク等を手動で貼る必要があるみたいです。

```bash
sudo ln -sfn $(brew --prefix)/opt/openjdk@11/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-11.jdk
```

### メモ

エラーのでるJavaのバージョンでionic capacitor add androidして生成したandroidのフォルダは一度削除したほうがいいでしょう（ファイル形式等のエラーがでる場合がある）。
Google fontの 'downloadable font: gasp: Changed the version number to 1' メッセージに対処する

# 概要

Google Fontsをダウンロードし、CSSのfont-faceで定義したときに、Windows版Firefoxのコンソールに以下のメッセージが出ることがあります(ブラウザコンソールで表示されるため、Webページの動作には問題は無いと思います)。

:::note warn
downloadable font: gasp: Changed the version number to 1 (font-family: "Quicksand" style:normal weight:700 stretch:100 src index:0) source: https://hostname/webfonts/Quicksand/Quicksand-Bold.ttf
:::

このメッセージ通り、`gasp.version`を`1`にすることで解消します。対象TTFのgaspテーブルの`version`が`0`になっており、Pythonのfonttoolsモジュールを使い、`gasp.version`を`1`にすることで回避することができました。

:::note
TTFのgaspテーブルとはGrid-fitting And Scan-conversion Procedure Tableというもののようです。Microsoftの仕様書の中でversionはset to 1と書かれており、1が正しい値のようです。

- gasp -- Grid-fitting and Scan-conversion Procedure Table (Microsoft Typography)
  - https://learn.microsoft.com/en-us/typography/opentype/spec/gasp
:::

# 解決手順
## 環境

CSSではこのように定義しています。

```css
@font-face {
  font-family: 'Quicksand';
  font-style: normal;
  font-weight: 700;
  src: url(../webfonts/Quicksand/Quicksand-Bold.ttf) format('truetype');
}
```

これが適用されたときに上記の警告が出るみたいです。
Google FontsのGitHubで数年前に議論されていますが、再現性が低いとされてクローズされているみたいです。
- GitHub google/fonts [#243 How to solve this error?](https://github.com/google/fonts/issues/243)

私の場合はWindows10(22H2) Firefox 109.0.1で発生しました(ずっと以前のバージョンから出ていたと思います)。Edge 109.0.1518.70ではメッセージは表示されませんでした。

## fonttoolsモジュールによるTTFファイルの修正

fonttoolsモジュールを使いTTFファイルの`gasp.version`の値を`1`に書き換えて保存します。

### fonttoolsのインストール

pipでインストールします。CentOS 7.9 + Python 3.6で実行しましたが、他の環境でも動作すると思います。

```bash
$ pip3 install fonttools
```

### gasp.versionの値を修正して保存します

```python
from fontTools.ttLib import TTFont
# フォントを読み込む
font = TTFont("Quicksand-Bold.ttf")
# gasp.versionが0の時に問題が発生しているように思うので1にする
if font["gasp"].version == 0:
    font["gasp"].version = 1
    font.save("Quicksand-Bold-v1.ttf")  # 修正後のttfを保存する
```

ここで保存した`Quicksand-Bold-v1.ttf`を使うことで警告が表示されなくなりました。Quicksandでしか試していないので他のフォントも同様かはわかりませんが。

動作には影響ありませんが、ずっと気になってたのが修正できました！

# 参考

- TTFの全グリフをPNGにしてみる -- fonttoolsの使い方を参考にしました
  - https://qiita.com/scrpgil/items/7c7c0a354b3688ddfc6b
- fonttoolsのRead the Docs
  - https://fonttools.readthedocs.io/en/latest/ttLib/ttFont.html
Azure Administrator(AZ-104)：Azure でのストレージの実装と管理「Azure Storage」

Microsoft Learnを用いたMicrosoft Azure Administrator(AZ-104)の試験内容をまとめる投稿です。
この投稿ではMicrosoft Learnで学ぶ内容をできるだけ簡潔にまとめております。
Azureの勉強を一から始め、AZ-900取得後の資格としてAZ-104取得を目指している方の参考になれば幸いです。
※AZ-900の内容は本投稿では省略しております。再度復習したい方は下記をご参照ください。
[Azure Fundamentals(AZ-900)：試験合格に向けた学習内容のまとめ](https://qiita.com/fsd-jume/items/e4ec76959adb547ac5e8)

## 今回の学習内容
**◆「Azure Storage」**
◇対応するMicrosoft Learn ラーニングパス
[AZ-104:Azure でのストレージの実装と管理](https://learn.microsoft.com/ja-jp/training/paths/az-104-manage-storage/)
◇対応するモジュール
[Azure Storage を実装する](https://learn.microsoft.com/ja-jp/training/modules/configure-storage-accounts/2-implement-azure-storage)

※前回の投稿は下記から確認できます。
[Azure Administrator(AZ-104)：Azure での ID とガバナンスの管理「Azure AD SSPRオプション」](https://qiita.com/fsd-jume/items/98028f85ea752d9195b3)

## Azure Storage
### Azure Storage
・最新のデータストレージシナリオ用のMicrosoftクラウドストレージソリューション
・データオブジェクト用に高可用性/スケーラビリティ/持続性/安全性に優れている
・ファイル/メッセージ/テーブル/その他の種類の情報を格納するためのサービス

**◆Azure Storageの使用例**
・ファイル共有のようなアプリに使用
・開発者が作業データ用に使用
※作業データ：Webサイト/モバイルアプリ/デスクトップアプリを含む
・IaaS仮想マシンとPaaSクラウドサービスに使用

### Azure Storageがサポートしているデータ
**◆仮想マシンデータ**
・仮想マシンのデータストレージにはディスク/ファイルが含まれる
　-ディスク：Azure IaaS仮想マシン用の永続的ブロックストレージ
　-ファイル：クラウド内のフルマネージドファイル共有
・データストレージはAzureマネージドディスクを通じて提供
・データディスクは下記のデータなどを格納するために仮想マシンで使用
　-データベースファイル
　-Webサイトの静的コンテンツ
　-カスタムアプリケーションコード
・追加できるデータディスクの数は仮想マシンのサイズにより決まる
・各データディスクの最大容量：32,767GB

**◆非構造化データ**
・データに明確なリレーションシップがない(非リレーショナル)
⇒特定のデータモデルや定義に従っていないデータ
・例：テキストデータ/画像データ/音声データなど
・ネイティブな形式のまま保存され、使用時まで処理されない
・下記を使用してデータを格納
　-Blob Storage：非常に拡張性が高い、RESTベースのクラウドオブジェクトストア
　-Data Lake Storage：サービスとしてのHadoop分散ファイルシステム(HDFS)

**◆構造化データ**
・共有スキーマを持つリレーショナル形式で格納
・多くの場合、行/列/キーから成るデータベーステーブルに含まれる
・テーブルは自動スケーリングするNoSQLストア
・下記を使用してデータを格納
　-Azure Cosmos DB：グローバル分散型データベースサービス
　-Azure SQL Database：SQLを基盤とするサービスとしてのフルマネージドデータベース

### ストレージアカウントレベル
・StandardとPremiumでアカウントの変換は不可

**◆Standardストレージアカウント**
・磁気ハードディスクドライブ(HDD)を基盤としている
・GBあたりのコストが最も低い
・Standardストレージアカウントの使用例
　-大容量ストレージを必要とするアプリ
　-データへのアクセス頻度が低いアプリ

**◆Premiumストレージアカウント**
・ソリッドステートドライブ(SSD)を基盤としている
・一貫した低待機時間のパフォーマンスを提供
・Premiumストレージアカウント
　-データベースのようなI/O集中型アプリがある仮想マシンディスク

### Azure Storage使用時の考慮事項
**◆持続性と可用性を考慮**
・冗長性により一時的なハードウェア障害の間もデータの安全を保証
・データは複数のデータセンターや地理的リージョンにわたってレプリケート
⇒地域の大事故や自然災害からの保護のため
・予期しない停止の間もレプリケートされたデータの高可用性を維持

**◆安全なアクセスを考慮**
・書き込まれるデータはすべて暗号化される
・データにアクセスできるユーザを細かく制御可能

**◆スケーラビリティを考慮**
・ニーズを満たすために高度にスケーラブルな設計が採用
⇒最新のアプリのデータストレージとパフォーマンスに関するニーズ

**◆管理のしやすさを考慮**
・ユーザに代わり、ハードウェアのメンテナンス/更新/重大な問題を処理

**◆データのアクセシビリティを考慮**
・データには世界中のどこからでもHTTP/HTTPS経由でアクセス可能
・様々な言語でSDKを用意(.NET/Java/Node.jsなど)
・PowerShell/Azure CLIでのスクリプト化をサポート
・Azure Portal/Azure Storage Explorerによる視覚的ソリューションを提供

## 次の学習内容
**◆Azure Storageの各サービス**

https://qiita.com/fsd-jume/items/14d57b24da9b11fc2a16

## 学習内容をまとめたページの一覧

https://qiita.com/fsd-jume/items/6eda24728c9c03c36bc3
[Xcode]ビルド環境を切り替える 備忘録

![スクリーンショット 2023-02-13 17.43.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517291/6290ba09-0a4e-7882-79e4-01fbb189478c.png)

![スクリーンショット 2023-02-13 17.44.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517291/d3f40e12-4f65-c909-0551-7ba956c091e3.png)

![スクリーンショット 2023-02-13 17.47.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517291/b4e883df-a463-287a-5da5-34ca7083e88f.png)

![スクリーンショット 2023-02-13 17.47.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517291/3bcc9719-7f78-9a54-c0ad-037660db129f.png)

```
#if DEBUG
    print("xxx")
#endif
```
PlantUMLについてのまとめ





## その他
- フローチャート作成時の条件部の参考  
https://plantuml.com/ja/activity-diagram-beta


- vscode の拡張でプレビューできない時は、 Java起動オプションが足りない時がある
https://qiita.com/zonbitamago/items/7946acfb4cbaa139f00a
AWS の RDS の MySQL8 でのユーザー作成

MySQL8のユーザー作成方法メモ [^contract57]。

[^contract57]: 例えば、MySQL5.7では `GRANT` でユーザーが作成＆パスワード設定できたが、8ではそれができなくなった。（参考） https://www7390uo.sakura.ne.jp/wordpress/archives/456

__※ワンポイント__
　AWSで、同じVPC内でネットワークセグメントを別にして複数環境を利用する場合などがあるかと思う。そういう場合、DBには対応するセグメントのユーザーを作成するのが良い。
　セキュリティグループのほうで環境を超えてアクセスできないように設定しておくのだが、DB側でセグメント指定でユーザーを作成することで、セキュリティグループの設定を忘れた時や間違って意図した設定になっていなかった場合の、アクセス制限の保険になる。　
　環境が１つであれば、セグメント指定せずに % でよいだろう。 （例： `'ユーザー名'@'%'` ）

## 実際のSQL

データベースはあらかじめ作成している前提。[^aboutflush]

```sql
CREATE USER 'ユーザー名'@'ネットワークアドレス/ネットワークマスク' IDENTIFIED BY 'パスワード';
GRANT ALL ON データベース名.* to 'ユーザー名'@'ネットワークアドレス/ネットワークマスク';

-- 以下、例

CREATE USER 'bocchi'@'192.160.100.0/255.255.255.0' IDENTIFIED BY 'SomePassword';
GRANT ALL ON kessokuband.* to 'bocchi'@'192.160.100.0/255.255.255.0';
```

（以上）


[^aboutflush]: なお `FLUSH PRIVILEGES;` コマンドは不要。（[MySQL8ドキュメント](https://dev.mysql.com/doc/refman/8.0/ja/privilege-changes.html)）
【React】PropTypesの型チェックチートシート

Reactはじめたて（JSもほぼ初心者）なので自分用にReact.PropTypesの型チェックチートシートを記述します。
公式サイトの情報をベースに自分が欲しい情報を調べて加えたものです。

# 型の種類

### 配列（Array)
```javascript
PropTypes.array
// [ "天海春香", "如月千早", "星井美希" ]

// 特定型の配列の指定も可能 下記は数値のみの配列の場合
PropTypes.arrayOf(PropTypes.number)
// [ 10, 20, 30 ]
```

### 論理型（Boolean)
```javascript
PropTypes.bool
// true, false
```

### 関数（func）
```javascript
PropTypes.func
// memo
```

### 数値型（Number）
```javascript
PropTypes.number
// 2023
```

### オブジェクト（Object)
```javascript
PropTypes.object
/*
{
  name: "天海春香"
  age : 17
}
*/

// objectのvalue値の指定も可能
PropTypes.objectOf(PropTypes.number)
/*
{
  width: 100,
  height: 200
}
*/
```

### 文字列型（String）
```javascript
PropTypes.string
// "piyo"
```

### シンボル型（Symbol）
```javascript
PropTypes.symbol
// Symbol('fuga')
```
:::note info
Symbol型とは？
その値が一意となるプリミティブ型の一種。
シンボル名が一意となるため、等価比較でもfalseとなる。
参考: https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Symbol
:::

### なんでも
```javascript
PropTypes.any
// なんでもいいのでそもそも書く必要がないと思われる。
```

### Node型
```javascript
// 数値型、文字列型、element型、array型を指定することが可能。レンダリングできるものならなんでも
PropTypes.node
// 例: "piyo", 2023, memo:elements, ["hoge", "fuga", "piyo"]
```

### element（React Element） / elementTypes（React ElementType）
```javascript
// React Element(インスタンス)
PropTypes.element
// 例: <MyComponent />

// React ElementType(クラス)
PropTypes.elementType
// 例: MyComponent

// 特定のComponentに限定したい場合
PropTypes.instanceOf(MyComponent)
```
:::note info
elementとelementTypeの違いについて
elementはインスタンス、elementTypeはクラスだそう
参考: https://gotohayato.com/content/527/
:::

# 型以外のオプション
### 指定したキーは指定した型でなければならない
```javascript
PropTypes.shape({
  name: PropTypes.string,
  age : PropTypes.number
})
// キーが必ず必要というわけではない
/*
{
  name: "如月千早"
  age : 16
}
*/
```

### 指定した配列の中の要素のいずれしか受け付けない
```javascript
PropTypes.oneOf(['男性', '女性', '無回答'])
// 男性, 女性, 無回答の3択しか受け付けない
```

### 型を複数指定でき、そのどれかであればいい
```javascript
PropTypes.oneOfType([
  PropTypes.string,
  PropTypes.number
])
// stringかnumberであればいい
```
### 指定したキー以外の値があるとNG
```javascript
PropTypes.exact({
  name: PropTypes.string,
  age : PropTypes.number
})
// nameとage以外の値があるとNG
```

### 指定した要素が欠けている場合NG
```javascript
PropTypes.string.isRequired
// 指定した型の値が必須
```

# その他
### デフォルト値
```javascript
PropTypesComponent.defaultProps = {
  sampleKey: 'defaultの値'
}
// defaultPropsを使用してデフォルト値を設定することができる
```

### カスタムルール
```javascript
PropTypes.string.custumRule
// 見たことのない型指定ならカスタムルールかも
```

# 参考
- https://ja.reactjs.org/docs/typechecking-with-proptypes.html
- https://zenn.dev/yumemi_inc/articles/2020-09-23-react-proptypes
- https://gotohayato.com/content/527/
- https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Symbol
if文やswitch文を用いた値の宣言でもconstで定義したい

JavaScript、TypeScriptで値を扱うとき、`let`を用いて宣言を行うと可読性が著しく下がるので可能な限り`const`を利用して宣言したいです。
この信条をもとに開発を行うと、宣言する値が分岐する場合でも`const`で定義することになります。そのように作られたコードは以下のように可読性が下がります(この例は分岐の階層が1なのでまだマシで、階層が増えるとさらに見にくいコードになります)。
```ts
const colorSchema = (
  type === 'info'
    ? ({
        color: '#0288d1',
        backgroundColor: '#03a9f4',
      } as const)
    : type === 'success'
    ? ({
        color: '#2e7d32',
        backgroundColor: '#4caf50',
      } as const)
    : type === 'warning'
    ? ({
        color: '#ed6c02',
        backgroundColor: '#ff9800',
      } as const)
    : type === 'error'
    ? ({
        color: 'd32f2f',
        backgroundColor: '#ef5350',
      } as const)
    : ({
        color: 'inherit',
        backgroundColor: 'inherit',
      } as const)
) satisfies ColorSchema;
```
そのため、分岐が複雑な場合はその可読性の低下が`let`を使うことによる可読性の低下よりも大きいと考えられ、以下のように`let`を使って宣言することが多いです。
```ts
let colorSchema: ColorSchema;

switch (type) {
  case 'info':
    colorSchema = {
      color: '#0288d1',
      backgroundColor: '#03a9f4',
    } as const;
    break;
  case 'success':
    colorSchema = {
      color: '#2e7d32',
      backgroundColor: '#4caf50',
    } as const;
    break;
  case 'warning':
    colorSchema = {
      color: '#ed6c02',
      backgroundColor: '#ff9800',
    } as const;
    break;
  case 'error':
    colorSchema = {
      color: 'd32f2f',
      backgroundColor: '#ef5350',
    } as const;
    break;
  default:
    colorSchema = {
      color: 'inherit',
      backgroundColor: 'inherit',
    } as const;
    break;
}
```
`switch`文による分岐になりましたので、どの分岐でどのような値が代入されているか分かりやすくなりました。この形式では`let`を使っているので今後変更されるかもしれないことを頭の片隅に入れて読んでいく必要があります。
さらに、`colorSchema`の型はこれだけ、実際に取りうるオブジェクトのユニオンではなく`ColorSchema`と推論されます。この例では対した問題にはなりませんが、オブジェクトが持つ値によって分岐を作るときに型を絞ること(制御フローによる型の絞り込み)が出来ないという面が劣っています。

これらを解決するのが分岐処理を関数で行わせてその結果を値として宣言するという方法です。
```ts
const colorSchema = (() => {
  switch (type) {
    case 'info':
      return {
        color: '#0288d1',
        backgroundColor: '#03a9f4',
      } as const;
    case 'success':
      return {
        color: '#2e7d32',
        backgroundColor: '#4caf50',
      } as const;
    case 'warning':
      return {
        color: '#ed6c02',
        backgroundColor: '#ff9800',
      } as const;
    case 'error':
      return {
        color: 'd32f2f',
        backgroundColor: '#ef5350',
      } as const;
    default:
      return {
        color: 'inherit',
        backgroundColor: 'inherit',
      } as const;
  }
})() satisfies { color: string; backgroundColor: string };
```
このようにすることで、分岐による可読性を保ったまま`const`で定義することが出来ます(型も詳細なオブジェクトのユニオンが得られます)。汎用的な分岐処理であれば都度無名関数で作成するのではなく、関数として宣言して使い回すようにしても良いと思います。
AWS LambdaのコードエディタでDeploy時の困りごと


:::note info
**【2024/10/23更新】**

**神アップデートが来ました！！**
**Lambda関数のコードエディタがVSCodeに！！**
https://aws.amazon.com/jp/about-aws/whats-new/2024/10/aws-lambda-code-editor-based-code-oss/
:::

なんと、このエディターの大幅改良により、以下のバグは再現が見られなくなっている模様で、解決されているようにみえます。
時間がかかったけど、ありがとうAWS！

以下は、参考までに残しておきます。


# Deployボタンを押して保存したはずなのに

AWS Lambdaでは、いくつかの言語でWeb上のコードエディタで直接コードが編集できます。

ある程度のコードを書いた後、保存するときに押すのが **Deploy** ボタンです。

以前から **Deployボタンを押す直前に入力したいくつかの文字が保存されない** 場合がある問題（バグっぽいもの）があり、悩まされています。

## 再現方法とログ

いつも再現できるか分かりませんが、手元では以下のように実施して一発で再現できました。

Pythonで、一から作成として、普通にサンプルのプログラムを作成します。

そこに、以下の1行を追記します。

```python
print('abcdefghijklmnopqrstuvwxyz')
```

まず1回目の **Deploy** ボタンを押します。

z の後に、今度は大文字で ```ABCDEFGHIJKLMNOPQRSTUVWXYZ``` を追記して、2回目の **Deploy** ボタンを押して更新します。

コードとしては以下が入力された状態です。

```python
print('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
```

サンプルの入力データで、テストを実行します。→　最後の3文字が抜け落ちました。

```XYZ``` が欠けた例

![lambda_edit_u1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204490/b8811840-a5e8-ec58-d329-a244498138e7.png)
（本筋ではないですが、TとUが逆でした..）

再度ページを開きなおすと、確かに保存できていませんでした。
![lambda_edit_u2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204490/955a4e29-d660-3fdd-bc0f-45b210b8f9d6.png)

感覚的には、25％以上の確率でこうなります。

## 原因？

異なるパソコン、異なるWebブラウザ、異なるAWSアカウントでも発生し、Skill Builderの一時的な環境でも発生することを確認していますので、自分の環境の問題ではないでしょう。

内部の動作であれば、推測することしかできないですが、エディタは Cloud9 が使われているようなので、そこへ最後の文字が渡るタイミングより前に、Deployの処理（Zip化とか）が先に動いているのでは？と思ったりします。

## 回避策

自分でやっているのは、全ての文字を入力した後に **意味のない改行を3～5文字ぐらい入れて、その改行を消す**、ということを、Deploy 前に毎回やっています。

一般的なスクリプト言語は、改行の量が多少違ってるぐらいだと全く影響がないですので。

## うーん、改善されてほしい

マネージメントコンソールの左下にある ```feedback``` リンクから、ここ1年以内で 日本語で2回、英語で1回、合計3回、フィードバックしていますので、ぜひ中の人はよろしくお願いします。
laravel API POSTリクエストを送ってもボディーを受け取れない

# 概要

- APIにてPOSTリクエストをリクエストボディー込で送ってもコントローラーとかで$request->allしても、空の配列しかない場合の対処法（筆者の場合）を簡単にまとめる。

# 対処法

- 大体がリクエストボディーのJSONが問題なことが多い。
- JSONの記法に則っているか。文字列には`""`で囲われているか。などを確認しよう。
- 筆者は下記のWebサービスを用いてJSONの構文が正しいか確認する事がある。

https://lab.syncer.jp/Tool/JSON-Viewer/
プログラムからpdfの長体を入れる【iText】

# PDFで長体（縦に長いor横に長い文字）を入れたかった
元々はAmazonのFBA商品ラベルを自分で作りたかった。（物販の人向け）
セラーセントラルからダウンロードできるものは文字数によりフォントの横幅をコントロールして、表示される文字数を変えていた。

出来上がりイメージはこちら
![スクリーンショット 2023-02-13 16.47.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120789/facc2f32-78b5-60b2-9e57-737133bd4985.png)

## 行き着くまで
最初は文字幅を変えられるのかと思いきや、あんまりそんな情報が見つからない。
こんなんとか
https://helpx.adobe.com/jp/indesign/kb/4096.html

### PDFLibにはあるみたいだった
https://www.softel.co.jp/blogs/tech/archives/4897

### ただ、有償のものは避けたかったので他のライブラリで探す
あんまりドンピシャの情報なし、というか長体を英語でどう表現されてるかわからず…

### PDFの内容を直接覗いてみる。
Amazonの商品ラベルのPDFには「iText 2.1.4」の文字が。
これは良いヒント、早速iTextのドキュメント漁る。
しかし、これでもよくわからず…

### まだググる
https://ateraimemo.com/Swing/CondensedFontLabel.html
こういうのはひかかったが、Swingなのでそのまま適用できず…

### アフィン変換？
http://www.nilab.info/z3/20070802_zlashdot_000694.html
アフィン変換でボックスサイズを色々変えられるみたい。
ただ、Paragraphには適用できない様子…

### iText 7系なら
https://api.itextpdf.com/iText7/java/7.1.13/com/itextpdf/io/font/constants/FontStretches.html
Font Condensedとか指定できるみたい。
ただ、7系じゃなくて２系で再現したかったので一旦見送り…

### 再度PDFの内容覗く
（参考にさせていただきました
https://www.antenna.co.jp/pdf/reference/pdftext.html
https://www.pdf-tools.trustss.co.jp/Syntax/font.html
PDFの内容を覗くと、
`FontDescriptor 8 0 R/W[1[250] ~~~~~`
みたいな情報があり、たぶんこれ(W以降)がフォント幅を制御してる、と思ったらそれであってるみたい。

### iTextでは
https://stackoverflow.com/questions/23664495/how-do-i-change-the-weight-of-a-simulated-bold-font-using-itext
似たような情報だったが、chunkごとにフォントの太さを変えたりできるみたい。
chunkのドキュメントを見ると
https://api.itextpdf.com/iText5/java/5.5.9/com/itextpdf/text/Chunk.html
https://api.itextpdf.com/iText5/java/5.5.9/com/itextpdf/text/Chunk.html#setHorizontalScaling-float-
で水平方向のスケーリングを変えられるみたいだ。

## ということで、
``` java
        p = Paragraph()
        for (i in 1..99) {
            val chunk = Chunk("$i ", font)
            chunk.setHorizontalScaling(i / 10.0f)
            p.add(chunk)
        }
        document.add(p)
```

こういう感じのコードで長体文字の追加ができました。
(結局2.~系での検証できていない…）

#### この後はPDFSharpあたりでもできないか調べる。
（分かり次第記事追加する）
paizaラーニング レベルアップ問題集 二分探索メニュー応用編 JavaScript 記念写真

記念写真 (paizaランク A 相当)

https://paiza.jp/works/mondai/binary_search_advanced/binary_search_advanced__photo

# 解答例(C++の場合参考)
ジャンプした高さの最小値で二分探索します。

各人が最小値の高さmid以上になるためには、燃料を`(最小値の高さ/ジェットパックの燃料 1 つにつき高さ A)の切り上げ`の個数、すなわち、`Math.ceil(mid / A)`個、使います。

全員、mid以上になる時に使った燃料がK個を満たすか調べます。

***

探索範囲rightの初期値が、問題文によると

>1 ≦ A_i ≦ 1,000,000,000 = 10^6

なのですが、1,000,000,000 と 10^6、どちらが正しいかわかりませんでした。paizaに問い合わせました。
模範解答から、ジャンプの最小値の探索範囲の最大値、右端rightを1000000000000000001=10^18+1にしたら、うまくいきました。

ジャンプの高さは、A_i * Kで、Kの最大値は10^12なので、おそらく、A_iの最大値は10^6が題意のようです。

```javascript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");
//あなたと友達の合計人数を表す整数 N, ジェットパックの燃料の個数 K
const [N, K] = lines[0].split(" ").map(Number);

//ジェットパックの燃料 1 つにつき高さ A_i だけ上昇
//ジャンプの最小値から、K個を満たすか探索する
//A_iの高さの範囲
let [left, right] = [0, 1000000000000000001];

while (right - left > 1) {
  const mid = Math.trunc((left + right) / 2);//仮のジャンプの高さの最小値
  
  //mid以上になるように、ジェットパック燃料を分配する
  let numFuel = 0;
  for (let i = 1; i <= N; i++) {
    const A = Number(lines[i]);
    numFuel += Math.ceil(mid / A);
    
  }
  //使った燃料がK個を満たすか
  if (numFuel <= K) {
    //燃料の個数がK以下なら、高さはもっと高くできる
    left = mid;
    
  } else { //燃料の個数がKを超えたら、高さは低く
    right = mid;
  }
}
console.log(left);
```


# 解答例(Pythonの場合参考)
ちなみに、x / y を切り上げた値を求める際には、(x + y - 1) / y を切り捨てた値を用いることができます。

こちらもleft=1<<47だとうまくいかず、1000000000000000001=10^18+1にしたら、うまくいきました。

```javascript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");
//あなたと友達の合計人数を表す整数 N, ジェットパックの燃料の個数 K
const [N, K] = lines[0].split(" ").map(Number);
//ジェットパックの燃料 1 つにつき高さ A_i だけ上昇
const A = lines.slice(1).map(Number);

//ジャンプの最小値から、K個を満たすか探索する
//k個以内でジャンプできるときは true, できないときは false
const check = x => {
  let cnt = 0;//燃料の個数
  for (let i = 0; i < N; i++) {
    cnt += Math.floor((x + a[i] - 1) / a[i]);
  }
  if (cnt <= K) {
    return true;
  } else {
    return false;
  }
};

//A_iの高さの範囲
//leftは常に条件を満たす，rightは常に条件を満たさない
let [left, right] = [0, 1000000000000000001];

while (right - left > 1) {
  const mid = Math.trunc((left + right) / 2);//仮のジャンプの高さの最小値

  //使った燃料がK個を満たすか
  if (check(mid)) {
    //燃料の個数がK以下なら、高さはもっと高くできる
    left = mid;
    
  } else { //燃料の個数がKを超えたら、高さは低く
    right = mid;
  }
}
console.log(left);
```
ガッチャモールで発生したバグ・不具合などまとめ

ガッチャモール内で過去に発生したバグ・不具合などをまとめてみました。

過去に発生したものなので、現在のバージョンでは解決済み・発生しないものも含まれていますので参考にする際にはご注意下さい。
今回は、３つのケースを紹介します。

> 「バグ」とは、その機能の不備を生むプログラム内の不具合を指す言葉です。
> また、不具合とは、プログラムが仕様書通りに動かないことです。
> つまり、思った通りに動かないプログラムを見て「バグがある」と表現します。
引用元：https://tech-camp.in/note/technology/94046/


### ソフトウェア構成図
![スクリーンショット 2023-02-14 11.23.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3103946/fbec8724-3a5c-eb93-755a-c942be140037.png)


## 1.Javascript「;」による閉じ忘れ
関数等、処理の最後の「;」による閉じ忘れが存在。
「 }) 」のような")"にセミコロン";"を付けないとブラウザによっては[SyntaxError](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError "SyntaxError")の原因となる
```javascript:sample.js
if(navigator.geolocation){
        navigator.geolocation.getCurrentPosition( successFunc , errorFunc , optionObj ) ;
} else {
        var apiUrl = '/api/foge/foge';
        var pathname = location.pathname;
        $.ajax( {
                type : 'GET',
                url  : apiUrl,
                beforeSend :
                        function( xhr ){
                        xhr.setRequestHeader("pathname", pathname);
                }
        } );
}
```
Javascriptに関しては、他にconstが利用できないブラウザ（IE10など）でエラーが発生したものもありました。
```javascript:対応前sample.js
const EXPIRING_MINUITES = 5;
```
```javascript:対応後sample.js
var EXPIRING_MINUITES = 5;
```

## 2．重複インサートに伴うロック場所の見直し
重複リクエストに伴う重複インサートの対策。
対象テーブルを行ロックしていなかった為、重複インサートにより重複エラーが多発した。
※unique keyを設定しているのでDB上のデータ不整合はなし

##### 対応内容：
トークンに一致する対象テーブルを行ロックすることによって現象を防ぐ。
以下に、SampleRepositoryクラスのメソッドを抜粋。

```java:SampleRepository.java
/**
 * <p>トークンによるSampleTableの取得（ロック）</p>
 * 
 * OPTIMISTIC : 楽観的
 * PESSIMISTIC : 悲観的
 *  PESSIMISTIC_READ : 共有ロック. lock in share mode 
 *  PESSIMISTIC_WRITE : 排他ロック. for update
 * 
 * @param token
 * @return
 */
@Transactional
@Lock(value = LockModeType.PESSIMISTIC_WRITE)
@Query("SELECT FROM sample_table WHERE registorToken = ?1")
public SampleTable findByRegistorTokenAndLock(final String token);
```

## 3.フロントサーバーログの肥大化によるディスクリソース逼迫
Line配信を開始したことで、新規ユーザーの大量流入でログが肥大化しEC2内のディスクリソースが逼迫した。
対応内容については、インフラチームと検討・調整し対応を実施。
また、不要なログ出力や出力内容を改めてアプリチームと精査した。

#### 対応内容：
・ログローテートとファイル圧縮
・日次でS3へログをバックアップ
・S3 Glacier Instant Retrieval導入によるコスト削減

##### ・ ログローテートとファイル圧縮
EC2内の当日ログは圧縮せず生ログのままとし、後はログローテート時にログファイルの圧縮する仕組みを導入した。
※EC2内のログの保存期間は１週間とした

##### ・ 日次でS3へログをバックアップ
上記にて、１週間経過したログファイルをS3へバックアップする仕組みを導入した。
S3にバックアップ後、S3にライフサイクルを設定することで、不要となったファイルを自動削除出来るようになった。
ライフサイクルに設定する期間については、分析・調査・参照することがなくなる期間を考慮。

##### ・ S3 Glacier Instant Retrieval導入によるコスト削減
上記２つを対応してから数年後、「S3 Glacier Instant Retrieval」というサービスがリリースされ、コスト削減目的で利用する事とした。
180日前のログは通常のS3ストレージに、半年（180日）経過した物は、「S3 Glacier Instant Retrieval」に移行するように設定することでコストを削減が出来た。（ストレージコストを最大 68% 節約）

詳細についてはこちら（[S3 Glacier Instant Retrieval](https://aws.amazon.com/jp/about-aws/whats-new/2021/11/amazon-s3-glacier-instant-retrieval-storage-class/ "S3 Glacier Instant Retrieval")）
laravel バリデーション リクエストクラス authorizeについて

# 概要

- laravelでリクエストクラスをartisanコマンドを使って作成すると、リクエストクラス内に`authorize()`が記載される。
- `authorize()`はユーザーが認証状態で当該のリクエストを投げることができるかをtrue or falseで設定するものである。
- `authorize()`は「ユーザーが認証状態で当該のリクエストを投げることができるか」をチェックしない場合、関数ごと削除して良いという記載を呼んだことが有る。
- なぜ関数ごと削除しても問題ないのかを簡単に調べてみる。

# 確認

- リクエストクラスの継承元のFormRequestクラスを見てみると下記のようなクラスがあった。

    ```vendor/laravel/framework/src/Illuminate/Foundation/Http/FormRequest.php
    /**
     * Determine if the request passes the authorization check.
     *
     * @return bool
     */
    protected function passesAuthorization()
    {
        if (method_exists($this, 'authorize')) {
            return $this->container->call([$this, 'authorize']);
        }

        return true;
    }
    ```

- 簡単に説明すると「自信（継承先も含める）に`authorize()`関数が定義されていた場合、実行して戻り値をそのまま`passesAuthorization()`の戻り値とする。`authorize()`関数が定義されていなかった場合、`passesAuthorization()`はtrueを返す。」
- なるほど`authorize()`関数が定義されていなかったら`passesAuthorization()`はtrueになるから、`authorize()`を定義しなくてもよいのか。。
AWS利用料の予算超過をSMS通知する(作成中)

# 概要
予算超過をSMS通知するための手順をまとめる
SMS通知の条件：1日あたり1ドルを超過

# 手順の流れ
+ SNSの設定
  + トピックの作成
  + エンドポイントの作成
  + サブスクリプションの作成
+ Budgetsの設定


# トピックの作成

### メニューの場所
Amazon SNS>トピック>トピックの作成

### タイプ
「スタンダード」を選択する

||FIFO|スタンダード|
|---|---|---|
|メッセージ順序|厳密に順位づけ|ベストエフォートの順位づけ|
|サブスクリプションプロトコル|SQS|SQS/Lambda/HTTP/SMS/Eメール/モバイルアプリケーションエンドポイント|

### 名前
なんでも良い

### 表示名
なんでも良い

### アクセスポリシー
"Statement"に以下の記述を追加する
※BudgetsからSNSへのアクセスを許可するポリシー
※your topic ARNはトピックのARNに書き換える

```json
{
  "Sid": "AWSBudgetsSNSPublishingPermissions",
  "Effect": "Allow",
  "Principal": {
    "Service": "budgets.amazonaws.com"
  },
  "Action": "SNS:Publish",
  "Resource": "your topic ARN"
}
```

# エンドポイントの作成

### 設定メニューの場所
「テキストメッセージング(SMS)」>「サンドボックスの送信先電話番号」>「電話番号を追加」

### 電話番号
通知先の電話番号を入力する
※「国際電話識別番号」と「国番号」は「+81」

### 検証メッセージの言語
「日本語(日本)」を選択する

### 検証コード
入力した電話番号に通知される検証コードを入力する

# サブスクリプションの作成

### トピックARN
作成したトピックを選択する

### プロトコル
SMSを選択する

### エンドポイント
作成したエンドポイントを選択する

# 予算の作成

### メニューの場所
「Budgets」>「予算を作成」

### 予算の設定
「カスタマイズ」を選択
※日時のアラートを設定したいため

### 予算タイプ
「コスト予算 – 推奨」を選択する

### 予算名
任意の名前を設定する

### 期間
「日」を選択する

### 予算更新タイプ
「定期予算」を選択する

### 開始日
任意の日付を設定する

### 予算設定方法
「固定」を選択する

### 予算額
「1」(ドル)を入力する

### 予算の範囲
「すべての AWS のサービス (推奨)」を選択する

### 閾値
「100%」を入力する

### トリガー
「実際」を選択する

### Amazon SNS ARN を選択
作成したARNトピックを選択する
/bin/sh: 1: react-scripts: not foundと/bin/sh: 1: react-scripts: not foundを解決したい

# はじめに
こちらの記事の派生になります。

https://qiita.com/does_not_exist/items/19c35639e466844e8b0e

1から環境を作るのに加えて、既存プロジェクトからReactフォルダのみ移す方法でも環境構築を行いました。
その際に発生したエラーの対応についてもまとめておきます。


## /bin/sh: 1: react-scripts: not found
・package.jsonにreact-scriptsが存在するかを確認
・存在する場合は、package.jsonがあるreactプロジェクトフォルダとコンテナがマウントできているかを確認
・マウントもできている場合はnode_modulesのフォルダがreactプロジェクト内に存在するかを確認
・node_modulesとreact-scriptsの再インストール

https://stackoverflow.com/questions/47612580/react-scripts-command-not-found

## EACCES: permission denied, mkdir /home/user/sample-project/react/node_modules/@aws-sdk
node_modulesフォルダに対する権限がないので以下を実行

```
$ sudo chmod 777 /home/user/sample-project/react/node_modules
```
dockerのphp8にGD ライブラリをインストール


dockerで起動したphp環境にGDライブラリがなかったので、なんとかインストールしました。


```Docker:Dockerfile
RUN apt-get update &&\
  # JPEG 対応
  apt-get install -y libpng-dev libjpeg62-turbo-dev &&\
  docker-php-ext-configure gd --with-jpeg &&\
  docker-php-ext-install -j$(nproc) gd
```
　　　　


あとDockerファイル編集したら --buildつけないといけなかったの忘れてしばらく悩んでしまった。。。

```
docker-compose up -d --build
```

　　
-----------

ここに全て書いてありました。
php8.0でも動いてるみたいです。

https://tt-computing.com/docker-php-gd



-----------


上記の方法よりも直接php.iniに設定追加した方が早かった・・・


```php.ini
extension=gd.so
```
RailsとReactの疎通を確認したい

# はじめに
前回の続きになります。今回はreactとrailsの疎通を行っていきます。

https://qiita.com/does_not_exist/items/19c35639e466844e8b0e


# ファイル準備
## react

```react/src/.../test.tsx
略
import axios, { AxiosResponse } from "axios";
import { apiURL } from "../../globalEnv";

type Data = {
  data: string;
};

略

  const testMethod = () => {
    axios
      .get(`${apiURL}/api/v1/test`, {
        params: {
          name: "test"
        }
      })
      .then((res: AxiosResponse<Data>) => {
        if (res.status === 200) {
          console.log(res.data);
        } else {
          console.log("失敗しました");
        }
      })
      .catch(() => {
        console.log("catch");
      });
  }

  return (
    <Button onClick={() => testMethod()}>ボタン<Button>
    );
略
```


```react/src/.../globalEnv.tsx
export const apiURL = "http://localhost:8080";

```

## rails

```backend/app/controllers/api/v1/test_controller.rb
class Api::V1::TestController < ApplicationController
  def index
    render json: { status: 200, message: "Hello World!:#{test_params[:name]}"}
  end

  private
    def test_params
      params.permit(:name)
    end
end
```

```backend/config/routes.rb

Rails.application.routes.draw do
  namespace :api do
    namespace :v1 do
      resources :test
    end
  end
end
```

# 必要な設定
・事前にreact側で画面(test.tsx)と、envを用意しています。
・reactからrailsにデータを送るのにaxiosを使っています。
・今回は localhost:8080/api/v1/test にパラメータとして「name: "test"」を送ることにします。
・rails側ではこのパラメータを受け取る設定の他に、cors設定(localhost:3000からのアクセスを許可)が必要になります。

# CORS設定
デフォルトでGemfileに「gem 'rack-cors'」がコメントアウトされているので、コメントアウトを外します。

```backend/Gemfile
略
# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possible
gem 'rack-cors'
```

Gemfileを更新するために以下を実行します

```
$ docker-compose build
$ docker-compose up
```

次にcors.rbを以下のように変更します。
ここではlocalhost:3000からget/postなどのリクエストを許可するようにしています。

```backend/config/initializers/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins 'http://localhost:3000'

    resource '*',
      headers: :any,
      methods: [:get, :post, :put, :patch, :delete, :options, :head]
  end
end

```

# ReactとRailsの疎通確認

画面でボタンをクリックして、コンソールに以下が表示されていればOK

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2889192/b7cfdee5-49c7-43a6-80af-3005a50cbc4e.png)


# おわりに
次はdynamodbとの連携などを学んでいきます

# 参考

https://qiita.com/kazama1209/items/86c0adc8b6d38fceb36a

https://zenn.dev/never_be_a_pm/scraps/d110146ce4b16a
I/Oコスト

# I/Oコスト
I/OコストがなかったがI/Oを見つけた
## I/O
```I/Oとは、Input/Outputの略で「入出力」を意味```しています。
コンピュータは情報を入力（Input）し、計算結果を出力（Output）するという処理を行なっていますが、これらの処理を総称してI/Oと呼んでいます。

## 出典
https://www.idcf.jp/words/io.html#:~:text=I%2FO%E3%81%A8%E3%81%AF%E3%80%81Input,%E3%81%A8%E5%91%BC%E3%82%93%E3%81%A7%E3%81%84%E3%81%BE%E3%81%99%E3%80%82

### 気づき
データベースにおける入出力のコストのことだろう。

入出力にかかる時間のことかな？
Windowsバッチファイルでネットワーク設定を変更したい件

# はじめに

在宅勤務でノートPCを会社から持ち出す時にネットワーク設定を一々切り替えるのが面倒！と言うときにはWindowsバッチファイルを使います。

# IPアドレスの設定

以下の内容を丸っと書いて **xxx.bat** にて保存。

```
netsh interface ipv4 set address name="イーサネット" source=static address="xxx.xxx.xxx.xxx" mask="255.255.255.0" gateway="xxx.xxx.xxx.1"
```

# DNSの設定

プライマリ、セカンダリを設定します。

```
netsh interface ipv4 set dns name="イーサネット" source=static address="aaa.aaa.aaa.aaa" register=primary validate=no
netsh interface ipv4 add dns name="イーサネット" address="bbb.bbb.bbb.bbb" index=2 validate=no
```

# pacファイルの設定

利用するプロキシが書かれているpacファイルを読み込むには、レジストリを操作する必要があるようです。

```
REM pacファイルを使うとき
reg add "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v "AutoConfigURL" /t REG_SZ /d "http://www.XXX.ne.jp/proxy.pac" /f

REM pacファイルを使わないとき（ダイレクトアクセス）
reg add "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v "AutoConfigURL" /t REG_SZ /f
```

# おまけ

Windows10でbatファイルを開こうとすると警告画面のようなものが表示されてびっくりした。

（おわり）
[Java] デザインパターン - Iterator

## 目的
以下の書籍を読んで、デザインパターンについて学習したため、その備忘録として記事を作成する。
* Java言語で学ぶデザインパターン入門 第3版 (著: 結城浩)

## Iteratorパターンとは
何かがたくさん集まっているときにそれを順番に指し示していき、全体をスキャンして処理を繰り返すもの。
* 具体例（配列`arr`の宣言は省略）
```java
for (int i; i < arr.length; i++) {
  Sysytem.out(arr[i]);
}
```

上記のように変数`i`が添字として役割を果たし、ループごとに次の要素を指し示している。
ここで使われている変数`i`を抽象化し、一般化したものをデザインパターンでは「`Iterator`パターン」 と呼ぶ。

## 実際に使ってみる

ライブラリに、`java.util.iterator<E>`のインターフェースがあり、以下メソッドを持つ。（詳細はURLを参照）

* forEachRemaining
* hasNext
* next
* remove

https://docs.oracle.com/javase/jp/8/docs/api/java/util/Iterator.html

書籍中のサンプルでは、`next()`と`hasNext()`が使われているため、今回は`forEachRemaining()`を使ってみる。

### サンプルコード
* 本棚をスキャンする

```java:Book.java
package Iterator;

public class Book {
  private String name;

  public Book(String name) {
    this.name = name;
  }

  public String getName() {
    return name;
  }
}
```

```java:BookShelf.java
package Iterator;

import java.util.Iterator;

public class BookShelf implements Iterable<Book> {
  private Book[] books;
  private int last = 0;

  public BookShelf(int maxSize) {
    this.books = new Book[maxSize];
  }

  public Book getBookAt(int index) {
    return books[index];
  }

  public void appendBook(Book book) {
    this.books[last] = book;
    last++;
  }

  public int getLength() {
    return last;
  }

  @Override
  public Iterator<Book> iterator() {
    return new BookShelfIterator(this);
  }
}
```

```java:BookShelfIterator.java
package Iterator;

import java.util.Iterator;
import java.util.NoSuchElementException;

public class BookShelfIterator implements Iterator<Book> {
  private BookShelf bookShelf;
  private int index;

  public BookShelfIterator(BookShelf bookShelf) {
    this.bookShelf = bookShelf;
    this.index = 0;
  }

  @Override
  public boolean hasNext() {
    if (index <  bookShelf.getLength()) {
      return true;
    } else {
      return false;
    }
  };

  @Override
  public Book next() {
    if(!hasNext()) {
      throw new NoSuchElementException();
    }
    Book book = bookShelf.getBookAt(index);
    index++;
    return book;
  };
}
```

* 実行用
```java:Main.java
package Iterator;

import java.util.Iterator;

public class Main {
  public static void main(String[] args) {
    BookShelf bookShelf = new BookShelf(4);
    bookShelf.appendBook(new Book("Sword Art Online"));
    bookShelf.appendBook(new Book("Fate/Stay night"));
    bookShelf.appendBook(new Book("Uncle from Another World"));
    bookShelf.appendBook(new Book("Vinland Saga"));

    Iterator<Book> it = bookShelf.iterator();
    it.forEachRemaining(book -> {
      System.out.println(book.getName());
    });
  }
}
```

```text:出力結果
Sword Art Online
Fate/Stay night
Uncle from Another World
Vinland Saga
```

## 感想
* 思っていたより馴染みのある書き方で使いやすかった。
* エンジニア1年目でこの本を渡された時は「？？？」だったが、Java Sliverくらいの知識を持っているとスラスラ頭に入って面白い。（完全な初心者は分かりにくいかも）

以上。
ChatGPTにHTML作成お願いしたら凄すぎた

こんなの答えれないだろうと思って以下をチャットしてみた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592705/c4c627a4-9f90-45de-2b88-387136773f42.png)

いとも簡単にソースを作ってきた。。。
<font color="red">**凄すぎて戦慄が走った。**</font>
テーブル構造の骨組みくらいは作ってくるのかなと思ったらご丁寧に参考の値まで入れてきたよ

**＜作成して頂いたソース＞**
```
<html>
  <head>
    <style>
      table, th, td {
        border: 1px solid black;
        border-collapse: collapse;
      }
      th, td {
        padding: 5px;
        text-align: left;
      }
    </style>
  </head>
  <body>
    <table style="width:100%">
      <tr>
        <th>名前</th>
        <th>年齢</th> 
        <th>特徴</th>
      </tr>
      <tr>
        <td>John Doe</td>
        <td>30</td> 
        <td>趣味は野球</td>
      </tr>
      <tr>
        <td>Jane Doe</td>
        <td>28</td> 
        <td>趣味は読書</td>
      </tr>
    </table>
  </body>
</html>
```
実際に作られるテーブルがこちら
<html>
  <head>
    <style>
      table, th, td {
        border: 1px solid black;
        border-collapse: collapse;
      }
      th, td {
        padding: 5px;
        text-align: left;
      }
    </style>
  </head>
  <body>
    <table style="width:100%">
      <tr>
        <th>名前</th>
        <th>年齢</th> 
        <th>特徴</th>
      </tr>
      <tr>
        <td>John Doe</td>
        <td>30</td> 
        <td>趣味は野球</td>
      </tr>
      <tr>
        <td>Jane Doe</td>
        <td>28</td> 
        <td>趣味は読書</td>
      </tr>
    </table>
  </body>
</html>

* * *

今時点でこの凄さなら5年後、10年後は仕様をバーーーっと書いたテキストを用意するだけでよくなるんじゃないかと。
そのうちシステム開発やってる会社の役割がめっちゃ変わるかも。怖っ。

**＜システム開発会社の役割＞**
**現在**：設計、コーディング、テスト、デプロイ、保守
**将来**：テスト、デプロイ、保守

発注者「大部分のコーディングをやったから後よろしく」
受注者「へい！あとは動くようにコンパイル→デプロイしときます！」みたいな時代が来るかも・・

なんなら内製で全部やるとこ増えてくるかも
/var/lib/docker/overlay2をrm -rf してしまった

## なぜ削除したか

今回は自分のお勉強環境でおきました。

dockerを扱うぞ～
思考錯誤しまくってました。
トライアンドエラーエラーエラーエラーエラーエラー

そしたら下のようなエラーがでるようになった
```
Service 'web' failed to build : Error processing tar file(exit status 1): open /workdir/node_modules/moment/src/locale/th.js: no space left on device
```

なんか空き容量ないよてきなエラー
どこのディレクトリがいらないデータあるのかな～
という感じで調査を開始

下記コマンドで容量確認 90~%とかなってた
```
# df

Filesystem              1K-blocks      Used Available Use% Mounted on
devtmpfs                   495560         0    495560   0% /dev
tmpfs                      507280         0    507280   0% /dev/shm
tmpfs                      507280      6928    500352   2% /run
tmpfs                      507280         0    507280   0% /sys/fs/cgroup
/dev/mapper/centos-root  42954248  41440764   1513484  97% /
/dev/sda1                 1038336    232604    805732  23% /boot
/dev/mapper/centos-home  20969468   1378968  19590500   7% /home
vagrant                 487026684 434455780  52570904  90% /vagrant
tmpfs                      101460         0    101460   0% /run/user/0
```

じゃあ実際どこにあるのか確認
ルートディレクトで下記コマンド

ファイル数確認のコマンド
```
# find . -xdev -type f | cut -d "/" -f 2 | sort | uniq -c | sort -nr

 991996 var
 135829 root
 115510 usr
   1702 etc
    333 opt
     14 tmp
```

一番多い階層へ移動またファイル数確認のコマンド実行
```
cd /var
# find . -xdev -type f | cut -d "/" -f 2 | sort | uniq -c | sort -nr
```

これを繰り返した結果
記事タイトルのディレクトリへとたどり着く
```
/var/lib/docker/overlay2
```

気にせず消してしまえ！！
```
rm -rf おーばーれい２ 
```


・・・・・・

# 消してなにが起きたか

```
# docker-compose build

Service 'web' failed to build : failed to create rwlayer: symlink ../c106f3628~e5d61a89/diff /var/lib/docker/overlay2/l/6FS3QLH~EPGV4JRBIE5: no such file or directory
```

下記エラーがでるようになった
```
failed to create rwlayer
```
buildできなくなってしまった

# 対応

下記コマンド実行
```
docker system prune --volumes -a
```

rm -rf でoverlay2を消していても
なんかうまいこと初期化してくれるみたいでした。

無事にbuildうごくようになりました。
ただデータとかボリュームとかはもちろん全部消えたので
注意です。今回はお勉強環境だったのでセーフでしたが

# まとめ

overlay2がどんなことしてるとかよくわからずに消しました

トライエラーでも調べて
なるべく正解に近いトライをしたほうがいいと思いました。
部分関係従属、推移的関数従属、無損失分解

# 部分関数従属
主キーの一部の列に対して従属する列がある場合、この関係を```部分関数従属```という。

これに対して主キーを構成するすべての列に銃属性がある場合を、```完全関数従属```と呼びます。

## 第二正規化
```部分関数従属を解消```することで得られる。

# 推移的関数従属
テーブル内部に存在する段階的な従属関係のことを```推移的関数従属```と呼びます。

### 気づき
* 主キー以外の従属関係に対して推移的関数従属というのか。
* 第三正規化は推移的関数従属を解消させるのか。

# 無損失分解
第二正規化は、必ず、正規化する前の状態にテーブルを戻すことができるようになっています。
こういう操作を```可逆性```と呼びます。
第二正規化は```可逆的```な操作なのです。
第二正規化に可逆性があるのは、```正規化によって失われる情報がない```からです。
```情報を完全に保存したままテーブルを分割する操作```のことを```無損失分解```と呼びます。
.
.
.
```正規化の逆操作は結合```

### 気づき
情報を完全に保存したあま分割する方法が無損失分解なのか。
idで関連づけられているからか。

# 出典
https://www.shoeisha.co.jp/book/detail/9784798124704
【Mac】Spring Boot + MySQL + MyBatis を使った、タスク管理アプリケーションの作成

# 概要
Spring Boot + MySQL + MyBatisを使って、タスク管理アプリケーションを作成しました。
忘備録として、Spring Boot + MySQL + MyBatisの使い方と、作成したアプリケーションの起動方法をまとめます。

# 環境
* macOSバージョン：12.3.1
* Spring Bootバージョン：3.0.0
* Javaバージョン：17.0
* MySQLバージョン：8.0

# 事前準備
以下を参考に、MacにJava 17、MySQL 8.0、STS（Spring Tool Suite 4）をインストールします。
* [【Mac】Spring Boot 開発環境構築](https://qiita.com/monkey0001/items/9689607b7200aa87b2fe)

# MyBatisの使い方
MyBatisは、Javaでデータベースを扱うためのフレームワーク。
ざっくりとして使い方としては、
「src/main/resource/template/任意のフォルダ/ファイル名.xml」に、DBを操作するためのSQLをxml形式で記載します。
「src/main/resource/java/任意のフォルダ/ファイル名.java」に、@Mapperアノテーションをつけて、上記SQLを呼び出します。
上記xmlとjavaファイルは、同じフォルダ構成、ファイル名にする必要があります。
参考：https://camp.trainocate.co.jp/magazine/about-mybatis-spring/

# タスク管理アプリケーション
以下に、作成したタスク管理アプリケーションのソースコードを作成したので、git cloneコマンドよりソースコードを取得します。
https://github.com/s-kii3/TaskList/tree/v1
### ディレクトリ構成
今回作成するプロジェクトのディレクトリ構成は以下となります。
|  ファイル名 |  内容  |
| ---- | ---- |
|  src/main/java/~/controller  |  コントローラーの内容を記載  |
| src/main/java/~/controller | サービス（業務ロジック）の内容を記載 |
| src/main/java/~/repository | DBへアクセスするための内容を記載 |
| src/main/java/~/entity | DBから取得したレコードを格納するための内容を記載 |
| src/main/resource/~/repository | MyBatisで実行するSQL文（XMLファイル）を記載 |
| src/main/resource/template | ビューの内容を記載 |
| src/main/resource/schema.sql | テーブル定義を記載 |
| src/main/resource/data.sql | 初期データを記載 |

### アプリケーションの起動
ダウンロードしたディレクトリ配下に移動して以下コマンドを実行します。
```
# ビルド
$ gradle build

# 実行
$ java -jar build/libs/TaskList-0.0.1-SNAPSHOT.jar 
```
http://localhost:8080/ にアクセスすると、タスク管理アプリケーションが表示されます。
![スクリーンショット 2023-02-13 15.48.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3123181/3d53264d-ca5b-f1c4-f465-6ccd26dc306d.png)

# 参考
https://qiita.com/t-yama-3/items/969825d5c1bc4a16866d
https://medium-company.com/spring-boot-mybatis/
Deprecated, SuppressWarnings

@Deprecatedをつけると非推奨
SuppressWarnings("deprecation")で警告を消すことができる
@Deprecated(forRemoval=true)をつけると非推奨削除予定
SuppressWarnings("removal")で警告を消すことができる

```java
class Sample {
    @Deprecated(forRemoval=true)
    public void method() {
        System.out.println("----");
    }
    @Deprecated
    public void method2() {
        System.out.println("----");
    }
}
public class Outer {
    @SuppressWarnings("removal")
    public static void main(String args[]) {
        Sample s = new Sample();
        s.method();    //no warning
        s.method2();   //deprecated warning
        method();
    }
    @SuppressWarnings("deprecation")
    static void method() {
        Sample s = new Sample();
        s.method();    //removal warning 
        s.method2();   //no warning
    }
}
```
```
/C:/Users/***/Documents/NetBeansProjects/mavenproject1/src/main/java/com/mycompany/mavenproject1/Outer.java: C:\Users\***\Documents\NetBeansProjects\mavenproject1\src\main\java\com\mycompany\mavenproject1\Outer.javaは推奨されないAPIを使用またはオーバーライドしています。
/C:/Users/***/Documents/NetBeansProjects/mavenproject1/src/main/java/com/mycompany/mavenproject1/Outer.java: 詳細は、-Xlint:deprecationオプションを指定して再コンパイルしてください。
/C:/Users/***/Documents/NetBeansProjects/mavenproject1/src/main/java/com/mycompany/mavenproject1/Outer.java: C:\Users\java\Documents\NetBeansProjects\mavenproject1\src\main\java\com\mycompany\mavenproject1\Outer.javaは、削除用にマークされた推奨されないAPIを使用またはオーバーライドしています。
/C:/Users/java/Documents/NetBeansProjects/mavenproject1/src/main/java/com/mycompany/mavenproject1/Outer.java: 詳細は、-Xlint:removalオプションを指定して再コンパイルしてください。
```
【MaterialUI】Warning: Failed prop type: Material-UI: `overlap="rectangle"` was deprecated. Use `overlap="rectangular"` instead.の解決方法

<h2>症状</h2>
MaterialUIのBadgeコンポーネントを使用したとき、下記のメッセージが表示されました。
翻訳すると、「失敗したプロップ タイプ: Material-UI: `overlap="rectangle"` は廃止されました。代わりに `overlap="rectangular"` を使用してください。」でした。

```terminal:error
Warning: Failed prop type: Material-UI: `overlap="rectangle"` was deprecated. Use `overlap="rectangular"` instead.
    at Badge (http://localhost:3001/static/js/bundle.js:22979:35)
    at WithStyles (http://localhost:3001/static/js/bundle.js:40210:31)
    at span
    at button
    at ButtonBase (http://localhost:3001/static/js/bundle.js:23656:22)
    at WithStyles (http://localhost:3001/static/js/bundle.js:40210:31)
    at IconButton (http://localhost:3001/static/js/bundle.js:26880:27)
    at WithStyles (http://localhost:3001/static/js/bundle.js:40210:31)
    at div
    at div
    at Toolbar (http://localhost:3001/static/js/bundle.js:34889:23)
    at WithStyles (http://localhost:3001/static/js/bundle.js:40210:31)
    at header
    at Paper (http://localhost:3001/static/js/bundle.js:31106:23)
    at WithStyles (http://localhost:3001/static/js/bundle.js:40210:31)
    at AppBar (http://localhost:3001/static/js/bundle.js:22556:23)
    at WithStyles (http://localhost:3001/static/js/bundle.js:40210:31)
    at div
    at MaterialUIPrivateHeader (http://localhost:3001/static/js/bundle.js:2860:19)
    at ThemeProvider (http://localhost:3001/static/js/bundle.js:39310:24)
    at Router (http://localhost:3001/static/js/bundle.js:98040:30)
    at BrowserRouter (http://localhost:3001/static/js/bundle.js:97555:35)
    at App (http://localhost:3001/static/js/bundle.js:104:78)
```

<h2>解決方法</h2>
warn通りに、Badgeコンポーネントにoverlapを渡すと、warnが出なくなりました。

```react:
//これを
<Badge></Badge>

//こうした
<Badge overlap="rectangular"></Badge>
```

<h2>参考</h2>

https://stackoverflow-com.translate.goog/questions/72159936/material-ui-warning?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja&_x_tr_pto=sc
開発環境docker編：MacのiTerm2でphpdotenvをインストールすると、PHP Composerのバージョンが古いため完了できない問題の解決

## 背景
Mac、iTerm2、Docker環境で、PHPの環境変数を設定するために、phpdotenvというライブラリをインストールしたところ、以下のメッセージが出て完了できなかった。
PHP Composerをバージョン2にせよとの内容。

#### 全てのメッセージ
```Warning from https://repo.packagist.org: Support for Composer 1 is deprecated and some packages will not be available. You should upgrade to Composer 2. See https://blog.packagist.com/deprecating-composer-1-support/
Info from https://repo.packagist.org: #StandWithUkraine
Using version ^5.5 for vlucas/phpdotenv
./composer.json has been updated
Loading composer repositories with package information
Warning from https://repo.packagist.org: Support for Composer 1 is deprecated and some packages will not be available. You should upgrade to Composer 2. See https://blog.packagist.com/deprecating-composer-1-support/
Info from https://repo.packagist.org: #StandWithUkraine
Updating dependencies (including require-dev)
Package operations: 6 installs, 0 updates, 0 removals
  - Installing symfony/polyfill-php80 (v1.27.0): Downloading (100%)
  - Installing symfony/polyfill-mbstring (v1.27.0): Downloading (100%)
  - Installing symfony/polyfill-ctype (v1.27.0): Downloading (100%)
  - Installing phpoption/phpoption (1.9.0): Downloading (100%)
  - Installing graham-campbell/result-type (v1.1.0):Downloading (100%)         )
  - Installing vlucas/phpdotenv (v5.5.0): Downloading (100%)
Writing lock file
Generating autoload files
6 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
```

## エラーが起こった場面
Macでdockerを起動し、iTerm2でインストールしたい階層へ移動し、以下のコマンドを入力。

```
docker-compose exec app composer require vlucas/phpdotenv
```

## 何をやっても「command not found」と返される
検索するとあちこちで共通の手法が紹介されていたがうまくいかない。アップデート、削除、インストール共にファイルがないと返される。

## 解決：全てのコマンドの前にdocker-composeでPHPを呼び出す記述を挿入
学習教材のDockerを見直し、あることに気づく。
これまで調べた情報は全てDocker環境ではないものであり、全てのコマンドの前にdocker-composeでPHPを呼び出す記述が必要では？と思い、実施したところ解決。
道理で何をしても変化がないわけである。以下は直接のアップデートのコマンドだが、その他のコマンドも全て同様であった。

```
docker-compose exec app composer self-update --2
```
※最後尾のバージョン指定を端折るとアップデートされなかった。