OmniAICreator/Qiita-1.07M huggingface dataset:
RailsとVue.js3のSPAアプリにDeepL apiを導入する

ポートフォリオ作りの過程でRails×Vue.js3のSPAアプリにDeepL apiを導入したので過程を初学者視点で紹介します。
開発環境にはdockerを使用しています。

```
#version
Ruby 3.0.2
Rails 6.0.4
Vue.js3

#開発環境
Docker
docker-compose
```

# APIで実現したいこと

![スクリーンショット 2022-01-27 20.19.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1640672/fe122651-feb6-82c8-f52e-2918314ab842.png)

上記の画像の「AI翻訳の結果を表示する」ボタンを押すと上部に表示された日本語文を英訳して表示する。

# DeepL apiの登録

https://www.deepl.com/ja/pro-api?cta=header-pro-api/

こちらから登録します。
50,000文字/1ヶ月の制約はありますが無料プランもあります。

登録すると自身のアカウントに認証キーが表示されるのでそれをコピーしておきます。

# Rails側の実装

```
gem httpclient 
```
上記gemをインストールします。DeepL apiは"https://api-free.deepl.com/v2/translate" というurlにget(もしくはpost)リクエストを認証キー、翻訳したいテキスト、変換結果の言語の３点をパラメーターとして含んだ上で送信する必要があります。httpclientはrailsのcontrollerからそのリクエストを送信するための記述を提供してくれるgemになります。

```
$ docker-compose build --no-cache
```
今回はdockerを使用しているので上記コマンドでgemをインストールします。

```
$ rails g controller api/translations
```
apiを叩くためのコントローラーを用意します。既存のコントローラーを使用しても問題ありません。

```
$ EDITOR="vi" bin/rails credentials:edit

deepl_api: 
    api_key: DeepL apiの認証キーを貼り付け
```
認証キーを直打ちしなくて済むようにcredentials.ymlに秘匿します。

```translations_controller.rb

class Api::TranslationsController < ApplicationController
  require 'httpclient'　#httpclientを使用できるようにします

  def translate
    @question = Question.find(params[:id])
    api_key = Rails.application.credentials.deepl[:api_key]
    uri = "https://api-free.deepl.com/v2/translate"
    client = HTTPClient.new
    params = {
      auth_key: api_key,
      text: @question.content,
      target_lang: "EN"
    }
    @response = client.get(uri, query: params)
    render json: @response.body
  end
end

```
前述の「実現したいこと」の画像に表示されている翻訳したい文章はQuestio モデルのcontentカラムに保存されているものになるのでparamsのtextには@question.contentを代入しています。

```routes.rb

namespace :api, format: 'json' do
  get '/translate/:id', to: 'translations#translate'
end
```
questionモデルのidをパラメーターとして送信するため/:idを付け加えていますが'/translate'の部分は自由に書き換えてください（例えば'/aaa/:id'でも'translations#translate'によってapi/translations_controllerのtranslateアクションを実行してくれます）。

# Vue側の実装

```
<template>
      <button @click="translateWithDeepL">
          AI翻訳の結果を確認する
      </button>
      <h1>翻訳結果: {{result}}</h1>
</template>

<script>
methods: {
  translateWithDeepL: function() {
     const question_id = this.question.id
     axios.get('/api/translate/'+ question_id)
     .then(response => {
     this.result = response.data.translations[0].text
    })
  }
}
</script>
```
axios.get('/api/translate/' + question_id)でroute.rbに設定したget '/translate/:id'にアクセスし、translations_controllerのtranslateアクションを実行という流れになります。

具体的には仮に翻訳したいテキストが[hello]で翻訳結果の言語を日本語に設定すると
https://api-free.deepl.com/v2/translate?auth_key=認証キー&text=hello&target_lang=JA
というURLにgetリクエストが送信され、

```
{
	"translations": [{
		"detected_source_language":"JA",
		"text":"こんにちは"
	}]
}
```
というresponseがjson形式でかえってきます。
このレスポンスのtextの部分だけ表示したいので

```
response.data.translations[0].text
```
という形でフロントエンド上では受け取っているわけです。
PythonでSeleniumするときに書いておいたほうがいいコード

メモとして残しておきます。

```scraping.py
from selenium import webdriver
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.service import Service

options = webdriver.ChromeOptions()
options.add_argument("start-maximized")  # 画面表示を最大にする
options.add_experimental_option("excludeSwitches", ["enable-logging"])  # よくわからん長文をコンソールに表示させない
s = Service(ChromeDriverManager().install())  # これでwebドライバーのパスの指定不要、ブラウザのバージョンに合わせなくて済む
driver = webdriver.Chrome(service=s, options=options)
# ここまで定型句

driver.get("{WEBページのURL}")
# 以下ご自由に
twitterAPIの取得に苦労したので情報共有します

#twitterAPIの取得方法（"Elevated"ライセンスまで）

1. twitterAPIには"essencial"と"Elevated"のライセンスがある。
2. "essencial"ライセンスはパーミッションが"Read"のみで情報の取得しかできない。
3. 一方、"Elevated"ライセンスはパーミッションが"Read&Write"でツイートやいいねができる。
4. APIの利用を開始すると最初は"essencial"ライセンスとなる。その際、英語の質問は特にされない。
4. "Elevated"ライセンスを取得するためにはディベロッパーポータルから申し込む必要がある。その際、英語の質問をされる。

英語の質問で気を付けたいことは下記２点
・自動でいいねやリツイートをするとは言わないこと。
・ツイッターの内容やコンテンツを外部で表示するといわないこと。
・いかなる政府機関や公共団体にもAPIのデータは利用されないこと
自動でいいねを押すことは禁止されています。

検索で出てくる情報と今の登録方法には少し違いがあるようです。
tweepyは"Elevated"ライセンスでのみ利用できます。
【Anaconda3】仮想環境で起動したAtomからコードを直接実行する（RDKit）

以前、RDkitという化学系ライブラリを使用するためにPython3.7系の仮想環境を作成しました（RDkitがPython3.8以上に対応していないため）。このような仮想環境下でAtomエディタから直接スクリプトを実行する方法を調べたのでメモしておきます。

```:利用環境
Python: 3.8.8 (Anaconda3で導入)
(RDkit用の仮想環境のPythonは 3.7.11)
OS: Windows 10
エディタ: Atom ("script" パッケージ導入済み)
```

※ここでは既にRDkit用の仮想環境が準備できているものとします。仮想環境を構築する方法については過去のエントリを参考にして下さい。

https://qiita.com/h-nabata/items/c1d16471bda6735a5d8a

# 手順

### ①　Anacondaパッケージに同梱されている「Anaconda Prompt」を起動
### ②　Anaconda Promptで`activate [仮想環境名]`を実行して仮想環境を起動

>環境一覧を取得したいときは`conda info -e`で表示できます。
>```
># conda environments:
>#
>base                  *  C:\Users\[ユーザー名]\anaconda3
>rdkitenv                 C:\Users\[ユーザー名]\anaconda3\envs\rdkitenv
>```
> ここでは仮想環境を `rdkitenv` という名前にしてあります。

### ③　Anaconda Promptで`atom`を実行してAtomエディタを起動

> コマンドプロンプトで起動してもOKです。

### ④　スクリプトを実行

> Atomに "script" パッケージを導入済みであれば「Ctrl + Shift + B」で実行できます。

問題が無ければ以下のプログラムが動くはずです。

```py:sample.py
from rdkit import Chem
import sys

print(sys.version_info)
# sys.version_info(major=3, minor=7, micro=11, releaselevel='final', serial=0)

# 周期表の取得（インスタンス化）
pt = Chem.rdchem.GetPeriodicTable()

# 1 ~ 9 番目までの元素記号を表示
for i in range(1,10):
    print(Chem.PeriodicTable.GetElementSymbol(pt, i))
# H
# He
# Li
# Be
# B
# C
# N
# O
# F
```

私のRDkit用の仮想環境 `rdkitenv` のPythonのバージョンは3.7.11なので、意図した環境で実行できていることが分かります。

# 後記

以上のことは単純に「仮想環境からAtomを起動することで仮想環境のバージョンのPythonが使われる」という理解で良いかと思います。私が知らないだけで実は常識だったのかは分かりませんが、参考になる日本語の記事を上手く見つけられなかったので個人的にまとめてみた次第です。
splitメソッドとそれに関連するメソッドの解説

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2485775/e4ed46f9-e4fd-b20f-7f62-cffe9617a99c.png)

ruby silverの勉強をしていく中で間違えたところがあったのでその解説記事を挙げていきます。


#splitメソッド
指定した文字列で分割し、それを配列で返すメソッドです。
基本構文は、
```
"文字列".split(区切り文字, 分割数)
```
論より証拠ということで、実際にコードを見ていきましょう

```
'Yamada, Satou, Itou, Suzuki'.split(',')
=> ["Yamada", " Satou", " Itou", " Suzuki"]


'Yamada, Satou, Itou, Suzuki'.split('u')
=> ["Yamada, Sato", ", Ito", ", S", "z", "ki"]
```
1個目の例でいえば、対象の文字列には、「,」があるので、,を目印に区切っていくメソッドなんですね
2個目の例でいえば、「u」を目印に文字列を区切っていくようなメソッドです。

##分割数の指定
分割数を指定することもできます。

```
'Yamada, Satou, Itou, Suzuki'.split(',', 2)
=> ["Yamada", " Satou, Itou, Suzuki"]


'Yamada, Satou, Itou, Suzuki'.split('u', 2)
=> ["Yamada, Sato", ", Itou, Suzuki"]

```
また、分割数を制限することもできるんです。

```
'Yamada, Satou, Itou, Suzuki'.split(',').first
=> "Yamada"
```

##正規表現とも組み合わせることが可能

```
'Yamada, Satou, Itou, Suzuki'.split(/[a | u ]/)
=> ["Y", "m", "d", ",", "S", "to", ",", "Ito", ",", "S", "z", "ki"]
```
正規表現に関しては、[こちら](https://murashun.jp/article/programming/regular-expression.html)のサイトを参照してみてください！

##1バイトの空白文字がある場合
1バイトの空白文字とは、文字列の半角スペースのことをいいます。

:::note info
この場合、その文字列の先頭と末尾の空白文字を除いてくれて、さらに、空白文字に一致する部分で分割します。
補足でいうと、改行(\n)、タブ(\t)、nilも対象になります。
:::
```
'Yama da Sat ou It ou Su zuki'.split(' ')
=> ["Yama", "da", "Sat", "ou", "It", "ou", "Su", "zuki"]
```

##今回の問題の正解
()で囲われたものを含んだ結果を返すんですね。なので、

```
["Apple", "-", "Banana", "-", "Lemon"]
```
が正解ですね

ちなみに、以下のようにすると答えはまた変わりますね

```
p "Apple-Banana-Lemon".split('-')
=> ["Apple", "Banana", "Lemon"]
```

#類似メソッド
##String#partitionメソッド
>[最初のセパレータより前の部分, セパレータ, それ以降の部分] の 3 要素の配列を返します。　by公式ドキュメント

セパレータって何？って方は、[こちら](https://wa3.i-3-i.info/word15368.html)の記事を読んでみてください

要は、[最初にヒットした場所より前の場所、最初にヒットした場所、それ以降の部分]ってことです。
実際にコードを見ていきましょう

```
p 'Ishida Keisuke'.partition('s')
=> ["I", "s", "hida Keisuke"]


p 'Ishida Keisuke'.partition('x')
=> ["Ishida Keisuke", "", ""]
ヒットしなかった場合は、第2要素、第3要素は空文字になる。
```

あまり、partitionメソッドは使われていないような気がしますね
今回はこの辺で終わりにします！
何か間違いがございましたら、ご教示いただけますと幸いです。

【参考文献】

https://pikawaka.com/ruby/split

https://docs.ruby-lang.org/ja/latest/method/String/i/split.html
Step Functions で States.ReferencePathConflict が起きたときの対処

# 概要

Step Functions の ResultPath を指定したものの、以下エラーが発生することがある。

```json
{
  "error": "States.ReferencePathConflict",
  "cause": "Unable to apply ReferencePath $.someTaskResult to input \"input1\""
}
```

ここでは `someTaskResult` という key に結果を出力しようと試みている。

# 原因

ステップの入力が Object 型ではない可能性がある。
例えば、プリミティブな String が入力された場合、当然ながら `someTaskResult` という key は設定できない。例えば Map を使う場合、イテレーションの対象として List を使わなければいけないが、List の各値がプリミティブ型だった場合、イテレータに渡る入力としてこのような事態が起こりうる。

# 対策

前段の出力を加工し、Object 型にしてしまえばよい。具体的には Parameter が使える。上述の Map による問題だった場合も、Map に Parameter が利用できる。イテレータへの入力が Parameter によって加工された値になる。

```json:Mapの例
  "Type": "Map",
  "Parameters": {
    "input1.$": "$$.Map.Item.Value",
      :
  },
  "Iterator": {
    "States": {
      "SomeTask": {
        "ResultPath": "$.someTaskResult",
              :
```

上記のようにすると、 `{ "input1": "～～～" }` という入力になるので、 `SomeTask` の出力 `.someTaskResult` はエラーなく入力の Object に追加されるようになる。
Python でウィンドウの閉じるボタンを無効化する

# 概要
Minecraftで遊んでいるとき、間違えてウィンドウの閉じるボタンを押してしまうと何の確認もなくゲームが終了してしまいます。これを防止するために閉じるボタンを無効化します。
# 前提

```
Microsoft Windows 10 Home
Python 3.7.7
pip 21.3.1
```

## pywin32 のインストール

```
pip install pywin32
```

# プログラム

```python:disableXbutton.py
import win32con
import win32gui

from typing import Union


def getHwnd(title: str) -> Union[int, None]:
    hwnd = win32gui.FindWindow(None, title)
    if not hwnd:
        return None
    return hwnd


def showXbutton(hwnd: int) -> None:
    win32gui.GetSystemMenu(hwnd, True)


def disableXbutton(hwnd: int) -> None:
    win32gui.GetSystemMenu(hwnd, True)
    hMenu = win32gui.GetSystemMenu(hwnd, 0)
    if not hMenu:
        print("couldn't find menu.")
        return

    win32gui.DeleteMenu(hMenu, win32con.SC_CLOSE, win32con.MF_BYCOMMAND)


def main():
    titles = []
    with open("titles.txt", mode="r") as f:
        titles = f.readlines()
        titles = list(map(lambda x: x.replace("\n", ""), titles))

    for title in titles:

        hwnd = getHwnd(title)
        if not hwnd:
            print("couldn't find window:", title)
            continue

        disableXbutton(hwnd)
        print("Disabled Xbutton: " + win32gui.GetWindowText(hwnd))

        # 無効化した閉じるボタンを有効化する関数
        # showXbutton(title)


if __name__ == '__main__':
    main()

```

```:titles.txt
Minecraft* 1.17.1 - Multiplayer (3rd-party Server)
```

# ウィンドウ名の調べ方
`titles.txt` に入力するウィンドウ名は、おそらく完全なものである必要があります。そのために、`Visual Studio` に同梱されている `Microsoft Spy++`([公式ドキュメント] (https://docs.microsoft.com/ja-jp/visualstudio/debugger/how-to-start-spy-increment))を使用します。

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659043/c36ce026-c332-7ad0-9e4c-003c53f74585.png)|
|:-:|

## 1.
|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659043/4371c721-60e7-216e-4356-649d271fa86a.png)|
|:-:|

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659043/4d705ff5-9a35-2350-333f-ee2e87923f0d.png)|
|:-:|

`ウィンドウ検索` を開き `ファインダー ツール` を調べたいウィンドウの上にドラッグし、`OK` を押します。

## 2.
|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659043/9d6316aa-803c-a3d2-ddcf-f9ec60397498.png)|
|:-:|

`OK` を押すと `プロパティインスペクター` が表示され、`ウィンドウキャプション` が調べたかったウィンドウ名となります。


# 実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659043/0a3dd2b6-d978-836b-9c03-a80a3cfa94e1.png)

実行すると、閉じるボタンが灰色になり無効化されます。

# 参考

https://stackoverflow.com/questions/29269436/disable-close-button-of-console-window
複数の AppFlow を実行するワークフローを書いた

# 概要

とある案件で AWS の AppFlow を複数件スケジュール実行したいという話があった。
運用コストを極力抑えたかったので、サーバレスの Step Functions を使ってワークフローを書いた。また、本稿では記載していないが、スケジュール実行部分に関してはセオリー通り EventBridge を用いた。

# ステートマシンの全体像

## 親

![stepfunctions_graph.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49525/9b673078-079a-278d-7c9b-c72851e0253d.png)

特に複雑なことはしておらず、実行対象のフロー (ここではバックアップ処理を行うフロー) の一覧を取得し、あとは Step Functions の Map を使って逐次処理しているのみ。一覧取得は若干複雑な条件を利用してフィルタリングしているため、 Lambda で実装している。
`Run AppFlow` は別のステートマシンであり、いわゆるネストされたステートマシンとなっている。理由としては、後述するステートマシンのイベント数上限を回避しやすくするため。

## 子

![stepfunctions_graph (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49525/dc528f6a-c924-0bc0-c67d-d8bd5251948f.png)

AppFlow の実行と、終了確認を一定時間ごとに行っている。数時間かかるような長いフローだとポーリングする回数が増大してしまい、結果として Step Functions のイベント数クオータ (25,000 events) に達してしまうため、親でひとまとめでやらずにステートマシンを子に分割してクオータに達しにくくしている。

特に Lambda は利用しておらず、Step Functions の SDK 統合機能を使って appflow:StartFlow や appflow:DescribeFlow を呼び出している。

`Whether Flow Ended` は Step Functions の Choice を使い、DescribeFlow の LastRunExecutionDetails.MostRecentExecutionStatus が

- InProgress: `Wait` へ
- Successful: `Flow Successful` へ
- それ以外: `Flow Error` へ

それぞれ移行するように制御している。

# まとめ

ほとんどの処理を Step Functions に任せられることができた。サーバレスであるため運用の手間がなく、また料金面も格安で利用が可能。
Step Functions の SDK 統合機能が強すぎる。

https://aws.amazon.com/jp/about-aws/whats-new/2021/09/aws-step-functions-200-aws-sdk-integration/
電子署名の仕組みについて

# 内容
この記事はAWS初学者を導く体系的な動画学習サービス
「AWS CloudTech」の講座を参考に作成しました。
https://aws-cloud-tech.com

##### 以下に電子署名の仕組みとそれを実現するための技術である`一方向ハッシュ関数`について記載します。

#電子署名とは
・「電子データ作成者」情報を電子データに付与し、電子ファイルが改ざんされていないことを証明する技術です。
・紙の書類におけるサインや押印を電子的に実現したものになります。

#一方向ハッシュ関数とは

・電子署名を実現するために用いられる暗号化技術です。
・対象のデータから特殊技術によりランダムな英数字（ハッシュ値：長さは固定）を生成することができます。
・対象のデータが１ビットでも異なるとまったく別のハッシュ値が生成されます。
・ハッシュ値から対象のデータを生成することは現実的ではありません。

#電子署名の仕組み

1. 署名者（Aさん）は、電子ファイルのハッシュ値を計算し、`Aさんの秘密鍵`で暗号化します。
1. 上記の`電子ファイル`、`暗号化したハッシュ値`、`Aさんの証明書`の3点を受信者に送信します。
1. 受信者は、`Aさんの証明書`に含まれる`Aさんの公開鍵`を用いて`暗号化したハッシュ値`を復号し、`電子ファイル`のハッシュ値と比較します。
1. 比較した結果が一致すれば、`電子ファイル`はAさんが作成し、改ざんされていないことが証明できます。

##### `Aさんの秘密鍵`はAさんしか持っておらず、`Aさんの公開鍵`とペアになっているため、復号できたということは、上記の`電子ファイル`はAさんが作成したものだ、ということが分かると思います。

#（参考）AWSにおける証明書発行サービスについて

・AWS環境で利用できるSSL/TLS証明書を発行・管理してくれるサービスとして、`ACM（AWS Certificate Manager）`があります。
・証明書の更新はAWSが自動で行なってくれます。
・無料で証明書を発行できます。
・コンソールから数分で発行でき、複数の証明書を一括管理できます。

ACMの使用については、以下の記事をご覧ください。

https://qiita.com/zakinicof/items/118c0e6dee648a7faa93
AWS_STEP_FUNCTIONS_STARTED_BY_EXECUTION_ID の有無による挙動の違い

# 概要

Step Functions でネストしたステートマシンを定義する場合、子のステートマシンを呼び出す際に `AWS_STEP_FUNCTIONS_STARTED_BY_EXECUTION_ID` を渡すのが一般的。

```json
        "States": {
          "Run Another State Machine": {
            "Type": "Task",
            "Resource": "arn:aws:states:::states:startExecution.sync",
            "Parameters": {
              "StateMachineArn": "arn:aws:states:ap-northeast-1:...",
              "Input": {
                "AWS_STEP_FUNCTIONS_STARTED_BY_EXECUTION_ID.$": "$$.Execution.Id",
                     :
```

なぜ渡さなければいけないのか、ドキュメントを読んでもよくわからなかったので、実際に試してみた。

https://docs.aws.amazon.com/ja_jp/step-functions/latest/dg/concepts-nested-workflows.html

# 実行結果

結論としては、子のステートマシンの実行結果の `Started By` の有無が差異としてあった。

## AWS_STEP_FUNCTIONS_STARTED_BY_EXECUTION_ID あり

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49525/f0958c80-5822-6a89-1ab8-01ad27cd0235.png)

Started By に呼び出し元 (親ステートマシン) の arn がある。

## AWS_STEP_FUNCTIONS_STARTED_BY_EXECUTION_ID なし

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49525/40ae1094-d1b2-f3fa-c575-44c7681bde92.png)

Started By がそもそもない。

# まとめ

- AWS_STEP_FUNCTIONS_STARTED_BY_EXECUTION_ID を渡すと、子の実行結果に Started By が追加される。
- AWS_STEP_FUNCTIONS_STARTED_BY_EXECUTION_ID を渡さなくても実行自体は問題なく行われる。
Goのスライスの中身がすべて同じ値になる

# 結論

range の左辺はただの変数である。
繰り返しのたびに再代入しているだけなので、気をつける。

# 現象

上手い例がかけないが、例えば以下の状況

```go

type Foo struct {
  Item string
}

foo1 := Foo{"1"}
foo2 := Foo{"2"}
foo3 := Foo{"3"}
slice := []Foo{foo1, foo2, foo3}

var foos []*Foo
for _, foo := range slice {
  foos = append(foos, &foo)
}

for _, foo := range foos {
  fmt.Println(foo.Item)
}

// => 3
// => 3
// => 3

// 中身が同じ、なぜ？
```

なぜか中身がすべておなじになる。

# 原因

range の第二引数のポインタを格納してしまっているため。

詳しくは `foos` の中身をプリントしてみるとわかる

```go

type Foo struct {
  Item string
}

foo1 := Foo{"1"}
foo2 := Foo{"2"}
foo3 := Foo{"3"}
slice := []Foo{foo1, foo2, foo3}

var foos []*Foo
for _, foo := range slice {
  foos = append(foos, &foo)
}


fmt.Println(foos)

// => [0x14000010230 0x14000010230 0x14000010230]

```

同じポインタが3つ格納されている。
これはどこで格納されたかと言うと、 繰り返し処理のときに range の左辺の変数のポインタが格納されている。

```go

type Foo struct {
  Item string
}

foo1 := Foo{"1"}
foo2 := Foo{"2"}
foo3 := Foo{"3"}
slice := []Foo{foo1, foo2, foo3}

var foos []*Foo
for _, foo := range slice {
  foos = append(foos, &foo) // <= ここで変数 foo のポインタを参照し、foos に追加している
}

```

1. range 文で何回繰り返そうと、左辺の変数は一度のみしか定義されない（同じ変数には破壊的代入を繰り返す）
2. そのため、ブロック内の `&foo` は常に同じポインタ値を返す
3. 3回の繰り返しのうち、すべて同じポインタが格納される
4. `foos` はすべて同じポインタ値を格納しているため、参照時にすべて同じ変数を見る
5. 3回目で `foo` に `Foo{”3”}` が代入されるため、すべて `Foo{"3"}` を見る

# 対策

for ブロックの中で、左辺の変数のポインタを取得しない。
Rails7でspring起因でrails consoleが立ち上がらなかった問題の解決方法

# はじめに

現在個人プロジェクトで

- M1 Mac
- Ruby3.1.0
- Rails7.0.1

という環境での開発を試しています。今までは

- Intel Core i7
- Ruby2.x
- Rails6.x

という環境だったので、やはり動くところ、動かないところが出てきます。
(特に、Docker周りは変なバグを踏まないか戦々恐々としています)

今回はRails7のプロジェクトにて、springのバージョンのせいでrails consoleの実行が失敗した件についてです。

# 事象

発生したエラーはこんな感じで、 `bundle exec rails c` を実行した時に発生しました。

```
/usr/local/bundle/gems/spring-2.1.1/lib/spring/application.rb:103:in `block in preload': undefined method `mechanism=' for ActiveSupport::Dependencies:Module                                                                     
                                                                                                                 
        ActiveSupport::Dependencies.mechanism = :load                                                            
                                   ^^^^^^^^^^^^ (NoMethodError)
```

# 原因

rails newをした時にはspring 4.0.0でプロジェクトが作成されていたのですが、gemを整理してbundleし直した時にspringのバージョンが2.1.1に巻き戻っていたようです。

↓該当の差分

![スクリーンショット 2022-01-27 19.50.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29737/1a0b606c-b282-8b75-2029-9d4cfad6a510.png)

# 対処方法

ググってたらRails Guideにてそのものズバリな記事を見つけました。

https://edgeguides.rubyonrails.org/upgrading_ruby_on_rails.html#upgrading-from-rails-6-1-to-rails-7-0-spring

ここに「springは最低でも3.0.0にしてね！」と書いてあったおかげで差分があることに気づけました。
新規でプロジェクトを立ち上げた時には問題なくrails consoleが使えていたので、原因を見失っていましたが、springのバージョンを戻したことで問題なく動いています。

デフォルトでrails newした時には4.0.0でプロジェクトが作成されるため滅多に踏むバグではないかも知れませんが、

- 他のgemとの依存関係でたまたま自分のようにバージョンが巻き戻ったケース
- Rails6以前のプロジェクトをRails7に上げた際、springのバージョンを上げ忘れたケース

で引っかかる可能性があります。

rails consoleだけでなく、rspecなどのspringを使うコマンド実行でも発生する可能性があるため、 Rails7プロジェクトで `undefined method 'mechanism=' for ActiveSupport::Dependencies:Module` というエラーを発見したらspringがバージョン2系以前になってないか確認してみてください。
matplotlib color for tasteful drafting

# Introduction

matplotlib memo

# Color

```python
import matplotlib.pyplot as plt
from matplotlib import colors as matcolors


colors = dict(matcolors.BASE_COLORS, **matcolors.CSS4_COLORS)

# Sort colors by hue, saturation, value and name.
by_hsv = sorted((tuple(matcolors.rgb_to_hsv(mcolors.to_rgba(color)[:3])), name)
                for name, color in colors.items())
sorted_names = [name for hsv, name in by_hsv]

n = len(sorted_names)
ncols = 4
nrows = n // ncols + 1

fig, ax = plt.subplots(figsize=(20, 10))

# Get height and width
X, Y = fig.get_dpi() * fig.get_size_inches()
h = Y / (nrows + 1)
w = X / ncols

for i, name in enumerate(sorted_names):
    col = i % ncols
    row = i // ncols
    y = Y - (row * h) - h

    xi_line = w * (col + 0.05)
    xf_line = w * (col + 0.25)
    xi_text = w * (col + 0.3)

    ax.text(xi_text, y, name, fontsize=(h * 0.8),
            horizontalalignment='left',
            verticalalignment='center')

    ax.hlines(y + h * 0.1, xi_line, xf_line,
              color=colors[name], linewidth=(h * 0.6))

ax.set_xlim(0, X)
ax.set_ylim(0, Y)
ax.set_axis_off()



fig.subplots_adjust(left=0, right=1,
                    top=1, bottom=0,
                    hspace=0, wspace=0)

plt.show()
```

![スクリーンショット 2022-01-27 19.34.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/896292/26ac9e34-119a-08d7-89f9-9046f869c08b.png)


# LGTM

https://matplotlib.org

https://matplotlib.org/cheatsheets/

https://matplotlib.org/stable/gallery/

https://colorhunt.co
Makefile で *** target pattern contains no `%'.  Stop. エラーが発生する

# 現象

例えば以下のような Makefile にて発生する。

```
foo-%:
    echo foo
```

# エラー

上記を実行すると、以下のエラーが発生する。

```
$ make foo-bar       
Makefile:1: *** target pattern contains no `%'.  Stop.
```

ターゲットに % は含まれているはずだが、果たして、、、。

# 原因

レシピのインデントがスペースになっている。

# 解決策

Makefile はタブが大好物なので、忖度する。

```
foo-%:
	echo foo
```

あるあるではあるが、以上。
Laravel sail AWS S3 画像をアップロードする

# 【Solved】 Laravel sail 本番環境で画像投稿 500 error
# はじめに
Laravel 初学者の私が学習した内容をアウトプットしていく記事になります。
冗長している点や軽い書き方などあれば御指南お願いいたします。。。:bow_tone5:
## 前提条件
・PHP
・Laravel sail
・Heroku
・AWS S3
## エラー
__" Missing required client configuration options: region While Trying to Implement S3 "__
と本番環境で画像投稿を試みたが、上記のエラーが出てきた。
要は、__「　画像を上げる際にクライアント設定オプションがない　」__ と注意された。。。
ローカル環境では上手くいっていたのに、本番環境でなんで！？
## 解決策
答えは、ものすごく単純、、、
デプロイ ( 今回は Heroku )に```config:set```( AWS )を忘れていたため。凡ミスてか詰めが甘い。

ローカル環境では、```.env```にそれぞれを設定していたためローカルでは正常に動作

```php:.env
AWS_ACCESS_KEY_ID={アクセスキー}
AWS_SECRET_ACCESS_KEY={シークレットアクセスキー}
AWS_DEFAULT_REGION=ap-northeast-1（東京の場合）
AWS_BUCKET={バゲット名}
```
しかし、```.env```ファイルは隠しファイルなのでリリースしようが反映されない。
なので、[Heroku](https://jp.heroku.com/home) に各情報を入れなければならない。
あとは、セットするだけです。簡単。
```heroku config:set```または、アプリ内で直に書いてセットするだけでした。
完了したら、```Web Applicaton Debud Mode```を```false```に直しておきましょう！！

## まとめ
エラーのまとめ記事になりますので、記録用として書かせていただきました！
調べていたら、```php artisan config:cache```したら直ったなどの記事をいくつか見受けましたが、あまりオススメはしません！！
ファイルの役割を理解して取り組むことが大事ですね。（切実に）
ご拝読ありがとうございました！！
logging 練習

# logging 練習

```python
from logging import ERROR, Formatter, Handler, getLogger, FileHandler, Formatter, DEBUG

# loggerを作る
logger = getLogger(__name__)

# 手下のhandlerを作る（手下:handlerには属性があり、filehandler:ファイル作るやつ、とstreamhandler：コンソールに出すやつがいる）
handler = FileHandler('log.txt',encoding='utf-8')

# loggerに手下を割り当てる
logger.addHandler(handler)

# 手下の報告書フォーマット決める
# reportForm = Formatter('[%(levelname)s] %(asctime)s - %(message)s (%(filename)s)')
reportForm = Formatter('%(levelname)s,%(asctime)s,%(message)s,%(filename)s')

# 報告書フォーマットでhandlerに指示する
handler.setFormatter(reportForm)

# 手下の報告基準を設定する
handler.setLevel(DEBUG)

# loggerの報告基準を設定する
logger.setLevel(DEBUG)


logger.debug('てすと')
logger.error('えらー')
```
VSCodeの検索結果からシンボリックリンクを除外する

## デフォルトでは検索結果にシンボリックリンクも含まれる

```shell
$ touch foo.txt
$ echo "foo" >> foo.txt
$ ln -s foo.txt bar.txt 
```

![Screen Shot 2022-01-27 at 18.11.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577446/c314a65c-e7ca-0e54-092b-6030f0905317.png)

## 検索結果からシンボリックリンクを除外する

settings.jsonに以下の1行を追加する。

```json:settings.json
{
    // ...
    "search.followSymlinks": false,
    // ...
}
```

![Screen Shot 2022-01-27 at 18.11.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577446/62f4cdd3-d494-b3a2-df79-bd47d454cddc.png)
ClickOnce を使用して .NET Windows デスクトップ アプリケーションを配置する

https://docs.microsoft.com/ja-jp/visualstudio/deployment/quickstart-deploy-using-clickonce-folder?view=vs-2022

１．ソリューション エクスプローラーで、プロジェクトを右クリックして、 [発行] を選択します (または [ビルド] > [発行] メニュー項目を使用します)。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516328/6a3f7410-e87c-0c30-dd1f-a0be89fd93ef.png)

２．以前に発行プロファイルを構成した場合は、 [発行] ページが表示されます。 [新規] を選択します。

３．[発行] ウィザードで、 [フォルダー] を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516328/bee0329e-e1b8-45fb-4a67-d549f1bddbf5.png)

４．[特定のターゲット] ページで、 [ClickOnce] を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516328/c51433fc-3a05-98f1-fa56-c0d9f2c66fb8.png)

５．パスを入力するか、 [参照] を選択して発行場所を選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516328/5e9978c8-4f2f-a108-19db-9d63af0c5d3c.png)

６．[インストール場所] ページで、ユーザーがアプリケーションをインストールする場所を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516328/85078163-35ea-a540-a9b4-7e068899a910.png)

７．[設定] ページで、ClickOnce に必要な設定を指定できます。

８．UNC パスまたは Web サイトからインストールすることを選択した場合は、このページでアプリケーションをオフラインで使用できるようにするかどうかを指定できます。 このオプションをオンにすると、ユーザーの [スタート] メニューにアプリケーションが一覧表示され、新しいバージョンが発行されたときにアプリケーションを自動的に更新できるようになります。 既定では、更新プログラムはインストール場所から入手できます。 更新プログラムに別の場所を使用したい場合は、[設定の更新] リンクを使用して、そのように指定できます。 アプリケーションをオフラインで使用できるようにしない場合は、インストール場所から実行されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516328/a029cfe7-a281-67d0-647b-88b7fc832b2f.png)


９．CD、DVD または USB ドライブからインストールすることを選択した場合は、このページで、アプリケーションで自動更新をサポートするかどうかを指定することもできます。 更新プログラムをサポートすることを選択した場合は、場所の更新は必須であり、有効な UNC パスまたは Web サイトである必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516328/d432b80c-fe2d-55ee-d6e1-7ecd6f86257d.png)

このページには、セットアップに含める アプリケーション ファイル、インストールする 前提条件 のパッケージ、およびその他の オプション を、ページの上部にあるリンクを使用して指定する機能が含まれています。

また、このページでは、発行バージョンと、発行のたびにバージョンが自動的に増分されるようにするかどうかを設定できます。

:::note alert
 [注意]
発行バージョン番号は、各 ClickOnce プロファイルに対して一意となります。 複数のプロファイルを使用する予定の場合は、この点に注意する必要があります。
:::

１０．[マニフェストの署名] ページで、マニフェストに署名するかどうかと、使用する証明書を指定できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516328/7125442b-522c-325b-23ec-22f26fda1de8.png)

１１．[構成] ページで、必要なプロジェクト構成を選択できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516328/9b9f8f71-5df9-b204-9843-cc1d3ae55e3a.png)

[フレームワーク依存と自己完結型の展開](https://docs.microsoft.com/ja-jp/dotnet/core/deploying/)
[ターゲット ランタイム識別子 (ポータブル RID など)](https://docs.microsoft.com/ja-jp/dotnet/core/rid-catalog)
[デバッグ構成とリリース構成](https://docs.microsoft.com/ja-jp/visualstudio/ide/understanding-build-configurations?view=vs-2022)

１２．[完了] を選択して新しい ClickOnce 発行プロファイルを保存します。

１３．[概要] ページで、 [発行] を選択すると、Visual Studio によりプロジェクトがビルドされ、指定された発行フォルダーに発行されます。 このページにはプロファイルの概要も表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516328/691acb20-2c3e-52b3-d1bd-c46c57892e39.png)

１４．再発行するには、 [発行] を選択します。
[Kotlin] 指定したプロパティが一致するオブジェクトを配列から削除したい

備忘録代わりのTipsです。

# やりたいこと

```kotlin
data class Student(
      var id: Int,
      var name: String,
      var age: Int,
)

var studentList: MutableList<Student> = mutableListOf()

for (i in 1..10) {
      studentList.add(
            Student(
                  id = i,
                  name = "hoge",
                  age = 18,
            )
      )
}
```

こんな雑なdata classの配列があったとして、指定したidのStudentをremoveしたい。

# やり方

### findを使う

```kotlin
fun removeStudent(id: Int) {
      studentList.find { it.id == id }?.run {
            studentList -= this
      }
}
```
書いていて思いましたが、よくあるequalsメソッドのoverrideみたいな感じですね。
containsでは中身の一致を確認してくれないので自作するやつです。

### removeIfを使う
removeIfを使うとよりシンプルに書けて見やすいコードになります。

```kotlin
fun removeStudent(id: Int) {
      studentList.removeIf {
         it.id == id
      }
}
```
※@n_takehataさんよりコメントいただきました。ありがとうございます。

### removeAllを使う
removeIfはJava1.8から追加されたため、それ以前のJVMや非JVMをターゲットとするときには使用できません。
その場合にはremoveAllを使うことができます。

```kotlin
fun removeStudent(id: Int) {
      studentList.removeAll {
         it.id == id
      }
}
```
※@sdkeiさんよりコメントいただきました。ありがとうございます。

### 動かしてみよう
Kotlin Playgroundにコードを書いておきましたので、気になる方は実際に動かしてみてください。
https://pl.kotl.in/zKrwYCiA7
Accessクエリ 関数【日付操作編】①

#ACCESSの日付操作でよく使用する関数　その１
備忘録として投稿します。
たまたま誰かの役に立てれば光栄です。
全13項目【日付操作編】④まであります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2517880/c229e0e9-773e-4513-6532-b56b6a05387a.png)
ちまたでよく聞くCPUの6コア・12スレッドと、プログラミングの中で使われるマルチプロセス、マルチスレッドは意味が微妙に異なる！！！！！！！！へっっ！ (# ﾟДﾟ)

サブルーチン、コルーチン、並列処理、並行処理、処理をプロセスで分ける？処理をスレッドで分ける？なんだっけってなってる人が見るとモヤモヤがスッキリする画像をお借りします。

---

一般に実行中プログラムとは、１つのプロセスでできていて、そのプロセスの中に複数スレッドを立てて、複数の処理を同時におこなったりする。

---

6コア/12スレッドとかいうのはCPUのスペックであり、この場合、OSに２つのコアであるように見せかけることができて、コアの利用率を上げることができる。

---

**いままでマルチスレッドというものは、上のCPUのスペックでいうと、１つのプログラムが同時に利用できるスレッドの数が１２スレッドまで、だと思っていた（少なすぎでしょ！笑）**

---

こちらのサイトから引用しました

https://milestone-of-se.nesuke.com/sv-basic/architecture/cpu/

---

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282788/2b811e66-24fd-e9ef-5a6e-cb6be9474a91.png)

---

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282788/a87ee31f-d5f0-b855-7dbe-f9f0da618145.png)
３０代初心者インフラエンジニアが知っておくべき　OracleDataBase SQLPLUS SQL

<H1>定義を変更にする【ALTER TABLE】</H1>

```sql
ALTER TABLE テーブル名 MODIFY 列名 NULL;
//テーブル名の列名をNULLを許す設定に変更
ALTER TABLE テーブル名 MODIFY 列名 NOT NULL;
//テーブル名の列名をNULLを許さない設定に変更
ALTER TABLE テーブル名 ENABLE CONSTRAINT 制約名;
//制約の有効化
ALTER TABLE テーブル名 DISABLE CONSTRAINT 制約名;
//制約の無効化
SELECT CONSTRAINT_NAME,CONSTRAINT_TYPE FROM ALL_CONSTRAINTS WHERE TABLE_NAME = テーブル名;
//テーブル設定されている制約を確認
ALTER TABLE テーブル名 RENAME COLUMN 既存のカラム名 TO 新規のカラム名;
//カラム名の変更
ALTER SESSION SET nls_date_format = 'YYYY/MM/DD HH24:MI:SS';
//DATE型のフォーマットをYYYY/MM/DD HH24:MI:SSに変更（デフォルトはRR-MM-DD）
```
<H1>範囲を指定して値を変更【BETWEEN 値 AND 値】</H1>

```sql
UPDATE テーブル名 SET 変更する列名=0 WHERE 検索する名 BETWEEN 1 AND 4;
//テーブル名の変更する列の検索する列が1～4のみ変更
```

<H1>トリガーの削除</H1>

```sql
DROP TRIGGER 削除するトリガー名;
//テーブル名の変更する列の検索する列が1～4のみ変更
```
<H1>表(テーブル)の中のデータ削除【DELETE/TRUNCATE】</H1>

```sql
DELETE FROM 削除するテーブル名;
//テーブルの中のデータ全て削除、commitしないと反映しない。FROMはなくてもいい。
DELETE FROM 削除するテーブル名 WHERE カラム名 = 値;
//カラム名の値で絞ったデータ削除、commitしないと反映しない。FROMはなくてもいい。

TRUNCATE TABLE 削除するテーブル名;
//テーブルの中のデータ全て削除、データを限定できない、トランザクションが終了即commitされる、索引は残る。
```

<H1>ORACLE_HOMEを調べる【@?】</H1>

```sql
SQL> @?
SP2-0310: ファイル"D:\app\test\product\11.1.0\db_1.sql"をオープンできません。
//ORACLE_HOMEを調べる D:\app\test\product\11.1.0
```

<H1>SQL実行時エラーが起きたら、エラーコードを返す【WHENEVER SQLERROR】</H1>

```sql
WHENEVER SQLERROR EXIT SQL.SQLCODE
UPDATE EMP_DETAILS_VIEW SET SALARY = SALARY*1.1;
//SQL UPDATEコマンドが失敗すると、SQL*Plusを終了し、SQLエラー・コードを戻します。
```
【Jbuilder】部分テンプレートでハッシュのオブジェクトを使いたい

##前提
@book_managerが配列ではなくハッシュのため、```json.array!```が使えない。


##今まで
ファイル名とインスタンス変数名が同じだと
Railsが部分テンプレートを自動的に予測してレンダリングしてくれていたので、
ファイル名など指定しなくても機能していた。

```api/v1/book_managers/show.json.jbuilder
json.book_manager do
  json.partial! @book_manager
end
```


##訳あってファイル名変更
ファイル名を変更した際、下記の様に部分テンプレートを指定してみたがうまく行かない...

```api/v1/book_infos/show.json.jbuilder
json.book_info do
  json.partial! 'api/v1/book_infos/book_info', collection: @book_manager, as: :book_info
end
```


##うまく行った例

ローカル変数```book_info```として```@book_manager```を渡す。

```api/v1/book_infos/show.json.jbuilder
json.book_info do
  json.partial! 'api/v1/book_infos/book_info', book_info: @book_manager
end
```

https://github.com/rails/jbuilder
クレジットカード不正利用被害により　対応をまとめる

皆様こんばんわ。今はITエンジニアとしてはあまりかかわっていない当方ですが、クレジットカードの不正利用により、被害を受けたので、
その事を書こうかと思います。

前提条件　
1，二段階認証はしていた。
2、パスワードはワンタイムパスワードでやっていた。
3、パソコンにセキュリティソフトは入れていたが、スマホのセキュリティは無料ソフト
(パソコンはノートン、スマホはAVG アンチウイルス 無料版)
ちなみにスマホの端末はpixel5
4、Windowsのアップデートはこまめにやっていた(windows11の状態)

メールはフリーのgmailとoutlookを使用。被害後にwordpressの有料メールを使用する。
------------------------------------------------------------------------------------------------------
それで今回のケースでは不正アクセスと、クレジットカードの情報流失の2段階にわけて勝手に考えている訳でありますが、

相手が一体どのような手段で情報を入手したかは不明です。偽サイトでクレジットカードの情報を入力という手もありますが、

クレジットカードの情報を入力する際、セキュリティソフトが感知すると思っている為に、その都度、気をつけてはいます。

-------------------------------------------------------------------------------------------------------
仮にあるとすれば、スマホ端末のchatworkアプリがウイルス感染していたので、アプリごと削除したという話ならあります。

そして香川県のうどんテックの人に聞いたところ、端末側か、或いはサーバー側から漏れたのか
どっちかという話に話題が移り、次に香川県警に相談のメールを送ることとなる。

被害にあった商品はMSの11500円がキーワードであるが、知人がいうに、これは100ドルを意味するのではないかとの指摘があった。

----------------------------------------------------------------------------------
そして肝心の警察への出頭ですが、警察の担当にクレジットカードの被害は会社によるものだそうで、
個人にまで請求権はないような雰囲気になり、どうやってセキュリティを破ったかや相手の素顔など、
真相解明にはほど遠くなります。

2022年2月2日　ワンタイムパスワード・トークンを使うようになりました。

2022年2月19日　犯行の手口がクレジットマスターだということがわかったので記録します。
二つのDataFrameを比較して代入を行う方法（pd.mergeの使い方）

毎回書き方を忘れるので、以下、備忘録です。

DataFrame① ```df```

| |time_index  |data  |
|---|---|---|
|0  |2001  |10  |
|1  |2002  |20 |
|2  |2003  |30  |
|3  |2004  |40 |
|
|3  |2011|40 |
|
|19|2020  |50  |

DataFrame ② ```dx```

| |time_index  |data  |
|---|---|---|
|0  |2010|1  |
|1  |2011|20|
|2  |2012|3  |
|3  |2013|4 |
|
|
|10|2020  |4|

このDataFrame①とDataFrame②をmergeする。

```python
df = pd.merge(df, dx, on='time_index', how='left')
```

とすることで、

| |time_index  |data_x  | data_y  | 
|---|---|---|---|
|0  |2001  |10  |nan|
|1  |2002  |20 |nan  |
|2  |2003  |30  |nan  |
|3  |2004  |40 |nan  |
|
|10  |2011|40 |20|
|
|19|2020  |50  |4  |

となる。
flutter docter で "cmdline-tools component is missing" と言われた時の対処方法

# 現象

`$ flutter doctor` 実行時に以下のようなログが出力された

```sh
$ flutter doctor
...
[!] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
    ✗ cmdline-tools component is missing
      Run `path/to/sdkmanager --install "cmdline-tools;latest"`
      See https://developer.android.com/studio/command-line for more details.
...
```

# 環境

- Flutter: 2.8.1_stable
- MacOS: 10.15.7
- Android Studio: 4.0.1

# 対処方法

Android Studio > Configure > SDK Manager > SDK Tools にて
`Android SDK Command-line Tools (latest) (cmdline-tools;latest)`
にチェックを入れてインストールする。 (下図参照)

![Screenshot_2022-01-27_17.24.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273914/934e5b7d-fc3e-adc6-2d28-8021998c3ac0.png)

# 検証方法

再度 `$ flutter doctor` を実行して
`cmdline-tools component is missing` が出力されなければ ok です。

```sh
$ flutter doctor
...
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
...
LaravelでのAmazonSES/SMTP設定

# 経緯
LaravelからAmazon SESへの接続がタイムアウトしたりエラーになって試行錯誤したときのメモです。
環境は下記の通り。SESはAPI経由でもよいですが、ひとまずSMTPで設定してみることにしました。

- 基盤構成： EC2 → Amazon SES
- PHPフレームワーク： Laravel 8.x

# 試行錯誤してるときに出たエラーたち
いずれもポートの設定などを誤っているために出力されていたものです。

```
(Swift_IoException(code: 0): Connection to tcp://email-smtp.ap-northeast-1.amazonaws.com:465 Timed Out at /＊**********************/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/StreamBuffer.php:166
```

```
ERROR: Expected response code 220 but got code "", with message
```

```
ERROR: Failed to authenticate on SMTP server with username "***********" using 2 possible authenticators. Authenticator LOGIN returned Expected response code 334 but got code "530", with message "530 Must issue a STARTTLS command first. 
```


# Amazon SESの画面
先達の知恵を借りつつもAWSドキュメントなどにあたって調べてみたものの何が問題かがぱっとわからず。
AWSコンソールのデザイン変更で、参考例のキャプチャの項目が見当たらず困るのは日常茶飯事ですが、
今回もSMTPの設定項目がどこにあるかがわからず時間を取られました。
2022/01現在のコンソール設定では「Account dashboard」の中段に、エンドポイントやポートが表示されている模様です。
![ses.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1293/1528cb7d-46fd-6f70-4aa0-74b3d4735325.png)
EC2では25番ポートはデフォルトで使用できず、申請が必要になるので、他のポートを使用することにしました。

SMTPで接続したいIAMユーザ設定がまだない場合は「Create SMTP credentials」から、ユーザ名を指定するだけで簡単にID/PWの接続情報を作成できます。

# PORTとENCRYPTIONの関係性
試行錯誤したのは結局ここでした。
STARTTLSのポートでは `tls` 、TLSのポートでは `ssl` で指定するとうまくいきそうでした。

| MAIL_PORT | MAIL_ENCRYPTION |
| --------- | --------------- |
| 465       | ssl             |
| 2465      | ssl             |
| 587       | tls             |
| 2587      | tls             |

# Laravelの.env設定例
EC2からセキュリティグループのアウトバンドで対象ポートを絞っていなければ、下記の設定で疎通できました。

```
MAIL_DRIVER=smtp
MAIL_HOST=email-smtp.ap-northeast-1.amazonaws.com
MAIL_PORT=465
MAIL_ENCRYPTION=ssl
```
または

```
MAIL_DRIVER=smtp
MAIL_HOST=email-smtp.ap-northeast-1.amazonaws.com
MAIL_PORT=587
MAIL_ENCRYPTION=tls
```

書き換えたあとは設定キャッシュをリフレッシュして反映し、疎通成功です。
`php artisan config:cache`
【Supabase】Row level secrityで認証が走らなくなった

## この記事の前提
この記事の前提として表題にあるとおり、SupabaseのRow level secrityというところを触ったところ、全てのAuth認証が通らなくなった方向けの記事になります。

## エラーが起こったきっかけ
Supabaseを使うにあたって認証と同時にユーザー情報の一部をデータベースに保存出来ないか調べてたところ何かをトリガーに書き込めるのがRow level secrityだと認識して、記事等を参考にコピペなどしてRunしてみました。

すると、アプリのすべての認証が走らなくなりUser情報のオブジェクトが返ってこなくなりました。。。

## 解決方法
こちらのスクラップでもみていただけますが改めて載せておきます。

https://zenn.dev/hirockysan/scraps/5234c7bb15a5ef

色々な記事を参考にポリシーを記入して右下のRunを押したら認証が走らなくなった。

![](https://storage.googleapis.com/zenn-user-upload/4e55be30460f-20220127.png)

記入ミスなどでポリシーが走らない場合、SQL Editorコンソール上でSQL snippetsを消去するだけではだめで、下記画像部分から消去する必要があった。

![](https://storage.googleapis.com/zenn-user-upload/1ee25acc9c44-20220127.png)

何はともあれ無事解決し、開発を続けることができました。

Supabaseはまだ日本語ドキュメンとが充実してないので誰かの役に立てば幸いです。
axiosのinterceptosとは。すべてのリクエストの前に実行される処理。


サッカーでの得意なプレーはインターセプトでした。
（相手のパスを味方に渡る前に奪うこと）

###interceptosとは

意味を調べて見ると
intercept
～を〕途中で捕まえる、妨害する、封じる、途中で押さえる 

といった意味があります。


##axios.interceptos でリクエストの前処理

```php:index.js

import axios from 'axios';

const API = axios.create({ baseURL: 'http://localhost:3000' });

//すべてのリクエストの前処理
API.interceptors.request.use((req) => {
 //処理
  return req;
});



//上記の前処理が実行されてから下記のリクエストがされる
/////////////////////////////////////////////////////////////

export const fetchPosts = () => API.get('/posts');
export const createPost = (newPost) => API.post('/posts', newPost);

//////////////////////////////////////////////////////////


```
リクエストを送る前に、毎回処理を記述する場合よりもスッキリ書くことができます。
システム開発における開発手法

　アジャイル開発やウォーターフォールと聞いても漠然としたイメージしか湧かなかったので、メリットやデメリットについてまとめてみました。

# 目次
- ウォーターフォールモデル
- アジャイル開発
- プロトタイプ開発
- スパイラルモデル

## ウォーターフォールモデル
　要件定義から設計、開発、テスト、導入という流れをウォーターフォール(滝)のように逆流することなく一方通行で管理する手法。

**メリット**
全体的な計画を立てやすい
工程や作業プロセスごとにチェックしやすい
人員変動に対応できる

**デメリット**
前工程で失敗すると後に響く
システムの仕様やクライアントの追加要望などの変更に対応しづらい

## アジャイル開発
　プロジェクトを小さく区切り、機能ごとに実装とテストを繰り返す開発手法。開発期間を短縮できることからアジャイル(素早い)と呼ばれる。

**メリット**
開発途中に問題が起きてもやり直しが効く
クライアントの確認を都度取りながら開発を進められる
仕様変更や追加機能の要望があっても柔軟に対応できる

**デメリット**
スケジュールや進捗管理のコントロールが難しい
開発の方向性がブレやすい

## プロトタイプ開発
　開発の途中段階でプロトタイプ(試作品)をクライアントに提供し、要望と相違が無いか検証しながらシステム開発する手法。

**メリット**
早い段階で完成品のイメージができる
開発後の大幅な修正を防げる

**デメリット**
開発側の負担が大きい
大規模なシステム開発に不向き

## スパイラルモデル
　システムの設計とプロトタイピングを短期間で反復しながら少しずつ先に進む手法。ウォーターフォールモデルとアジャイル開発の良さを組み合わせたような手法。

**メリット**
スケジュールや進捗管理のコントロールができる
仕様変更にも柔軟に対応できる

**デメリット**
開発期間の長期化
システム仕様の肥大化

# まとめ
　今まで開発しかしていなかったので、現場でのシステム開発のパターンについて知ることができてよかった。どの開発手法も一長一短があると感じ、開発するシステムによって使い分けているのだろうと思った。

# 参考
https://www.biz.ne.jp/matome/2003233/

https://onetech.jp/blog/what-are-the-four-types-of-system-development-methods-7101
リレースイッチでAC100V入力機器のON/OFF制御

分解した延長タップに繋いだ100V入力機器を、
リレースイッチを使ってArduinoからON/OFFしたので、その方法をまとめておきます。

# 材料
- Arduino Mega（デジタル出力があれば何でも）
- [リレースイッチ](https://www.amazon.co.jp/gp/product/B07W5MZ2C7/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1)
- ジャンパーワイヤ
- 分解してもよい延長タップ
- AC100V入力機器

# 環境
- MacOS Catalina 10.15.7
- Arduino IDE 1.8.12

# 事前準備
**※自己責任です。実施する場合は、コンセントから外して通電していない状態で、十分に注意して取り扱ってください※**

リレースイッチに接続するために、延長タップのケーブルの皮膜を剥きます。
大体2本横並びに配線があります。
![皮膜を剥いた写真.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256451/87cd5088-3031-21da-d35e-4f3a0b231750.jpeg)
2本あるうちの1本の配線を切断し、中の導線を剥き出しにします。
はんだ付けして導線をまとめると、後々リレースイッチに挟みやすいかもしれません。
![半分剥いたところ.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256451/e07068e9-3de8-5e2c-e7a8-0da6ec300a6e.jpeg)
![切断した様子.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256451/c867fd59-60a9-0334-3ce0-427b51013c1e.jpeg)
![リレースイッチに挟んだ様子.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256451/7b26cf73-d5a8-8062-b3d8-1febcae4cc17.jpeg)


# 配線
下記の図のように配線します。
![配線図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256451/1eeec8e3-0c0b-92d4-bba2-432615c80624.png)

# コード
簡単に、5秒毎にHIGH/LOWの信号を送るだけのコードです。
<details><summary>コードはこちら</summary>
<div>

```c++:relayControl.ino
#define SIGNAL_PIN  13

void setup() {
  pinMode(SIGNAL_PIN, OUTPUT);
}

void loop() {
  digitalWrite(SIGNAL_PIN, HIGH);
  delay(5 * 1000UL);
  digitalWrite(SIGNAL_PIN, LOW);
  delay(5 * 1000UL);
}
```
</div>
</details>

# 結果
PGでのHIGH/LOWに合わせて、モバイルバッテリーの充電のON/OFFが制御されています。
![ONの様子.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256451/e2948fde-5869-5ba8-98e6-b32ffa654d41.jpeg)
![OFFの様子.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256451/96172e78-d484-f6e3-3535-d59b4a3f6bf7.jpeg)
13番を使用しているので、ArduinoのビルトインLEDと同じ周期でON/OFFしているのが確認できます。
![モバイルバッテリーONOFF制御.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256451/50c82dc2-6a4d-a582-8acf-751447d81cc6.gif)


# まとめ
理論だけ知っていたリレースイッチを実際に扱うことができたので、良い経験になったなと思います。
また、型番やデータシートが詳細に載っていないAmazonで売っている電子部品を、
自分でデータシートを探し出して無事使用できたのも安心しました。
そこまで複雑な仕様を必要としない出来合いのモジュールを、安価で入手・使用できると心強いです。
色々と応用が効きそうなので、自宅で洗濯物を室内干しするときのサーキュレーター制御や、自作インターホンカメラの制御などに使ってみようかと思います。
Vue3.0＋VeeValidate4.0で関数内の任意の場所でバリデーション実行する

やることはタイトルの通りなんですが、公式のドキュメントは薄めだし、意外とググっても国内海外ともに情報が出てこなかったので、忘れないように残しておきます。

## やりたいこと

submit時ではなく、ボタンのクリック時とかにFormレベルのバリデーションを噛ませたい

こんな感じで

```vue
export default defineComponent({
  setup() {
  },
  methods: {
    onClick() {
      // ここでバリデーションしてエラーしてたらreturnみたいなこと
    }
  }
})
```

## どうやる？

他にもやり方はあるかもしれないですが、一旦こうやればやれた、というのを書いておきます。

### template

Formのv-slotにvalidateを設定して、clickイベントで呼ぶ関数の引数に渡してやる

```vue
<template>
<Form v-slot="{ validate }" :validation-schema="schema">
  <!-- Fieldとかは必要なものを -->

  <button type="button" @click="onClick(validate)">
</Form>
</template>
```

### script

```vue
<script>
import { Form, defineComponent } from 'vee-validate'

export default defineComponent({
  setup() {
    const schema = { 
      // 省略 
    }

    return {
      Form,
      schema,
    }
  },
  methods: {
    onClick(validate: any) {
      // ここでvalidation実行
      validate().then((result: any) => {
        if (result.valid) {
          // バリデーション突破
        } else {
          // バリデーション失敗
        }
      }
    }
  }
})
</script>
```
【LevelUp】甘え上手なエンジニアになる

#具体的なアクション
##1.ざっそうを意識せよ
Slackなら『見る義務もないし、読む義務もないchを作りましょう』
https://blog.y-yuki.net/entry/2019/09/05/233000
https://craftsman-software.com/posts/56/

そこで『自分』を発信してみるのです。
好きなもの、今してる作業、


いきなり1on1の会話はむずいし、
相手も『あなたのことがわからない』のは同じ
なので心の壁を取り除いてみましょう。

ルールはこれだけです🐾

```
好きなときに好きなこと（仕事上でもプライベートでもの課題や感情）を書いていい場所
書く義務もなければ読む義務もないので気軽にどうぞ
```


##2.「タスク分解する」

タスク分解とググったらいくらでもノウハウは手に入れる事ができると思います。

>一人でタスク分解をする事が難しかったら、
「タスク分解の手伝いをして欲しいです」と頼る

>一人で分解できたら、
必ず分解されたタスクについてレビューをもらう


不慣れなことは、「できない」「できていると思い込んでしまう」ことがあります。
必ずタスク分解の過程ごと、まわりに頼ることをオススメします。



##3.手戻り&勝手に進めることが最大に迷惑だと知ろう
先輩エンジニアに質問したところ
上記が一番新人にやってほしくないところらしいです。

>『なんども聞いて申し訳ないな』と思う前に
『手戻りするのも自分は面倒だし、余計な労力を先輩に割かせちゃう！』と前向きに考えましょう。


以下の手順で
こまめに聞いてみるのがよさげｂ

>チャットツールで簡潔に依頼して
1.まず、聞きたいことを一言で記述すること
2.聞きたいことの背景を記述すること
3.納期を必ず伝えること



#『相談』のハードルが高い要因

##1. 話したことがなくて声をかけづらい
Slackの業務連絡、報連相だけでは相手のことがわかりません。

だからこそ、聞いてみたい人がいても

>「どんな人なんだろう」
「質問したときどんな風に接してくれるんだろう」

というイメージを持てていないのです

##2.そもそも、何を聞けばいいか分からない
「分からないことだらけで何から聞けばいいのかすら分からない」という事がよく発生します。

なぜそういう状況に陥るかというと、
自分がやるべき事が具体化されていないから、人に聞くこともできないのです。


不慣れなことは、「できない」「できていると思い込んでしまう」ことがあります。必ずタスク分解の過程ごと、まわりに頼ることをオススメします。


##3. 忙しそうにしていて、声をかけづらい
先輩が忙しそうにしていたら聞くのを躊躇ってしまうと思います。
しかし、ここで大切になってくるのはその場で声をかけに行くことだけが頼る手段では無い、ということです。頼り方のレパートリーが少ないということが壁になってしまうと考えられます。



#付録1：仕様把握のために「5W1H」
登る山を決めずに、山は登れません。
エンジニアとしてのタスクも同じです。

新しいタスクがわからなかったら、
まずはこの６つを先輩と埋めていきましょう。

>5W1H 問い 例
why なんのためにやるのか？ 日の出を見る
what 何をするのか？ 富士山を登る
who 誰がやるのか？ 私と友達
how どのようにやるのか？　 5合目から歩く
where どこに基準を置くのか？ 5時間で登頂
when いつまでにやるのか？ 12月31日

#付録2：タスク分解
経験者に聞くのが一番早いです！


メリット
>1. タスク中にやってはいけないことがわかる
2. タスクの工数がわかる 山頂到達時間の把握
3. タスク分解の妥当性が確認できる 


#付録３.GoogleEngineerの仕事術

```
１．「何かを学ぶ時は、常に大事な20%はどこだろうかを考えて勉強しよう」
２．本当に使う予定のあるもの以外を勉強するのは時間の無駄になる可能性が高い
３．上手くいっている人のやり方をパクって自分用にカスタマイズする
４．独学＜＜＜＜優秀なメンターをつけた方が格段に効率が良い（FBがもらえるから）
５．最初の2割の時間で8割を終わらせる
　　　　元マイクロソフトenginer仕事術(中島聡)
　　　　そこで8割終わらなければ見積もりが甘い→→期限を伸ばしてもらう
　　　　→→納期：確実に間に合わせる　＆　かつ質の高い製品
Hamlの基本

# はじめに
RailsでWebアプリにPay.jpを用いた決済機能を実装しようとしていました。
実装フローを検索していたところ、Hamlを使ってビューが実装されているドキュメントが多く、興味本位で学習しました。
これから学習しようとしている方の参考になればと学習したことをまとめてみました。

# TL;DL
・RubyをベースとしたHTMLのテンプレートエンジンのこと
・HTMLよりもシンプルに記述できる
・Ruby / Ruby on Railsでも使われている


# 前提知識
・HTML
・Ruby（Rubyがベースになった記法だから）
・Ruby on Rails（Railsで使いたい場合）


# 大枠の使い方
① 拡張子がhamlのファイルを作成する（Ex.index.haml）
② 作成した①をhamlコマンドに通す（Ex. haml index.haml index.html ）
③ htmlファイルが生成される（Ex.index.html）

※ hamlのコマンドオプション（よく使うもの）
-f format → アウトプットのフォーマットを指定（html5）
-q → ダブルクオーテーションを出力





# 具体的な記述の仕方
```:【POINT】hamlの記法
１. 接頭辞でコンテンツの内容を表現
２. インデントで階層構造を表現
```
この二つの概念と接頭辞の種類さえ抑えれば、基本的な表現であれば、hamlで表現できないことはなくなるはずです。


## 接頭辞
|    接頭辞     |    接頭辞の意味    |
|-------------|------------|
|!!! |DOCTYPE|
|%| 開始タグと終了タグ|
|{:属性 => 値}|タグに属性を追加する（Rubyっぽい）|
|(属性 = 値)|タグに属性を追加する（HTMLっぽい）|
|%p テキスト|pタグに囲われたテキスト|
|<|タグ内部の改行を除去|
|>|タグ外部の改行を除去|
|%p{:id=>"id", :class=>"class"}|`<p id="id" class="class"></p>`|
|%p(id="id" class="class")|`<p id="id" class="class"></p>`|
|%p.class|`<p class="class名"></p>`|
|%p#id|`<p id="id名"></p>`|
|#id.class|`<div id="id" class="class"></div>`|
|:css|styleタグ|
|:javascript|scriptタグ|
|#{〜}|〜にRubyのコードを実行して表示|
|%p=〜|〜のRubyのコードを実行して表示|
|- 〜|〜のRubyのコードを実行して表示しない|
|/|HTMLとHaml両方に残したいコメント|
|-#|Hamlにだけ残したいコメント|

## インデント
HTMLの入れ子構造を作るために使用する
※ 同じ階層の要素は同じインデントの数に統一すること


## コメント
/ → HTMLでも残したいコメント
-# → Hamlにだけ残したいコメント


# フォーマット
HTMLと同様、最初に記載する型は決まっているので、自分用に念の為記載します。

```:①hamlファイルを作成する
!!!
%html{:lang => "ja"}
  %head
    %meta(charset="UTF-8")
  %body

    / 一般的なタグの生成
    %p hellow world!

    / ul, liタグの生成
    %ul
      %li<
        item

    / divの生成
    %div#id.class
    %div{:id=>"id", :class=>"class"}
    %div(id="id" class="class")
    #id.class
    
    / Rubyの実行と表示
    #{ 3 + 5 }
    %p= 3 + 5
    - 3 + 5
```

```:②作成したファイルをhamlコマンドに通す
haml index.haml index.html
```

```:③htmlファイルが生成される
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
  </head>
  <body>

    <!-- 一般的なタグの生成 -->
    <p>hellow world!</p>

    <!-- ul, liタグの生成 -->
    <ul>
      <li>item</li>
    </ul>

    <!-- divの生成 -->
    <div id="id" class="class"></div>
    <div id="id" class="class"></div>
    <div id="id" class="class"></div>
    <div id="id" class="class"></div>

    <!--  Rubyの実行と表示  -->
    8
    <p>8</p>

  </body>
</html>
```
上のhamlファイルをhtmlに変換すると、下のhtmlファイルのような記載になります。

# 参考文献
- [ドットインストール haml入門（全8回）](https://dotinstall.com/lessons/basic_haml)

※ hamlをRailsで使う方法は以下の記事が参考になります。
- [【rails】htmlからhamlに一括で変換するコマンド](https://satoru103.hatenablog.com/entry/2020/02/27/012706)
- [Railsでhamlを使う](https://qiita.com/mzmz__02/items/fa9a2f5f120b03d7a42d)
【本】リーダブルコード

ざっくりと
Qiitaでもかけそうなことを
読んでみたのでアウトプット


#コードは短いほうが良い？

>鍵となる考え「コードは理解しやすくなければならない」
鍵となる考え「コードは他の人が最短時間で理解できるように書かなければいけない」

結論は、
コードは短くしたほうが良いが、
<b>「理解するまでの時間」を短くするほうが大切。</b>

ライブラリを活用することでも、
コードを小さくすることができる。


```
最も読みやすいコードは何も書かれていないコードだ。
「その機能の実装について悩まないで」---きっと必要ないから
```


#命名規則に命かけろ

>鍵となる考え「気取った言い回しよりも明確で正確なほうがいい」
鍵となる考え　名前が「他の意味と間違えられることはないだろうか？」と何度も自問自答する。


以下例としてありました。


>１．tmpなどの汎用的な名前は避ける。
ただし、生存時間が短い変数などの場合には可。


>2.明確な単語を選ぶ。
単純にGetではなく、状況に応じてDownloadなどの言い回しに変える。

>3具体的な名前を使って、物事を明確に説明する。
名前をつけるときに、省略してよい情報とダメな情報がある
省略可な例：string⇒str　
省略不可な例：BackEnd⇒BE

>4.・スコープの大きな変数には長い名前をつける。
スコープが数画面に及ぶ場合などは、名前が長くなってもよいので明確でわかりやすい名前をつける。


以下具体例：

```
・あいまいになる
例1）filter()
results = Database.all_objects.filter("year <= 2015") どっち？
　選択⇨select
　除外⇨exclude

例２）limit = 10
⇨min, max

・ユーザの期待に合わせる
getXXXX()：取得するだけのメソッド

convertXXX()：変換するメソッド

・複数の名前を検討する

 template/ reuse / copy / inherit

```


#コメントはするべきでは「ない」こと

>コードを見たらすぐ分かるコメントは書かない
コメントが必要な変数名は名前を変える
優れたコード＞酷いコード＋優れたコメント


つけたいときは
TODOなどのアノテーションコメントを使用する

>TODO 後で手をつ行ける
FIXME 基地の不具合があるコード
HACK あまり綺麗じゃない実装
XXX 危険！大きな問題がある

「その、あの」は使用✖コメントは簡潔に🐾


#1度に1つのことを

>鍵となる考え:コードは1つずつタスクを行うようにしなければいけない

「一度に1つのタスクをする」ためには
コードが行っている「タスク」をすべて列挙する。
タスクをできるだけ異なる関数に分割する。


読みにくいコードがあれば、そこで行われているタスクのすべてを列挙する。
そこには別の関数に分割できるタスクがあるはず。
プログラムが行っていることを正確に説明することが大切。


#さいごに
> おばあちゃんがわかるように説明できなければ、本当に理解したとは言えない。　―アルバート・アインシュタイン



草を生やして
精進していきたいわん🐾

https://www.youtube.com/channel/UCCFdWKwWOJQszdjd5J_au3w
Bearer？ Bearer認証とは？[メモ用]


Bearerって？
Bearer認証 ？

と疑問に思ったので、参考記事をまとめておく。



##参考
https://idmlab.eidentity.jp/2013/09/bearer-token.html

https://ja.wikipedia.org/wiki/Bearer%E3%83%88%E3%83%BC%E3%82%AF%E3%83%B3#:~:text=Bearer%E3%83%88%E3%83%BC%E3%82%AF%E3%83%B3%E3%81%AF%E3%80%81%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3%E3%83%88%E3%83%BC%E3%82%AF%E3%83%B3,%E7%BD%B2%E5%90%8D%E3%81%AA%E3%81%97%E3%83%88%E3%83%BC%E3%82%AF%E3%83%B3%E3%81%A8%E3%82%82%E5%91%BC%E3%81%B0%E3%82%8C%E3%82%8B%E3%80%82


https://qiita.com/h_tyokinuhata/items/ab8e0337085997be04b1
【Python】独自例外の作成

Pythonでの独自例外の作成方法と使い方を簡単にメモしておく。

# 独自例外の作成
Pythonで独自の例外クラスを定義する場合、```Exception```クラスを親クラスとして継承したクラスを作成する。

```python:sample1
class MyException(Exception):
    pass
```

また、例外オブジェクトを出力(```print()```)したときに表示されるメッセージを例外クラスで指定することもできる。

```python:sample2
class MyException(Exception):
    def __str__(self):
        return "例外クラス：MyException"
```
さらに、```__init__```を使うことで、引数を受け取ることもできる。


# 独自例外を使う
独自例外も```Exception```クラスから派生したクラスであるため、```raise <例外名>```を使って例外を投げることができる。
例外処理の方法は、他の例外と同じように行うことができる。

```python
# sample1場合
try:
    raise MyException("例外が発生しました!")
except MyException as e:
    print(e)  # 例外が発生しました

# sample2場合
try:
    raise MyException()
except MyException as e:
    print(e)  # 例外クラス：MyException
```