OmniAICreator/Qiita-1.07M huggingface dataset:
Python入門 文字列の取り扱い

## 概要
初学者向けにPythonの基本的な内容をまとめて寄稿します。今回は、文字列の取り扱いについてまとめました。
※あまりに自明すぎる基礎知識は省いている場合が御座います。

## 文字列の取り扱い

### 文字列を表現する方法
文字列を表現する為には**シングルクォーテーションまたはダブルクォーテーションで囲む**事で行えます。

### エスケープシーケンス
エスケープシーケンスとは**バックスラッシュと特定の文字を組み合わせる事で表現された特殊な文字列**(具体的に何を表現出来るかは以下参照)。

**改行:`\n`**
**タブ:`\t`**
**文字列の中でも'と"を使う:`\'(\")`**

### 対話型インタープリタでの出力結果
対話型インタープリタで文字列を出力すると**引用符に囲まれた状態で出力されます**。
また特殊文字は**エスケープされた状態で出力されます**。

### print関数
print関数は**文字列や数値を画面に出力**します。

```python:例
print('hogemaru\nhogesuke')
>>hogemaru
>>hogesuke
```

### raw文字列
raw文字列は**特殊文字として解釈してほしくない場合に使用**します。

```python:例
print(r'名前は\"hogeking\"です。')
>>名前は\"hogeking\"です。
```
### トリプルクォーテーション
**複数行にわたって文字列を記述する際はトリプルクォーテーション(""" """または''' ''')を使用**します。
```python:例
print("""
こんにちは。
私はhogeです。
仲良くして下さい。
""")
>>こんにちは。私はhogeです。仲良くして下さい。
```

### 文字列の連結
文字列の連結は<b>加算演算子(+)</b>を用いて行います。
```python:例
print('hoge' + 'hoge')
>>hogehoge
```

### 文字列を繰り返す
文字列を<b>"文字列" * 回数</b>で繰り返す事が出来ます。
```python:例
print('hoge' * 3)
>>hogehogehoge
```

### 文字列のインデックス指定
インデックス指定を行う事で**文字列の中の文字を取得**する事が出来ます。
```python:例
str1 = "hoge"
print(str1[0])
>>h
```

右から数える場合は**マイナスの値で指定**します。
```python:例
str1 = "hoge"
print(str1[-1])
>>e
```

インデックス指定したものを連結する事も出来ます。
```python:例
str1 = "hoge"
print(str1[0] + str1[1])
>>ho
```

範囲外を指定した場合は**IndexError**になります。
```python:例
str1 = "hoge"
print(str1[4])
>>IndexError: string index out of range
```

### スライス
スライスを用いる事で**部分文字列を習得する事が出来ます**。
```python:例
str1 = "hoge"
print(str1[0:2])
>>ho
```

またスライスは以下のように省略も出来ます。
省略の場合は
```python:例
str1 = "hoge"
print(str1[:2])
>>ho

print(str1[2:])
>>ge

print(str1[:])
>>hoge
```

そしてこちらもスライスしたもの同士で連結するが可能です。

一つ注意点としてスライスで範囲外のインデックスを指定した場合**エラーにならない**のは注意しなくてはいけない点です。
```python:例
str1 = "hoge"
print(str1[4:5])
>>on
```

### 文字列は改変出来ない
文字列はstr型ですので**イミュータブルな型**の一つな為、改変出来ません。
イミュータブルとは**変更できないオブジェクト**の事です。
```python:例
str1 = "hoge"
str1[0] = 'a'
>>TypeError: 'str' object does not support item assignment
```

### ビルトイン関数
ビルトイン関数とは**最初から組み込まれている関数**の事です。
例として
- len関数
- print関数
- type関数
などがあります。

まだ紹介してないlen関数とtype関数について補足説明致します。
len関数は**オブジェクトのサイズを取得する関数**。
type関数は**オブジェクトのデータ型を取得する関数**。

例は以下の様になります。
```python:例
str1 = "hoge"
print(len(str1))
>>4

print(type(str1))
>><class 'str'>
```
laravel.logをclearにする方法

# はじめに
Laravelでlogger()などでデバックを行っていたところ、laravel.logの容量が大きくなってしまい、laravel.logをクリアにする方法を調べたので、備忘録として残します。

# ~~「echo "" > storage/logs/laravel.log」を行う。~~
こちらの方法を行ったところ、laravel.logで文字化けするようになってしまったため、非推奨になります。
以下の「laravel.logを削除する」方法をお試しください。
~~対象のプロジェクトのディレクトリに移動し、~~
```php
echo "" > storage/logs/laravel.log
```

~~これでlaravel.logがクリアlaraになると思います！~~

# laravel.logを削除する
storage/logs/laravel.logを削除しましょう。
私も最初削除しても大丈夫なのかなと思いましたが、削除後自動でlaravel.logが生成されました！
JenkinsのGit Parameterで特定のブランチのみ表示する

以下の手順で設定できる。

1.対象のジョブの「設定」を押下
2.「ビルドのパラメータ化」→「Git Parameter」→「高度な設定...」を押下
3.「Branch Filter」で「origin/ブランチ名のパターン.\*」を設定する

例えば「feature/\*\*\*」的なブランチに絞る場合は「origin/feature/.\*」とすることで絞り込める。
ワイが出会ったエラーについて①（PHP）



Warning: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens in 

どんな時に出る？

→　引数の数が合いませんえ、
と、上記のエラーは申しているようです。
後述しますが、最初に:deflag だけしか宣言してないのに
後からarrayで出てくる：idとはなんぞや。
とこのケースでは言われてるわけです。


ワイが実際にこのエラーに直面した際の具体例を書いていく。

どんな時に出た？

→ TODOリストを作っている最中。
htmlで作ったチェックボックスにチェックを入れると、
そのtodoの内容を消す、ということがしたかった。
正確には、DELETE文で消すわけではなくて、チェックボックスにチェックが入ると
UPDATE文が走ってデリートフラグが立つようにしたかった。


そこで書いたのがこのようなコード。（抜粋）
もしコードがポンコツだったらごめんなさい。

$sql = 'UPDATE td SET delete_flg = :deflag’;

$stmt = $dbh->prepare($sql);
return $stmt->execute(array(
':deflag' => １, ':id' => $id));
}

deleteflg();

はい。:idが最初に宣言されてないので、数が合いませんけど、
って言われてしまったわけです。

下記のようにしたら出なくなりました。
要は:idを最初に書いてあげればよかったのです。
数が合うようになりました。
エラーは解消です。

$sql = 'UPDATE td SET delete_flg = :deflag, 
WHERE id = :id';


$stmt = $dbh->prepare($sql);
return $stmt->execute(array(
':deflag' => １, ':id' => $id));
}

deleteflg();

まだTODOアプリで、うんうん唸りながら作っている最中です。
もしかしたらこのコード自体全部書き直すかもしれません。
なんか自分で言うのもアレですが全体的に仕様やコードがいけてない気しかしない。。
とりあえず今回は、備忘のためと自身のアウトプット並びに言語化のために
エラーの話がしたかっただけなので、これで以上とします。

記事の内容が誤っていたり、改善点がある場合はお知らせいただけたら幸いです。
ご指摘は真摯に受け止める所存です。
青色申告、やってみた。

# 概要
青色申告、やってみた。

# 写真

![s0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/6a73b0af-4d83-486d-85df-c10f27b497c2.png)

![s1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/02f00603-1e4e-006c-4caf-c9c552697eff.png)


# 手順１ 所得金額を算出する。

営業等所得、農業所得は、事業所得。
不動産は、不動産所得。
給与は、給与所得。
公的年金等	(国民年金、厚生年金、恩給、確定給付企業年金、確定拠出企業年金、など)は、雑所得。

# 給与所得の計算。

|給与等の収入金額|給与所得|
|:--|:--|
|1円 ～ 550,999円	|0円
|551,000円 ～ 1,618,999円	|（A）－550,000円
|1,619,000円 ～ 1,619,999円	|1,069,000円
|1,620,000円 ～ 1,621,999円	|1,070,000円
|1,622,000円 ～ 1,623,999円	|1,072,000円
|1,624,000円 ～ 1,627,999円	|1,074,000円
|1,628,000円 ～ 1,799,999円	|（B）×60%+100,000円
|1,800,000円 ～ 3,599,999円	|（B）×70%－80,000円
|3,600,000円 ～ 6,599,999円	|（B）×80%－440,000円
|6,600,000円 ～ 8,499,999円	|（A）×90%－1,100,000円
|8,500,000円 ～	|（A）－1,950,000円

（B）＝（A）÷4（千円未満切捨て）×4

# 公的年金等の雑所得
公的年金等雑所得以外の所得に係る合計所得金額による。

- 昭和28年1月2日以後に生まれた方（65歳未満の方）の計算

|Aの金額|	1,000万円以下の場合|1,000万円超2,000万円以下の場合|2,000万円超の場合 |
|:--|:--|:--|:--|
|1,299,999円まで|	収入金額-600,000円	|収入金額-500,000円	|収入金額-400,000円
|1,300,000円から4,099,999円|収入金額×0.75-275,000円	|収入金額×0.75-175,000円	|収入金額×0.75-75,000円
|4,100,000円から7,699,999円|収入金額×0.85-685,000円	|収入金額×0.85-585,000円	|収入金額×0.85-485,000円
|7,700,000円9,999,999円|収入金額×0.95-1,455,000円	|収入金額×0.95-1,355,000円	|収入金額×0.95-1,255,000円
|10,000,000円以上	|収入金額-1,955,000円	|収入金額-1,855,000円	|収入金額-1,755,000円

- 昭和28年1月1日以前に生まれた方（65歳以上の方）の計算

|Aの金額|	1,000万円以下の場合|1,000万円超2,000万円以下の場合|2,000万円超の場合 |
|:--|:--|:--|:--|
|3,299,999円まで	|収入金額-1,100,000円	|収入金額-1,000,000円	|収入金額-900,000円
|3,300,000円から4,099,999円|収入金額×0.75-275,000円	|収入金額×0.75-175,000円	|収入金額×0.75-75,000円
|4,100,000円から7,699,999円|収入金額×0.85-685,000円	|収入金額×0.85-585,000円	|収入金額×0.85-485,000円
|7,700,000円から9,999,999円|収入金額×0.95-1,455,000円	|収入金額×0.95-1,355,000円	|収入金額×0.95-1,255,000円
|10,000,000円以上	|収入金額-1,955,000円	|収入金額-1,855,000円	|収入金額-1,755,000円

# 青色申告特別控除

青色申告者に対しては種々の特典がありますが、その1つに所得金額から55万円（一定の要件を満たす場合は65万円）または10万円を控除するという青色申告特別控除があります。


# 手順２　所得控除を算出する。
年末調整の控除に順じる。

# 扶養控除

|区分	|控除額|
|:--|:--|
|一般の控除対象扶養親族	|38万円
|特定扶養親族	|63万円
|老人扶養親族	同居老親等以外の者	|48万円
|老人扶養親族 同居老親等	|58万円

# 基礎控除

|納税者本人の合計所得金額	|控除額
|:--|:--|
|2,400万円以下	|48万円
|2,400万円超2,450万円以下	|32万円
|2,450万円超2,500万円以下	|16万円
|2,500万円超	|０円

# 社会保険料控除
厚生年金保険料は、加入者と会社が折半して半分ずつを負担します。
被用者年金（厚生年金保険、共済組合等）の保険料については、お勤め先で控除額を算出のうえ、市区町村や税務署に届出します。そのため、日本年金機構で被用者年金の保険料について控除証明書を作成し、その加入者の方にお送りすることはありません。

# 生命保険料控除
旧契約（平成23年12月31日以前に締結した保険契約等）に基づく場合の控除額

|年間の支払保険料等	|控除額
|:--|:--|
|25,000円以下	|支払保険料等の全額
|25,000円超 50,000円以下	|支払保険料等×1/2+12,500円
|50,000円超 100,000円以下	|支払保険料等×1/4+25,000円
|100,000円超	|一律50,000円

新契約（平成24年1月1日以後に締結した保険契約等）に基づく場合の控除額


|年間の支払保険料等	|控除額
|:--|:--|
|20,000円以下	|支払保険料等の全額
|20,000円超 40,000円以下	|支払保険料等×1/2+10,000円
|40,000円超 80,000円以下	|支払保険料等×1/4+20,000円
|80,000円超	|一律40,000円

# 手順３　税金を算出する。

|Cの金額|	課税される所得金額に対する税額|
|:--|:--|	 
|1,000円～1,949,000円	|C×0.05
|1,950,000円～3,299,000円	|C×0.1－97,500円
|3,300,000円～6,949,000円	|C×0.2－427,500円
|6,950,000円～8,999,000円	|C×0.23－636,000円
|9,000,000円～17,999,000円	|C×0.33－1,536,000円
|18,000,000円～39,999,000円	|C×0.4－2,796,000円|
|40,000,000円～	|C×0.45－4,796,000円


以上。
React Selectでの選択した値の取得


## React Selectとは

・select機能の便利なライブラリ
・複数選択とかアニメーションとか検索機能とか自分で実装すると難しい機能が簡単に実現できる

https://react-select.com/home

・Searchable Dropdown

![react-select.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2907902/5dca2c52-96ef-ad45-a3c2-b8159b76797b.gif)

## 選択肢の設定

・選択肢は公式にあるようにオブジェクトの配列で渡す
・ただの配列では渡せないので注意

```data.ts
export const colourOptions: readonly ColourOption[] = [
  { value: 'ocean', label: 'Ocean', color: '#00B8D9', isFixed: true },
  { value: 'blue', label: 'Blue', color: '#0052CC', isDisabled: true },
  { value: 'purple', label: 'Purple', color: '#5243AA' },
  { value: 'red', label: 'Red', color: '#FF5630', isFixed: true },
  { value: 'orange', label: 'Orange', color: '#FF8B00' },
  { value: 'yellow', label: 'Yellow', color: '#FFC400' },
  { value: 'green', label: 'Green', color: '#36B37E' },
];
```

## 選択した値の取得

イベントで受け取ることが可能

```App.tsx
const handleChange = (e: any) => { 👈 ここ
  console.log(e)
}

<Select
  aria-labelledby="aria-label"
  inputId="aria-example-input"
  name="aria-live-color"
  onMenuOpen={onMenuOpen}
  onMenuClose={onMenuClose}
  options={colourOptions}
  onChange={handleChange}　👈 onChangeやonClickイベントに関数を設定
/>
```


<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2907902/ac69fc4f-45cb-32ee-6317-dde9ddd05860.png" width="800"/>

## 終わりに

値の取得がわからなくてハマったのでまとめました。
terraform init で AWS VPC をインポートしてTerraform管理下に置く

# AWSでVPCを作成しておく


# tf ファイルを定義

中身は空で良いので定義しておく

 `vpc.tf`

```
resource "aws_vpc" "example" {
}
```

# VPC ID を確認

<img width="1440" alt="image" src="https://user-images.githubusercontent.com/13635059/217127989-2a4451a1-60e5-41e5-b31c-9a06f7816895.png">

# import する

`terraform import aws_vpc.example vpc-0e4bdfa5f98f4136a`


これでVPCをTerafform管理下に置けるわけだが、別に今の状態からtfファイルを作成してくれるわけではないようだ

# 生成されたStateファイルの例

```json
{
  "version": 4,
  "terraform_version": "1.3.7",
  "serial": 1,
  "lineage": "2f0d4879-1b5c-f056-fc90-0789baa23c7a",
  "outputs": {},
  "resources": [
    {
      "mode": "managed",
      "type": "aws_vpc",
      "name": "example",
      "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
      "instances": [
        {
          "schema_version": 1,
          "attributes": {
            "arn": "arn:aws:ec2:ap-northeast-1:842696858454:vpc/vpc-0e4bdfa5f98f4136a",
            "assign_generated_ipv6_cidr_block": false,
            "cidr_block": "10.0.0.0/16",
            "default_network_acl_id": "acl-0bb942c98f06a1128",
            "default_route_table_id": "rtb-0ed5c6d1d0739abcb",
            "default_security_group_id": "sg-09189d0b06f959c26",
            "dhcp_options_id": "dopt-896f56ee",
            "enable_classiclink": false,
            "enable_classiclink_dns_support": false,
            "enable_dns_hostnames": true,
            "enable_dns_support": true,
            "enable_network_address_usage_metrics": false,
            "id": "vpc-0e4bdfa5f98f4136a",
            "instance_tenancy": "default",
            "ipv4_ipam_pool_id": null,
            "ipv4_netmask_length": null,
            "ipv6_association_id": "",
            "ipv6_cidr_block": "",
            "ipv6_cidr_block_network_border_group": "",
            "ipv6_ipam_pool_id": "",
            "ipv6_netmask_length": 0,
            "main_route_table_id": "rtb-0ed5c6d1d0739abcb",
            "owner_id": "842696858454",
            "tags": {
              "Name": "eex"
            },
            "tags_all": {
              "Name": "eex"
            }
          },
          "sensitive_attributes": [],
          "private": "eyJzY2hlbWFfdmVyc2lvbiI6IjEifQ=="
        }
      ]
    }
  ],
  "check_results": null
}

```

# Apply

VPCに新しい名前をつけて `terraform apply` するとAWS上でもVPC名が変わるのが分かる

```
resource "aws_vpc" "example" {
  tags = {
    Name = "exexex"
  }
}
```


<img width="1440" alt="image" src="https://user-images.githubusercontent.com/13635059/217129515-f0ca79fb-95c5-46de-b089-9ed15391a3d2.png">


# チャットメンバー募集


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

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


# Twitter

https://twitter.com/YumaInaura
Pandasの基本的な分析操作

# Pandasの基本的な分析操作 
個人的に覚えておきたいコード
```python
#データのソート（昇順）
df.sort_values('Weight').head()

#データのソート（降順）
df.sort_values('Weight', ascending=False).head()

#列の削除
df = df.drop(labels = 'Origin' , axis=1)

#データの絞り込み
df[df['Origin'] == 3].head()

#データの絞り込み２
df[(df['Origin']==3) & (df['Weight']>=2000)].head()

#要約統計量の確認
df.describe()

#グループ化
df.groupby('Origin').mean()

#クロス集計表
pd.crosstab(df['Cylinders'],df['Origin'])

#ピボットテーブル
pd.pivot_table(df, values='MPG', index='Model Year', columns='Origin', aggfunc='mean')
```
dropとかは今のところよく使いますね
「やることが多い！」と感じたときにすべき1つのこと

仕事を普通にやっていれば「やることが多い！」と感じたことのない人はおそらくいないはずです。

しかしこの感覚は、本当に「やることが多い」から感じているのでしょうか。

たくさんのタスクに囲まれても集中力や判断力が鈍らないときもあれば、**それほど忙しくないのになぜか全てが手につかない**こともあります。

つまり「やることが多い！」というのは、**実際の忙しさにそのまま結びつく感情ではなさそうです**。

## 結論を出せていないから

「やることが多い！」と感じているとき、その人は一種の小さなパニックに陥っていると筆者は考えています。なにか行動しないといけない気持ちはあるけれど実際に身体が動かない、という状態です。

この原因を、タスク管理方法のひとつであるGetting Things Done(GTD)の提唱者であるデビッド・アレンは、次のように述べています。

> 私たちに最も欠けているのは、考えて結論を出す能力である。[...]私たちがやるべきことの大半は、カレンダーに書き込んだ予定のようなものを除いて、まだ判断しなければならないことがずいぶんとたくさん残っている。[...]**この手の「気になること」で問題なのは、意識に上ってきたときに複雑でとらえどころのないものだと感じられて、考えることを拒絶してしまいがちなことである**。いろいろ考えないといけない気がするが今はそんな時間も気力もない、と思ってしまうのだ。[^1]
> (※太字は筆者によるもの)

あらゆるタスクやプロジェクトに対して結論を出せていない、なにかしら判断すべきことがあるのだけれど判断までいたらない。このような状況が続いたりあらゆるプロジェクトで起こると、どうやら「やることが多い！」となりそうです。

## 「次の行動を決める」

この状態は根性論では解決しません。デビッド・アレンは次のようなアプローチを紹介しています。

> 必要なのは、それらのこと[考えることを拒絶してしまいそうなこと]を**今の状態から一歩前に進めるために必要な、次の物理的行動を見極める**ことだけなのだ――そしてそれこそが「結論を出す」ことに他ならない。あなたは自分が抱えているすべての「気になること」について、もう少しだけ考える必要があるのだ(ただ、それはあなたが思っているほど難しい作業ではない)。[^2]
> (※太字は筆者によるもの)

たとえばあるプロジェクトについて、課題やTODOが山積みだけれどそのプロジェクトを「今の状態から一歩前に進めるために必要な、次の物理的行動」は明確でないというケースはよくあるでしょう。

そのようなときこそ、まずは今の状態を振り返って「次に何をするべきか」を考えて実行してみる。

きっと小さなことでしょうが、それで車輪は回り始めるはずです。

それが終わったら？　次の行動を考えるまでです。

## 補足

GTDでは、本記事で紹介した「次の行動を見極めること(**見極め**)」は「頭の中にあるものをすべて書き出してみる(**収集**)」の次のステップとして定義されています。

もし「次の行動すら考える余裕がない」という場合は、実際にいま直面している状況や課題、頭の中にあるさまざまな情報や感情をとにかくアウトプットしてみる、というのもオススメです。


[^1]: デビッド・アレン『ひとつ上のGTD ストレスフリーの整理術 実践編――仕事というゲームと人生というビジネスに勝利する方法』、p52。

[^2]: 同、p52。
preventDefault()に気づかず苦戦した話

## はじめに
こんにちは。
駆け出しフロントエンドエンジニアのももたれです。

最近はJavaScriptの基礎部分をひたすら書いてました。
自分の備忘録も兼ねて、preventDefault()に気づかず苦戦した話を書きます。

## 実装内容
### ページTOPへ戻るボタン
ページに入り、ちょっとスクロールしたら右下に出てくる「ページTOPへ戻るボタン」
クリックしたら**するするっと**ページTOPに戻る、まあよく見るあのボタンを作ろうとしてました。

htmlとcssで**ただの**「ページTOPへ戻る」は作ったことありますが、JavaScriptを使っては初めて。
調べたらよさげな記事出てきたので、「お、いけそう」と思いきや、だいぶ苦戦しました。

### コード
こんな感じで書いてました。

htmlは大した内容じゃないので省略します。
大事なのは、**aタグ**使ってました。

``` javascript
// スクロールしたらボタンが出てくる
const topBtn = document.querySelector("[data-target-following]");
window.addEventListener("scroll", scrollTrigger);
function scrollTrigger() {
  if(window.pageYOffset > 500) {
    topBtn.classList.add("is-show");
  } else {
    topBtn.classList.remove("is-show");
  };
};
```

どうってことないコードです。
クラスの付け替えで、スクロールしたらボタンが出たり消えたりを制御してます。
JavaScript初心者のわたしでも容易に書けました。

しかしこれではクリックすると、するするっとはページTOPにいってくれません。
瞬間移動した感じですね。

### スムーススクロール
調べて出たのが、「スムーススクロール」（正式な名前ではないのかな）

``` javascript
// クリックしたときsmoothな動きで一番上まで移動
topBtn.addEventListener("click", (e) => {
  window.scrollTo({
    top: 0, 
    behavior: "smooth"
  });
});
```

なんだー簡単じゃん！！と思ってましたが、あれ、、思った挙動にならない、、
するするっとページTOPにいってくれない、、

ここで時間めっちゃ溶かしました。。。

### preventDefault()
結論、
``` javascript
preventDefault()
```
この1行がなかっただけでした。それだけ

今回aタグを使って書いていたので、aタグのデフォルトの動作が発生してしまっていたようです。
それを打ち消した上で、スムーススクロールを書く必要がありました。

下記のコードで無事に成功！
もう絶対忘れない。。

``` javascript
// スクロールしたらボタンが出てくる
const topBtn = document.querySelector("[data-target-following]");
window.addEventListener("scroll", scrollTrigger);
function scrollTrigger() {
  if(window.pageYOffset > 500) {
    topBtn.classList.add("is-show");
  } else {
    topBtn.classList.remove("is-show");
  };
};
// クリックしたときsmoothな動きで一番上まで移動
topBtn.addEventListener("click", (e) => {
  e.preventDefault()
  window.scrollTo({
    top: 0, 
    behavior: "smooth"
  });
});
```

## まとめ
``e.preventDefault()``で本来の動作を打ち消さないと思った通りの挙動になってくれませんでした。
フォーム送信ボタンの`type="submit"`を打ち消して、送信する前にバリデーションを出すときなどにも使うっぽいです。
（浅はかな理解）

挫折しかけたJavaScriptだけど、初歩的な部分は理解できるようになってきました。
引き続きがんばります。
gulp ブラウザのデベロッパーツールでscssの場所が表示されない

# gulp ブラウザのデベロッパーツールでscssの場所が表示されない

ブラウザのデベロッパーツールでscssが表示されず, cssの場所が表示されてしまうことがあった

以下、コンパイル処理を「※」のコードで囲むと表示されるようになります。

```
    .pipe(sassGlob())
    .pipe(sourcemaps.init()) // ※
    .pipe(sass().on('error', sass.logError)) // コンパイル処理
    .pipe(sourcemaps.write({includeContent: false}))  //  ※
    .pipe(sourcemaps.init({loadMaps: true}))      //  ※
```
Audiusのオンチェーン分析_vo1 【Dune】

## はじめに

*ProgateのSQL編を一周しただけのSQL初学者ですので、間違いなどあれば教えていただけると嬉しいです
web3に関しても勉強中なので、間違いを含む可能性があります。*

　ここ数日分散型ストリーミングサービスのプラットフォームであるAudiusにハマっていて、色々と調べています。今回はその一環としてSQLの勉強も兼ねながら、独自トークンであるAUDIOを見ていきます。
## Audiusとは
　web3版のSpotifyという説明が一番分かりやすいかと思います。プラットフォーマーや中間業者が利益のほとんどを取ってしまい、ほんの一部しか利益を得ることのできない音楽業界を変えるべく創業されGeneral Catalyst, LightspeedといったVCだけでなくKaty PerryやSteve Aokiなどからも出資を受けています。
 簡単なリサーチ記事も書いてみたので、興味のある方は読んでくださると励みになります。
 https://chaichai.substack.com/p/audius

AUDIOとはAudiusがethereumネットワーク上の構築している独自トークンです。このトークンがプラットフォーム内の通貨として機能しアーティストへの報酬として分配されます。加えて
1. ネットワークのセキュリティー確保
2. 限定音源などへのアクセス権
3. ガバナンスへの投票権

などの役割も果たしています。

## AUDIOのオンチェーン分析
　ここから本題です。Duneを使って出来る範囲で分析を行ってみました。SQLの勉強を進めていく中で徐々に分析できる範囲も増やしていければと思っています。以下が成果物です。
 https://dune.com/chaichai/audius
 今回は
 1. ウォレットアドレスに関する分析
 2. トランザクションに関する分析
 
 を行っています。
 ### ウォレットアドレス
  まずは総ウォレット数を出してみました。
 ```sql
SELECT COUNT(DISTINCT to) AS "総アドレス数"
FROM erc20_ethereum.evt_Transfer
WHERE "contract_address" = 0x18aAA7115705e8be94bfFEBDE57Af9BFc265B998
;
```
　トークンの送信先を重複なく数えています。
結果を見てみると、トークン保有者≠ユーザーかつアドレス数≠ユーザー数であることに注意する必要がありますがAudius公式が出しているMAUと比べてもかなり少ない数となりました。
(私のクエリが間違っているのか、他に理由があるのか分からないため調べてみたいところです。)
https://dashboard.audius.org/#/

----
次に日付別の新規アドレス数を算出しました。
```sql
SELECT B."firstDay" AS "Date", B."newAddress" AS "newAddress", SUM(B."newAddress") OVER(ORDER BY B."firstDay") AS "total"
FROM (
    SELECT COUNT(A."address") AS "newAddress", A."FirstDay" AS "firstDay"
    FROM (
        SELECT DISTINCT to AS "address", date_trunc('day', min(evt_block_time)) AS "FirstDay"
        FROM erc20_ethereum.evt_Transfer
        WHERE "contract_address" = 0x18aAA7115705e8be94bfFEBDE57Af9BFc265B998
        GROUP BY 1
        ORDER BY 2
    ) AS A
    GROUP BY 2
    ORDER BY 2
) AS B
```
局所的に分かりやすく新規登録数が増加しています。理由としては
1. 周期的なもの(夏は登録しやすくなるとか)
2. 単発のキャンペーンやイベント
3. 参加しているアーティストの活動によるもの

などが考えられそうですが、データを見る限り1は無さそうです。

----
 最後にウォレットの増加を累計値として算出し調べてみました。
 ```sql
--- ウォレットがAUDIOを獲得した日、アドレス値、累計値
SELECT B."firstDay" AS "date", B."newAddress" AS "newAddress", SUM(B."newAddress") OVER(ORDER BY B."firstDay") AS "total"
FROM (
    SELECT COUNT(A."address") AS "newAddress", A."FirstDay" AS "firstDay"
    FROM (
    --- 送信先のアドレスを重複なく列挙、最初の日付を取得
        SELECT DISTINCT to AS "address", date_trunc('day', min(evt_block_time)) AS "FirstDay"
        FROM erc20_ethereum.evt_Transfer
	--- AUDIOのコントラクトアドレス
        WHERE "contract_address" = 0x18aAA7115705e8be94bfFEBDE57Af9BFc265B998
        GROUP BY 1
        ORDER BY 2
    ) AS A
    GROUP BY 2
    ORDER BY 2
) AS B
```
基本的にはサービス開始から着実にユーザーを増やしてきたように見えます。もちろん前述のように必ずしもユーザー獲得の過程を示しているわけではありませんが。

### トランザクション
```sql
SELECT date_trunc('day', evt_block_time) AS date, CAST(value as double)/1e18 AS AUDIO, SUM(CAST(value as double)/1e18) OVER(ORDER BY evt_block_time) AS "累計取引量"
FROM erc20_ethereum.evt_Transfer
WHERE "contract_address" = 0x18aAA7115705e8be94bfFEBDE57Af9BFc265B998
ORDER BY "evt_block_time" ASC
```
こうやって振り返ってみると、ASの後の書き方など統一されておらず良くないと感じました。本当はdateをGROUP BYでまとめたかったのですが、力量不足です。
こちらも線形的増加を辿っています。

## 感想
第一回はここまでにしておきます。簡単な分析をしただけでも色々な学びがあったので、次回以降より詳細なユーザー属性などについても分析できればと思います。
[Slack API] Slackに投稿できるテキストの文字数上限が3000文字でした

# APIを使ってslackにメッセージを送るときにエラーが出た

slackにメッセージを送るために下記の関数を使っていました。(コードはGoogleAppsScriptです)

```js
function sendToSlack(url, text) {
  const payload = {
    "blocks": [
      {
        type: "section",
        text: {
          type: "mrkdwn",
          text: text
        }
      }
    ]
  };

  const options = {
    'method': 'post',
    'contentType': 'application/json',
    'payload': JSON.stringify(payload)
  };

  UrlFetchApp.fetch(url, options);
}
```

これまでは問題なかったのですが、ある時下記のエラーが出ました。

```
Exception: Request failed for https://hooks.slack.com returned code 400. Truncated server response: invalid_blocks (use muteHttpExceptions option to examine full response)
```

# 結論: テキストの上限は3000文字

上記サンプルでいうと、`text.length` が 3000以下の場合は問題ないのですが、3001以上になると上記のエラーになることが確認できました。

ポイントとしては、markdownとしての修飾文字 (`*` とか `_` など)や、 emoji (`:smile:`など) も文字数としてカウントされるので、markdown使うときは注意ですね！
案件準備　2023

![Study.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271383/0bce6d84-7b78-09a4-37ec-0a280596aa1e.jpeg)
# 案件準備
## サクってやるところはサクってやってしっかりやるところはしっかりやろう。
## Java
・改行
・インデント
・Staticメソッド
・現行とあまり変えない。ロジックとか・・・
・選択　Ctrl C Ctrl V
## Docker
◾︎ ドットインストール
https://dotinstall.com/lessons/basic_docker
◼︎Dockerのとこを読む。
さわって学ぶクラウドインフラ　docker基礎からのコンテナ構築 Tankobon Hardcover – June 11, 2020
by 大澤 文孝  (著), 浅居 尚 (著)
www.amazon.co.jp/dp/4296106422
◼︎必要そうなコマンド
docker version
docker-compose up -d 

## CSS 
◼︎急にちょっと使いたい時があるのでその時のための　コードと参考にしたリンク

```
HTML
<p style="color: red;">HTML内に直書</p>
```
https://web-camp.io/magazine/archives/90625
◼︎Progateで学んでおく。デバックモードの練習はやっておいたほうが良い。
道場以外上級までやる。
https://prog-8.com/courses/html
## Lpic
学んでみようかと思います。

## SQL データベース
Udacityで
『Intro to Relational Databases』 を学ぼうと思います。

## その他
sudo lsof -i :5432
sudo kill 68
下記は基本的なコマンド
Ruby slice!メソッド

# slice!メソッド
配列や文字列から指定した要素を削除し、削除したあとの要素を返します。
「　!　」の付くメソッドは***破壊的メソッド***と言います。<br>

## 破壊的メソッド
元の配列や文字列そのものを変化させてしまうメソッドのことを破壊的メソッドと言います。
ちなみに、調べてみると「　!　」が付かない破壊的メソッドもあります。
勉強する必要がありますね！


## slice!メソッドの例

```ruby
string = "おはようございます！"
string.slice!(2)
puts string
#=> "おはうございます！"
# 2番目の要素の「　よ　」が取り除かれて、返ってきた
```


# slice!メソッドを使って任意の文字列を部分的に削除するプログラムの作成

条件は以下の通りです。
- 対象となる文字列からn番目の文字を削除すること
- 削除された文字以外の文字列を出力すること


```ruby
def string(str, n)
  str.slice!(n - 1)
  puts str
end
# 以下は呼び出し例
string('Helloworld', 1)
string('Helloworld', 2)
string('Helloworld', 4)
```

## 解説
stringメソッドの引数strは、
対象となる文字列（今回だと、Helloworld）、nは○番目の文字を消すのかを指示する数字が入ります。
2行目の(n - 1)についてですが、先頭の文字列は0番目としてカウントされてしまうため、-1を付け加えています。
Azure Active Directoryから取得したJWTをNuxt3でVerifyしたい

# はじめに

なんか丁度いい記事がなかなか見つからなかったので書いてみました。

**クライアントがAzure Active DirectoryからJWTを取得して、それを `Authorization: Bearer` に付与してリクエストしてくるケースにおいて、受け側のAPIでJWTのVefiryをしたい**

これをどうやるのが良さそうか・・・と色々調べたんですが、ジャストフィットするようなサンプルが見つからなかったので。
callbackつかって非同期処理してるやつが多いんですよね。それだと色々とやりにくいんで。

# 結論

自分はこんな感じで実装しました。なにかの参考になれば。

Nuxt3の `server/api/token.get.ts` として保存してますので、エンドポイント的には `GET localhost:3000/api/token` になります。

エラー判定や型は若干（というかかなり）適当です。あくまで主目的が開発ベンダーさんに依頼するためのサンプルだったというのもあり。

```javascript
import * as jwt from 'jsonwebtoken';
import  jwksClient from 'jwks-rsa'

export default defineEventHandler(async (event) => {
  const req = event.node.req

  const authHeaderValue = req.headers['authorization']
  if (!authHeaderValue) {
    console.log('No authorization header specified')
    return
  }

  var token, 
      tokenHeaderBase64Encoded,
      tokenHeader,
      kid : string

  try {
    // Authorization: Bearer [JWT]となるので、Bearer部分を除外
    token = authHeaderValue.split(' ')[1]
    console.log(`token: ${token}`)

    // Header部(.つなぎの最初)を抽出
    tokenHeaderBase64Encoded = token.split('.')[0]
    console.log(`tokenHeaderBase64Encoded: ${tokenHeaderBase64Encoded}`)

    // Base64デコードしてkid部を抜き出す
    tokenHeader = Buffer.from(tokenHeaderBase64Encoded, 'base64').toString()
    console.log(`tokenHeader: ${tokenHeader}`)

    kid = JSON.parse(tokenHeader).kid
    console.log(`kid: ${kid}`)
  } catch (error) {
    throw createError({
      statusCode: 401,
      statusMessage: 'Token structure is not valid',
      message: error.message || ''
    })
  }

  // 取得したkid部からKey情報を取りに行く
  const client = jwksClient({
    jwksUri: 'https://login.microsoftonline.com/common/discovery/keys'
  })

  var signingKey: string
  try {
    const key = await client.getSigningKey(kid)
    console.log(`key: ${JSON.stringify(key)}`)

    signingKey = key.publicKey || key.rsaPublicKey;
    console.log(`signingKey: ${signingKey}`)
  } catch (error) {
    throw createError({
      statusCode: 401,
      statusMessage: 'Unable to get correct key information from JWT',
      message: error.message || ''
    })    
  }

  const config = useRuntimeConfig()
  console.log(`Runtime Config: ${JSON.stringify(config)}`)

  const verifyOptions = {
    audience: `api://${config.clientId}`
    // audience: 'invalid audience' // for test
  }
  console.log(`Verify Options: ${JSON.stringify(verifyOptions)}`)
  // Verifyメソッドを同期型で呼ぶことでdecode結果直接受領
  try {
    const decoded = jwt.verify(token, signingKey, verifyOptions)
    console.log(`Decoded JWT: (${JSON.stringify(decoded)}`)
    return {
      message: 'JWT has correctly verified'
    }
  } catch (error) {
    throw createError({
      statusCode: 401,
      statusMessage: 'JWT is not valid',
      message: error.message || ''
    })
  }
})
```
数独の問題作成を ChatGPT に依頼してみました

## 概要

今、巷で噂の「ChatGPT」を利用して、[数独](https://www.nikoli.co.jp/ja/puzzles/sudoku/) のPythonプログラムの作成依頼をすればどのような答えが返ってくるか試してみました

### 実行環境

macOS Ventura 13.0
python 3.8.12

### マシンスペック

- プロセッサ : 2.3 GHz 8コア Intel Core i9
- メモリ : 32GB 2667MHz DDR4

### ChatGPTへのログイン

以下のURLにアクセスします。アカウント登録後利用できます。
https://chat.openai.com/auth/login

### ChatGPTへの問い合わせ

```
数独の問題を作成するPythonプログラムは？
```

### ChatGPTからの返事

```
数独の問題を作成するPythonプログラムは様々な方法で作成することができますが、一般的なアルゴリズムには以下のようなものがあります:

数独テンプレートを作成し、そこから必要な数字を適当に消去する。
順番に数字を埋めていくアルゴリズムを作成する。
ランダムな数字を適当な位置に配置し、正解を求めるためのアルゴリズムで問題を解いていく。

具体的な例は以下のようなものがあります:

----------------------------------------------------------------
import random

def create_sudoku():
    board = [[0 for x in range(9)] for y in range(9)]
    for i in range(9):
        for j in range(9):
            board[i][j] = (i * 3 + i // 3 + j) % 9 + 1
    for i in range(9):
        for j in range(9):
            k = random.randint(0, 8 - j) + j
            board[i][j], board[i][k] = board[i][k], board[i][j]
            k = random.randint(0, 8 - i) + i
            board[i][j], board[k][j] = board[k][j], board[i][j]
    return board

sudoku = create_sudoku()
for row in sudoku:
    print(row)
----------------------------------------------------------------

このプログラムは、数独テンプレートを作成し、数字をランダムに配置することで数独の問題を作成します。
```


### 実行プログラム

なにも編集せずに、、、、、

```python:Sudoku_charGPT.py
import random

def create_sudoku():
    board = [[0 for x in range(9)] for y in range(9)]
    for i in range(9):
        for j in range(9):
            board[i][j] = (i * 3 + i // 3 + j) % 9 + 1
    for i in range(9):
        for j in range(9):
            k = random.randint(0, 8 - j) + j
            board[i][j], board[i][k] = board[i][k], board[i][j]
            k = random.randint(0, 8 - i) + i
            board[i][j], board[k][j] = board[k][j], board[i][j]
    return board

sudoku = create_sudoku()
for row in sudoku:
    print(row)
```

### プログラムの実行

プログラムを見て結果はわかっていましたが、とりあえず、実行してみました。

```
$ python Sudoku_chatGPT.py
[5, 5, 9, 9, 2, 7, 8, 2, 5]
[8, 6, 8, 9, 7, 4, 3, 4, 2]
[1, 1, 2, 6, 9, 5, 9, 7, 4]
[3, 4, 1, 2, 3, 3, 5, 1, 8]
[8, 9, 2, 6, 1, 4, 2, 3, 6]
[6, 5, 7, 2, 4, 2, 4, 1, 5]
[7, 6, 1, 5, 9, 7, 8, 3, 4]
[9, 7, 5, 8, 8, 9, 6, 3, 4]
[6, 8, 3, 6, 3, 7, 7, 1, 1]
```

### まとめ

世の中あまくないですね、、、、、しかし、ChatGPTでエラーなしのPythonコードが帰ってきたのには驚きです！ プログラミングに関する質問はスコープ（範囲）を明確にしてあげれば利用できそうな気がします。
varnishのresolves to too many addressesを解決する

ブログからの転載

# TLDR
- libvmod-dynamicを追加でインストールする
- ホワイトリスト設定を忘れない

# varnishの仕様
varnishでは基本的にバックエンドとの対応付けは1対1が基本であり、複数IPなどには対応することができない。
（注:ドメインなどを記載した場合はコンパイル（起動）時にDNSを引いた際のIPアドレスを利用しているっぽい[^3]）
つまりbackendに"s3-ap-northeast-1.amazonaws.com"のような複数のAレコードを持つようなものを指定しようとすると、`resolves to too many addresses`と怒られる[^1]。


varnishのドキュメントやggってみると[gotoというライブラリ](https://docs.varnish-software.com/varnish-cache-plus/vmods/goto/)が出てくるが、これはシェアウェアのバンドルなので利用できない。


調べてみるとgotoとは別に[libvmod-dynamic](https://github.com/nigoroll/libvmod-dynamic)というモジュールがあったのでこちらを利用する。
libvmod-dynamicはバックエンドに接続する際にDNSを引くという動作をする。つまりDNSレコードが変わるような環境でも利用できる。
また、複数のレコードがある場合にも問題なく利用できる。

## 環境
OS: Amazon Linux 2

varnish: 6.0.10（yumからインストール）


構成としてはALBでSSL終端しVarnishが受けて各種バックエンドやS3などに振り分けるといったもの（画像書くのが面倒だった）。
varnishはリバースプロキシとして利用しており読み替えでs3を呼び出す。
s3は静的ファイルが主においてありcssなどを要求する際に利用される。

s3のDNSのAレコードは8つあり、しかもおよそ**5秒ごとに変更される**ためTTLを長めにしてしまうとアクセスできなくなるので注意（2022/10/28現在）。

## 構築
1. 必要なライブラリを追加する `sudo yum install getdns-devel varnish-libs-devel`
1. [リポジトリ](https://github.com/nigoroll/libvmod-dynamic)にアクセスし、varnishのバージョンと同じブランチを選択する。今回は6.0。
1. CodeをクリックしDownload ZIPのリンクをコピー
1. wget する。今回は`wget https://github.com/nigoroll/libvmod-dynamic/archive/refs/heads/6.0.zip`
1. unzip `unzip 6.0.zip`
1. ディレクトリに入りmake&install
```
./autogen.sh
./confugure
make
```
7.問題なく`make`できたら`sudo make install` 
8.完了を確認したらvclの設定へ


## varnish vmod-dynamicの使い方
基本的には`src/vmod_dynamic.vcc`に書いてあるのでそれを見て設定する。
今回は以下のように設定した。

s3.vcl
```
import dynamic;

probe www_probe {
    .window = 5;
    .initial = 7;
    .threshold = 3;
    .interval = 5s;
}

acl www_acl {
    "0.0.0.0/0";
}

sub vcl_init {
    new s3 = dynamic.director(
        port = "80",
        probe = www_probe,
        whitelist = www_acl,
        ttl = 1s);
}
```

default.vcl
```
set req.backend_hint = s3.backend("s3-ap-northeast-1.amazonaws.com");
```

ここで重要なのは、`whitelist`の設定である。

`vmod_dynamic.vcc`には「ACLに一致する名前解決結果のみが使用される」と記載があるので、これを記載しないと**動作しない**ようである。
今回はAWSがAWSIPからランダムに（実際はラウンドロビンか何か）IPを変更しているため設定値を`0.0.0.0/0`としている[^2]が、利用IPの範囲が決まっていれば`192.168.0.0/31`のように範囲指定すべきである。
設定例では`"192.168"/24;`となっているのだがこの場合は"192.168.0.0/24"となるんだろうか…？この書き方なら`/16`が適切な気がするんだけども。

また、TTLは基本的にはDNSの設定値と同様か少し小さい値を設定しておけば良い。
今回はAWSの設定に振り回されないように`1sec`にしてあるが、普通は`5m`でも`1h`でもいいと思う。


## 反映
`sudo systemctl restart varnish`で反映させる
再起動してもいいかも。

## 気になること
- ドキュメント記載の`"192.168"/24;`を設定したときの許可範囲
- www_probeの各パラメータの適切さがそもそもわかっていない
  - varnishのドキュメントとlibvmod-dynamicのドキュメントではinitialの定義が違うんだけどlibvmod-dynamicが間違ってる？

varnishわからないことだらけなので誰か教えて下さい。。。


最後までお読みいただきありがとうございました。

### 参考文献
https://siguniang.wordpress.com/2014/02/03/proxy-dynamic-ip-address-from-varnish/


[^1]: ちなみに2022/10/20辺りではこのようなエラーが出なかったのだが、varnishがアップデートしたのかAWSのDNSが変わったのか原因はわからなかった
[^2]: ドキュメントには0.0.0.0/0にするとIPv4に限定できると書いてある
[^3]: https://siguniang.wordpress.com/2014/02/03/proxy-dynamic-ip-address-from-varnish/
irb起動時に表示されるプロンプト（irb(main):0001:0>みたいなやつ）を非表示にする方法

## 環境

ruby version : 3.1.1p18 

## 結論から

`irb --noprompt`で起動する

参考：[library irb](https://docs.ruby-lang.org/ja/latest/library/irb.html)


## 調べた経緯

irbを普通に起動すると、`irb(main):0001:0>`のようなプロンプトが表示されます。
ローカルでちょっとrubyを動かしてコードをコピペしたい時、以下のようにプロンプトも一緒についてきてしまって見づらいので非表示にできないかなーと思って調べました。


```ruby:irb
irb(main):005:1* class Hoge
irb(main):006:2*   def fuga
irb(main):007:2*     'fuga'
irb(main):008:1*   end
irb(main):009:0> end
=> :fuga
irb(main):010:0> hoge = Hoge.new
=> #<Hoge:0x000000015531b8b0>
irb(main):011:0> hoge.fuga
=> "fuga"
irb(main):012:0>
````

```ruby:irb --noprompt
class Hoge
  def fuga
    'fuga'
  end
end
:fuga
hoge = Hoge.new
#<Hoge:0x0000000104ee5890>
hoge.fuga
"fuga"
```

コードのメモを取る時等に活用しようと思います。
Pythonによるグラフ化コードまとめ

# グラフ関係
コード忘れたとき用にメモしてます。
```python
#横軸の値
x = df['Origin'].value_counts().index
#縦軸の値
height = df['Origin'].value_counts().values

#図のサイズを規定
plt.figure(figsize=(12,8))

#グラフのスタイル変更
plt.style.use('seaborn')

#棒グラフ
plt.bar(x=columns, height=model.coef_);

#折れ線グラフ
plt.plot(x, y)

#ヒストグラム
plt.hist(df['Acceleration'], bins=50)

#ヒストグラム２
sns.distplot(df['Acceleration'], kde=False, bins=10)

#ヒストグラムを線で表現したやつ
sns.distplot(df['Acceleration'], kde=True, bins=10)

#散布図
plt.scatter(df['Weight'], df['MPG'])

#要素同士の散布図一覧（重くなりがちだが、分析してる感が出る）
sns.pairplot(df)


#ヒストグラムと散布図
sns.jointplot(x='x1', y='x16', data=df)

#箱ひげ図
plt.boxplot(df['Acceleration'])

#ヒートマップ
sns.heatmap(df_corr.iloc[:20, :20],annot=True, cmap='Blues')

#円グラフ
x = df['満足度'].value_counts()
plt.title('満足度') # タイトルの表示  
plt.pie(x, labels=x.index, autopct='%.1f%%');
```
グラフのほかのコードを見つけたら追記してきます。
[JavaScript]URLSearchParams.toString()がnull値を"null"とするのを避ける為、nullをオブジェクトから除外する


# 前提

　GET用のURLパラメータを構築する時、URLSearchParams.toString()が便利です。次のように使います。

```javascript
const params = {
	search: "abc",
	searchtype: 2,
	userid: 1234,
}

const url = "https://host/api/getXXX" + (new URLSearchParams(params)).toString()
console.log(url);
```

```
https://host/api/getXXX?search=abc&searchtype=2&userid=1234
```

# 問題点

　paramsのプロパティ値にnullやundefinedを含むものがあった場合、それらは"null"、"undefined"という文字列としてエンコードされます。

```javascript
const params = {
	search: null,
	searchtype: undefined,
	userid: 1234,
}

const url = "https://host/api/getXXX" + (new URLSearchParams(params)).toString()
console.log(url);
```

```
https://host/api/getXXX?search=null&searchtype=undefined&userid=1234
```

これは URLSearchParamsの仕様ではありますが、この仕様がサーバ側で役に立つケースはほぼないでしょう。
nullという入力値を本当にnullとして扱ってしまうと、今度は"null"という文字列を送信できないことになってしまう為です。

# 解決策（コード付き）

例えば ASP.NET Core等は、サーバ側でGET/POSTパラメータをモデルクラスにマッピングする際には、そのパラメータが存在しなければ自動的にデフォルト値（文字列やNull許容値の場合はnull、数値の場合は0）で初期化されます。

よって、paramsの中にnullやundefinedなプロパティがあれば、プロパティ自体を除外してしまえば良いでしょう。

```javascript:オブジェクトからnullやundefinedなプロパティを除外して返す
function filterNullProperties(obj) {
    return Object.keys(obj).reduce(
        (retObj, key) =>
            (obj[key] === null || obj[key] === undefined)
                ? retObj    // null プロパティは無視
                : Object.assign(retObj, { [key]: obj[key] })    // null でないプロパティのみretObjに追加
        , {});
}
```

上記を用いると、次のような結果が得られます。

```javascript
const params = filterNullProperties({
	search: null,
	searchtype: undefined,
	userid: 1234,
});

const url = "https://host/api/getXXX" + (new URLSearchParams(params)).toString()
console.log(url);
```

```
https://host/api/getXXX?userid=1234
```

一見落着です。

# 気がかりな点

どうして URLSearchParamsがこのような仕様になっているのかが分からないのでその点は気がかりです。
null値を"null"という文字列にして送信することでうれしいケースがある、ということでしょうか？

また、もっとシンプルに書ける方法などありましたらコメントでご教授頂ければと思います。
データのない CnosDB エクスポート スキーマ

MySQL 側から来て、次のようにスキーマをダンプできることを知っています。

1. データベース全体:

mysqldump -u user -h localhost --no-data -p database > database.sql

2. 個々のテーブルの場合:

mysqldump -u user -h localhost --no-data -p database tablename > table.sql

同様の方法で CnosDB スキーマをダンプするにはどうすればよいですか?つまり、測定値、タグ、フィールドのみで、データは含まれていません。ここでドキュメントに欠けている引数はありますか?
yfinance Timestamp から influxdb に日付を書き込み、日付をクエリします - タイムゾーンのサポート

Flux は単純な線形クロックである UTC ですべての作業を行い、表示を理解するためにユーザーに任せます。したがって、タイムスタンプの一貫性を保つには、データを挿入する前にタイムスタンプを UTC に変換し、クエリが完了したら、データの結果を対応するタイムスタンプに変換する必要があります。

1.yfinance ライブラリでタイムスタンプを UTC に変換します。

dt.replace(tzinfo=timezone.utc)

2.UTC タイムスタンプをローカルのタイムスタンプに変換します。

import "timezone"

option location = timezone.location(name: "America/New_York")
RStudio - R言語の基礎 #03、モルモットの歯の成長に関するデータを分析

Googleデータアナリティックスプロフェッショナルを受講しています。
今回はR言語のパッケージ・tidyverseの基本的な機能について学びました。

https://www.coursera.org


## R言語のパッケージ

R言語では、ユーザーが作成した再利用可能なR言語の関数・ドキュメントが含まれたパッケージを再利用することができます。インストールされているパッケージを確認するには、`installed.packages()`というコマンドを実行します。
他にも、packagesペインからもアクティブなパッケージを確認できます。

![R007.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/337578/c9cd81ec-4808-a294-2635-6915cd82a0e4.png)


## Tidyverse

データ分析に活用できるパッケージとして、多くの場合tidyverseが使われます。
tidyverseにはコアとなる8つのパッケージ(ggplot2, tibble, tidyr, readr, purrr, dplyr, stringr, forcats)が含まれています。

## パイプ演算子を使う

```r
#dplyrの関数を使ってフィルタリングする
library(dplyr)

#モルモットの歯の成長に関するデータ
data("ToothGrowth")
View(ToothGrowth)
summary(ToothGrowth)

#アスコルビン酸、オレンジジュースの投薬量が0.5である場合をフィルタリングする
filtered_tg <- filter(ToothGrowth, dose == 0.5)
View(filtered_tg)

#薬量が0.5であるケースを歯の伸長で並べる
filtered_tg_arranged <- arrange(filtered_tg, len)
View(filtered_tg_arranged)

#フィルタリング・ソートをネストにして一度に行うことも可能
filtered_tg_nest <- arrange(filter(ToothGrowth, dose == 0.5), len)
View(filtered_tg_nest)

#パイプ演算子を使うと、どのような処理が行われるか記述しやすくなる
#ctrl + shift + m - パイプ演算子を入力
filteres_toothgrowth <- ToothGrowth %>%
	filter(dose==0.5) %>%
	arrange(len)

#投薬した薬ごとに分類 → 平均値を比較する 
filteres_toothgrowth <- ToothGrowth %>%
	filter(dose==0.5) %>%
	group_by(supp) %>%
	summarize(mean_len=mean(len, na.rm=T), .group="drop")

View(filteres_toothgrowth)
```

![R008.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/337578/6ac56de6-143d-8412-a1d1-3d9fef0877a1.png)

![R009.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/337578/88f594c8-9896-e1c4-25c6-6cb4c38c3358.png)
STUDIOのカルーセルにインジケーターをつける

# 環境
- STUDIO(Starter以上)
- GoogleTagManager

# 経緯
STUDIOでLPを作っていてインジケーター付きのカルーセルを実装する必要があったのですが、
2023/1/25時点でまだインジケーターが未実装だったため、GoogleTagManager（以下タグマネ）でつけました。

# 実装
流れとしては以下になります。
※タグマネの導入は省きます
1. STUDIOのカルーセルを設置
1. インジケーターをボックスなどで設置
    1. インジケーターは地道に自作します
1. 1のulとインジケーターにJS用のidを付与
    1. STUDIOの右側の設定にある`ID`から付与します
1. タグマネのカスタムHTMLにJavaScriptを記述
    1. STUDIOの方が公開されていればプレビューできる
1. カスタムHTMLを公開

JSの方はこちらを参考にさせていただきました
scrollIntoViewを使ったカルーセル： 
https://zenn.dev/phi/articles/modern-javascript-css-carousel
インジケーターとの連動： 
https://blog.ver001.com/javascript-slider-thumbs/


#### 注意点
今回STUDIOやタグマネ使うのが初めてだったため色々ハマりました。
- STUDIOが公開されていないとタグマネのプレビューで確認できない
- カルーセル（リスト）のアイテムには個別でidをつけられない（アイテム全部に同じidがついてしまう）
- タグマネではJSの`const`、`let`、アロー関数などは非対応
【備忘録】Ruby 2.7で RubyXLを使っているとFrozenError can't modify frozen String: ""  というエラーが出る

Rubyのバージョンを2.7系に上げたときにRubyXLを使っているファイル内で```FrozenError can't modify frozen String: ""```というエラーが出るようになりました。

#### 結論

rubyXLを3.4.11以上のバージョンに上げることで解消された。

#### 原因
調べてみるとrubyのバージョンを2.7にあげた時に、gemのバージョンが追いついておらず同じエラーが起きたという記事がありました。
Ruby2.7からnil.to_sがfrozen stringを返すようになったことが原因のようです。

以下のcommitで修正されたようなので、バージョン3.4.11以降であれば動くと思います。

https://github.com/weshatheleopard/rubyXL/commit/f0ed6a28dd4f5a1b39e64123be6dbfcdee439145
Web技術の基本 Chapter3　まとめ

## HTTPメッセージ

- HTTP(HyperText Transfer Protocol)は、HTMLやテキストファイルなどのコンテンツのやりとりを行うときに使われるプロトコル。
- HTTPメッセージとは、サーバーとブラウザ間で行われる通信のこと。
- HTTPメッセージには、「HTTPリクエスト」「HTT Pレスポンス」の２つがある。
    - HTTPリクエストとは、webブラウザからの要求のこと
    - HTT Pレスポンスとは、webサーバーからの返答のこと

## HTTPリクエスト / HTTPレスポンス

- HTTPリクエスト は、「リクエスト行」「メッセージヘッダー」「メッセージボディ」の3つに分けることができる。
    - リクエスト行
        
       どのような処理をしてほしいかという要内容。
        
    - メッセージヘッダー
        
        ブラウザの種類やバージョン、送信データの形式などの付加的な情報。
        
    - メッセージボディ
        
        webページ内のフォーム欄などのデータをサーバーに転送
        
- HTTPレスポンスは、「ステータス行」「メッセージヘッダー」「メッセージボディ」の3つに分けることができる。
    - ステータス行
        
        HTTPリクエストに対して処理結果を送信。
        
    - メッセージヘッダー
        
        ブラウザの種類やバージョン、送信データの形式などの付加的な情報。
        
    - メッセージボディ
        
        ブラウザからリクエストされたHTMLなどのデータを格納
        

## HTTPメソッド

- HTTPメソッド、HTTPリクエストを用いてwebサーバーに具体的な内容を伝えている。
    - GETメソッドとは、HTMLなどのコンテンツを取得したい場合に使用。
    - POSTメソッドは、データをサーバーに送信する際に使用。
    
    この二つが主に使用される。
    

- 他にもHEAD,PUT,DELETE,CONNECT,OPTIONS,TRACEがある。
    - PUTは、データをアップロードをする
    - DELETEは、指定したデータを削除する
    

## ステータスコード

- ステータスコードとは、HTTPレスポンス内に含まれる処理結果
    - 100 → HTTPリクエストを処理していることを通知
    - 200 → HTTPリクエストに対して正常に処理できたかを通知
    - 300 → HTTPリクエストに対してブラウザ側で追加の処理が必要であること
    - 400 → クライアント(ブラウザ)のエラーであること
    - 500 → サーバーのエラーであること

## メッセージヘッダー

- メッセージヘッダーとは、HTTPリクエストとHTTPレスポンスで詳細な情報を送信するときに必要。複数のヘッダーフィールドからなる。

## HHTP/1.1のやり取り

- HTTPには、HTTP/0.9、HTTP/1.0、HTTP/1.1、HTTP2という風にアップデートしてきた。
- HTTP/1.1より以前の場合は、一回の通信でコネクションを切断していたが、1.1以降はコネクションを継続して利用することでwebページないに多くの情報を載せることができるうになった。これをHTTPキープアライブという。
- HTTPパイプラインと呼ばれるサポートが1.1以降追加されたのでデータ転送時間を短縮できるようになった。

## HTTP2へアップデート

- 基本的にはHTTP1.1と変わらない。
- HTTP1.1では、HTTPレスポンスが終わるまで待つ必要があったので、HTTP2から仮想的な通信経路(ストリーム)を複製することでHTTPリクエストとレスポンスのやり取りをスムーズにした。

## HHTPの仕組み

- なりすましサイトなどによって個人情報を抜き取られる場合がある。そのような脅威からデータを守る仕組みをHTTPSという。
- HTTPSとは、HTTPに加えてSSL(Secure Sockets Layer)やTLS(Transport Layer Security)を利用して通信の暗号化を行なっている。
- HTTPSでは3つの仕組みにより安全性を確保している。
    - 盗聴防止
        - データの暗号化を行う。
    - 改ざん防止
        - データから一意の短いデータを取り出し計算して一致するかをみる。
    - なりすまし防止
        
        SSLサーバー認証という電子証明書を配置していることにより、運営の身元がわかるようになっている。
        

## HTTPのやりとり

<暗号化の決定> → <通信の証明> → <鍵の交換> → <暗号化方式の確認>

- これら4つのフェーズのやり取りをSSL/TLSハンドシェイクと呼ばれる。

## ステートフルとステートレス

- ステートレスとは、状態を維持しないことを表し、1往復の処理が完結された処理であること。(HTTPの通信)
- ステートフルとは、状態を維持し続けることを表し、相手の情報を保持したまま処理を行う。
    
    複数のクライアントに対しては負担が大きくなる。
    

## Cookie(クッキー)

- webサイトに情報を保持管理する必要がある場合には、Coookieというデータが用いられる。
- Cookieの送信でwebサーバーはHTTPレスポンスに「Set-Cookie」ヘッダーを含めることで送信できる。
- webブラウザーは、HTTPリクエストに「Cookie」ヘッダーを含めることで送信できる。
- 有効期限が設定されていないCookieはブラウザーを閉じると同時に削除され、「セッションCookie」と呼ぶ。
- 有効期限が設定されたCookieはブラウザーを閉じても消去されず有効期限が来るまで残り続ける。

## セッション

- webブラウザーとwebサーバーのやり取りにおいて、一連の関連性のある処理の流れをセッションと呼ぶ。
- セッションを管理するに置いてwebブラウザーを認識するための情報を「セッションID」と呼ぶ。
- セッションIDを用いてcookieを使う場合がほとんどですが、cookieが使えないwebブラウザーがあるため、その場合はURLにセッションIDを含めることができる。だが、情報漏洩の危険があるためその手法は利用されない。

## URL

- 情報やデータを識別するための記述方法をURI(Uniform Resource Identifiler)と呼ぶ。
- URIのうちリソースが存在する場所をあらわす物をURL(Uniform Resource Locator)という。
- URIのうちリソースの名前をあらわす物をURN(Uniform Resource Name)という。
顧客分析の手順 -  分析フォーマットの適用例：パーセンタイルプロファイリング  削除候補商品と優良顧客の関係

:::note
この本書は2017年4月1日にTeradata Japanのブログに掲載された内容を、再掲載したものです。
掲載内容の正確性・完全性・信頼性・最新性を保証するものではございません。
また、修正が必要な箇所や、ご要望についてはコメントをよろしくお願いします。
:::


著者 山本 泰史 （やまもと やすし）

# 顧客分析の手順

## 第15回： 削除候補商品と優良顧客の関係
「パーセンタイルプロファイリング」を利用した分析例として、今回は「優良顧客の育成」をテーマとした分析例をご紹介します。顧客により多く支出いただくためには、それに見合う価値を提供しなければなりません。価値の主たるものとして、商品やサービスが存在します。そして今日、企業は数多くの商品やサービスを扱うようになってきています。

### 分析の前提
今回は分析実施の前提として、物販業を営む企業を想定します。オンライン販売や物理店舗における小売販売がその代表ですが、物質として存在する商品を直接消費者に対して販売する企業では、一般に数多くの商品を扱っています。目的は一回の来店機会においてより多くの商品を販売できるように、そして「何も買うものが無い」ために顧客ががっかりしてしまわないようにすることです。

そして、次々に新たな商品が開発され、投入されると、それと引き換えに社会的な役目を終えた、もしくは役割が縮小する商品も出てくることになります。売れ筋の商品は移り行き、そこから外れた商品は削除されることになります。そして扱う商品が膨大になればなるほど、削除商品の選定は雑になりがちです。

### 全体 vs. 特定セグメント
この分析では、全顧客を対象としたクインタイル(5等分割)分析と、扱い停止予定の商品を購入している顧客セグメントを対象としたクインタイル分析を実施し、比較しています。図23 は全顧客が対象、図24 は扱い停止予定商品購入セグメントが対象です。


<img width="700" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2768546/218d51f4-8cbe-3f4f-1c18-d9db90c71de2.png">


<img width="700" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2768546/f8d3e554-76e0-052f-1cf4-3830941c10d8.png">


両方の分析ともに、年間買上金額順で顧客を並び替え、年間買上金額の高い順から顧客を 5つのグループに分割しています。グラフのバーとして表示している指標値は所属する顧客の年間買上金額の合計値を所属顧客数で割った、平均的な 1人あたりの年間買上金額です。一方は全顧客を対象としており、一方は特定の商品を購入した顧客に絞り込んでいるため、当然ながら顧客数は大きく異なります。従って比較をし易くするために 1人あたりの年間買上金額を指標値として利用しています。

このケースでは、扱い停止を予定している商品を購入している顧客セグメントは、全般的に全顧客の平均的な買上金額よりも高い買上金額を記録していることが分かります。本来、この商品が扱い停止になる理由は、おそらく販売数量が少なくなっているか、後継の商品を投入するためのいずれかと想定できます。

### アプローチの方向性
しかしながらこの分析結果が示すように、当該商品がこのような高い買上金額を示す顧客群に支持されていることが分かれば、この商品を簡単に削除するわけにはいきません。扱いボリュームを減らす等の検討は必要かもしれませんが、扱いを停止してしまうのは、これらの顧客の来店理由を 1つ無くしてしまうことになりますし、来店いただけたにしてもこの商品の買上が減り、来店あたりの支出額が低下する可能性があります。

物販業に限らず、「ビジネスにおいてもっとも希少性が高いのは、顧客が自社チャネルに足を運んでくれた瞬間」です。この瞬間において良い提案(=商品の陳列)ができれば、顧客はそれを受け入れ、支出を許容してくれます。でも欲しいものが見つからなければ、がっかりしてしまいます。当然ながら支出も増加しません。この分析例においてこの商品は、もしかしたら来店理由になっているかも知れず、また支出増の 1ファクターになっているのです。

また、後継の商品を投入する場合には、それが本当に後継としての役割を担っているのかが検討されなければなりませんし、これら顧客群の後継商品への移行をスムーズに進めるためのアプローチが必要になります。陳列レベル、もしくはダイレクトメール等を通じたアプローチで「従来商品(今回扱い停止の商品)より良くなった点、メリット」等を伝え、顧客に理解を促すことが必要になります。

### パーセンタイルプロファイリングの適用分野
パーセンタイルプロファイリングは大きく、以下の内容を定義して実施されます。

１． 分析の対象となる顧客セグメントの特定

２． 顧客をグルーピングする基準定量指標の決定

３．グルーピングする数の指定

４．表示させる定量指標の特定

これらは全て任意に指定します。例えば 3.の値を「4つのグループ」に指定すればクォータイル、「5つのグループ」に指定すればクインタイル、「10のグループ」に指定すればデシル分析となります。最大100(パーセンタイル)までの任意の整数を指定可能であるため、「パーセンタイル」プロファイリングと呼ばれています。 また、2.で指定した基準定量指標と、4.で指定される定量指標は異なっていても構いません。例えば、図23、図24で表示する基準定量指標を買上金額で把握しつつ、定量指標を「平均買上点数」とすることも可能です。これにより、買上金額が高い顧客は、平均買上点数が高い故に買上金額が高いのか、それとも単価の高い商品を購入しているために買上金額が高いのかを理解できるようになります。

パーセンタイルプロファイリングのコンセプトは、「等しい顧客数で等分したにも関わらず、定量指標で分割した場合にどのような指標量差異が現れるか？」を把握するための分析であり、定量指標で顧客セグメントを分解することによってセグメント構造を明らかにすることが目的です。



#### Teradata Vantageへのお問合せ
[Teradata Vantage へのお問合せ](https://www.teradata.jp/About-Us/Contact)
派遣社員のための記事

派遣社員には様々な悩みがつきものです

将来どうなるんだろうか
このまま派遣社員を続けてもいいのかな

しかし、派遣の仕組みや働き方を知ることで、将来に役に立つ働き方ができるのです。

https://papadanblog.com/
【初心者向け】Rubyのinitializeメソッド（初期化）とは？

今回は、`initialize` メソッドについてについて解説します。

## initializeメソッドとは？

`initialize` は特殊なメソッドで、インスタンスを初期化したい処理が発生する場合に使います。

そのため、必要がない場合は記載する必要はありません。

では、何が嬉しくなるかということを説明します。

## initializeを定義した場合

まず、下記のサンプルコードを見てください。

```ruby
class Animals
  def initialize(name)
    @name =name
  end

  def hello
    "#{@name}が鳴きました"
  end
end

animals = Animals.new('象').hello
p animals

#"象が鳴きました"
```

上記コードで `Animalsクラス` を作成する際に、象を引き渡し `.hello` でインスタンスメソッドを実行します。

そうすると「象が鳴きました」と出力されます。

インスタンス、クラスの概念が分かりきっていない方は

まぁこんなものかという感じで、頭に入れておいて下さい。

## initializeを定義せずに同じ動作をするコード

```ruby
class Animals
  def name=(name)
    @name = name
  end

  def hello
    puts "#{@name}が鳴きました"
  end
end

animals = Animals.new
animals.name = '象'
p animals.hello
#"象が鳴きました"
```

initializeを実行しない場合は、

1. クラスを新規作成
2. インスタンスメソッドのnameへ引数を設定
3. pメソッドで表示

鳴き声だけを表示させるなら、これだけでもいいかもですが、

複数の処理が発生した場合、「クラスをnewしてインスタンスメソッドへ引数を引き渡してという処理」を、各処理毎に毎回設定しなければいけません。

この手間を削減できるのが `initializeメソッド` になります。

なかなか難しいメソッドですが、Railsではしっかりと使うメソッドにもなりますので、全て理解しきれないかもしれませんが、こういうものだという部分だけ理解しておくと良いでしょう。
SAA試験備忘録

### プロビジョンドIOPS SSDとスループット最適化HDDの比較

・　プロビジョンドIOPS SSD
I/O負荷の高いワークロード、特にストレージパフォーマンスと一貫性に左右されるデータベースワークロードのニーズを満たすように設計されている。

・　スループット最適化HDD
コスト効率の良いHDDを利用してビッグデータやログデータ処理向けのEBS。
高いスループット機能があるという点においてはプロビジョンドIOPS SSDと同じだが、性能は劣る。
コストを最優先する場合にこちらを使う


### 異なるAWSアカウント上のリソースへのアクセスの委任

クロスアカウント許可とIAMロールを設定。
→特定のアカウントにある特定のリソースを別のアカウントのユーザーと共有できる。


### API Gatewayに対するアクセス権限の設定方法

IAMアクセス権限によって制御することができる。
APIの呼び出し等をAPIコール元にアクセスを許可するIAMポリシーを作成して設定することが必要。


### DynamoDBのプロビジョンドスループットモードとオンデマンドモード

プロビジョンドスループットモード

>プロビジョニングモードを選択した場合、アプリケーションに必要な 1 秒あたりの読み込みと書き込みの回数を指定します。Auto Scaling を使用すると、トラフィックの変更に応じて、テーブルのプロビジョンドキャパシティーを自動的に調整できます。これにより、コストの予測可能性を得るため、定義されたリクエストレート以下に維持されるように DynamoDB を制御することができます。

>>参照　https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/HowItWorks.ReadWriteCapacityMode.html

以下条件の場合に適切なオプション
・アプリケーションのトラフィックが予測可能
・トラフィックが一定した、徐々に増加するアプリケーションを実行
・キャパシティの要件を予測してコストを管理できる

オンデマンドモード

>Amazon DynamoDB オンデマンドは、容量計画なしで 1 秒あたりに数千ものリクエストを処理できる柔軟な請求オプションです。DynamoDB オンデマンドには、読み取りおよび書き込みリクエストのリクエストごとの支払い料金が用意されているため、使用した分だけ課金されます。
オンデマンドモードを選択すると、DynamoDB は、前に到達したトラフィックレベルまで拡張または縮小して、ワークロードを即座に受け入れることができるようにします。ワークロードのトラフィックレベルが新しいピークに達すると、DynamoDB はワークロードに対応するように迅速に対応します。オンデマンドモードを使用するテーブルは、同じ 1 桁ミリ秒のレイテンシー、サービスレベルアグリーメント (SLA) のコミットメント、DynamoDB が既に実現しているセキュリティを提供します。オンデマンドは、新しいテーブルと既存のテーブルの両方に選択できるだけでなく、コードを変更せずに既存の DynamoDB API を引き続き使用することができます。

>> 参照　https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/HowItWorks.ReadWriteCapacityMode.html

以下条件の場合に適切なオプション
・不明なワークロードを含む新しいテーブルを作成
・アプリケーションのトラフィックが予測不可能
・わかりやすい従量課金制の支払いを希望


### 暗号化されたAMIを別のAWSアカウントと共有する方法

AMIのLaunchPermissionプロパティを変更することが必要。
AWS KMSを利用して暗号化されたAMIを利用するには、その暗号化に利用したCMK自体を共有することが必要。


### DynamoDBトランザクション機能

DynamoDBテーブルに対する1つのオペレーションとして複数の項目の追加、更新、削除が必要となる複雑なビジネスワークフローを管理できる。


### Lambda関数が他のAWSリソースにアクセスする場合

その際はLambdaリソースを使用する他のアカウント
AWSサービスへのアクセス許可を付与するには、リソース自体に適用するポリシーをIAMロールに設定する。

### Amazon eventBridge
AWS サービスを自動化して、アプリケーションの可用性の問題やリソースの変更などのシステムイベントに自動的に応答する機能を作成できる
AWS Certificate Manager（ACM）に対して、更新の対象となる ACM 証明書に対して AWS ヘルスイベントを生成することができる


### Route53レコードは標準のDNSレコード
AWSリソースを構成する場合はALIASレコードを使用する必要がある。（エンドポイントのIPアドレスが動的に変更するため）


### IAMロール
AWSサービスやアプリケーションなどのエンティティに対してAWS操作権限を付与するための仕組み。
ロールにはパスワードやアクセスキーを関連づけられない。ロールを使用するときは、一時的なセキュリティ認証情報が動的に作成される。
アクセスキーIDおよびシークレットアクセスキーが不要のため、アクセスキーの流出といったセキュリティリスクを回避できる。
IAMロールを利用すると、AWSサービスから別のAWSサービスへのアクセスをキャ化することも可能になる。
例)
Lambda関数からS3バケットにオブジェクトをコピーしたい場合、Lambdaの特定の関数に対してS3バケットへの書き込み権限を持つIAMロールをアタッチすることで実現できる。

### セキュリティグループとネットワークACL
・セキュリティグループ
インスタンス単位で許可
ステートフルなので戻りのトラフィックは不要

・ネットワークACL
サブネット単位で許可/拒否
ステートレスなので戻りのトラフィックの設定も必要


### 参考
https://www.udemy.com/course/aws-knan/