OmniAICreator/Qiita-1.07M huggingface dataset:
【Tableauの基本】初心者向け_テーマ3：表計算(2/2)

# 1 主要な表計算関数

■ 今回学んだ関数
①FIRST()
②INDEX()
③LAST()
④LOOKUP(expression, [offset])
⑤PREVIOUS_VALUE(expression)

■ 今回学んでいない（もしくは以下で登場した関数）
・RANK関数
（RANK、RANK_DENSE、RANK_MODIFIED、RANK_PERCENTILE、RANK_UNIQUE）

・RUNNING関数
RUNNING_AVG、RUNNING_COUNT、RUNNING_MAX、RUNNING_MIN、RUNNING_SUM

・WINDOW関数
（WINDOW_AVG、WINDOW_COUNT、WINDOW_MEDIAN、WINDOW_MAX、WINDOW_MIN、WINDOW_SUM）


https://qiita.com/tableau_oji_san/items/55ac2bc3b44136f02b6b



# ①FIRST()
:::note info
・数：0 → ‐1 → -2 → -3 → -4 → -5 と数える
最初の行→現在の行まで何行離れているかを返す関数です。
その離れている行数のことをオフセットと呼称します。
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618835/b4568f53-dbe7-c765-3072-731b88298710.png)




# ②INDEX()
:::note info
・数：1 → 2 → 3 → 4 → 5 → 6 と数える
・FIRST関数同様、行番号を振る関数です。
・INDEX関数は1からカウントが始まります。
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618835/d7945e87-3be9-d1f8-0105-85fd7a7a5877.png)








# ③LAST()
:::note info
・数：6 ← 5 ← 4 ← 3 ← 2 ← 1 ← 0 と数える
・FIRST関数と逆で、最後の行から最初の行に向かってカウントします。
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618835/e76a1896-2391-8a4f-5f22-19cda0c964d8.png)



# ④LOOKUP(expression, [offset])
:::note info
・現在の行からの相対オフセットとして指定されたターゲット行にある式の値を返します。
・パーティション内の最初/最後の行に相対的なターゲットには、オフセット定義の一部として FIRST() + n と LAST() - n を使用してください。
・offset を省略した場合は、比較対象行をフィールド メニューで設定できます。
・この関数は、ターゲット行を特定できない場合は、NULL を返します。
:::



 ■ 初年度、来年度、昨年度
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618835/037c8e65-fa2c-ff88-2d93-8f030f4e5269.png)

■ 初年度との差
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618835/5afc8b3d-d55a-17be-2623-679bb3462ebf.png)



## ・関数の記入例

#### ・[offset]=-1：昨年度を参照
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618835/474665a8-eeec-d21c-680b-88cbb599d41e.png)

#### ・[offset]=1：翌年度を参照
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618835/82437b79-3b9b-b7e3-5d25-0eeca3a817ae.png)

#### ・[offset]=FIRST()：初年度を参照
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618835/a4b13f9c-9c5a-68ef-7809-ec6c49000977.png)




# ⑤PREVIOUS_VALUE(expression)

:::note info
・前の行のこの計算の値を返します。
・現在の行がパーティション内の最初の行の場合は、指定された式を返します。
・累積値を返す
:::


#### ・例：PREVIOUS_VALUE(0) + SUM([売上])
・これではTableau標準機能の「累計」等で代用可能

#### ・例：IF文と組み合わせて、特定の条件下で累積するなどで活用可能

利益70万円以上が続いた回数

IF SUM([利益])>700000 THEN
PREVIOUS_VALUE(0)+1 ELSE 0 END



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618835/4e6c931c-4e2f-222a-83af-c3c4b34166a0.png)





# 参照させていただいたサイト

Tableau公式HP

https://help.tableau.com/current/pro/desktop/ja-jp/functions_functions_tablecalculation.htm

クラスメソッドさん

https://dev.classmethod.jp/articles/tableau_function_table1/

@zaki_001(zaki)さん

https://qiita.com/zaki_001/items/b783a044c1fc1681db98

プリンシパルさん

https://www.principle-c.com/column/tableau/tableau-how-to-previous_value-function/
一言概要：システム構築編（１）

# 導入

![_25a02f4e-74af-493f-be2d-31271f989b81.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2290515/6f8db431-9422-c2fb-8d33-d3ca75db2be7.jpeg)

こんにちは。AIシステムの構築に欠かせない技術、「**マイクロサービス**」、「**コンテナ技術**」、「**サーバーレスアーキテクチャ**」について、一言で紹介したいと思います。

これらの技術を活用することで、より効率的な開発プロセスとシステム運用を実現できます。さらに柔軟でスケーラブルなアプリケーションの構築が可能となり、デジタルトランスフォーメーション（DX）の重要な礎となるでしょう。

:::note warn
この記事は生成AIを活用しています。
:::

# **マイクロサービス**

![_91f635f2-827a-4e16-8549-ca16e261fcfc.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2290515/2b25c42f-d3ba-69e8-3847-350964ea33f0.jpeg)


**概要:**

マイクロサービスとは、大きなアプリケーションを小さくて独立した部分に分ける手法です。それぞれの部分は自分固有のタスクを持ち、他の部分とは独立して機能することができます。

**仕組み:**

例えば、学校のクラブ活動を思い浮かべてみてください。サッカー部、美術部、科学部など、それぞれが独自の活動をしているけれども、学校全体としては一緒に機能しています。各部は自分たちの活動を自由に計画できますが、学校全体のルールには従わなければなりません。マイクロサービスも同じで、各サービスは独立して動きますが、全体として1つの大きなアプリケーションを形成しています。

# **コンテナ技術**

![_776b8143-8b97-4d95-b877-55a448f82d1e.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2290515/58953e9b-f644-102b-5668-93846a536501.jpeg)

**概要:**

コンテナ技術とは、アプリケーションを小さな箱（コンテナ）に入れて、どこでも同じように動かせるようにする技術です。この箱の中には、アプリケーションが動作するために必要なすべてが含まれており、どのコンピューター上でも問題なく動かすことができます。

**仕組み:**

学校の文化祭で、各クラブが自分たちのブースを持っているところを想像してみてください。各ブースでは、そのクラブの活動に必要なものがすべてそろっており、クラブのメンバー以外は何も用意しなくても、そのブースで活動できるようになっています。コンテナも同じで、アプリケーションが必要とする環境や設定がすべて含まれているため、どんなコンピューターでもそのコンテナを開けば、アプリケーションがすぐに動き出すことができます。

# **サーバーレスアーキテクチャ**

![_34989db4-cf82-40f0-a5b4-61ec525bfe48.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2290515/a545b7af-5baa-a501-808c-be0ed58adbf4.jpeg)

**概要:**

サーバーレスアーキテクチャとは、アプリケーションを動かすためにサーバーを自分で管理する必要がなくなる技術です。クラウドサービスがサーバーの管理をすべて行ってくれるため、開発者はコードの記述に集中することができます。

**仕組み:**

学校の図書館を使うときに、本を読みたいだけなのに自分で本棚を建てたり、本を並べたりする必要はありませんよね。図書館がそれをすべて行ってくれるため、あなたは好きな本を選んで読むだけで済みます。サーバーレスも同じで、プログラムを動かすための「本棚や本」の管理をクラウドサービスが行ってくれるため、あなたはプログラムの「読書」に集中することができます。

# まとめ

![_f553a8a1-bdad-438a-9c12-61af71120a88.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2290515/6883e43e-0b9c-ed0a-9c6b-2b76f94a49d4.jpeg)


以上、マイクロサービス、コンテナ技術、サーバーレスアーキテクチャについて説明させていただきました。これらの技術は、現代のソフトウェア開発において非常に重要な役割を果たしています。

これらの技術を適切に組み合わせることで、「AIシステム」という学校をより効率よく構築し、管理やメンテナンスが容易になるでしょう。今後も、これらの技術はソフトウェア開発の世界で中心的な役割を果たし続けるでしょう。

つまり、**卒業に必要なポイント**です。
プログラミング向けフォント「0xProto」の紹介

# 「0xProto」フォントとは

「0xProto」フォントは、プログラミング向けのフォントです。文字の読みやすさを重視しています。

https://github.com/0xType/0xProto

最初のリリースは2023年5月で、その後も何度かアップデートされています。この記事は、執筆時点のバージョンである0xProto 1.500をもとに書かれています。

* 1.000：2023年5月
* 1.500：2023年12月
* 2.000：2024年5月、イタリック体が追加、MacではHomebrewでインストール可能に
* 2.200：2024年9月、ボールド体が追加

# プログラミング向けのフォントとは

プログラミングにおけるフォント選択は、単なる見た目だけの問題ではなく、それ以上の意味があります。ソースコードが読みやすくなるようにデザインされているフォントを選ぶべきです。たとえば、以下のような観点があります。

* インデントやコードの構造が見えやすいか。縦のラインが揃っていると見やすい場合が多いため、等幅フォントが好まれます。
* 文字の識別がしやすいか。似たような文字、たとえば、`0`（ぜろ）と`O`（オー）、`1`（いち）と`l`（エル）と`I`（アイ）などの文字が明確に区別できることが重視されます。
* 長時間の作業でも疲れにくいか。文字の形が明確で、コントラストやサイズが適切に調整されていることが大事になります。

また、モダンなフォントのなかには、リガチャ（合字）を使って、プログラミングでよく使われる記号列を見やすくする工夫がされているものもあります。たとえば、`!`と`=`が並んだ場合に`≠`（ノットイコール）として表示する、などです。

# 0xProtoの特徴

0xProtoは、プログラミング向けのフォントとしてデザインされている、文字の識別がしやすい字形の等幅フォントです。

同様のプログラミング向けのフォントはいくつかありますが、0xProtoは各アルファベットの字形が独特です。個人的に一番癖を感じるのは小文字の`f`でしょうか。

![](https://github.com/0xType/0xProto/blob/811b631109dbde8332a845f3df077a55f37eb03e/images/examples.png?raw=true)

アルファベットとしての美的バランスという観点では他のフォントに劣る感じもありますが、その字形によって、0xProtoならではの特徴がより良く出るようになっています。

他の文字と異なる部分がはっきりと強調されています。そのため、文字の識別がしやすくなっています。

![](https://github.com/0xType/0xProto/blob/811b631109dbde8332a845f3df077a55f37eb03e/images/distinction.png?raw=true)

また、わずかに丸みを帯びた広がりのある字形で、小さなサイズでも読みやすいように工夫されています。

![](https://github.com/0xType/0xProto/blob/811b631109dbde8332a845f3df077a55f37eb03e/images/legibility.png?raw=true)

一般に、等幅フォントでは暗い部分と明るい部分が不均一になりがちですが、0xProtoはその独特の字形によってバランスが良くなっています。

![](https://github.com/0xType/0xProto/blob/811b631109dbde8332a845f3df077a55f37eb03e/images/whitespace.png?raw=true)

一方、リガチャは（他のモダンなフォントと比較すると）少し控えめです。たとえば、`!`と`=`が並んだ場合にそのふたつが近づいてひとかたまりになりますが、`≠`のような別の文字にはならず`!`と`=`として認識できます。このくらいが本来の意味でのリガチャ（合字）であり、読みやすく編集もしやすいです。

![](https://github.com/0xType/0xProto/blob/811b631109dbde8332a845f3df077a55f37eb03e/images/all_ligatures.png?raw=true)

もちろん、リッチなリガチャが好きな人もいるでしょう。その場合は0xProtoの代わりにFira CodeやJetBrains Monoなどのフォントを使うのが良さそうです。

# Texture Healing

0xProtoの最新版では、読みやすさ向上のために「Texture Healing」という機能が導入されています。これは[monaspace](https://github.com/githubnext/monaspace)フォントで採用されている機能で、0xProtoにも採用されました。

プロポーショナルフォント（等幅でないフォント）では、横幅が狭い文字は狭い幅で、横幅が広い文字は広い幅で表示されます。しかし等幅フォントでは、横幅が狭い文字も広い文字と同じ幅で表示されます。そのため、横幅が狭い文字と広い文字が並ぶとバランスが悪くなります。

これを改善するのがTexture Healingです。全体的には等幅フォントとしての幅を保ちつつ、横幅が狭い文字と広い文字が並んだときには狭い文字の幅を狭く、広い文字の幅を広くするように調整します。たとえば`minimum`という単語の場合、`m`と`i`が並んでいる箇所で`m`の幅を広く、`i`の幅を狭くします。これによって、等幅フォントでもバランスが良くなり、読みやすくなります。

![](https://github.com/githubnext/monaspace/blob/380f29b3277ff46b8bd8577bdd7d1b60358e6c6c/docs/images/LM-GH-TextureHealing-Documentation-10.png?raw=true)

# おわりに

プログラミング向けのフォントはいろいろありますが、0xProtoはそのなかでも良いフォントだと考えています。私はしばらくこれを使っていくつもりです。
画像生成AI for WindowsをPythonでやってみた

背景：

昨今、画像生成AIがメディアに登場し、筆者もやってみた。
なお、今回はAIモデルそのものを構築するのではなく、構築されたものを使用することとする。
※筆者はAI生成モデルを構築できるほどの知識量はないため

目的：

Pythonを使用して、プログラムを駆使して、画像の生成まで挑戦する
※Promptについては、深追いしません。

環境：
- OS: Windows
- IDE：VSCODE
- Git for windowsインストール済
- 必要ソフト：CUDA12.3
- Pythonの仮想環境整備済

準備：
① CUDAのインストールは[ここ](https://developer.nvidia.com/cuda-downloads?target_os=Windows)
②関連ライブラリをpipでインストール
```terminal
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121
pip install --upgrade diffusers transformers scipy
```
③AIのライブラリサイト（Hugging Face）のユーザアカウント作成は[ここ](https://huggingface.co/)
※このサイトはいろんなAIを訓練できるモデルがたくさん集まっている

④たくさんのモデルがあるない中で、[これ](https://huggingface.co/CompVis/stable-diffusion-v1-4)を選んだ。

ソースコード：

```py
# ライブラリーのインポート
from diffusers import StableDiffusionPipeline
import os 
 
# モデルのインスタンス化
model = StableDiffusionPipeline.from_pretrained("CompVis/stable-diffusion-v1-4")
model.to("cuda")

prompt = "Tokyo Sky Tree by Marc Chagall"
# 画像数
num = 4

filename = 'ai_test'

for i in range(num):
  # モデルにpromptを入力し画像生成
  image = model(prompt).images[0]
  # 保存
  outputfile = f'{filename}_{i:02} .png'
  image.save(os.path.join(os.getcwd(), outputfile))
```

生成された画像：

![ai_test_ _00 .png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576081/fac1daac-92b5-5b0b-5c02-38c576dae675.png)

![ai_test_ _01 .png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576081/08ad0a69-b9ba-ff48-c735-9390b67e91fd.png)

感想：

筆者のPC環境では20分程度で一枚の遅さでしたので、onlineで生成したほうが早いかもしれません。
each などのarrayメソッド時の、break, return, nextの挙動

## break
ループを抜ける

```
users.each | user | do
 puts user
 break if user == 'hoge太郎'
end
　→userが「hoge太郎」の時、ループを終了しeach処理を抜ける
```

# return
メソッドを抜ける

```
class hogehoge
 def puts_name(users)
  users.each | user | do
  puts user
  return if user == 'hoge太郎'
 end
end
　→userが「hoge太郎」の時、hogehogeメソッドを抜ける
```

# next
ループの次の要素に行く

```
users.each | user | do
 puts user
 next if user == 'hoge太郎'
 puts 'hoge太郎のときは出力されないよ'
end
　→userが「hoge太郎」の時、次の要素に即座に行く、後続の処理（ここで言う、puts）は実行されない
```
ActiveRecord scopeについて

## scope とは
クエリを定義できるもの
よく使うものであったり、変数的に命名したいものを定義できる
引数を渡すこともできる

## 例
```
class Post < ApplicationRecord
  scope :published, -> { where(published: true) }
  scope :recent, ->(days_ago = 7) { where("created_at >= ?", Time.now - days_ago.days) }
end
```

## クラスメソッドとの使い分け
条件分岐など、ロジックが複雑になりそうなものに関しては、クラスメソッドを定義する

```
class Post < ApplicationRecord
  def self.recent(days_ago = 7)
    where("created_at >= ?", Time.now - days_ago.days)
  end
end
```
素数の個数

https://paiza.jp/works/mondai/double_roop_problems/double_roop_problems__prime_number_easy

全然分からなかったですね。。。
これで行けるかなと思ったんですが。

```py
N = int(input())
cnt = 1 #2も素数のため
for i in range(3,N+1):
    for j in range(2,10):
        if i % j == 0:
            continue
    else:
        cnt += 1

print(cnt)

```
とりあえず素数って
１とその数以外割り切れない数ってやつですよね。

とりあえず2以上なのは間違いないでしょう。
条件にも入ってますし。

とりあえず10まで考えてみます。

2 = 1, 2　と2つしかないので素数。
3 = 1, 3　と2つしかないので素数。
4 = 2で割り切れちゃうので素数ではない。
5 = 1, 5 と2つしかないので素数。
6 = 1, 2, 3, 6と　２も３も割り切れるので素数ではない。
7 = 1, 7と、2つしかないので素数。
8 = 1, 2, 4, 8　と２と4で割り切れてしまうので素数ではない。
9 = 1, 3, 9 と3で割り切れてしまうので素数ではない。
10 = 1, 2, 5, 10　と2と5で割り切れてしまうので素数ではない。

パターンを見ると、どうも、半分にできるものは約数と考えて良さそうです。
逆に、半分以上だと絶対に正解は出ない感じです。
たしかにそうだわ。
ちなみに乗の出し方は**xだった。0.5乗はそのままだけど、数字型である必要があるので
intで小数点以下切り捨て。
ルートって忘れてたけど、0.5乗だったな。

ロジックを理解したところで本題

```py
N = int(input())
cnt = 0
for i in range(2,N+1):
    flag = True
    for j in range(2,int(i ** 0.5) + 1):
        # 余り０なら約数
        if i % j == 0:
            flag = False
            break
    if flag:
        cnt += 1

print(cnt)

```
[fill_between(x, y1, y2)] 平均値とｙ軸で幅を出した結果のプロットをしたいのにうまくいかない

# 問題
グラフの表現が一次関数的にならない


下記のグラフ（ぐちゃぐちゃすぎて）すごくないですか？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3334349/8ace923a-9601-dfb3-6523-f408041b88b3.png)

こちらは、下記をやろうとしたものです。　

https://matplotlib.org/stable/plot_types/basic/fill_between.html#sphx-glr-plot-types-basic-fill-between-py


本当なら一次関数的に一本の線がしゅっとでてくれるのを期待していたのですがうまくいきませんでした。
具体的には、ｘ軸を月日、ｙ軸をとある

~~~
# make data for depth - fill between plot
np.random.seed(1)
x = file[' date']
y1 = file['maximum'].astype(float)  # 数値に変換
y2 = file['minimum'].astype(float)  # 数値に変換

# plot
fig, ax = plt.subplots()
# ★プロットのサイズ調整


ax.fill_between(x, y1, y2, alpha=.5, linewidth=0) #label='Between Top and Bottom Filtering')
ax.plot(x, (y1 + y2) / 2, linewidth=2) # label='Average of xxxx')

ax.set(xlabel='Sampling date', ylabel='Values', title='Fill Between Example')
plt.show()
~~~


### あり得る原因１： 読み込みデータのｙ１とｙ２の絶対値的な差が異なる

ｙ１のほうが基本的にｙ２より大きい値のデータだけどたまに逆もあり得る
解決方法としては、データをきれいにする。

### あり得る原因２： ｘ軸が月日のデータになっていて暴れてる

何故暴れるかはわからないのですが、月日のデータを数値にしてあげるといい感じです。

具体的な解決方法としては

~~~
x = np.arange(len(file))  # 数字の配列に変換 
~~~
x = np.arange(len(file))  # 数字の配列に変換 
はなにをしていますかというと

x = np.arange(len(file)) は、file データフレームの行数（データの個数）に基づいて、0から始まる連続した整数の配列を生成しています。これにより、データの順序に応じて一連の整数が x 軸に対応します。

この整数列は、file データフレームの行数分の数値で構成され、例えば、0, 1, 2, 3, ... というようにデータの先頭から順に割り当てられます。このような数値の配列を用意することで、matplotlib などのプロットライブラリでグラフを描く際に、x 軸にこの整数列を指定することができます。


### あり得る原因３：タイムシリーズ（時系列データ）の場合、一日に２つ以上のサンプルがあってブルってる

これ一番可能性高いのでは。そもそも線で結ぶことに向いてないということですね、データが

#### 解決方法
Groupbyを使ってコードを修正する

Ｏｒ
線グラフではなくてスキャッターにする（これが一番簡単）
GASでWebアプリ実現するときにGET通信でハマったこと

## 背景
GoogleAppsScript(GAS)を使用して在庫管理のWebアプリを作ります。
以下のようにGoogleサービスで構成を組むことで、お金をかけずにWebアプリを組んでしまおうと考えてます。

Google Site <-----> GAS <---> Googleスプレッドシート


# ハマったこと
GASへのGETが通らずCORSエラーが発生する。
（POSTも同様と思います）

# 結論
* GASのdoGet関数内にエラーがないか確認。
* アクセスできるユーザーを「全員」にしてデプロイする。

# 詳細
Javascript(jQuery)からGASへGETで通信を試みるが、
CORSエラーが出続けているのでサーバー(GAS)からの`Access-Control-Allow-Origin`設定が悪いのか？！とヘッダ付与方法をずっと探していました。
```:Developer Console
Access to XMLHttpRequest at 'https://script.google.com/macros/s/xxxxxxxxxxxxxx/dev?func=allget' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

```
## ハマりポイント1
**CORSエラーはCORSエラーではなかった。**

要は、GASのdoGet関数内でエラーが発生する状況になっていました。
以下コードで`createTextOutput`に`setHeaders`をメソッドチェーンで繋げていますが、こんな関数は存在しません（）
ここでエラーし、失敗の返却ヘッダに`Access-Control-Allow-Origin`がないことでブラウザではCORSエラーとして認識したようです。詳細は[1]の記事を参考ください。

https://developers.google.com/apps-script/reference/content/text-output?hl=ja#methods

```Javascript:doGet
function doGet(request) {
  let func = request.parameter.func;
  //中略
  return ContentService.createTextOutput(JSON.stringify(result))
    .setMimeType(ContentService.MimeType.JSON)
    .setHeaders({'Access-Control-Allow-Origin': '*'});
}
```
## ハマりポイント2
**「デプロイをテスト」は外部から呼び出せない**
GASを他ドメインからWEBアプリとして実行するには以下画像のようにデプロイ時にアクセスできるユーザーを「全員」にする必要があります。URLの末尾は「デプロイをテスト」では`/dev`ですが、デプロイでは`/exec`です。

![スクリーンショット 2024-01-29 22.39.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3640997/2b97c940-6dfe-0e83-a720-49f844837286.png)


# 参考
[1] https://www.bugbugnow.net/2019/06/gasweb.html
[2] https://zenn.dev/iwatos/books/752824c25d84fc4e1d2f/viewer/make-debug-settings
[Streamlit] サイドメニューに複数ボタンを作成する方法

## 環境
- Python（v3.12）
- Streamlit（v1.30.0）
- venv

## サイドメニュー作成
### 1つだけボタンを作成する場合

```python:test.py
import streamlit as st

if st.sidebar.button("Don't PUSH"):
    st.title("緊急警報発令！")
```

![スクリーンショット 2024-01-29 21.51.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2728622/857151ab-ecdb-1822-5bd9-c5550e9fd0a2.png)


サイドメニューの作成が便利すぎる！
ただ、この中にボタンを複数作成しないといけない場合、if文を何個も続けて書くのは冗長ですね……。

### 複数のボタンを作成したい時はこう書く

```python:test.py
BUTTON_WEEK_MAPPING = {
    '月曜日': 'monday',
    '火曜日': 'tuesday',
    '水曜日': 'wednesday',
    '木曜日': 'thursday',
    '金曜日': 'friday',
    '土曜日': 'saturday',
    '日曜日': 'sunday',
}

for label, day_of_week in BUTTON_WEEK_MAPPING.items():
    if st.sidebar.button(label):
        st.title(day_of_week)
```

![スクリーンショット 2024-01-29 22.28.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2728622/a0ea7df1-3354-dee2-b82a-a2465225bcb5.png)

## 参考
- [[公式]Streamlitドキュメント](https://docs.streamlit.io/)
- ChatGPTパイセン

## おわりに
- UIがデフォルトで良すぎる・・・

以上
WebApi json形式

```
        public class UserApiModel
        {
            [JsonProperty("user_id")]
            public int UserId { get; set; }

            [JsonProperty("user_name")]
            public string UserName { get; set; }
            // 他に必要なプロパティがあれば追加
        }

        public class ErrorResponseModel
        {
            public string ErrorMessage { get; set; }
            // 他に必要なエラープロパティがあれば追加

            public override string ToString()
            {
                return $"ErrorMessage: {ErrorMessage}";
            }
        }

        static async Task Main()
        {
            // HttpClientのインスタンスを作成
            using (HttpClient client = new HttpClient())
            {
                // Web APIのエンドポイントを指定
                string apiUrl = "https://api.example.com/user";

                try
                {
                    // GETリクエストを送信し、応答を取得
                    HttpResponseMessage response = await client.GetAsync(apiUrl);

                    // リクエストが成功したか確認
                    if (response.IsSuccessStatusCode)
                    {
                        // 応答コンテンツを文字列として読み取る
                        string responseData = await response.Content.ReadAsStringAsync();

                        // JSON応答をUserApiModelにデシリアライズ
                        UserApiModel userApiModel = JsonConvert.DeserializeObject<UserApiModel>(responseData);

                        // デシリアライズされたデータを使用
                        Console.WriteLine($"UserID: {userApiModel.UserId}");
                        Console.WriteLine($"UserName: {userApiModel.UserName}");
                        // 他のプロパティも必要に応じて表示または使用

                        // ここでuserApiModelを使って何かを行う
                    }
                    else if (response.StatusCode == HttpStatusCode.BadRequest)
                    {
                        // エラーメッセージを取得
                        string errorResponseData = await response.Content.ReadAsStringAsync();

                        // エラーレスポンスをデシリアライズしてエラーメッセージを取得
                        ErrorResponseModel errorResponse = JsonConvert.DeserializeObject<ErrorResponseModel>(errorResponseData);

                        // エラーメッセージを表示
                        Console.WriteLine($"Error: {response.StatusCode} - {response.ReasonPhrase}");
                        Console.WriteLine($"Error Message: {errorResponse.ErrorMessage}");
                    }
                    else
                    {
                        // その他のエラーハンドリング
                        Console.WriteLine($"Error: {response.StatusCode} - {response.ReasonPhrase}");
                    }
                }
                catch (Exception ex)
                {
                    // 通信エラーなどの例外ハンドリング
                    Console.WriteLine($"Exception: {ex.Message}");
                }
            }
        }
```
【まとめ】先読み！IT×ビジネス講座 量子コンピューター

以下の本を読んでみたので、まとめと感想を備忘用に載せておきます。

![スクリーンショット 2024-01-29 21.51.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1693780/8205df9d-9454-e378-0144-758641d658b3.png)

[amazonリンク](https://www.amazon.co.jp/%E5%85%88%E8%AA%AD%E3%81%BF%EF%BC%81-%C3%97%E3%83%93%E3%82%B8%E3%83%8D%E3%82%B9%E8%AC%9B%E5%BA%A7-%E9%87%8F%E5%AD%90%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF%E3%83%BC-%E6%B9%8A%E9%9B%84%E4%B8%80%E9%83%8E/dp/429501737X)

## まとめ

### 量子コンピュータの概要
- 2023年3月に国産初の量子コンピュータが稼働開始
- 日本の量子コンピュータ界隈も結構すごい
    - 理研の中村泰信氏が超伝導量子コンピュータの量子ビット素子を開発
    - 量子アニーリングタイプは東工大の西村秀稔氏が発案。
- 古典コンピュータには限界がある。CPUの性能はサイズが小さくなるほどよくなるが、サイズが一定以下になると量子的な振る舞いをしてしまう。
- 方式がいくつかある
    - 半導体方式
    - イオントラップ方式
    - 冷却原始方式など
- 日本と海外の量子コンピュータの違い
    - ビット数（日本初号機64ビット、アメリカIBM1121ビット）
    - 得意な方式（日本は超伝導、半導体が強い。）

|方式|超伝導|イオントラップ|冷却原子|半導体|光|
|---|-----|----------|-------|-----|-|
|量子|電子２個|イオン|原子|電子|光子|
|主な開発国|世界中|欧米|欧米|米|世界中|
|特徴|早くから開発、商用化|高精度|量子ビット数の多さ|量産化、商用化|常温で動作|
- クラウドで利用するのが一般的

### 量子とは

- 原始、電子、陽子などの粒子の総称
- どの量子を使用するかで方式が異なる。
- 量子の鍵は「重ね合わせ」と「もつれ」
- 量子もつれにより、組み合わせの数を減らせ、計算が効率化する。
- 量子コンピュータ以外でも「量子通信」「量子センサー」などもポテンシャル高い

## 量子コンピュータの仕組み

- 古典コンピュータにおけるCPUが、量子コンピュータのQPU（演算のみ）
- 量子ビットにマイクロはを当てて、状態を変化させる。
- 量子ビットが多いほど優秀になるが、エラーも増える
- QPUの構造は方式で異なる。
    - 超伝導方式：超伝導素子にマイクロ波を当てる
    - イオントラップ：イオンを空中に静止させる
    - 半導体（シリコン）：従来のシリコンを改造、電気を止める機能がついたイメージ
    - 冷却原子：レーザーで原子を平面上に並べて止める。冷却されるのは原子のみ
    - 光方式：QPUに光子が通る。
- アルゴリズムには「FTQC(Fault Tolerant Quantum Computer)アルゴリズム」と「NISQ(Noisy Intermediate-Scale Quantum)」がある。
    - FTQCは化学計算と暗号解読で期待
    - FTQCはまだ二十年くらいかかる
    - NISQは化学計算、最適化、機械学習で期待。
    - NISQでは短い計算を何度も行う。
- 量子の重ね合わせの状態の維持は結構難しい。そのためエラーが生じる
    - エラーを直す「誤り訂正」が必要
    - 論理量子ビットを使う。これは複数の物理量子ビットを集めてつくる

### シミュレーション
$$\newcommand{\ket}[1]{\left|{#1}\right\rangle}$$
$$\newcommand{\bra}[1]{\left\langle{#1}\right|}$$
$$\newcommand{\braket}[2]{\left\langle{#1}\middle|{#2}\right\rangle}$$

（私はIBM Quantum Composerで実施しました。）

![スクリーンショット 2024-01-29 22.22.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1693780/bf4a4c59-b2c8-e236-6784-04badffa5007.png)

画像のように足し算が実装されている。
q[0], q[1]が入力、q[2], q[3]が出力となっている。
Hゲートにより
$\ket{0}\rightarrow \frac{1}{\sqrt{2}}(\ket{0} + \ket{1})$ と変換されCX,Tofforiゲートによって１桁、２桁目の加算が行われている。
これによって
$0+0=0, 0+1=1, 1+0=1, 1+1=2$が一度に表現されている。

## 感想

去年は量子コンピュータという言葉を非常によく聞き、とても夢があると感じていた。
量子コンピュータによって素因数分解が効率的に解かれるという話を聞いた時、アルゴリズムが全然想像できなかったが、このシミュレーションを通じて、すこし（ほんとに少しだと思うが）理解できたような気がする。
これからも量子コンピュータの勉強を進めていきたい。
(高速?)digitalWrite(6, 1);の直レジ、マクロ化



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


![o_cop910.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/54e98056-5108-cd4b-e331-0b7bd15697fe.jpeg)


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


目的
ioを高速化する為にマクロ化して遊ぶ
(注意)かなり、いろいろ、はしょつている。　Dポートしか動かない
ピンの初期化のレジ直化は、めんどいのでしない。


いろいろ
自分で書いた記事の集計を取っているが
Arduino R3 UNOの人は、「ArduinoUno」の
記事しか読まない。
STM32やESP32に範囲を広げて検索することは、しない
同じ内容の記事の場合は、ArduinoUnoの方が2倍から3倍
アクセスがおおい。
範囲を広げて検索するならアクセスカウント数が
STM32、ESP32、UNOが同じになるはず。
アクセスのカウントを取るだけなら「ArduinoUno」の記事
だけ書いた方がいい。
難しいを簡単にするとカウント数が上がる。
結論-よって、移植性からいって、性能は、
STM32 x ESP32 > ArduinoUnoである。
上の行の「x」 は、　OR (オア) と定義する。

```

#define DW(aa,bb) PORTD=((bb==0)?PORTD&~(1<<aa):PORTD|(1<<aa))

```

三項演算子

```

c = (a < b) ? a : b;

```

参考



↓ここをクリック↓


https://qiita.com/shirokuma89dev/items/3d73d1450fb398eedf2e


↓ここをクリック↓

https://qiita.com/shirokuma89dev/items/6ed42c906c153fb86fb9

↓ここをクリック↓

https://qiita.com/caa45040/items/8eaf14e9f6bef2d81d0a

![o_cop908.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/c3e9a0c0-0cf3-cc8d-3f70-4eaa32b600df.jpeg)




プログラム


```c++


//これは、GPIOレジスターを直接操作する方法
//GPIO_IO_REG_UNO_1


//定義
#define DW(aa,bb) PORTD=((bb==0)?PORTD&~(1<<aa):PORTD|(1<<aa))


//初期化
void setup() {

  //ピンの初期化 6
  pinMode(6, OUTPUT);

} //setup


//メインループ
void loop() {

  //6をオン
  DW(6,1);
  //digitalWrite(6, HIGH);

  delay(1000); //1秒待つ

  //6をオフ
  DW(6,0);
  //digitalWrite(6, LOW);

  delay(1000); //1秒待つ

} //loop


```
【DeepSecurity】お勉強Vo.1～Deepsecurityの機能について～

### 【経緯】
DeepSecurityについていろいろとお勉強したので、
参考にしたリンクなどと併せてまとめます。

アップグレード対応から入ったので、そっちに偏りがちになってしまうのはご承知おきください><


### 【[DeepSecurity](https://www.trendmicro.com/ja_jp/business/products/hybrid-cloud/deep-security.html)ってなに】
Trend Micro Deep Securityは、サーバに必要な7つのセキュリティ機能を1製品で提供するサーバ環境向けの総合セキュリティ製品。

いろいろできるセキュリティソフトと認識
以下の機能があります


<dt>不正プログラム対策</dt>
<dd>文字通りの機能。不正プログラム、ウイルス、トロイの木馬、スパイウェアなどのファイルベースの脅威からリアルタイムに保護する機能と、管理者の要求に応じて保護する機能がある。</dd>
<dt>Webレピュテーション</dt>
<dd>不正なURLへのアクセスをブロックすることによって、Webの脅威から保護する機能。
レピュテーションってのは「評判」って意味で、過去の実績とカ利用状況などを基に判断する仕組みのことらしい。</dd>
<dt>変更監視</dt>
<dd>不審なアクティビティを示している可能性があるファイルや重要なシステム領域 (Windowsレジストリなど) への変更を検出する。</dd>
<dt>アプリケーションコントロール</dt>
<dd>保護対象サーバのソフトウェア変更を継続的に監視します。ポリシー設定に基づいて、アプリケーション制御は、許可されていないソフトウェア</dd>
<dt>セキュリティログ監視</dt>
<dd>文字通りの機能。この機能を有効化することで、OSおよびアプリケーションのログに含まれている可能性のある重要なセキュリティイベントを特定するときに役立つ。</dd>

<dt>ファイアウォール</dt>
<dd>受信/送信トラフィックの双方向のステートフルインスペクションを提供する。
ステートフルインスペンス(ステートフルインスペクション)とは、パケットフィルタリング型ファイアウォールにおいて、通信内容の通過可否を動的に判断する機能のとこ。（ネットワークはお勉強中なので今度掘り下げて勉強。。。）</dd>
<dt>IPS/IDS（侵入防御）</dt>
<dd>SQLインジェクション攻撃、クロスサイトスクリプティング攻撃、およびその他のWebアプリケーションの脆弱性に対する脆弱性攻撃からコンピュータを保護する。</dd>
<dt>EDR/XDR機能 </dt>
<dd>別途課金が必要なモジュール、EDR/XDRの違いについては分からないので別途お勉強。</dd>

🌟詳しくは[管理者ガイド＞保護モジュールの設定](https://help.deepsecurity.trendmicro.com/20_0/on-premise/ja-jp/anti-malware.html)を確認！そこに書いてないやつも調べたら出てくる。

私が使用したことのある機能は以下のみ
+ 不正プログラム対策

もう少し深堀ってみる

### 【[不正プログラム対策機能について](https://help.deepsecurity.trendmicro.com/20_0/on-premise/ja-jp/anti-malware.htmll)】
以下の機能がある。
クイック検索のみ使用したことのない機能・・・。

<dd>リアルタイム検索</dd>
<dd>手動検索</dd>
<dd>予約検索</dd>
<dd>クイック検索</dd>


### 【最後に】

引き続き勉強が必要だなと実感、、マニュアル見にくいのでアウトプットも、、、
Qiita書きなれてなくて改行もろくにできなかった；；
要素を固定させたいときに。position: sticky; の使い方を紹介！


## 要素を一定の場所に常に表示させたい！
そんな時ってありますよね！
例えば、こんな時・・・

:::note info
- 「TOPへ戻る」ボタンを作りたい時
- ネットショップなど外部サイトへの導線を作りたい時
- キャラクターなどを置いて遊び心を出したい時
:::

今回、常に右下に「TOPへ戻る」ボタン:banana:が表示されるようにしてみました。

▼デモ映像です。
右のバナナが常に右下に表示され、フッターに到着したらそこで止まっているようにしてみました。:banana:
![Adobe Express 2024-01-29 21.39.58.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3638020/840824f2-c343-39c1-6264-ce1a5a84e1cb.gif)

冒頭に戻りますが、「要素を一定の場所に常に表示させたい」時、とても簡単なcssがあります！

### 解決方法

　「**position: sticky;**」

これを使ってみましょう。:sunny:


最初「position: sticky;」を知ったときは、難しそうかも？と感じたのですが、めっちゃカンタン、めっちゃ便利なcssでした:sparkles:
positionと聞くと、absoluteやrelativeを使うんでしょ？？とお思いでしょうが、そんなことないです。デモ実装の手順を次から解説します。

### 実装方法

上記のデモ実装の実装手順は、まずは、バナナを、フッター上部に配置します。
下図のように、
`　<footer class="footer">　`
の直前に置きました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3638020/48154091-dfa3-52d2-e017-433f26ebe3fd.png)

そうすることで、フッターの上部に（赤い線まで）置くことができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3638020/96123e1d-2e7d-8714-35e1-5ec78d46c158.png)

そして、右下に配置したいので、cssを記述します。

```
.TopBanana-wrapper {
    display: flex;
    justify-content: flex-end;
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3638020/8f8139dc-42b9-3204-3826-1643f9351107.png)

この段階で、右下にバナナが表示されますが、下のデモ実装を見ると常に右下に表示はされない状態です。

![Adobe Express 2024-01-29 22.10.08.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3638020/3131c4f4-7cb3-aa1d-81b8-5cbcc0e19b87.gif)

ここで、やっと

　「**position: sticky;**」

の出番です！！！

```
.TopBanana-wrapper {
    display: flex;
    justify-content: flex-end;
    padding-right: 27px;
    position: sticky;
    bottom: 10px;
    left: 0;
}
```
上のcssのように、

　「**position: sticky;**」

 を記述して、あとは位置をbottomなどで調整すれば、すぐに実装ができます。
 とても簡単なので、ぜひ試してみてくださいね:relaxed:
【Laravel】レイアウトの出しわけ


# はじめに
Laravelで、ユーザー用と管理者用でレイアウトの出しわけを行う。

# レイアウトファイルの作成

viewsにlayoutsディレクトリを作成。
ここにレイアウト用ファイルを入れる。
```
resources
　└ views
 　└ layouts
```

### ユーザー用レイアウトの作成
ユーザー用に「uer.blade.php」を作成。
```
resources
　└ views
 　└ layouts
 　　└ user.blade.php
```
```
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>ユーザー</title>

        @vite(['resources/scss/app.css', 'resources/js/app.js'])
    </head>
    <body>
        @yield('main')
    </body>
</html>

```
### 管理者用レイアウトの作成
```
resources
　└ views
 　└ layouts
 　　└ admin.blade.php
 　　└ user.blade.php
```
```
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>管理者</title>

        @vite(['resources/scss/app.css', 'resources/js/app.js'])
    </head>
    <body>
        @yield('main')
    </body>
</html>
```

# 読み込み側のファイル作成
views配下に読み込み側の「admin.blade.php」と「user.blade.php」を作成
```
resources
　└ views
 　└ layouts
 　　└ admin.blade.php
 　　└ user.blade.php
　└ admin.blade.php
　└ user.blade.php
```

### user.blade.php

```
@extends('layouts.user')

@section('main')
<main>
ユーザー
</main>
```

### admin.blade.php

```
@extends('layouts.admin')

@section('main')
<main>
管理者
</main>
```

これで2つのレイアウトで出しわけできる！
git で一部のディレクトリ or ファイルのみをgit pull したい時ありませんか？？

こんにちは！！最近、かなりgit を使う場面が増えてきたので、色々git に苦しみながら、try and error を重ねていってます。普段git clone する時や git pull する時って、全部のファイルをディレクトリを取得することが多いと思います。けれども、一部のファイルのみを取得したいときってありますよね？？

# 前提

- git アカウントをお持ちであること
- git config の設定が完了していること
- git init を既に実行していること

# sparse-checkout の設定

sparse checkout をtrue にする

        git config core.sparseCheckout true

        # 設定が反映されているかを確認できます
        git config -l

これをすることによって、sparseCheckout の設定をローカル内で適用させることができます。今回はglobal に適用させることは目的としておらず、その作業ディレクトリのみで適用させていきます。

  sparse checkout のリストを確認

        git sparse-checkout list 

現在はなにも設定していないので、何も表示されないと思います

これから、取得したいファイルの設定を行います

        # test.html を取得したい場合
        git sparse-checkout set path/to/your/sparse-checkout/test.html

        #複数ファイルを取得したい場合
        git sparse-checkout set path/to/your/sparse-checkout/test.html path/to/second/sparse-checkout/second.txt

一つのファイルのみ取得したい場合は、一つのパスとファイル名をコマンドで設定します。複数の時は複数のファイルとそのパスを設定してあげます。

設定が適用されているかを確認します

        git sparse-checkout list

        => 想定される表示(下記ファイルとそのパス)
        path/to/your/sparse-checkout/test.html
        path/to/second/sparse-checkout/second.txt

実際に pull してみるとこの二つのファイルが取得できると思います！！

# まとめ

もし全部のファイルを編集しないけど、一部のファイルを編集したいとか思っている人がいれば、ぜひ使ってみてください。この例ではファイルを取得しましたが、ディレクトリでも対応可能なようです。

# 参考資料

https://git-scm.com/docs/git-sparse-checkout
preload, eager_load, include の違い

## preload, eager_load, includeとは
N+1を解消する、ActiveRecordのメソッド

## 前提
下記、違いについての説明は、この2モデルが存在すると仮定する
usersモデル、postsモデルの2テーブルある
postsモデルはusersモデルに紐づいている

## preload
二つのクエリを発行し、関連するモデルを取得する
クエリをモデルごとに発行するため、where旬の条件としては使えない
JOINをするわけではないので、条件を指定しないのであれば、比較的軽量

```
users = users.all.preload(:posts)

上記は、usersに対してのall、usersに紐づくpostsの取得、この二つのクエリを発行している
```

## eager_load
関連するモデルに対して、LEFT OUTER JOINする
JOINするため、条件として使用可能
大規模なテーブルになった場合、JOINする数が多くなり、複雑になり、パフォーマンスに影響する可能性あり

```
users = users.all.eager_load(:posts).where('posts.text = ?', 'hogehoge')

上記は、usersに対してのallし、関連するpostsモデルをLEFT OUTER JOINしている
JOINしているため、検索条件にpostsモデルを指定できる
```

## include
preloadとeager_loadどちらが効率がいいかを判断し、よしなにやってくれる
大量にデータがある場合には注意が必要らしいが今のところみたことはない

```
users = users.all.include(:posts)
上記は、whereでの条件しても行える
```
Flutterのurl_lanucherとuni_linksでOAuth

[この記事](https://qiita.com/meique/items/c1933247803d92829020)の補足記事になります。

認証部分は読んだ前提で話を進めるので、読んでください！

webviewを使ったGoogleのOAuthがセキュリティ的にちょっとアレなため、url_launcherとuni_linksを使用した正攻法(?)で実装してみます。

サンプルのリポジトリは同じです。
https://github.com/Taichiro-S/notion_sample

## 使用するFlutterパッケージ

- [url_launcher](https://pub.dev/packages/url_launcher) : 端末のデフォルトブラウザでWebページを開く
- [uni_links](https://pub.dev/packages/uni_links) : deeplinkするやつ

## 実装

修正箇所は以下の2点です。

1. **「連携」ボタンクリック時にnotionの認証ページをurl_launcherで開くようにする**
2. **uni_liksの`linkStream.listen`で自分のアプリへのリクエストをlistenする**

修正が必要なのは`main.dart`のみです。

まず連携ボタンを修正。

```main.dart
child: ElevatedButton(
    onPressed: () async {
        if (await canLaunchUrl(Uri.parse(Env.notionOauthUrl))) {
         launchUrl(Uri.parse(Env.notionOauthUrl));
        }
    },
    child: const Text('Notionと連携する'),
)
```

次にlistenerを設定
MyAppをConsumerWidgetからConsumerStatefulWidgetに変更します。
`linkStream.listen`内で、自分のアプリに対するリクエストで、URLに`code`パラメータを含むものを検知してauthenticateメソッドを実行し、providerを更新します。

```dart
class MyApp extends ConsumerStatefulWidget {
  const MyApp({super.key});

  @override
  ConsumerState<MyApp> createState() => _MyApp();
}

class _MyApp extends ConsumerState<MyApp> {
  StreamSubscription? _sub;
  @override
  void initState() {
    super.initState();
    initUniLinks();
  }

  Future<void> initUniLinks() async {
    _sub = linkStream.listen((link) async {
      if (link != null &&
          link.startsWith('notionsample://oauth/callback?code')) {
        await ref.read(notionOauthApiProvider).authenticate(link);
        ref.invalidate(notionAuthProvider);
      }
    }, onError: (e) {
      print(e.toString());
    });
  }

// build以降はそのまま
}
```

これで一応実装できました。

動かしてみるとこんな感じ。

https://youtube.com/shorts/L57JhLel_y4

2つほど気になるところが...

### 1. 二度目以降の連携では最初に連携をしたアカウントの連携ページに飛ばされてしまう

ブラウザに初回ログイン時の情報が残っているため？
webviewでは毎回ページを開く前にキャッシュを削除していた(`clearCache: true`に設定)が、url_launcherではできないみたい。
Githubに同様のissueがあったが、

>url_launcher is intended to have a minimal API for launching, and the API of SFViewController is extremely limited so this couldn't be implemented on iOS anyway. Use cases that need detailed control of the webview should build on webview_flutter instead.
>
>Closing as out of scope.

webviewを使わないと無理っぽい。

https://github.com/flutter/flutter/issues/29976

### 2. 認証完了後に自動でブラウザを閉じることができない

ので、ユーザーに手動で閉じてもらう必要がある。
こちらちょっとめんどい程度の問題なのでまあ許せるが、1つ目は今のところ解決策が思い浮かばない。

**ということで、いい解決方法知ってる人、教えてください！**
【PUG】input-requires-labelエラーが出たら



# はじめに
PUGのエラー「input-requires-label」が出た時の対応の備忘録

# input-requires-label
inputタグを使う時はlabelをセットにしないと「"input-requires-label"」のエラーが出る。
ただ、input(type="hidden")にもlabelがないとこのエラーが出るので場合によってはエラー自体が不要になる。

# .htmlhintrcを変更する
.htmlhintrcファイル内の下記記述をfalseにすることでこのエラーはスルーされる。

```
"input-requires-label": true
```
↓
```
"input-requires-label": false
```
Centos8と９どう違う？

#SELinuxは最初から無効化されているため、設定は割と楽かもしれません。


dnf -y update

色々と検証していきます。

まずはLAMPとJava
sudo vi 0S9LAMPPJ.sh
```
#apache:php:mysqlインストール

yum install https://rpms.remirepo.net/enterprise/remi-release-9.rpm
yum config-manager --set-enabled remi
dnf -y install php
dnf -y install httpd
dnf -y install dnf-utils

rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022
dnf -y install wget
dnf -y install git
dnf -y install unzip
dnf -y install php-cli php-devel php-common php-mbstring php-fpm php-gd php-opcache php-pdo php-xml php-intl php-zip php-pear php-bcmath
dnf -y install php-mysqlnd
dnf -y install mod_ssl
    dnf -y install php php-devel php-mysqlnd php-gd php-pear php-pecl-apc-devel php-pecl-zip php-gd php-zip php-mysqlnd
dnf -y install httpd httpd-tools httpd-devel httpd-manual
dnf -y update


#開発ツールなど、基本的なパッケージをインストールしておきます。
dnf -y groupinstall base
dnf -y groupinstall development
rpm --import http://rpms.remirepo.net/RPM-GPG-KEY-remi

#Python３系インストールコマンド
dnf -y install python3




```
sudo chmod u+x 0S9LAMPPJ.sh
sudo ./0S9LAMPPJ.sh


```
 #インストールされているか確認
dnf list --installed | grep httpd 
systemctl start httpd

#Apacheを起動できているか確認
systemctl status httpd  
systemctl enable httpd  

```

mysqlは明日以降に更新します。
teratermには英語表記で日付は記載されるようです。

Centos8も同じだった気がします。。。
【Git】ローカルブランチを一括削除する方法

# 今いるブランチ以外を全削除する方法

```
$ git branch | xargs git branch -d
```

# 今いるブランチ + 特定の文字列から始まるブランチを削除する方法

例) feature/ から始まるブランチを削除します。

```
$ git branch | grep "feature/*" | xargs git branch -d
```

# 今いるブランチ + 指定したブランチ以外を全削除する方法

例）main, develop, master ブランチ以外を削除します。

```
$ git branch | grep -v "main\|develop\|master" | xargs git branch -d
```

# 今いるブランチ + 特定の文字列から始まるブランチ以外を削除する方法

例) feature/ から始まるブランチ以外を削除します。

```
$ git branch | grep -v "feature/*" | xargs git branch -d
```

# おわりに

たまにローカルブランチを一括削除するのですが、毎回コマンドをド忘れするので記事にしました。
StreamlitでMPA(サイドバーなし)

## はじめに
Streamlitはpagesフォルダ内にスクリプトを配置するだけで、MPA(マルチページアプリケーション)を簡単に実装できます。(自動でサイドバーが設定されて各ページへのリンクが配置されます。)
※Next.js的な感じですね。

非常にお手軽で便利なのですが、サイドバーのリンクからしかページ遷移できなかったり、サイドバー自体を非表示にすることはできませんでした。

バージョン1.30.0で、サイドバーを隠しつつページ遷移もプログラムから実行できるようになりましたのでご紹介です。

https://docs.streamlit.io/library/changelog

※該当部分抜粋
> 🔄 Announcing st.switch_page to programmatically switch pages in multipage apps! Check out our docs to learn about this highly anticipated feature!

> 🧭 Sidebar navigation for multipage apps can be hidden via configuration (#7852).


## やり方
- .streamlit/config.tomlとpages/にスクリプトを配置します。

```
.
├── .streamlit/
│   └── config.toml
├── pages/
│   ├── page_1.py
│   └── page_2.py
└── app.py
```

``` toml: config.toml
[client]
showSidebarNavigation = false
```

- ページ遷移は以下のように指定できます。
``` python
import streamlit as st

if st.button("Home"):
    st.switch_page("app.py")
if st.button("Page 1"):
    st.switch_page("pages/page_1.py")
if st.button("Page 2"):
    st.switch_page("pages/page_2.py")

```


## おわりに
あとはCSSの自由な指定とパフォーマンス向上に期待です！
【Golang】go mod を理解せず自作の package を動かす

  【Golang】go mod を理解せず自作の package を動かす

  # 概要
  バージョンいくつかは知らんが、あるバージョンから go mod やらで既存の記述での自作 package が使えなくなってしまった。
  go mod を理解して使おうという気は無いので、動けば OK 程度に既存の環境からの変更を記録する。

  # 環境
  PC：M1 Macbook Sonoma
  Go
  ```
> go version
go version go1.21.6 darwin/arm64
  ```

# 既存環境（昔の記述：今これじゃ動かないよ（？））
## ディレクトリ構造
```
> tree
.
├── main.go
└── testlib
    └── testfunc.go

2 directories, 2 files
```
## ファイル記述
```main.go
package main

import "./testlib"

func main() {
	println("hello from main func")
 	testlib.TestFunc()
}
```

```testfunc.go
package testlib

func TestFunc() {
	println("Hello From TestLib")
}
```

## 動かしてみる（動かない）
```
> go run main.go
main.go:3:8: "./testlib" is relative, but relative import paths are not supported in module mode
```

# 更新手順
### ディレクトリ位置（ホームまでは省略）
```
> pwd
~/work/forqiita
```

## 1. go mod init する
現在の作業ディレクトリが `~/work/forqiita` なので以下のコマンドを実行する
```
go mod init forqiita
```
実行例
``` 
> go mod init forqiita
go: creating new go.mod: module forqiita
go: to add module requirements and sums:
	go mod tidy
```
go mod tidy しろという表示がでるが **無視する**
実行後に `go.mod` ファイルが生成されていることがわかる

```
> tree .
.
├── go.mod
├── main.go
└── testlib
    └── testfunc.go

2 directories, 3 files
```
```
> cat go.mod
module forqiita

go 1.21.6
```
## 2. main.go を編集する
上記 `main.go` の 3 行目の自作パッケージの import を変更する。
```diff
- import "forqiita/testlib"
+ import "./testlib"
```
変更後
```main.go
package main

import "forqiita/testlib"

func main() {
	println("hello from main func")
	testlib.TestFunc()
}
```

# 以降は普通に実行できる（はず）
```
> go run main.go
hello from main func
Hello From TestLib
```

他者の package を github 等から使いたいときはまたお作法が違いそうなので気をつけたい
AppImageでSquashFSがunmountされない事象

nvim.appimage 使ってると、rootは大丈夫でも 一般ユーザだと/tmp/.mount_nvimXXXXX とかが残る。
放っておくとmountのしすぎで怒られて AppImageの実行ファイルが起動しなくなる。

それの解決方法の一つとして以下、

```bash
sudo ln -s /proc/self/mounts /etc/mtab
```

追わないといけないのが、squashfuse の後処理。
umount2 で MNT_DETACH(lazy unmount)にはroot権限必要。
これにEPERMで失敗すると fusermount -u (fusermount3だと-zでlazy unmountになるけど多分使ってない) にfallback するみたい。
ただ、このときに /etc/mtab が無いと、fusermountが こけて umount処理されない。

あとでちゃんと記事書く。
[初心者向け]テストの7原則

[徹底攻略 JSTQB Foundation教科書&問題集 シラバス2018対応](https://www.amazon.co.jp/%E5%BE%B9%E5%BA%95%E6%94%BB%E7%95%A5-JSTQB-Foundation%E6%95%99%E7%A7%91%E6%9B%B8-%E5%95%8F%E9%A1%8C%E9%9B%86-%E3%82%B7%E3%83%A9%E3%83%90%E3%82%B92018%E5%AF%BE%E5%BF%9C/dp/4295017671/ref=asc_df_4295017671/?tag=jpgo-22&linkCode=df0&hvadid=654833321247&hvpos=&hvnetw=g&hvrand=7317531869461544354&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1009293&hvtargid=pla-2199686852302&psc=1&mcid=140f9d5d8ea8321d9cdbe1b981b50a4c&th=1&psc=1)を勉強しているので、自分のメモとしてまとめています。第3弾。

# テストに共通するガイドライン（原則）
## 原則1：テストは欠陥があることは示せるが、欠陥がないことは示せない
品質保証（QA）は品質が合格レベルでに達していることを示す作業ではあるけれども、完全に欠陥がないとは保証できない。

## 原則2：全数テストは不可能
ソフトウェアは、条件分岐で通るロジックが変わる。システムによっては条件分岐は山のようにあるため、全ての組み合わせをテストしようとすると、分岐数のべき乗となり膨大な数になる。分岐ごとに関連ありそうなものは組み合わせでテストするが、それ以外は分岐単独でテストするのに止めることになる。
### 境界値分析
例えば、商品の合計が500円以上か未満かで分岐するとした場合、500円になる値と499円になる値だけを試すテスト技法のこと。
### 全数テスト
入力値と条件の全てを組み合わせるテストのこと。
入力値と条件分岐の組み合わせまで考えると天文学的な数字になる。そのため、これは非現実的なものだとして割り切る必要がある。
その代わりに、リスク分析・テスト技法・テストの優先度などをもとにして、テストにかける労力を削減するべし。

## 原則3：早期テストで時間とコストを節約
**早期テスト**とは、ソフトウェア開発ライフサイクルのなるべく早い時間（上流）にテストすることを意味する。**シフトレフト**ともいう。早い段階でテストすればするほど、まだ欠陥の数が少ないため、1つの欠陥が多くのコンポーネントに入り込むのを未然に防ぐに防ぐ事ができ、コスト削減につながる。

## 原則4：欠陥の偏在
リリース前のテストで見つかる欠陥や運用時の故障の大部分は、特定のモジュールに集中する。モジュールの数や人のスキルに依存する場合もある。
欠陥の偏在の傾向を見つけると、効率良くテストすることができる。　そのため、テストや運用における欠陥の発生状況をもとにリスク分析し、どこを集中的にテストすればいいかを予測する。

## 原則5：殺虫剤のパラドックスにご用心
同じ殺虫剤を使い続けると、虫に耐性ができて効きにくくなるということ。
テストで言えば、「**同じテストを何度も繰り返すと、最終的にはそのテストで欠陥を見つけられなくなる**」ことだ。例えば、境界値分析は条件分岐の毛感を見つけやすいため、これを徹底的に行なって欠陥を修正すれば、条件分岐の欠陥は見つからなくなる。しかし、入力値に値が入っていない（NULLの状態）場合、や意図しない文字種などを入力してみないと、NULLや文字種のバリデーション（妥当性）に関する欠陥は残ったままになる。
欠陥には様々な種類があるため、色々なテストパターンやテストデータを試す必要がある。


## 原則6：テストは状況次第
状況が異なれば、テストの方法。
### システムの適用分野
例えば、安全性が重要産業用制御ソフトウェアでは、フェールセーフ（以上が発生した場合に安全側に動作する）が機能するかを重点的にテストする。また、利用者の数が一定でないeコマースシステムでは、キャンペーンなどでアクセスが急増した際の負荷テストを重点的に行う。
システムの用途によってテストで重視するポイントが異なる。

### システムの開発手法
アジャイル開発とウォーターフォール開発では、テストの実行方法が異なる。
アジャイル開発では、イテレーション（開発サイクルのこと）ごとにテストを行なってリリースする。ウォーターフォール開発では、開発フェーズが終了した後にまとめてテストを行う。
このように、開発手法によってテストをするタイミングが異なる。

## 原則7：「バグゼロ」の落とし穴
よくある思い違い（落とし穴）には以下がある。
1. テスト担当者は、可能なテストを全てを実行できる
2. テスト担当者は、全ての欠陥が検出できる
3. 大量の欠陥を検出して修正すれば、システムを正しく構築できる。

この3つは、**１+２=３**という関係になります。
つまり、徹底的にテストして（1）、可能な限りの欠陥を全て検出し（2）、それらの欠陥を全て修正すれば、ただしシステムとなる（3）という考え方である。
しかし、これらは全て思い違いだ。

# 次回
https://qiita.com/1225/items/26b2af90a6d429188eeb
【Xcode】タイプミス・スペルミスを検出する

# はじめに
僕めちゃくちゃ英語できないのでめっちゃスペルミスするんです。
僕以外にもいますよね？

そんなあなたに朗報です。

なんと！Xcodeにはスペルチェック機能あるらしいんです！
知りませんでした。

設定方法を記録しておきます。

# 今回検出したいスペルミス
本当は`digital`ですが、スペルミスをして`degital`になっています。

![スクリーンショット 2024-01-29 20.53.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/768cbc2a-e045-a3ce-1e56-a599c35e82f5.png)

これを検出したいです。

# やりかた
① 「Edit」を押します。
② 「Format」を選択します。
③ 「Spelling and Grammar」を選択します。
④ 「Check Spelling While Typing」にチェックを入れます。
![スクリーンショット 2024-01-29 20.35.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/897d4958-573f-098d-b889-542e80f1c00f.png)

# おわり
間違ったスペルのものに赤の波線を引いてくれるようになりました！
![スクリーンショット 2024-01-29 20.53.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/526bb573-0306-b131-fed5-4947e08ff111.png)

# 参考記事
https://blog.pentagon.tokyo/2064/#index_id1
AWS WAFについて書いてみた

## はじめに
おはこんばんにちは。キティちゃんです。最近は突然の頭痛に悩まされたりしています。今回はAWS WAFについて書いてみようと思います。

## きっかけ
AWS WAFもクラウド設計するうえで重要なセキュリティ対策の一つとして挙げられるため書いておこうと思いました。

## AWS WAFとは
お客様が定義する条件に基づきウェブリクエストを許可、ブロック、または監視するルールを設定し、Webアプリケーションを攻撃から保護してくれるサービスです。

## 通常のWAFとどう違うの？
基本的には同じですが、何より個別にソフトウェアをインストールしたり、アプライアンス機器を導入する必要がないため、初期費用が抑えることができます。また、AWS WAFの場合、従量課金制となるのも、特徴の一つと言えるでしょう。

## デメリットはない？
初期費用も抑えられて、従来のものと基本的には同じであれば完璧にも感じますが、デメリットもあります。例えばですが、高い専門性が求められてしまう点です。AWS WAFで脆弱性を検知するためには、検知できるようなシグネチャを更新する必要があります。シグネチャを更新する作業は攻撃に対しての知識といった専門性はもちろんのこと、運用者が常に最新の情報を収集することが求められます。そのため、正しく運用することができる人材を確保する必要があります。

## 所感
AWS WAFを導入することで、アプリケーションに対しての攻撃を防御することが可能となります。ですが、専門的な知識が必要となるため、初心者の方やセキュリティの知見がない人が扱うには難しいと思われます。使用する場合は、より専門的な知識を有する技術者も必要になるので結果的に費用は大きくなってしまうのではないかと考えます。AWS WAFだけで完璧なセキュリティを作れるわけではありませんが、アプリケーションのセキュリティ対策をしたい場合、AWS WAFは大いに役立つと思うので、あとは費用をかけるかどうか選択の問題かなと思います。

## まとめ
今回はAWS WAFについて書いてみました。正しく運用するためには専門的な知識が必要となりますので、セキュリティ系の人材がいない企業にとっては悩ましい問題となるかもしれません。また、従来のWAFとは異なり、ソフトウェアを別途インストールしたり、アプライアンス機器を導入する必要がないため、初期費用を抑えられるという点はメリットかもしれませんが、専門知識を有する人材を確保するので±0になる可能性がありそうですね。必ずしもAWS WAFに拘る必要はないかもしれません。

## 参考
・『AWS WAF　一般的な攻撃からウェブアプリケーションを保護』
https://aws.amazon.com/jp/security-hub/

・『AWS WAFとは？用途・メリットや料金体系から設定方法まで解説』
https://business.ntt-east.co.jp/content/cloudsolution/column-39.html#section-14
Microsoft Azure Data Scientist Associate (DP-100) 資格試験に合格するまでに実施したこと

# 概要
この度、私はMicrosoft Azure Data Scientist Associate (DP-100) 資格試験に合格しました。この資格試験は、Azure Machine Learningを使用してデータサイエンスソリューションを設計、実装、監視するための知識が必要とされます。
データサイエンスに関わるプロジェクトや職種に関心がある人は、この資格試験にチャレンジし学習することで、Azure Machine Learningを使用してデータサイエンスプロジェクトを実行するための知識やスキルを身につけることができます。

# Azure 資格 「Azure Data Scientist Associate 」とは

「Microsoft Certified: Azure Data Scientist Associate」は、Microsoft Azure 上で機械学習ワークロードを実装し、実行するための専門知識を持つことを証明する資格です。この資格には、データサイエンスと機械学習の知識が必要であり、データサイエンスワークロードに適した作業環境の設計と作成、データの探索、機械学習モデルのトレーニング、パイプラインの実装、ジョブの準備、スケーラブルな機械学習ソリューションの管理などのスキルが求められます。この資格を取得するための試験は「DP-100: Designing and Implementing a Data Science Solution on Azure」です。

https://learn.microsoft.com/ja-jp/credentials/certifications/exams/dp-100/

# 学習方法
私は、以下に示す Microsoft Learn や eラーニング講座を使用して学習を進めました。受験にあたっては、模擬試験問題集を解いて正解率が70%以上を目指し自分の理解度が十分なレベルに達しているか確認しました。

| カテゴリ | 学習リソース名称 | 学習内容（参考） | 学習期間（参考） |
|:--|:--|:--|:--|
| セルフペースeラーニング | [Microsoft Learn, "Exam DP-100: Designing and Implementing a Data Science Solution on Azure"](https://learn.microsoft.com/ja-jp/credentials/certifications/exams/dp-100/) | データサイエンスやAzure に関する基本的な用語を理解する。無料  | 1ヶ月 |
| セルフペースeラーニング | [Coursera, "Microsoft Azure Data Scientist Associate (DP-100) Professional Certificate"](https://www.coursera.org/professional-certificates/azure-data-scientist) | Azure 上でのデータサイエンスやAzure Machine Learning, Azure Databricks 等に関する包括的な知識やスキルを、演習を通じて学習する。有料 | 2ヶ月 |
| 模擬試験  | [Practice Assessment for Exam DP-100: Designing and Implementing a Data Science Solution on Azure](https://learn.microsoft.com/en-us/credentials/certifications/exams/dp-100/practice/assessment?assessmentId=62&assessment-type=practice) | 最新の試験バージョンに沿った試験問題を解いて、試験傾向を理解する。無料 | 1,2週間 |

個人的には、Courseraのコースは試験対策としてだけではなく、Machine Learning 全般的に非常に勉強になりました。

# 試験にあたって
今回受験した DP-100 試験では、試験中、Microsoft Learn のオンラインドキュメントを閲覧できます。たとえば、「ある API の必須パラメータは何か？」等詳細を思い出せない場合でも、その場でオンラインドキュメントで正解を検索し回答することができます。
「調べれば正解を出せる問題」は、オンラインドキュメントを活用して確実に得点すると合格率が高まります。

# 合格までの期間
私は、上記の学習リソースを順番に約3ヶ月かけて学習した結果、試験に合格することができました。

# 認定
[Microsoft Certified: Azure Data Scientist Associate](https://learn.microsoft.com/en-us/users/markkiyota-6108/credentials/f1405905bf8f8d82)

# 今後の展望
[Parul Gautamさんのツイート](https://twitter.com/Parul_Gautam7/status/1748935248874733797)にて、Data Engineer, Data Scientist, Data Analyst, Machine Learning Engineerの違いについて述べられています。
データサイエンスや機械学習に関心がある方は、自身がどの分野に興味があるか、選択すべきか参考になるかと思います。
今後、私は、データ分析、データエンジニアリング、データサイエンスに加え、これまでに蓄積してきた Machine Learning の分野の知識やスキルを体系立てて整理し強化したいと考えています。

![dataroles.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55793/197c3bb3-be01-6f68-2635-e4b558361735.jpeg)


以上
AlmaLinux 9.3に Bitwardenをインストールする

下記方法ではサーバー再起動後にアカウントの作成やログインができない

```
dnf upgrade -y
dnf update -y
```

dockerをインストールする　[引用元](https://higmasan.com/docker/almalinux-9-1%E3%81%ABdocker%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B/)

```
dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo Adding repo from: https://download.docker.com/linux/centos/docker-ce.repo
dnf install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
systemctl start docker
systemctl enable docker
docker -v
```

docker-composeをインストールする　　[引用元](https://blog.mitsuto.com/docker-compose-v2)　[最新バージョン取得](https://github.com/docker/compose/releases/)
```
curl -sL https://github.com/docker/compose/releases/download/v2.24.3/docker-compose-linux-x86_64 -o /usr/libexec/docker/cli-plugins/docker-compose
chmod +x /usr/libexec/docker/cli-plugins/docker-compose
ln -sf /usr/libexec/docker/cli-plugins/docker-compose /usr/bin/docker-compose
docker-compose -v
```

bitwardenをインストール　　[引用元](https://bitwarden.com/ja-JP/help/install-on-premise-linux/)
```
adduser bitwarden
usermod -aG docker bitwarden
mkdir /bit
chmod -R 700 /bit
chown -R bitwarden:bitwarden /bit
```

bitwardenをインストール　[引用元](https://vpsie.com/knowledge-base/how-to-install-bitwarden-on-ubuntu/)
```
su bitwarden
cd /bit
curl -Lso bitwarden.sh https://go.btwrdn.co/bw-sh
chmod +x bitwarden.sh
./bitwarden.sh install
```

続きは[こちら](https://bitwarden.com/ja-JP/help/install-on-premise-linux/)をする
[キー生成ページ](https://bitwarden.com/host/)
AWS Well-Architected Frameworkについて書いてみた

## はじめに
おはこんばんにちは。キティちゃんです。寒かったと思ったら突然寒くなく感じたり、体調管理が難しい時期がやってきたなと思います。今回はAWS Well-Architected Frameworkについて書いてみようと思います。

## きっかけ
意外と重要なことなので、書いておこうと思いました。

## AWS Well-Architectedとは
クラウドアーキテクトがさまざまなアプリケーションやワークロード向けに高い安全性、性能、障害耐性、効率性を備えたインフラストラクチャを構築する際に役立つものです。

## AWS Well-Architected Frameworkとは
AWS Well-Architectedの各6つの柱でそれぞれのベストプラクティスをまとめたものとなります。

## 利用するメリット
AWS Well-Architected Frameworkを利用することで、ベストプラクティスなクラウドアーキテクトを設計することができます。AWSのソリューションアーキテクトとお客様が長年の経験から作り上げたもので、10年以上の歳月をかけて作り上げたベストプラクティスをすぐさま入手できるのが最大の特徴です。

## 注意点
AWS Well-Architected Frameworkは確かに便利なフレームワークですが、必ずしもベストプラクティスに沿う必要がなく、ビジネス的な判断をもって構築する必要があるということです。企業には企業ならでは事情があります。つまり、単に「なんとなくこうしている」ではなく、「ベストプラクティスはこうなっているが、うちの設計上、こうするしかない」という明確な根拠をもった上でリスクや改善点を顕在化させる必要が出てきます。

## 所感
AWS側のみで長年の経験則をもとに作ったと思っていたので、利用者たちと歳月をかけ作り上げたというのは驚きました。協力して作り上げたからこそ、多くのノウハウが詰め込まれているのだなと思います。特にAWS始めたての人は何がベストな設計なのかを理解しているわけではないですし、もしかしたら何となくでこう設計しているというのもあるかもしれません。本来であれば、根拠をもった上で、設計をする必要があり、何となくは情報漏洩のリスクも高まります。ですので、そうなる前に是非AWS上で設計をする際は、AWS Well-Architected Frameworkを活用してみるのがいいでしょう。

## まとめ
今回はAWS Well-Architected Frameworkについて書いてみました。私自身、AWS側とそのお客様によって長年の月日を経て、フレームワークは作られたのだというのを初めて知りました。また、必ずしもベストプラクティスに沿う必要はなく、根拠をしっかりもった上で、リスや改善点を顕在化させる必要があるというのも確かにそうだなと思います。利用するにあたって、何も根拠をもたず構築されたものというのは恐怖でしかありません。そういった甘い考えから情報漏洩などに繋がったりするわけです。構築する際は、しっかり根拠を明確にした上で、最適なベストプラクティスを追求していきましょう。

## 参考
・『AWS Well-Architected　アーキテクチャのベストプラクティスを使って、学習、測定、構築を行う』
https://aws.amazon.com/jp/architecture/well-architected/?wa-lens-whitepapers.sort-by=item.additionalFields.sortDate&wa-lens-whitepapers.sort-order=desc&wa-guidance-whitepapers.sort-by=item.additionalFields.sortDate&wa-guidance-whitepapers.sort-order=desc

・『【AWS Black Belt Online Seminar】AWS Well-Architected Framework』
https://www.youtube.com/watch?v=jMJFFo1Oybo&ab_channel=AmazonWebServicesJapan%E5%85%AC%E5%BC%8F