OmniAICreator/Qiita-1.07M huggingface dataset:
dart / flutterで三項演算子のネスト(入れ子)を理解したい

三項演算子とは、いわゆる:?を用いて条件分岐を作るもの。
↓サンプルコード
```dart
void main() {
   true // 条件式
    ? print('true') // trueの場合に実行する処理
    : print('false'); // falseの場合実行する処理
}
// 実行結果
// true
```

分岐する先が2つなら三項演算子を使うとうまく書けることが多いです。
しかし分岐先が3つ4つと増えてくると、ネストさせて書く必要が出てきます。


### ネストした三項演算子の書き方
三項演算子の処理の部分に条件式を書き、その条件式を元に新しい三項演算子を作ることでネストできます。インデントの位置を見るとどの処理をしているのか理解しやすいかも。いくつか例を上げてみます。
※条件式であることを明示するために()で囲っています。この記述はあってもなくても問題ありません。

#### 1. 分岐先が3つ、ひとつめの条件がtrueなら分岐
```dart
void main() {
  (true)
    ? (false)
      ? print('1')
      : print('2')
    : print('3');
}
// 実行結果
// 2
```
#### 2. 分岐先が3つ、ひとつめの条件がfalseなら分岐
```dart
void main() {
  (false)
    ? print('1')
    : (false)
      ? print('2')
      : print('3');
}
// 実行結果
// 3
```
#### 3. forループ内で、1回目、2回目、3回目で別の処理をする
```dart
void main() {
for (int i = 0; i < 3; i++;){
  (i == 0) 
    ? print('$i') 
    : (i == 1) 
      ? print('$i') 
      : print('$i');
  }
}
// 実行結果
// 0
// 1
// 2
```
例2と同じ書き方で分岐させることができる。

### 余談？ ぶっちゃけif else~を使えばいいのでは
例ではインデントで誤魔化したものの、やはり三項演算子は少し読みにくいですよね。ネストしてるとなると尚更それは顕著だと思います。
なので、基本的にはif elseを使って書くのがベターかなというのが僕個人の意見です。
ただ、if文が使えず三項演算子なら使える場面があるので今回の記事を書くに至りました。具体的な状況については以下の記事で詳しく記載されています。
[【Flutter】Widgetをif文で制御する方法](https://zenn.dev/ryu2021/articles/3d2d0345445435)
記事内では関数の返り値として利用する方法も紹介されていますが、Providerを使っていると関数内でrefオブジェクトがそのまま取得できず、それはそれで面倒になりました......
そのため、分岐先が3つくらいまでなら三項演算子で分岐させて、それ以上の分岐が必要なら関数として切り出してif elseを使うのがバランスがいいかなと思いました。

### 参考にした記事
[Javaで3項演算子をマスターしよう！使い方やネスト・省略など応用も紹介](https://style.potepan.com/articles/28034.html)
【Kotlin】Javaのラムダ式との違い

KotlinとJavaのラムダ式の違いについて、サンプルコードから学ぶ

## ラムダ式とは

関数を簡潔に表現する方法の一つ

- 名前を持たないため、直接呼び出すことはできない
- その代わりに、他の関数に引数として使用される
    - 以下のコードでいう`{ it % 2 == 0 }`がラムダ式

## Kotlin

```Kotlin
val numbers = listOf(1, 2, 3, 4, 5)
val evenNumbers = numbers.filter { it % 2 == 0 }
println(evenNumbers) // [2, 4]
```

numbersの要素から偶数のみを抽出し、evenNumbersに格納される

:::note info
Kotlinのラムダ式では、`it`という暗黙的な変数を使用することで引数の省略が可能となっている
:::

## Java

次に、同様の処理をJavaで記載する

```java
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> evenNumbers = numbers.stream()
    .filter(n -> n % 2 == 0)
    .collect(Collectors.toList());
System.out.println(evenNumbers); // [2, 4]
```

Javaのラムダ式では、引数を明示的に宣言する必要があるため`n`を使用している

また、Streamの処理結果を`Collectors.toList`を使用してListに変換している

## まとめ

Kotlinのラムダ式はJavaのラムダ式と比較して、簡潔で直感的に理解しやすいことが分かった


## 参考文献

[Collectors (Java Platform SE 8 )](https://docs.oracle.com/javase/jp/8/docs/api/java/util/stream/Collectors.html)
[9cubed Kotlin - ラムダ式](https://9cubed.info/article/kotlin/0021)
かつてのRenovateがファイル名を勝手に変えていた振る舞いの原因を深堀り


## 要約

Renovateがホストしているプロダクションのコンテナの中で[`core.quotePath`](https://git-scm.com/docs/git-config#Documentation/git-config.txt-corequotePath )が有効になっていた。このふるまいは[#18963](https://github.com/renovatebot/renovate/pull/18963)以降で修正され、`34.27.3`以降では問題とならない…はずだ。

## 事象

ASCII範囲外の文字がバックスラッシュと8進数3桁の文字列に置き換わる。

## 事象例

* [Japanese file names are renamed incorrectly every time in PR.](https://github.com/renovatebot/renovate/issues/15538)
* [File with umlaut ü (special character) in its name gets corruped](https://github.com/renovatebot/renovate/issues/18805)

## 原因

もし原因がRenovate自身やどこかのライブラリにあるとすれば、作為的にエスケープしなければそのような振る舞いは埋め込めないと仮定できる。ここで言う「作為的にエスケープ」というのは`String.prototype.charCodeAt`などを必要とするものである[^1]。そのため、`git`の何らかの振る舞いによって引き起こされていると見るのが妥当だろう。

[^1]: Pull Request中の全てのファイルを反復し、その名前の非ASCII文字をUTF-8 (など―最も、現代においてWindows以外の大半のマシンはUTF-8を用いているだろうが―) でエスケープし、再度連結する必要がある。

## core.quotePath

`core.quotePath`は以下のように説明されている (git-scm.com):

> Commands that output paths (e.g. `ls-files`, `diff`), will quote "unusual" characters in the pathname by enclosing the pathname in double-quotes and escaping those characters with backslashes in the same way C escapes control characters (e.g. `\t` for TAB, `\n` for LF, `\\` for backslash) or bytes with values larger than 0x80 (e.g. octal `\302\265` for "micro" in UTF-8).

参考訳:

> パスを出力するコマンドが「普通ではない」文字を出力する際、全体をダブルクォーテーションで囲んだ上でCと同じようにエスケープする (例. `\t`がタブ文字、`\n`がラインフィード、`\\`がバックスラッシュ) 上、0x80よりも大きいバイトもエスケープする (例. UTF-8の「マイクロ」は8進数で `\302\265` とエスケープされる)

ウムラウトつきの「ü」はUnicodeコードポイントでは252、日本語文字は全てが非ASCII範囲内なのでこの変数の影響を受ける。

## 寄り道: core.quotePathはいつからあるのか

さすがに現代に[^2] [^3]このようなオプションを追加しないとは思うので、いつからあるのか調べてみた。

バージョン`1.5.3-rc0`から[入った](https://github.com/git/git/commit/9378c16135100fb65ad575cd35074af166de1cab)ようだ。つまり、現代の`git` (>= 2.0.0) は**すべて**この影響を受ける。

[^2]: シェルスクリプトに埋め込むときに便利とかならまだわかるが、今は2023年なのでシェルスクリプトにもUTF-8対応のぶん別が求められるところだ
[^3]: Unicodeは1993年から存在しているし、UTF-8の前身のFSS-UTFは1992年に存在している

## 終わりに

私達日本語話者からすればほとんど意味不明[^3]だが、当時の彼は必要だと思ったのだろう[^4]。ASCII帝国主義の呪いは根深いと言わざるを得ない。

[^4]: そこまで考慮できなかったのだろう
Linuc 第四回　プロセス

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3293109/022141a1-9d96-7e82-993f-138750d2de20.png)

### systemd　
Linuxの起動処理やシステム管理を行う仕組み
ユニット（Unit）　systemdの処理単位（設定ファイル）
・ユニットの種類
ターゲット:～.target　　　
サービス：～.service　　
ファイルシステムのマウント：～.mount

設定ファイルが一つずつ分かれているため、簡単に変更できる。

##### systemctlコマンド
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3293109/65c3da09-dcb7-7f86-5a2b-e9a0fa9e8583.png)

systemctl get-default   現在のデフォルト設定を調べる
systemctl set-default ターゲット名 　システム起動時のデフォルトターゲットを変更する
systemctl isolate ターゲット名



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3293109/b39f6b47-f698-9edc-2311-e9e06dc5b722.png)
初心者が触れたCentOS firewalld


# firewalldに感謝

CentOS7から使用できるとてもありがたい存在、そしてCentOSサーバー初心者が必ず出会う存在。
簡単に説明するとシステムのセキュリティを強化し、トラフィックの制御を行ってくれます。

## 感謝するまでの経緯

### ssh用portの変更

ssshd_configのPortを弄っても接続できず調べた所が始まりでした。
configの設定だけでは使用を宣言しているだけでfirewalldの設定によって接続が許されていない状態。
なので/etc/firewalld/zones/public.xmlにPortを追加する事で繋がる様になりました。

~~~
<port protocol="tcp" port="[number]"/>
~~~

この時点ではpublicにする事で使用可能になるんだなくらいの印象でした。

### Apacheのインストール、動作確認

インストールと実行に関しては以下のコマンドによって問題なく行われました。
~~~
# sudo yum install httpd
# sudo systemctl start httpd
~~~

正しく機能しているかどうかの確認を行う際にhttpのportを開けようとし

~~~
# sudo firewall-cmd --add-service=http --permanent
# firewall-cmd --reload
~~~

によって開けれたのですが、参考にした記事に気になる文章がありました。

https://qiita.com/miyazawa214/items/88bb5e3a8c8b2c7840a1


「firewalldにzoneが9つあり」
ここまで書かれてしまうとむしろどんな種類があるのか気になってしまい調べてみました。

## firewalldとzone
https://firewalld.org/documentation/concepts.html

iptablesに代わるファイアウォール管理ツール

### firewalld,zoneの利点
:::note info
- ネットワークインタフェース(NIC)ごとにzoneを振り分け、異なるセキュリティレベル、ファイアウォールを柔軟に設定する事ができます。
- 新しいサービスやアプリケーションを追加した際に、再起動なしでファイアウォールのルールを適用可能
- customを用いる事で独自のセキュリティ要件に対応する事もできる。
- 異なる要件に対応する為の切り替えが楽
:::

### zoneの種類

https://firewalld.org/documentation/zone/predefined-zones.html

事前に準備されたzone

:::note info
##### drop
- すべての受信ネットワークパケットは破棄、応答はなし。ただし、出力側からのネットワーク接続は可能。

##### block
- すべての受信ネットワーク接続は拒否、IPv4ではicmp-host-prohibitedメッセージ、IPv6ではicmp6-adm-prohibitedメッセージが返る。このシステム内でのネットワーク接続のみが可能。

##### public
- 公共の場で使用するためのzone。他のネットワーク上のコンピュータが自分のコンピュータを傷つけないと信頼していない。選択された受信接続のみを受け入れる。

##### external
- IPv4のマスカレーディングが有効な外部ネットワークでの使用が目的。特定の受信接続のみを受け入れる。他のネットワーク上のコンピュータが自分のコンピュータを傷つけないと信頼していない。
    - IPマスカレーディング:一つのIPアドレスをLAN内で複数共有する

##### dmz
- デミリタリズドゾーン（DMZ）にある公開可能なコンピュータ向けのzone。内部ネットワークへのアクセスは制限。特定の受信接続のみを受け入れます。
    - DMZ:外部に公開する為の隔離したネットワーク

##### work
- 職場のエリアでの使用を目的。他のネットワーク上のコンピュータが自分のコンピュータを傷つけないと信頼している。特定の受信接続のみを受け入れる。

##### home
- 家庭のエリアでの使用を目的。他のネットワーク上のコンピュータが自分のコンピュータを傷つけないと信頼している。特定の受信接続のみを受け入れる。

##### internal
- 内部ネットワークでの使用を目的。他のネットワーク上のコンピュータが自分のコンピュータを傷つけないと信頼している。特定の受信接続のみを受け入れる。

##### trusted
- すべてのネットワーク接続を受け入れる。
:::

## まとめ
firewalldは初心者にとても優しく理解しやすいと思います。
もっと気になる人は

https://firewalld.org/documentation/concepts.html

を読もう！！！！！
Zscaler環境でPythonが証明書を利用してhttpsのURLへアクセスする方法


# ステップ1: 証明書の取得
Zscaler環境でhttpsのURLにアクセスするためには、Zscalerのルート証明書を取得する必要があります。Zscalerのルート証明書は、Zscalerの公式ウェブサイトからダウンロードすることができます。

# ステップ2: Pythonのリクエストの送信
ステータス：証明書のインポートとプロキシの設定が完了したら、Pythonのリクエストを送信

~~~
import requests
import ssl
import certifi

# 証明書のインポートと検証の有効化
ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH, cafile=certifi.where())
ssl_ctx.load_cert_chain(cert_file)

# プロキシの設定
proxy = {
  'http': 'http://proxy.xxx.com:8000',
  'https': 'http://proxy.xxx.com:8000',
}

# httpsのURLにアクセス
response = requests.get('https://xxx.com', proxies=proxy, verify=ssl_ctx)

# レスポンスの内容を表示
print(response.content)

~~~

Tips:
うまくいけない場合
証明書を変数REQUESTS_CA_BUNDLEに設定すれば、Pythonコード上証明書の指定は不要になります。
linux:
echo "export REQUESTS_CA_BUNDLE=<Path to Certificate>/ca-bundle.pem" >> $HOME/.bashrc
Windows:
[System.Environment]::SetEnvironmentVariable("REQUESTS_CA_BUNDLE", "<Path to Certificate>\ca-bundle.pem", "Machine")


https://help.zscaler.com/zia/adding-custom-certificate-application-specific-trust-store#python
マーケティング戦略を一枚の図にまとめてみた

マーケティング戦略に関する手法を一枚の図にまとめてみました。
細かい説明は調べればたくさん出てくるので割愛。

抜けている箇所や間違いあれば、順次修正していきます。
![marketing_strategy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/250468/817eafb3-f4d1-a9e3-d517-ca6d966857f6.png)

以下、検索用キーワード

* マーケティング戦略の策定プロセス
    * 環境分析
    * 市場細分化
    * ターゲット定義
    * ポジショニング決定
    * マーケティングミックス決定
    * 実行計画策定
* 3C分析
    * Customer(顧客)
    * Competitor(競合)
    * Company(自社)
* PEST分析
    * Politics(政治や法律の環境)
    * Economics(経済環境)
    * Society(社会環境)
    * Technology(技術動向環境)
* RFM分析
    * Recency(最新購買日)
    * Frequency(勾配頻度)
    * Monetary(累計勾配金額)
* セグメンテーション
    * セグメンテーション変数
        * 地理的変数
        * 人口統計的変数
        * 心理的変数
        * 行動的変数
* AIDMA
* イノベータ理論
* ポジショニングマップ
* 4P分析
    * Product(製品)
    * Promotion(広告宣伝)
    * Price(価格)
    * Place(流通)
* 4C分析
    * Customer Value(顧客価値)
    * Communication(コミュニケーション)
    * Customer Cost(顧客コスト)
    * Convernience(利便性)
* FSP
* 価格戦略
Windows Terminalをコンテキストメニューから起動する

## はじめに

WSL2が起動エラーとなり再インストールをしたら、Windows Terminalが右クリックメニューから起動してもカレントディレクトリがその場所にならなくなった。
そしてWindows Terminalを再インストールしたら、メニューがなくなったので復活させる方法をメモ。

こちらのページを参考にしました。→ https://banatech.net/blog/view/29

## レジストリ操作

`regedit`を起動し以下の以下のキーへ移動。

```
HKEY_CURRENT_USER\SOFTWARE\Classes\Directory\shell
```

新規キー「WindowsTerminal」を作成。（キー名は何でも良い）
作成したらその下に「command」キーを作成。

```
HKEY_CURRENT_USER\SOFTWARE\Classes\Directory\shell\WindowsTerminal\command
```

右ペインの「（規定）」をダブルクリックし、データに以下を追加。

```
"C:\Users\{username}\AppData\Local\Microsoft\WindowsApps\wt.exe" "-d" "%V"
```

{username}は実際のパス（アカウント名）にすること。

これでディレクトリを選択して右クリックするとコマンドが追加されている。（この例だと「WindowsTerminal」が追加）

何もないところで右クリックして起動したい場合は、以下のキーへ同様に作成する。

```
HKEY_CURRENT_USER\SOFTWARE\Classes\Directory\Background\shell
```
Bootstrapのボタンで文言を日本語にしたら、文字が縦に並んだ話

# 目的

Bootstrapのボタンで文言を日本語にしようとしたら、文字が縦に並んて縦長のボタンになってしまった...
原因はわからなかったけど、いろいろ考えたので備忘録。
知ってる人がいたら教えてくださいな。


# 環境
* windows 10
* ruby 3.0.4
* rails 6
* Bootstrap 5.0.2


# 問題

https://getbootstrap.jp/docs/5.0/components/navbar/#supported-content

ここにある例を元にヘッダーを作ろうとして、とりあえずコピペした。
最初の検索ボタンは「Search」と書かれていたので、
日本語に直そうという浅はかな気持ちで「検索」としたら、縦になっちゃった。

■ 変更前
```html:
<button class="btn btn-outline-success" type="submit">Search</button>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693325/8e48d5df-d6a7-3a76-ef19-1c0bf29da686.png)


■ 変更後
```html:
<button class="btn btn-outline-success" type="submit">検索</button>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693325/0a9b0929-4ce2-2e54-f02e-a74b2651db01.png)

いやいやいや、そんなわけないじゃん。

# 考えたこと

単純に英語ならどうなるんだろうと思って、
```html:
<button class="btn btn-outline-success" type="submit">aaaaaaaaaa</button>
```
とすると、横に伸びてくれた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693325/62c00f96-82cb-8808-e672-dfe936844a22.png)

# 結論
多分、文字数で判断している。（多分）
日本語の「検索」と、英語の「aa」が同じ `2文字` と判定されるから、
文字の大きい日本語ではボタンが縦になると思った。

scssに `min-width` を指定して、気持ち悪いけど解決。
```scss:scss
.btn {
    min-width: 70px;
 }
```


# 余談
だれか本当のことを教えてくれ―――
PythonのSeleniumについて動作確認


~~~
from selenium import webdriver

chrome = webdriver.Chrome()
chrome.get("https://www.nttdocomo.co.jp/mydocomo/")
~~~

# 初回実行時
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3300735/1a785b70-b7b9-e3dc-17f0-26a2e7c93f59.png)
LINEBOTをHeroku無しで完全無料で構築した話

# はじめに
お久しぶりです。[しなもん](https://qiita.com/CinnamonSea2073)です。
とある思い付きでLINEBotを作成しようと思ったのですが、
**LINEのWebhookがSSLのリンクしか対応しない** とかいうあまりにも個人で作れる設計じゃないので、
その辺を対応していった話をつらつらーと書いていきます。
※LINEBotの作り方については今回解説しません。

結論を先に出すと、**主にGASにたどり着くまでの話**になります。

追記：すでに似たような記事がありましたがまぁ気にしないでおきます。

:::note info
SSLとは？
URLの最初が「https://」から始まるアレです。「http://」に「s」がついたやつです。
~~LINEBOTのためだけに建てるとか最高にめんどくさいからSSLやるという選択肢は無しで~~
:::

# 対処法その1：Herokuを使う
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1927831/c01aabdf-4fa0-85ca-5867-241a2c7cff17.png)

一番最初に思いつくであろう[Heroku](https://dashboard.heroku.com)です。
使える人は使ってると思います。

**しかし私（学生）にとって最もめんどくさい問題があります。**

アプリケーションの作成に**クレジットカードの登録が必須らしい**んです。

別にお金を取られるとか（もあるけど）ではなく、本人確認用です。
**持ってないぞ！！！（迫真）**
というわけで、Herokuは颯爽と諦めました。

:::note info
メリット：
・ネットの情報がとにかく多い
・ある程度無料で使えるっぽい
・Gitと似たシステムでデプロイしやすい
:::
:::note alert
デメリット：
**・クレジットカードの登録が必須**
・アクセス数が多いサービスには向いてない（当たり前）
:::

登録ができる方は、ぜひ使ってみてください。

Heroku：

https://dashboard.heroku.com

# 対処法その2：サーバーを立てる
**正直最高にめんどくさかったです。**

https://github.com/localtunnel/localtunnel/blob/master/README.md

具体的に言うと、localtonnelという**テスト用にSSLのドメインを生成する超便利なやつ**を見つけました。
一応使い方を載せておきます。一瞬で終わります。

まずjavascriptとlocaltonnelをインストールした環境で
```cmd
$ npx localtunnel --port 3000(開けたいポート番号)
```
です。
すると、
```cmd
your url is: https://hogehoge.loca.lt
```
ってurlが出てきます。ｽｺﾞｲ。

しかし大切なのはこれが「テスト用」ということです。
**これ、url固定されません。一時的です。**

まぁでも固定する方法もなくはないですが使えなかったです。
先ほどのコマンドに
```cmd
$ npx localtunnel --port 3000(開けたいポート番号)　--subdomain fugafugafuga
```
こう付け加えれば、（他人とかぶらない限りは）fugafugafugaというurlになるようです。

**私の環境ではこいつは動きませんでした。（クソデカボイス）**

:::note info
メリット：
・似たサービスもあるが、こちらは無料でurl指定できるのが強い
・テスト用にWebhookを送りたい人におすすめ
:::
:::note alert
デメリット：
・ある程度ネットワークの知識が必要
・ポート開放とかめんどい
・javascript分からないと分からない
:::

あと執筆してて気づいたんですが、localtonnelを実行してるウィンドウを閉じなければurl変わりませんね。
でもどっちみちローカルで建てるのは難しいと断念しました。

# 対処法その3：Googleに頼る
インフラ業界、やはり最後に頼れるのはGoogleだった...
ということで、GoogleAppScriptに丸投げしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1927831/0243f206-ad61-3c8c-c9cb-292c8934279c.png)
**隠しすぎだろ！！！**
個人情報だからねしょうがないね。
これの便利な点は、専門知識がいらないことです。
GUI操作で、デフォルトでバージョン管理機能があり、即デプロイできます。
**なんだったんだ今までの苦労は！！！**

Javascript自体初めて書いたのでほぼコピペですが...

:::note info
メリット：
・**無料。** さすがGoogle
・操作がGUIで便利
・Google関連のAPI（カレンダー、エクセルもどきなど）を簡単に呼び出せる
:::
:::note alert
デメリット：
・多分Javascriptしか使えない
・1処理あたり最大30秒という制限がある
:::

# さいごに
なんだかGoogleをほめたたえるだけの記事になってしまいました。
私のように、学生でLINEBOT、特にWebhookを無料で扱いたい人は
GASを使ってみてね。

以上です。
OpenSSLのビルドオプション

# はじめに
Yewを使ってWebアプリ作ってみようと思いました。
けど、wasm-packをインストール中にOpenSSL関連のビルドの段階でエラーが出たんですよ。
ここを見たら一発で解消したけど、なんか気になったから色々脇道に逸れたのは仕方ないですね。

https://qiita.com/t_katsumura/items/526bd21442e3c4bf2f8b

ちなみに以下で解消しました。
`cargo install wasm-pack --no-default-features`

# ビルドオプション
wasm-packに指定されていたOpenSSLのビルドオプションは以下の通りです。

|ビルドオプション|意味|
|---|---|
|VC-WIN64A|Visual C Windows AMD64アーキテクチャビルド|
|no-asm|アセンブラを利用しない|
|no-dso|DSO（Dynamic Shared Object）APIのサポートをしない|
|no-shared|静的ライブラリを作る|
|no-unit-test|Unit testなし|
|no-comp|zlib外で行われる圧縮を無効化する|
|no-zlib|zlibを使わない|
|no-zlib-dynamic|動的なzlibライブラリを使わない|
|no-ssl3|SSL3プロトコルを無効化する|
|no-md2|MD2ハッシュアルゴリズムを無効化する。|
|no-rc5|RC5暗号化アルゴリズムを利用しない。|
|no-weak-ssl-ciphers|RC4暗号化アルゴリズムを利用しない|
|no-camellia|Camellia暗号化アルゴリズムを利用しない|
|no-idea|IDEA(International Data Encryption Algorithm)を利用しない|
|no-seed|SEED暗号化アルゴリズムを利用しない|
|no-engine|Engine（プラグイン）を利用しない|

# おまけ情報
## 推奨されるプロトコルは？
TLS1.3（2023年4月時点において）

## TLS1.2以前だと何がダメなの？
以下の攻撃に対して脆弱です。
### POODLE攻撃
攻撃の前提：MITMできること+リクエストを自由に操作できること（スクリプトインジェクションが可能であるとか、もしくは、CSRFみたいな感じでiframeにひっそりターゲットのサイトにリクエストを何回も飛ばすような小窓を仕込んでおくとか。）
攻撃者にとって、CBCモードのパディングと暗号文は既知ということを利用して1バイトずつ暗号文を復号するMITM攻撃です。
自動化すれば比較的容易にセッションCookie程度なら復号できる、みたいな感じ。
とはいえ、前提でスクリプトインジェクションが必要とか言ってますが、CookieにHttp-Only属性とかない場合そのままXSS攻撃に派生してぶっこ抜けるので、この攻撃って用途が限定的なんですよね。

https://engineering.dena.com/blog/2014/10/poodle/

### BEAST/CRIME攻撃
攻撃の前提：MITMできること+リクエストの一部を自由に操作できること（スクリプトインジェクションが可能であるとか、もしくは、CSRFみたいな感じでiframeにひっそりターゲットのサイトにリクエストを何回も飛ばすような小窓を仕込んでおくとか。fetchとかはCORSポリシで弾かれるので）
圧縮後に暗号化することで、平文を推測できるMITM攻撃です。
これも自動化すれば比較的容易にセッションCookie程度なら復号できる、みたいな（ｒｙ
圧縮って同じ文字（バイト）をまとめるので、Cookieに含まれそうな文字を送ると圧縮されて小さくなります。
一番小さかった文字がCookieと同じ文字使ってるよね、って発想でやる感じですね。
とはいえ、前提でスクリプトインジェクションが必要とか言ってますが、CookieにHttp-Only属性とかない場合そのままXSS攻撃に派生してぶっこ抜けるので、この攻撃って用途が限定的なんですよね。（大事なことなので2回言いました。みたいに成ってる。）

https://www.scutum.jp/information/waf_tech_blog/2012/09/waf-blog-014.html

#### 攻撃者が被害者のリクエストを弄くる方法
1. スクリプトインジェクションな脆弱性がある（俗に言うXSSに派生するやつ）
1. 攻撃者のサイトに誘導してリクエストを強制的に出力する方法（CSRF的な手法）
    - fetch APIとかを使ってGET/POST/HEADのいずれかでリクエストを送出させる（GETでいいかな）
        - レスポンスがCORS制約で処理されないだけで、リクエストは飛んでる
        - プログラム上使用できないだけであって、レスポンスも飛んでくる。
        - 通信を吐ければ良いので通信上にリクレスが流れてれば十分

### 鍵交換方式が脆弱
TLS1.2以前では鍵交換方式は以下の3種類が実装されていました。
1. 静的な秘密鍵を用いた鍵交換(RSA暗号化を用いたハイブリッド暗号方式)
    - 証明書の秘密鍵を使っている。
    - サーバ証明書の秘密鍵が漏れた瞬間に、通信の内容まで全部漏れる。困る
    - Static-RSAみたいに言われることも有ったりする。
2. 静的なDHパラメータを用いたDH鍵交換(Static-DH鍵交換)
    - すべての通信セッションで、ずっと同じDHパラメータを使っているのでヤバい。
    - DHパラメータから共有鍵（秘密鍵）を生成しているのでDHパラメータが同じ=共有鍵も同じ。
    - 共有鍵がどこからか漏れた瞬間に、過去の通信まで全部漏れる。困る
3. 動的なDHパラメータを用いたDH鍵交換(DHE鍵交換)
    - DHEのEはEphemeral（読み：エフェメラル）、一時的なとかそういう意味合いです。
    - 通信セッション毎にDHパラメータを変更します。（=共有鍵がセッションごとに変わります）
    - 最新のセッション（特定の復号対象のセッション）で使っている秘密鍵と暗号文が漏れても過去のデータが漏れないという性質があります。これをPFS（Perfect Forward Security）といいます

この内、1と2が脆弱です。
3はTLS 1.3でも使用されています。


代表的なところだと、こんな感じです。（1.2以前なので、厳密にはHeartbleedとか他にも色々あるけど、一旦スルーさせてほしい。）
※ざっと書いてみましたが、暗号難しい。若干不安なのでツッコミ（編集リクエスト）募集中でございます。

# まとめ
SSL/TLSの脆弱性を踏まないようにサーバの設定を変えるだけでなく、自分でビルド時に「そもそも脆弱な暗号スイートを使わせない」という方法もアリ寄りのアリかなーと。
【Linux】スペースを含む文字列を繰返し処理する

## `read`を使用

以下のように記述するとスペースを含む文字列を行単位で繰り返し処理できます。  
  
```bash:sample.sh
data=$( cat <<-EOF
    ai 12
    ue 34
    oo 55
EOF
)

while read line
do
  echo $line
done < <(echo "$data")
```

```terminal
$ bash sample.sh
ai 12
ue 34
oo 55
```

また以下のようなこともできます。  

```bash:sample.sh
data=$( cat <<-EOF
      ai 12
      ue 34
EOF
)
while read -a line
do
  echo '行全体'
  echo ${line[*]}
  echo '最初の単語'
  echo ${line[0]}
  echo '2番目の単語'
  echo ${line[1]}
done < <(echo "$data")
```

```terminal
$ bash test.sh
--行全体--
ai 12
--最初の単語--
ai
--2番目の単語--
12
--行全体--
ue 34
--最初の単語--
ue
--2番目の単語--
34
```

## `IFS`を変更

以下のように記述してもスペースを含む文字列を行単位で繰り返し処理できます。  

```bash:sample.sh
data=$( cat <<-EOF
      ai 12
      ue 34
      oo 55
EOF
)

IFS_BACKUP=$IFS
IFS=$'\n'
for line in $data
do
  echo $line
done
IFS=$IFS_BACKUP
```

```terminal
$ bash sample.sh
ai 12
ue 34
oo 55
```
文学部卒社会人が大学院で人工知能研究に挑戦〜2日目〜

本日の授業はPython基礎です。

## 本日の講義内容

- Python概要
- 環境設定
- 他言語との違い
- print文
- コメントアウト
- データ型
- if文
- for文

ポイントだと思った部分をかいつまんでご紹介します。
※初学者ゆえ誤った内容を含む部分がある場合もあるのでご了承ください。

### ■データ型
代表的なもの
- int型：整数を表します。
1、10、2023等
- float型：浮動小数点数を表します。
3.14等
- bool型：真偽値を表します。
TrueまたはFalse
- str型：文字列を表します。" "か'　'で囲います。
”こんにちは”、”A”、‘apple’等
- list型：要素を複数持つことができるリストを表します。［］で囲います
[‘apple’, ‘orange’, ‘banana’,‘peach’] 等
- tuple型：要素を複数持つことができるイミュータブル（変更不可）なリストを表します。（）で囲います。
（‘apple’, ‘orange’, ‘banana’,‘peach’）等
- dict型：キーと値のペアを持つ辞書を表します。
※dict型は正直よく理解できてないので要復習です

### ■if文
分岐処理を行うときに利用します

⚫︎if
if 条件:
　　　処理　
※：を忘れないように！　インデントを下げ忘れないように！ 

●if~else
if 条件: 
　　　処理A
else:
　　　処理B

●if~elif〜else
if 条件: 
　　　処理A
elif:
　　　処理B
else:
　　　処理C

```python:
#変数xの値が負の値であれば‘negative’と、そうでなければ‘nonnegative’、0の時は'zero'と表示
x=0

if x < 0 :
  print('negative')
elif x == 0 :
  print('zero')
else:
  print('nonnegative')
```
### for文

●for i in range(数値):
基本形。数値の回数を繰り返すということになります。(0から数値-1の数)iには、実行中の回数を格納しています

```python:
＃11から20までの自然数を、1つずつ、改行しながら表示
for i in range(11,21):
  print(i)
```
●for i in range(数値A,数値B):
数値Aから数値B-1まで繰り返す 

●for i in range(数値A,数値B,-1):
数値Aから数値Bまで逆順で繰り返す

●for i in リスト:
リストの中身を繰り返す

```python:
＃リストの中身を一要素ずつ表示
list = ['apple', 'orange', 'banana','peach'] 
for i in list:
  print(i)
```

## 所感

うーん。3ヶ月間は勉強してたけど忘れてたりちゃんと理解してなくて結構辛い、、、1.5Hの授業もスピーディでなかなかついていけず。
※基本的な姿勢として大学院は職業訓練をするところではなく研究をするところなので、基礎理論や基礎スキルのケアは最小限です。

## 本日の学習内容＆時間
- 予習：15分
- 授業：90分
- 復習：180分
    - Python(本日の授業の範囲)
    - 数学（線形代数）

計：295分（約5時間）

明日は授業はなしだけど、勉強頑張ろう。。。
【Laravel】JOIN句のテーブル名をModelから取得する

はじめまして。もふもふおじさんです。

Laravelのjoin句に指定するテーブルについて、Modelから取得が可能ならばModelで「DB接続先・テーブル名」を一元管理できるじゃん！と思い本記事を執筆することとしました。
結論から申し上げると対応案は思いつきましたが、実際に使うか?と言われたら微妙です。
(コード量が増える + テーブル名直書きの方が直感的で分かりやすい)

以下、参考までに。。


<h1>JOIN句のテーブル名をModelから取得しよう</h1>

今回、元となるjoin句のサンプルコードは下記の通りです。

<pre># サンプルコード
\App\Models\User::join('consumer.user_boookmark', fn($join) => $join
        ->on('user.id', '=', 'user_bookmark.user_id')
    )
    ...
</pre>

上記サンプルをDB接続先指定の有無で対応案を記載します。

<h2>DB接続先を指定しない場合</h2>

例えば、プロジェクトで1つのDBしか取り扱っていない場合、テーブル名のみの指定で問題ありません。
そこで\Illuminate\Database\Eloquent\ModelのgetTable()を用いることでテーブル名を取得することとします。

<pre># 修正後のサンプルコード
\App\Models\User::join((new \App\Models\UserBookmark)->getTable(), fn($join) => $join
        ->on('user.id', '=', 'user_bookmark.user_id')
    )
    ...
</pre>

<h2>DB接続先を指定する場合</h2>

例えば、プロジェクトで複数のDBを取り扱っている場合、デフォルトのDB以外のテーブルを指定する際には接続先を含めたテーブル名を指定する必要があります。(例: consumer.user_bookmark)
そのため、モデルに新たにgetTableWithConnection()を定義し、その中で\Illuminate\Database\Eloquent\Modelの$this->getConnectionName()およびgetTable()を用いることで「DB接続先.テーブル名」を取得することとします。




・\App\Models\UserBookmark
<pre>..
protected $connection = 'consumer';
protected $table = 'user_bookmark';
..
public function getTableWithConnection()
{
  return sprintf('%s.%s', $this->getConnectionName(), $this->getTable());
}
</pre>

<pre># 修正後のサンプルコード
\App\Models\User::join((new \App\Models\UserBookmark)->getTableWithConnection(), fn($join) => $join
        ->on('user.id', '=', 'user_bookmark.user_id')
    )
    ...
</pre>
気合いでGenerambaみたいなことをする

# 経緯
アーキテクチャはVIPER。
手作業でフォルダやそれぞれのファイルを作成していた。(プロジェクトでは1つのモジュールに6ファイル）
Generambaの導入をそれとなく伝えてみたが、通らず…
仕方がないので、それっぽくファイルと定型文の作成をライブラリに頼らず行う。

# やり方
Makefileで指定のパスにファイルの生成。さらに生成したファイルにコメントなどを追加する
```makefile:Makefile
# Makefileのターゲット内に複数行の文字列を持つことが出来ないので、defineを使う
define text
//
//  $(FILE_NAME)
//  プロジェクト名
//
//  Created by 名前 on $(DATE).
//

import Foundation

class $(CLASS_NAME) {}
endef
export text

DATE:=$(shell date "+%Y/%m/%d")

.PHONY: create-module
create-module:
	touch $(PATH)/$(MODULE_NAME)View.swift
	make add-template-text PATH=$(PATH) FILE_NAME=$(MODULE_NAME)View.swift CLASS_NAME=$(MODULE_NAME)View DATE=$(DATE)
	touch $(PATH)/$(MODULE_NAME)Interactor.swift
	make add-template-text PATH=$(PATH) FILE_NAME=$(MODULE_NAME)Interactor.swift CLASS_NAME=$(MODULE_NAME)Interactor DATE=$(DATE)
	touch $(PATH)/$(MODULE_NAME)Presenter.swift
	make add-template-text PATH=$(PATH) FILE_NAME=$(MODULE_NAME)Presenter.swift CLASS_NAME=$(MODULE_NAME)Presenter DATE=$(DATE)
	touch $(PATH)/$(MODULE_NAME)Entity.swift
	make add-template-text PATH=$(PATH) FILE_NAME=$(MODULE_NAME)Entity.swift CLASS_NAME=$(MODULE_NAME)Entity DATE=$(DATE)
	touch $(PATH)/$(MODULE_NAME)Router.swift
	make add-template-text PATH=$(PATH) FILE_NAME=$(MODULE_NAME)Router.swift CLASS_NAME=$(MODULE_NAME)Router DATE=$(DATE)

.PHONY: add-template-text
add-template-text:
	echo "$$(text)" >> $(PATH)/$(FILE_NAME)
```

作成したMakefileを適当な場所（自分ははホームディレクトリ）に置いておく。
Makefileが置いてあるパスで以下のコマンドを実行すれば、ファイルの作成とコメントなどは入っている状態になる
```bash
make create-module PATH=モジュールを作成したいディレクトリ MODULE_NAME=モジュール名
例： make create-module PATH=/Users/ユーザ名/Desktop/Hoge MODULE_NAME=hogeFuga
```
PATHに渡す部分は~を使うとエラーになるのでフルパスで指定する必要がある。
なおかつ、ファイルの生成を行うディレクトリが存在しないとエラーになるため、あらかじめフォルダを作成しておく必要がある。
その他、protocolの宣言など、defineを使えばもっと正確にGenerambaに近づけられることは可能。
1つ1つファイルを生成して、クラス名書いてーみたいなことをしていたのが、多少は楽になったのでヨシッ！とする。

# 参考文献
https://scrapbox.io/snaka/Makefile_%E3%81%A7%E5%A4%89%E6%95%B0%E3%81%AB%E8%A4%87%E6%95%B0%E8%A1%8C%E3%81%AE%E6%96%87%E5%AD%97%E5%88%97%E3%82%92%E6%A0%BC%E7%B4%8D%E3%81%97%E3%81%9F%E3%81%84

https://pod.hatenablog.com/entry/2017/06/13/150342

https://www.gnu.org/software/make/manual/html_node/Multi_002dLine.html
全パターン網羅する方法

プログラムを組むうえで、**全パターン網羅**が必要になることがあります。
（私はpaizaのスキルチェックで必要になりました）
ここでは、全パターン網羅する方法について説明します。

全パターン網羅するには、`itertools`モジュールの`combinations`関数を使います。
まずは list から決められた個数を選んだ時の全パターン網羅について、
具体的なコードを使って説明します。

```Python
# itertools を import
import itertools

test_list = ["a", "b", "c", "d", "e", "f"]
all_pattern = []

# test_list から2個選んだ場合の全パターン検索
for pattern in itertools.combinations(test_list, 2):
    all_pattern.append(pattern)
print("test_list から2個選んだ場合の全パターン数 -> ", len(all_pattern))
print(all_pattern)
print()
all_pattern = []

# test_list から3個選んだ場合の全パターン検索
for pattern in itertools.combinations(test_list, 3):
    all_pattern.append(pattern)
print("test_list から3個選んだ場合の全パターン数 -> ", len(all_pattern))
print(all_pattern)
```

test_list から2個を選んだ場合の全パターン、3個を選んだ場合の全パターンについて
それぞれ個数と、実際のパターンを出力しています。
結果はこちら。

```Python
test_list から2個選んだ場合の全パターン数 ->  15
[('a', 'b'), ('a', 'c'), ('a', 'd'), ('a', 'e'), ('a', 'f'), ('b', 'c'), ('b', 'd'), ('b', 'e'), ('b', 'f'), ('c', 'd'), ('c', 'e'), ('c', 'f'), ('d', 'e'), ('d', 'f'), ('e', 'f')]

test_list から3個選んだ場合の全パターン数 ->  20
[('a', 'b', 'c'), ('a', 'b', 'd'), ('a', 'b', 'e'), ('a', 'b', 'f'), ('a', 'c', 'd'), ('a', 'c', 'e'), ('a', 'c', 'f'), ('a', 'd', 'e'), ('a', 'd', 'f'), ('a', 'e', 'f'), ('b', 'c', 'd'), ('b', 'c', 'e'), ('b', 'c', 'f'), ('b', 'd', 'e'), ('b', 'd', 'f'), ('b', 'e', 'f'), ('c', 'd', 'e'), ('c', 'd', 'f'), ('c', 'e', 'f'), ('d', 'e', 'f')]
```

　

続いて、上記を少し応用し、選ぶ個数も含めて全パターン網羅するにはどうするか？を考えます。
上記の例だと`test_list = ["a", "b", "c", "d", "e", "f"]`の中から、
1個を選んだ場合の全パターン、2個を選んだ場合の全パターン、3個を選んだ場合の全パターン、
・・・、6個を選んだ場合の全パターンの全てを網羅することを考えます。

具体的なコードを使って説明します。

```Python
import itertools

test_list = ["a", "b", "c", "d", "e", "f"]
all_pattern = []

# test_list から選べる全パターン検索
for i in range(1, len(test_list)+1):
    for pattern in itertools.combinations(test_list, i):
        all_pattern.append(pattern)
print("test_list から選べる全パターン数 -> ", len(all_pattern))
print(all_pattern)
```

「list から何個選ぶのか」という部分を、
`for`文で「1～全個数」まで指定することで全パターン検索しています。
結果はこちら。

```Python
test_list から選べる全パターン数 ->  63
[('a',), ('b',), ('c',), ('d',), ('e',), ('f',), ('a', 'b'), ('a', 'c'), ('a', 'd'), ('a', 'e'), ('a', 'f'), ('b', 'c'), ('b', 'd'), ('b', 'e'), ('b', 'f'), ('c', 'd'), ('c', 'e'), ('c', 'f'), ('d', 'e'), ('d', 'f'), ('e', 'f'), ('a', 'b', 'c'), ('a', 'b', 'd'), ('a', 'b', 'e'), ('a', 'b', 'f'), ('a', 'c', 'd'), ('a', 'c', 'e'), ('a', 'c', 'f'), ('a', 'd', 'e'), ('a', 'd', 'f'), ('a', 'e', 'f'), ('b', 'c', 'd'), ('b', 'c', 'e'), ('b', 'c', 'f'), ('b', 'd', 'e'), ('b', 'd', 'f'), ('b', 'e', 'f'), ('c', 'd', 'e'), ('c', 'd', 'f'), ('c', 'e', 'f'), ('d', 'e', 'f'), ('a', 'b', 'c', 'd'), ('a', 'b', 'c', 'e'), ('a', 'b', 'c', 'f'), ('a', 'b', 'd', 'e'), ('a', 'b', 'd', 'f'), ('a', 'b', 'e', 'f'), ('a', 'c', 'd', 'e'), ('a', 'c', 'd', 'f'), ('a', 'c', 'e', 'f'), ('a', 'd', 'e', 'f'), ('b', 'c', 'd', 'e'), ('b', 'c', 'd', 'f'), ('b', 'c', 'e', 'f'), ('b', 'd', 'e', 'f'), ('c', 'd', 'e', 'f'), ('a', 'b', 'c', 'd', 'e'), ('a', 'b', 'c', 'd', 'f'), ('a', 'b', 'c', 'e', 'f'), ('a', 'b', 'd', 'e', 'f'), ('a', 'c', 'd', 'e', 'f'), ('b', 'c', 'd', 'e', 'f'), ('a', 'b', 'c', 'd', 'e', 'f')]
```
【Android】アカウント削除要件についてまとめてみた（2023年4月）

## はじめに
[Giving Users More Transparency and Control Over Account Data](https://android-developers.googleblog.com/2023/04/giving-people-more-control-over-their-data.html) などについて調べたことをまとめます。


### この記事で分かること

- アカウント削除要件について
- 必要になること
- スケジュール



## アカウント削除要件

- アカウント削除はアカウント作成と同じくらい簡単である必要がある
- 関連：[Provide information for Google Play's Data safety section](https://support.google.com/googleplay/android-developer/answer/10787469?hl=en)
    - インストール前にアプリが収集・共有するデータなどをユーザーが把握できるようにする
- メリット
    - ユーザー：個人データの管理が容易になる
    - デベロッパー：信頼できる方法でデータを扱っていることをユーザーに知らせることができる


### 必要になること
1. 全てのデベロッパーはGoogle Play ConsoleのData safety formで**データ削除に関する新しい質問に回答する**
1. アカウントを作成するアプリの場合
    - ユーザーが作成したアカウントと、アカウントに紐づくデータの削除をリクエストするための方法を**２種類**用意する
        - **アプリ内ページ**
        - **ウェブリンク**
    - （ユーザーがアンインストールした場合でもアプリ以外で手続きを行えるようにするため）
    
## 表示される項目
- アプリのストアの掲載情報ページ
    - Data safety section内にデータ削除バッジを表示
- データ管理エリア
    - アカウントの削除
        - ユーザーはリンクをタップ → Webリソースを表示
        - アクティビティ履歴、画像、動画などのデータも削除できるようにする
    - アカウントの整理


## アカウント削除要件のスケジュール

- 2023年4月
    - Data safety formで新しいデータ管理の質問を公開
- 2023年12月7日
    - 全要件の期限（延長可）
- 2024年上旬
    - Google Playに新しいデータ管理機能を表示
- 2024年5月31日
    - 延長期限の最終日
- （ユーザーのリクエストによってアカウントを削除する場合、アカウントに紐づいたデータも必ず削除する）





## 参考資料

https://android-developers.googleblog.com/2023/04/giving-people-more-control-over-their-data.html

https://support.google.com/googleplay/android-developer/answer/13327111?hl=en

https://youtu.be/4N_cmJkRwR0




## おわりに
ここまで読んでいただき、ありがとうございました！何かありましたら、コメントをお願いいたします
gemそしてbundlerとは何か?

# はじめに
Railsチュートリアルを実践して`gem`に関してはある程度意味合いは理解したが、`bundler`の必要性がわからなかったので、まとめてみました。

# `gem`とは
Rubyのパッケージ管理システム、正式にはRubyGemsと言う
`gem`というパッケージを利用し複雑な機能の実装を簡単に行うことが可能になる


## `bundler`とは
`gem`の依存関係とバージョンを管理するためのツール

### 役割
> Bundler makes sure Ruby applications run the same code on every machine.
>(日本語訳: Bundlerは、Rubyアプリケーションをどのマシンでも同じコードで実行できるようにします。)
>([GitHub: rubygems/bundler](https://github.com/rubygems/bundler 'budler')より)

つまり`bundler`があることで複数人開発、チーム開発が容易になる

### `bundler`を使わないとどうなるのか
例えば`gem install bootstrap-sass`と実行したとする。(2023/4/12現在だと3.4.1が最新)

|Aさんの依存Gem環境  |Bさんの依存Gem環境  |
|---|---|
|autoprefixer-rails(5.2.1)  |autoprefixer-rails(5.3.5)   |
|sassc(2.2.1)  |sassc(2.4.1)  |

チーム開発だと必ずしも依存gemのバージョンが全員一致しているとは限らないので、上の表の様に依存しているgemのバージョンが違い、Aさんは動くけどBさんは動かないみたいな状況が起きてしまう

### `bundler`を使うとどうなるのか
`bundle install パッケージ名`で以下のように`gem`がインストールされる

```mermaid
graph TD;
    rubygem.org-->bundler;
    bundler-->R[ruby 3.2.1];
    R[ruby 3.2.1]-->A[gem A];
    R[ruby 3.2.1]-->B[gem B];
    A[gem A]-->a1[依存gem A];
    A[gem A]-->a2[依存gem A];
    A[gem A]-->a3[依存gem A];
    B[gem B]-->b1[依存gem B];
    B[gem B]-->b2[依存gem B];
   B[gem B]-->b3[依存gem B];
```
インストールした`gem`とその`gem`に依存する`gem`も、`bundler`を経由して結びつけることによって、アプリを利用する全ての人が依存する`gem`も含めて同じ環境でアプリを動作させることが可能になる。



# 参考記事
[Rubyのgemとは？概要から使い方までの解説まとめ](https://techplay.jp/column/529 'Gem')
[【Ruby】 gemの仕組みを図解形式で学ぼう](https://pikawaka.com/ruby/how-gem-works 'Gem')
[【Ruby入門】今更聞けない！Ruby bundlerとは](https://www.sejuku.net/blog/19426 'Gem')
[【Rails】 結局bundlerって何？bundlerの仕組みを図解形式で徹底解説](https://pikawaka.com/rails/bundler 'bundler')
playwright-core で Codegen（PC にインストール済みのブラウザを利用 ＋ 結果を年月日などがついたファイル名で書き出す等）

## はじめに
この記事の内容は、タイトル通りです。

`npm install playwright-core` でインストールした「[playwright-core](https://www.npmjs.com/package/playwright-core)」で「[Codegen](https://playwright.dev/docs/codegen#running-codegen)」を使います。それと、そこで生成されたコードをユニークなファイル名で保存できるように、ファイル名に年月日などがついたファイル名を出力先に指定した書き出しを行います。

そのようなことを試した際の、メモ的な記事です。

### この内容を試したきっかけ
今回の内容を試したきっかけは、以下の 2つの内容です。

#### playwright-core でインストール済みのブラウザを利用
1つは、playwright-core を使う際に、PCにインストール済みのブラウザをシンプルな記述をして利用するというものです。

●playwright-coreと、PCにインストール済みのChromeやEdgeを使って自動操作する
　https://zenn.dev/yusukeiwaki/articles/90bf05c2cf9a90

上記は JavaScript のプログラムで playwright-core を使うものですが、そこで `launch({channel: 'chrome', headless: false})` といったように、 `channel: '【ブラウザを示す文字列】'` というシンプルな指定をして、PC にインストール済みのブラウザを利用しています。

#### Playwright で Codegen を利用するコマンド
上記の PC にインストール済みのブラウザを利用する記載をキーワードに検索をしていて、 Playwright と [Codegen](https://playwright.dev/docs/codegen#running-codegen) を組み合わせたコマンドで使われた事例が出てきました。

●PlaywrightでChromeを使って操作をレコード(codegen)してみた - 絶壁侍の日記
　https://zeppekisamurai.hatenablog.com/entry/2022/02/07/Playwright%E3%81%A7Chrome%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E6%93%8D%E4%BD%9C%E3%82%92%E3%83%AC%E3%82%B3%E3%83%BC%E3%83%89%28codegen%29%E3%81%97%E3%81%A6%E3%81%BF%E3%81%9F

上記の記事では、以下のコマンドで Codegen を使っていました。

```bash
playwright codegen --channel 【ブラウザを示す文字列】 【URL】
```

これらを見て、「playwright-core で同様のことができるか試してみよう」と思ったのが最初のお試しの流れです。

## 今回のメインの内容
### 1） playwright-core で Codegen（PC にインストール済みのブラウザを利用）

結果から書くと、PC にインストール済みのブラウザを利用する形で playwright-core と codegen を使うには、以下のコマンドで OK です。

```bash
npx playwright-core codegen --channel chrome 【URL】
```

playwright-core をローカルインストールするため、コマンドに npx をつけています。

### Codegen の結果を年月日などがついたファイル名で書き出す
その後、Codegen のオプションなどを見ていて、以下のように外部ファイルへの内容の書き出しができるものを見ました。

```bash
npx playwright-core codegen --channel chrome 【URL】 -o 【ファイル名と出力先のパス】
```

このファイル名指定に関して、「実行ごとにユニークなファイル名にできたら良さそうかも？」というのがあり、それをさらに試しました。

最終的に、以下のコマンドを実行して、想定通りの結果を得ることができました。
（以下は Mac で実行していて、そして結果の出力先は、コマンドを実行したフォルダ直下の「codegen」としています）

```bash
npx playwright-core codegen --channel chrome 【URL】 -o ./codegen/code`date +%Y%m%d%H%M%S`.js
```

#### ファイル名指定の部分に関して参照した記事

- [日時をファイル名に付けるには](https://atmarkit.itmedia.co.jp/flinux/rensai/linuxtips/240datefilename.html)
- [date コマンド | コマンドの使い方(Linux) | hydroculのメモ](https://hydrocul.github.io/wiki/commands/date.html)

## おまけ（？）
JavaScript のプログラムで page.pause() を入れると、そこで Codegen を実行する使い方もできるというのを見かけて、それも playwright-core でやってみました。

```javascript
const playwright = require("playwright-core");

(async () => {
  const browser = await playwright.chromium.launch({ channel: "chrome", headless: false });
  const page = await browser.newPage();
  await page.goto("【URL】");

  await page.pause();
})();
```

あとは、以下の Inspector が立ち上がっているので、そこで「Record」を押せば記録を開始できます。
![手動操作で Codegen](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/30bad2f2-8f20-c6d9-36eb-5a85fb78ee51.png)

### おまけの部分の参考記事

- [Playwrightの使い方メモ - 新しいことにはウェルカム](https://www.kwbtblog.com/entry/2023/02/10/091552)
- [これだけはおさえておきたいPlaywrightコマンド集 - Qiita](https://qiita.com/oh_rusty_nail/items/d955e3273994214a0afa)
PHP ディレクトリを作成する

# 概要

- PHPにてディレクトリを作成する方法をまとめる。

# 方法

- PHPにてディレクトリを作成するには`mkdir()`を使う。

    ```php
    mkdir('作成するディレクトリのパス');
    ```

- ディレクトリの作成に成功するとtureが、失敗するとfalseが返される。
- 何も設定しないと0777のディレクトリを作成するが、第二引数で指定することも可能である。

    ```php
    mkdir('作成するディレクトリのパス', 0644);
    ```

# 参考文献

https://www.php.net/manual/ja/function.mkdir.php
UdonSharp ハローワールド バグなしRTA Any% およそ約3時間くらい

# 背景
## 動機
UdonSharpのことが何も分からないし、そもそもUnityも全然なので凄い勢いで触る。
動くものを作る（HelloWorldする）までは結果が目に見えなくてモチベーションが上がらない。しかし、一度HellowWorldができてしまえば、自分が変更したところが反映されていく様子を楽しむことができる。

ということで手始めにWorldを作って、UdonSharpで何らかの仕組みを記述する。
- 些末なTipsが多くなるかもしれない
    - Unityからして全然わかってないので備忘録を兼ねる
- 環境依存な話が多くなるかもしれない
    - OS,Unity,VRChat,UdonSharpという色々なモノを扱うので

## VRChatの仕組み
VRCはUnity上で動く。
VRCのワールド（空間）等はUnityで製作する。
ただし、VRCにおいてUnityの全機能を使える訳ではないらしい。
SDKやUdonで記述できる範囲で開発する。

# インストール
windows10で以下のものを入れた
- Unity Hub
    - Editorは `2019.4.31` 
        - 注：`.exeのパス`を控えとく
- VRC Creator Companion `2.0.3` 
    - (インストーラにしかバージョン書いてない)
    - SDKとUdon類をプロジェクトに適用してくれるっぽい
- VRCそのもの `2023/03/27最新`
    - steam経由（関係ないはず）
    - `C(かDドライブ)：SteamLibrary\steamapps\common\VRChat\VRChat.exe`とかに存在する


下記手順でプロジェクト編集にこぎつける。
1. Creator Companion にUnityEditorを指定する（控えておいた`.exeのパス`）
2. Creator Companion でプロジェクトを作る
3. （多分おま環）Creator Companionでプロジェクトを開けなかったがUnityから開くといけた

Creator Companionによってデフォルトで下記が適用された。
- VRChat SDK - Worlds  `3.1.11`
- VRChat Package Resolver Tool  `0.1.17`
- VRChat SDK - Base  `3.1.11`
- UdonSharp  `1.1.7`
- VRChat Client Simulator  `1.2.2`

# 最低限のワールドを作る
## 最低限を揃える
- vrcworld.prefabを用意する（左側のpaneにドラッグ&ドロップする）
    - [vrcworld.prefabが無いよ！](https://wikiwiki.jp/vrc_toshiaki/vrcworld.prefab%E3%81%8C%E7%84%A1%E3%81%84%E3%82%88%EF%BC%81) -> 検索範囲をallにしたら見つかる

- 地面（plane）を配置する
    - 重力があるので

## 一旦ローカルテスト
- パネルを開く
`上部タブ > VRChat SDK > Show Control Panel`

- VRChatアカウントでログイン
`Auth...`

- VRCクライアント指定
`Settings > VRChat Client > Edit > なんやかんや\VRChat.exe`

- ローカルテスト（Force Non-VRにチェック）
`Builder > Local Testing > Build & Test`

- 地面を歩けることを確認

# Udonに触る
- asset作る
`Assetで右クリック > Create > VRChat > Udon > Udon C# Program Asset`

- 紐付くC#ファイルを作る
`Inspector > create script`

```csharp
using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;

public class UdontryAsset : UdonSharpBehaviour
{
    public override void Interact() {
        GetComponent<Transform>().Rotate(10f, 0, 10f);
    }
}
```

- Cubeを作って`Add Component`でさっき作ったふるまいを追加

- ローカルテスト
    - 豆腐をクリックすると回転することを確認

- シーンとして保存する
- （アップロードしたければする（ある程度VRChatを遊ばないとできない））

# 感想
ここまでで大体**3時間くらい**だった。思ったよりも簡単（深入りしなければ...）。
- UnityとVRChatは走る前から入っていた
- VRC Creator Companionとかをインストールしてプロジェクトを作るまでに約2時間
    - この合間にUdonSharpのこととかを調べていた
- 「どんなことやろう」「何ができるんだ」に約30分
- 地面を作ってローカルテストに約30分
- 豆腐を回すのに約3分

色々なもののバージョンを合わせるのがしんどそうだった。ここら辺を解決しようとしているのが「VRC Creator Companion」らしい。うまく働かないケースもあるらしいが、開発も継続しているらしい。

# 参考にさせていただいた記事
ワールド作成部分
https://note.com/npaka/n/nfcfcdfdd2739
https://unitystudygo.com/2021/01/01/vrchat%E3%83%AF%E3%83%BC%E3%83%AB%E3%83%89%E3%82%92%E4%BD%9C%E3%82%8B1%E5%9F%BA%E7%A4%8E%E7%B7%A8/

Udon部分
https://qiita.com/vrc_sour/items/21c31533b4ddd3ba910f#udon-behavior%E3%81%AE%E3%83%86%E3%82%B9%E3%83%88
https://qiita.com/Milcia/items/242b240816a03fc9928e#uscript%E3%82%92%E4%BD%9C%E3%82%8B

オブジェクトを回す部分
https://qiita.com/uroshinse/items/87b84b5133ec7307e104

Renderer.materialのメモリリークについて（結果的には関係なかった）
https://light11.hatenadiary.com/entry/2019/11/03/223241
Renderer.material
https://kan-kikuchi.hatenablog.com/entry/Material
Webpackで作ったライブラリーで○○is not constructorエラーが出る原因と解決方法

この記事では、Webpackで作ったライブラリーを使おうとしたときに、○○is not constructorというエラーが出る原因と解決方法について説明します。

このエラーは、Webpackのビルド設定におけるoutput.library.typeの値に関係しています。output.library.typeとは何か、どう指定すればいいのか、そして指定しないとどうなるのかについて詳しく解説します。

## output.library.typeとは

output.library.typeとは、Webpackのビルド設定でoutputオブジェクトの中にあるプロパティの1つです。

このプロパティは、ライブラリーがどのような形式で出力されるかを制御するものです。たとえば、ライブラリーをCommonJS形式で出力したい場合は、output.library.typeに``commonjs``を指定します。以下は、webpack.config.jsファイルの一部です。

```js
module.exports = {
  // 省略
  output: {
    // 省略
    library: {
        name: "ライブラリーの名前",
        type: "commonjs"
    }
  },
  // 省略
};
```

output.library.typeには、他にもさまざまな値があります。詳しくは[公式ドキュメント](https://webpack.js.org/configuration/output/#type-var)を参照してください。

なお、output.libraryTargetでも同様に設定できますが、こちらはすでに[非推奨](https://webpack.js.org/configuration/output/#outputlibrarytarget)になっているためoutput.library.typeを使用しましょう。

## エラーが出る原因

では、なぜoutput.library.typeを指定しないとエラーが出るのでしょうか。

それは、Webpackがデフォルトではライブラリーとしての使用を意図していないコードを出力するためです。変数名がminify化されてしまったり、コードが即時実行関数に囲まれてしまったりします。

そのため、ただ読み込むだけで動作するライブラリーなら問題ありませんが、外部のコードからライブラリーの関数やクラスを呼び出したい場合には、エラーが発生します。

## 解決策

解決策は単純です。output.library.typeを指定しましょう。私の場合はブラウザーとNode.jsの両方に対応させたかったので``umd``を指定しました。

## まとめ

この記事では、Webpackで作ったライブラリーで○○is not constructorエラーが出る原因と解決方法について解説しました。もちろん、今回解説したoutput.library.typeだけが原因とは限りませんが、私の場合はこれで解決したので記事にしました。皆さんのお役に立てれば幸いです。
[Ruby] RubyでAtCoder に参加するためのVSCode設定 [AtCoder]

# はじめに
RubyでAtCoderに参加するためにVSCodeのローカル環境を構築しました。
試しに[ABC294A](https://atcoder.jp/contests/abc294)をサンプルにしています。

## フォルダ構成
フォルダ構成は次の通りです。
>./answer.rb # コードを書くところ
>./input.txt.   # デバッグ時の標準入力

例えば、ABC294Aのサンプルだと次のようになります。

answer.rb
```ruby
N = gets
s = gets.chomp.split(" ").map(&:to_i)

even = []
s.each { |val| even.push(val) if val % 2 == 0 }

puts even.join(" ")
```

input.txt
```txt
10
22 3 17 8 30 15 12 14 11 17
``` 

次のコマンドでお試し実行できます。
```shell
ruby answer.rb < input.txt
```
しかし、やはりデバッグがしたいです。

# VSCodeの設定
VS Codeでデバッグするための方法を調べました。

## Extension
デバッグするためにこちらのExtensionを追加しました。
[VSCode rdbg Ruby Debugger](https://marketplace.visualstudio.com/items?itemName=KoichiSasada.vscode-rdbg)


## Gemfile
gemfileです。
```
source "https://rubygems.org"
gem "debug"
```

## launch.json
続いて、launch.json
```json
{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "rdbg",
            "name": "Debug current file with rdbg",
            "request": "launch",
            "script": "${workspaceFolder}/answer.rb",
            "args": [
                "<",
                "${workspaceFolder}/input.txt"
            ],
            "askParameters": false,
            "useTerminal": true
        }
    ]
}
```

ここで、大切なのは２箇所です。
１つ目はargsで先ほどのコマンド同様にinput.txt を入力にしています。
２つ目はuseTerminalです。なぜか、このコマンドがないと標準入力としてファイルを受け取ることができませんでした。

これで、BreakPointを設定してF5で実行すれば、デバッグできました。


# さいごに
あとは、answer.rbで書いたコードをAtCoderにコピペすればACです。　

誰かの役に立てれば幸いです。
decoratorとhelperの違い


今日はdecoratorとhelperの違いって何だろうと思ったので調べてみました。

例えば、下のようなコードを書く場合
・他の箇所でも使うとビューが汚くなる（可読性が落ちる）
・コードを変更したいときに変更しづらい

```
<%= "#{@user.first_name} #{@user.last_name}" %>
```

などのデメリットが出てきます。


そこで下記のようなメソッドに分けるわけですが、
```
  def full_name
  end
```

「これはどこに定義するべきなのか？」という疑問が出てきます。

基本的にはmodelに定義で良いのですが、規模が大きくなると
それはそれで可読性が落ちたり、保守が大変になります。

そんな時にhelperとdecoratorを使っていきます。

しかし、これらはどう使い分けるのか？

結論
__モデルに依存するかしないかで判断する__

* helper　モデルに依存しない
モデルにアクセスする際に定数が必要
```
module ApplicationHelper
  def full_name(model)
    model.first_name + model.last_name
  end
end
```
* decorator　モデルに依存する
* gemの'draper'をインストールする必要がある。
モデルにアクセスする際に定数は必要ない

decoratorを使用する場合は、記述の通りgemをインストールして、
```
$rails g decorator User
# user_decorater.rbを作成
```

すると、以下のファイルが作成されます。
（そういえば、以前decoratorのテストの書き方がいまいち分からずに苦戦した記憶が、、、）
```
      invoke     decorator
      create     app/decorators/user_decorator.rb
      invoke     test_unit
      create     test/decorators/user_decorator_test.rb
```

```
class UserDecorator < Draper::Decorator
 delegate_all
 def full_name
   "#{object.last_name} #{object.first_name}"
 end
end
```
ビューでの呼び出し方は以下の通り
```
<%= @user.decorate.full_name %>
```

毎回、decorateと書くのは面倒なので、以下のようにコントローラーに書くのもありかと。
```users_controller.rb
@user = User.first.decorate
```


# まとめ
まずはモデルにメソッドを定義することを検討する

ただ、肥大化して可読性が落ちそうな場合は、helperやdecoratorに切り分けることを検討する

* モデルに依存しないときはhelper
* モデルに依存するときはdecorator

この辺りを押さえながら書けば良さそうですね。
MacBookのiTerm2でPageUp/PageDownがうまく入力できない問題

![スクリーンショット 2023-04-12 午後10.23.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131146/5ccd551b-a59b-db1e-12d4-092c8f9a21cc.png)

上記の「Page up, page down, ...」のところにチェックマークを入れれば解決。
.envファイルの変数を参照できない

## 背景
Udemyで勉強していたら、.envライブラリが上手く動かなかったので共有。

https://www.udemy.com/course/nodejs-comp-guide/

## 本題
ディレクトリ図

07_mongodb

├── 010_connect_find/ start/ Example.mjs

├── node_modules

├── .env

└── package.json



```Example.mjs
import env from 'dotenv';
env.config();
// console.log(env.config())
import { MongoClient } from 'mongodb';
const client = new MongoClient(process.env.MONGO_URI);

async function getCollection() {
    try {
        await client.connect();
        console.log("接続完了")
        const db = client.db('bookshelf');
        return db.collection('books');
    } catch (e) {
        console.log(e)
        await client.close();
    }
}

async function getAllBooks() {
    const col = await getCollection();
    const cursor = col.find();
    const result = await cursor.toArray();
    console.log(result);

    await client.close();
}

getAllBooks();
```

env.config();でenvファイルの変数(process.env.MONGO_URI)を使えるようになっているはず、、

がエラー。

![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2082391/1ec614cc-eab6-dca2-c226-6c9ed5b0325f.png)


[Cannot read properties of undefined]を調べると、.envファイルの変数を呼び出せていないことが分かった。

[https://qiita.com/whiteraccoon/items/34e593dbe305e37ac6e4](https://qiita.com/whiteraccoon/items/34e593dbe305e37ac6e4)

ので、console.log(env.config())で調べる。

すると

![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2082391/d1e7c903-4e7a-00b8-9140-558689afc448.png)



startディレクトリ下に.envファイルがないよーとのこと

だって、07_mongodbディレクトリ下にあるんだもの、、、

### error理由

dotenvライブラリはnodeを実行したディレクトリ下で.envファイルを探す。

今回だとstartディレクトリ下でExample.mjsファイルを実行した場合、startディレクトリ下の.envファイルを探そうとする。

なので、07_mongodbディレクトリ下でnodeを実行したらOK。
老兵の手引き書　１

# しぇいしぇいの仕事方法　小出し
:::note info
本記事では僕の仕事に対しての取り組み方を小出しでお披露目します。ぺこり
:::
# 格言
:::note info
仕事とは日々勉強あるのみ
:::
# 僕のやり方
　覚える時は只管書くべし！描くべし！書くべし！
　ということで、手を使って色々書いていきます。とはいえ、紙のノートとかは情報漏洩のリスクもあるので使いたくない。
　そんな僕の使っているツールはEvernoteの[Penultimate](https://evernote.com/intl/jp/products/penultimate)です。iPadを使ってメモをとっていきます。
　そしてPCの方と同期させて、PCからPDF出力！
　と行きたいところですが、PDF出力何やら様子がおかしい。
　１２ページ書いたのに、３ページしかPDFに出てこない。~~バグかな？~~
　そこで僕は、HTMLへ出力し、HTMLをブラウザで開いた後に印刷し、PDFに書き出しすることにしています。
　
# 相方の意見
![スクリーンショット 2023-04-12 22.08.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3322151/aa361941-6b07-2f39-fcef-41d106db7a72.png)
　君もそう思うようで何より！
　理にかなっているみたいですね。皆さんはどのような勉強方法を取られていますか:relaxed:
Fundamentals of Data Engineering (English Edition) 輪読会資料第2回分 2023/4/17開催

## 本記事の位置づけ
下記書籍を用いた輪読会の資料として作成しています。
https://amzn.asia/d/bC6DhKi

今回の対象範囲は、下記のとおりです。
I.Foundation and Building Blocks > 3.Designing Good Data Architecture >
Major Architecture Concepts > Tight Versus Loose Coupling:Tiers, Monoliths, and Microservices 

## 概要
- Monolith = tightly coupled, Microservices = loose coupled
- Microservicesがおすすめだけど、Monolithの方がプロトタイプ作るのは向いている。

## 本編
### Data architectureの種類
- tightly coupled：相互に依存している "centralized,中央集権化されている"
- loose coupling：お互いに強く依存していない"decentralized,中央集権化されていない"
    - common standards, ownership, 責任、説明可能性を設定(assign)することが大切。

### Architecture tiers
Architectureとはデータ、アプリケーションなどの層のこと。理解することが大切。
- Single tier : データベースとアプリが強く結合されている(tightly coupled)
    - databaseなどが落ちればすべてが落ちる。
    - プロトタイプには向いているが、本番環境には向いていない。
- Multitier : n-tierともいう
    - 層が独立している。
    - lower layerはupper layerに依存しないが、upper layerはbottom layerに依存する。 
    - e.g. three-tier-architecture
    - リソースの競合がなくなる。
    - shared-nothing architecture : 一つ一つのリクエストを一つのnodeが担当。リソースを共有しない。
    - shared disk architecture :同じdisk,メモリに全てのnodeがアクセスする。
    
### Monolith
- 一つのcodebase,一つのマシンでアプリとUIを提供する
    - Technical coupling : Architecture tiersを指す
    - Domain coupling :　ドメインの結合方法を指す
- tight couplingはモジュール化の不足を伴う。コンポーネントの再利用が難しいor不可能になる。
- データチームは複雑化するMonolithを解決することを無視し、大きな泥の塊（big ball of mud）してしまう。
- chap4でmonotlith/distributed technologiesの議論をする。またdistribuetd monolithもある
- (感想)Monolith = tightly coupled. distribuetd monolithは両刀使い？

### Microservices
- Monolithの反対
- Microservicesは、分かれていて、一元化されておらず、loosely coupledである。
- それぞれのサービスは特定のfunctionがあり、それぞれ結合していない。
- Monolithを分解できない場合は、並行してmicroservices-friendly のarchitectureを作り始めましょう。
- Monolithを分解する場合は、ステークホルダーからも賛同を得ましょう。

### Considerations for data architecture
- 理想としては、現実に合う（pragmatically）loose couplingを使いましょう。ただし限界などを認識しましょう。
- モジュール化、loose couplingするようなreversible technologyも選択しましょう。
- Single vs Multitiered : domainをどうやってarchitectureから分けるか検討しましょう。
    - centralization : 一つにすべてのドメインのデータを集約
    - data mesh: それぞれのソフトウェアチームがデータの準備に責任がある。
- Monolithは必ずしも悪いわけではない。早く実装したいならMonotlithの方が簡単だが、次第に分けていくことも踏まえておいてね。


## 英語で困ったこと
英訳で困った
- keeping them agnostic of data　(kindle P159周辺)
　- "データに関係なく"
　- Schema on write, Schema on read
- Monolith 一枚岩？
- ";"の役割 e.g.Monolithの1文目

技術面で困った
- Figure3-5下、build in redundancy(冗長性)とは具体的にどのような状況？またその後"For instance~"の例もあまりイメージ的なかった
- function, domain, tier, layerのそれぞれの違いは？（domainの例として、sales,inventoryと記載がある）
    - tierとlayerは同じでは。DatabaseやFunctionの単位のこと。
[AWS Q&A 365][Secret Manager]AWSのよくある問題の毎日5選 #27

# 1. AWS Secrets Managerとは何ですか？
AWS Secrets Managerは、データベースの資格情報、APIキー、その他の機密情報など、秘密情報を格納および取得するためのAmazon Web Servicesが提供するサービスです。ユーザーは、独自のキーを使用して自分の秘密を暗号化し、AWS Identity and Access Management（IAM）を使用して秘密へのアクセスを管理できます。

# 2. AWS Secrets Managerの機能は何ですか？
AWS Secrets Managerは、プログラムで暗号化された秘密の値を実行時に取得したり、さまざまな種類の秘密を格納したり、秘密データを暗号化したり、自動的に秘密をローテーションしたり、秘密へのアクセスを制御したり、規格に準拠することができます。また、ユーザーフレンドリーなコンソール、コマンドラインツール、AWS SDKなども提供されており、使いやすくなっています。

# 3. AWS Secrets Managerで秘密へのアクセスをどのように制御できますか？
ユーザーは、AWS Identity and Access Management（IAM）を使用してAWS Secrets Managerの秘密へのアクセスを制御できます。ユーザーのID、時刻、IPアドレスなどの特定の基準に基づいてアクセスを許可または拒否するIAMポリシーを作成できます。また、タグを使用して秘密へのアクセスを制御することもできます。

# 4. AWS Secrets Managerはどのように規格に準拠していますか？
AWS Secrets Managerは、HIPAA、PCI DSS、SOCなどの業界規格に準拠しています。秘密を休止中および転送中に保護するために暗号化を使用し、秘密へのアクセスを追跡するための監査トレイルを提供します。また、クレデンシャルの頻繁なローテーションを要求する規格に準拠するために、自動的な秘密のローテーションを設定することができます。

# 5. AWS Secrets Managerで秘密を作成する方法は何ですか？
ユーザーは、コンソール、コマンドラインツール、またはAWS SDKを使用してAWS Secrets Managerで秘密を作成できます。秘密の名前、説明、値を指定し、暗号化キーとローテーションスケジュールを選択することができます。さらに、タグを追加して組織を改善し、IAMポリシーを使用して秘密へのアクセスを制御することもできます。