OmniAICreator/Qiita-1.07M huggingface dataset:
ヒープソートの説明、シェルソート、クイックソート、バブルソート

応用情報技術者平成28年秋期 午前6

ヒープソートの説明として，適切なものはどれか。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/2bfd3a04-2960-4838-c550-cf30dba0e01d.png)

１、ヒープソートは、
未整列データを「親の値≦子の値」(または「親の値≧子の値」)の関係をもつ順序木として表現し、整列後の根の値(最小値または最大値)を取り出すことを繰り返して整列を行う方法です。

ヒープとはtreeであって、なおかつheap propertyを満たす物のことです。
heap propertyとは、全てのノードは子のノードよりも小さいというものです。
特に今回は標語的に「上は小、下は大」という感じで読み進めてください。

これがヒープの例
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/5f532ea7-a4e3-5dd3-5f50-2312805685ae.png)

必然的に根が最小値になります。

２、
・ある間隔おきに取り出した要素から成る部分列をそれぞれ整列し，更に間隔を詰めて同様の操作を行い，間隔が1になるまでこれを繰り返す。
⇒シェルソートの説明です。

・中間的な基準値を決めて，それよりも大きな値を集めた区分と，小さな値を集めた区分に要素を振り分ける。次に，それぞれの区分の中で同様な処理を繰り返す。
⇒クイックソートの説明です。

・隣り合う要素を比較して，大小の順が逆であれば，それらの要素を入れ替えるという操作を繰り返す。
⇒バブルソートの説明です。


参照：
シェルソート　整列法
https://qiita.com/lymansouka2017/items/1904540a19486a040e75

https://www.ap-siken.com/kakomon/28_aki/q6.html

ヒープソートの解説とその可視化
https://qiita.com/jajaja-qiita/items/aabcad1dd9e9238e3c1b


https://www.cnblogs.com/JVxie/p/4859889.html
RuboCopでこんなエラーが出た。Assignment Branch Condition size for search is too high. 

## なにこのエラー
```
Assignment Branch Condition size for search is too high. [<10, 21, 5> 23.79/20] 
```
コミットをする前にこんなエラーが出た。
調べてみると、なげーよ、幅取りすぎだろみたいなエラーらしい。

## RuboCopとは。簡単に
>RuboCopのGithub
https://github.com/rubocop-hq/rubocop/tree/v0.28.0

このRubCopはコードを検査してくれるものらしくて、コードが長いとか、インデントが変だとかいろんなことを教えてくれる。勝手に直してくれる（不自然なインデントを修正）ときもあれば、警告文だけだして、自分でどうにかしてくれみたいな時もある。ただ、このRuboCopからの指摘も全てが正しい訳ではないっぽい。

##　今回のエラーに関して
```
Assignment Branch Condition size for search is too high. [<10, 21, 5> 23.79/20] 
```
最初に述べたように、なげーよ的な意味らしい。

### 実際に指摘を受けたコード
``` ruby
  def search
    if params[:city_id]
      pagy, offices = pagy Office.where(city_id: params[:city_id])
      pagy_headers_merge(pagy)
    elsif params[:keyword]
      keywords = params[:keyword].split(/[[:blank:]]+/).select(&:present?)
      pagy, offices = pagy_array([])
      pagy_headers_merge(pagy)
      keywords.each do |keyword|
        offices += Office.where('name LIKE (?) OR
                                 address LIKE (?) OR
                                 near_station LIKE (?) OR
                                 introduction LIKE (?) OR
                                 company LIKE (?)',
                                "%#{keyword}%",
                                "%#{keyword}%",
                                "%#{keyword}%",
                                "%#{keyword}%",
                                "%#{keyword}%")
      end
    else
      pagy, offices = pagy(Office.all)
      pagy_headers_merge(pagy)
    end
    render json: offices, each_serializer: OfficeIndexSerializer, include: '**'
  end
```
自分でも書いていて、長いなと思った。縦に長い。ただ、今の知識ではどうやってコードをより簡潔なものにすればいいか思いつかなかった。だれか教えてください。

## それで結局どうしたか・・・
``.rubocop.yml``RuboCopの設定を変更した。
エラー文を見てみると、、、、

```
Assignment Branch Condition size for search is too high. [<10, 21, 5> 23.79/20] 
```
```[<10, 21, 5> 23.79/20]```この部分が、点数を表しているっぽい。これでみると、これだと『MAXスコアが20なのにお前のは23.79だよ』ってことらしく、これをどうにかするしかないと思った。

それで、.rubocop.yml内にある設定を変更した。

どう変更したかというと、、、

``` ruby
Metrics/AbcSize:
  # The ABC size is a calculated magnitude, so this number can be a Fixnum or
  # a Float.
  Max: 15 
```
このMaxの部分を 25に設定を変更した。そしてコミットすると、RubCopからの指摘を受けずにすんだ。

## おわりに
設定変えられるのかー程度に、この記事では感じていただければ、幸いです。
ブロックチェーンについて

# ブロックチェーンとは？
**ブロックチェーンとは、ビットコインなどの仮想通貨（暗号通貨）に用いられている基盤技術のことです。**

ブロックチェーン＝仮想通貨ではありません。

ブロックチェーンは技術のことです。

今回は、ブロックチェーンを構成する主な4つの技術である、
**①暗号化技術
②コンセンサスアルゴリズム
③ピア・トゥ・ピア（P2P）
④DLT（分散型台帳技術）**

について1つずつ解説していきます。

# ①暗号化技術
暗号化技術とは、
**1回ごとのトランザクション（取引）**ごとに**暗号化**される技術のことです。
これにより、1トランザクションごとのセキュリティ対策が施させます。

ブロックチェーンの暗号化技術は、ブロックチェーンという名前の通り、
暗号化されたトランザクションをブロック管理します。

例えると、引越しの際に
衣服など関連したものを詰めるイメージです。
図解すると下のようなイメージになります！
![ブロック管理](https://i.gyazo.com/1e249c098742de9192ad3cf55064f9de.png)



実際に、**ブロックチェーンの技術が使用されているビットコイン**を例に出すと
1つのブロック(箱)の中に、暗号化されたトランザクションが4200件入ります。

そして、暗号化されたトランザクションがブロックいっぱいになると、
新たなブロックの中に箱詰めされます。

この暗号化されたブロックを順番が分かるように、チェーンで繋いで管理する。

これがブロックチェーンの暗号化技術です。


# ②コンセンサスアルゴリズム
コンセンサスアルゴリズムとは、
暗号化されたトランザクションを箱詰めする際のルールのことです。

コンセンサスアルゴリズムにはいろんな手法がありますが、

ブロックチェーンの場合、

暗号化されたデータをブロックに詰める際に、

・これでブロックにして良いか？
・本当にこのブロックに正しい情報が入っているのか？

等のように、
**全員で確認してからブロックに詰めるのがブロックチェーンのコンセンサスアルゴリズム**です。


先ほどの暗号化技術の時に説明した例を用いて説明すると、
衣服をダンボールに入れてしまう前に、
全員で他のものが入っていないか確認し、
全員がOKを出したら封を閉じて箱詰めするイメージです。
![コンセンサスアルゴリズム](https://i.gyazo.com/1bedd138002b3471c01da866f8b86acf.png)

こうすることで、
**取引の連続性を保ち、過去データの改ざんを防ぐことが出来ます。**

# ③ピア・トゥ・ピア（P2P）

P2Pとは、クライアント＝サーバー型とは異なり、特定のサーバーやクライアントを持たずにノードと呼ばれる各端末が対等に直接通信することで、ユーザー同士の情報共有や決済のやりとりを可能にするネットワークのことです。

このP2Pネットワークによって、先ほど説明した
全員で確認するというブロックチェーンのコンセンサスアルゴリズムを可能にしています。

銀行のATM、株式の取引所などはサーバーがダウンして全体が機能しなくなる事が時々ありますが、P2P技術で分散型のネットワークを作ると、どこかで不具合が起きて全体が機能しなくなるような事態をなくす事ができます。

# ④DLT（分散型台帳技術）
DLTは、Distributed　Ledger　Technologyの略で、
台帳を共有して分散管理する仕組みのことです。

以下のように、全員がそれぞれのデータを持つ事で、もし一箇所で誰かのデータを消されたとしてもみんながデータを持っている事でそのリスクを回避する事ができます。
![DLT（分散型台帳技術）](https://i.gyazo.com/dc84e5af6ad80a23ea5671a943417ac2.png)

また、DLTの最大の利点は、データ改ざんへの強さです。
どこかでデータを改ざんされたとしても、他の人とのデータの相違が生まれることになるからです。
なので、全員の台帳が一斉に改ざんさせられない限り、改ざんが事実上不可能になります。

だからこそ、
**ブロックチェーンではデータの改ざんされないことが担保されています。**


# 終わりに
今回は仮想通貨などに使用されるブロックチェーンについて解説しました。
ブロックチェーンは今後仮想通貨以外にも用いられていく技術だと思うので、
是非参考にしてみてください！

参考にした記事
・坪井 大輔『WHY BLOCKCHAIN なぜ、ブロックチェーンなのか?』2019年
・https://www.nttdata.com/jp/ja/services/blockchain/001/
有限オートマトンの状態遷移表

応用情報技術者平成28年秋期 午前4

次の表は，入力記号の集合が{0，1}，状態集合が{a，b，c，d}である有限オートマトンの状態遷移表である。長さ3以上の任意のビット列を左(上位ビット)から順に読み込んで最後が110で終わっているものを受理するには，どの状態を受理状態とすればよいか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/8e84c2ee-4c6b-f6b4-562c-59940db0c038.png)

１、表の有限オートマトンを図にする　※これが大事です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/2ca70b24-947f-b8d1-827c-a0b2a7a0a932.png)

２、
・ビット列「110」が入力されるときに、a～dのどの状態であるかはわかりませんが、最後の0が入力されて遷移する先はaかcのどちらかしかないですね。

xxc
or
xxa　です。

・cが最後とすると
a->(1)->b->(1)->d->(1)->c
。。。
正しいのようですね。

・aが最後とすると
cのみが来るので、且つ0ので、110にはできないですね。


参照：
https://www.ap-siken.com/kakomon/28_aki/q4.html
ARKitのトラッキング状態を保存、ロードして再開する

###１、ワールドマップを保存

```swift
sceneView.session.getCurrentWorldMap { [self] worldMap, error in
    self.sceneView.session.pause()
    self.map = worldMap
}
```
![75ae3206-121a-47ed-9464-af0f322443cc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/987e3c43-b631-71fb-caba-1aaf8fd56cf8.png)

###２、保存したワールドマップ構成でセッション再開

```swift
let configuration = ARWorldTrackingConfiguration()
configuration.initialWorldMap = map
sceneView.session.run(configuration, options: [])
```

****
Core MLを使ったアプリを作っています。
機械学習関連の情報を発信しています。

お仕事のご依頼は
rockyshikoku@gmail.com
まで

[Twitter](https://twitter.com/JackdeS11)
[MLBoysチャンネル]
(https://www.youtube.com/channel/UCbHff-wfjTnB3rtXIP6y0xg)
[Medium](https://medium.com/@rockyshikoku)

[相棒](https://twitter.com/oka_yuuji)
[note](https://note.com/oka_yuuji)
FileZilla文字化けファイルが削除出来ない時

#フォルダやファイル削除方法

フォルダやファイルが文字化けして、さらにそれが削除できなくなることありますよね。
設定を変えるだけで簡単に削除できるのでメモします。

FileZillaの『サイトマネージャー > 文字セット > UTF-8を強制』に変更すれば大体は大丈夫です。
WindowsとMacでUIは違いますが同じようにやれば削除出来ます。

##手順
**1.サイトマネージャーを選択**
<img width="500" alt="スクリーンショット" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/710589/b8660e65-3e5c-0617-84e4-858fb2c36722.png">
**2.文字セットを選択**
<img width="500" alt="スクリーンショット" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/710589/3ebd9ca4-6b4b-a01e-4342-c0aa5a989b33.png">
**3.カスタム文字コードを変更**
「UTF-8を強制」に変更する
<img width="500" alt="スクリーンショット" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/710589/849863f8-3b31-e8da-3431-81c54b816c80.png">
それでも文字化けする場合は「カスタム文字コードを使用」を選択（Shift_JISなど設定）
<img width="500" alt="スクリーンショット" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/710589/12ec5028-6a56-a030-9ceb-ebc8522f0cea.png">
これでもダメな場合はパーミッションかも知れませんね。
逆ポーランド表記法

応用情報技術者平成28年秋期 午前3

逆ポーランド表記法で表された式を評価する場合，途中の結果を格納するためのスタックを用意し，式の項や演算子を左から右に順に入力し処理する。スタックが図の状態のとき，入力が演算子となった。このときに行われる演算はどれか。ここで，演算は中置表記法で記述するものとする。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/33dcc5ff-91d4-83d3-a0f1-169b5474f7f7.png)

１、逆ポーランド表記法は、
演算子を被演算子の右側に記述する表記法です。

[文字1,演算子,文字2]　→　[文字1,文字2,演算子]　に変えます。

スタックに
ＤＣＢＡとすると、
演算子はＡＢ、文字１はＣ、文字２はＤですね。

逆ポーランド表記法になる前に、Ｃ　演算子　Ｄ　でしょう。



例えば、
　A＝4×5－6＋3×2

という式を逆ポーランド表記法で記述すると、
　A45×6－32×＋＝

となります。

構文木で表すと次のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/e3fac8c7-e8fa-a525-276d-97b61a522e23.png)

この構文木は式の並び順のとおりに「左の葉→右の葉→節」という後行順序で操作が行われます。

問題に戻ると、演算子の前にCとDがスタックに積まれています。つまり先に積まれている「C」が左の葉の値、「D」が右の葉の値ということになります。これを逆ポーランド表記の式にすると「CD演算子」と変換することができます。


参照：
https://www.ap-siken.com/kakomon/28_aki/q3.html
FlutterのiOS14対応で個人的にやったことまとめ

2020年9月17日にiOS14が正式リリースされました。

仕事でFlutterを使っているのですが、その時に対応したことのまとめです。

## Flutter対応

iOS14正式版にアップデートして既存の開発アプリの動作確認をしたところ(ビルドが通り)正常に動きました。
(元々ベータ版iOS14を使っていたので当然っちゃ当然ですが)

ただし、本当に大丈夫かなと思ってドキュメントを読んだところ、

> Upgrading to Flutter 1.22 beta allows you to build, test, and deploy to iOS without issue. Upgrading to 1.20.4 stable allows you to build and deploy to iOS 14, but not debug.

https://flutter.dev/docs/development/ios-14

Flutetrのバージョンが `1.20.4 stable` でビルドとデプロイはできるがデバッグはできない、 `1.22 beta` でビルドとデプロイ、デバッグができるとのことでした。

自分は諸事情でベータ版を使っており、Flutterのバージョン `1.22` になっていたので問題なく使えのでした。

```
% flutter --version                                                                                                                                               [19:47:38]
Flutter 1.22.0-1.0.pre • channel dev • https://github.com/flutter/flutter.git
Framework • revision ce40de69b7 (5 weeks ago) • 2020-08-20 07:31:50 -0700
Engine • revision 81027ab0cc
Tools • Dart 2.10.0 (build 2.10.0-45.0.dev)
```

※ Flutterのベータ版は `stable` と比べると不安定なので基本的に非推奨です。

どうしてもベータ版を使う必要がある場合は、 [以前の記事](https://qiita.com/qst_exe/items/b5cf125e44d4dd51335c#%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E7%A2%BA%E8%AA%8D%E3%81%A8%E3%82%A2%E3%83%83%E3%83%97%E3%83%87%E3%83%BC%E3%83%88) にも書いたようにchannelの切り替えが必要です。

## Xcode対応

iOS14で動くようにビルドするにはXcodeのアップデートは不要でした。ただし、iOS14特有の機能を使うにはXcodeのアップデートが必要です。幸いにも、自分は「Xcodeガチャ」には遭遇しませんでした。
海外FX業者で利用できるEAはMT4とMT5で別物のプログラム

自動売買（システムトレード）をMT4やMT5で行うときに必須なのが**EA**です。

EAとは、Expert Advisorsの略で直訳すると「専門家の助言」となり、メタトレーダー上で動作するソフトウェアのことです。

今回はEAとMT4/MT5の関係について紹介します。
##MT4とMT5で別物のプログラム
同じロジックのEAでもプログラム上、MT4とMT5では互換性がないためお互いのプラットフォームでは動作しません。

- MT4用EAはMT5では動作しない
- MT5用EAはMT4では動作しない

##mql4とmql5
MQL4はMetaQuotes社が提供するプラットフォームMT4（MetaTrader4）のプログラム言語です。MT4は2005年にリリースされました。

MQL4はC++をベースに開発された言語になります。

一方、MQL5はMT5（MetaTrader5）のプログラム言語でmql4と同様にC++がベースになっていますがmql4とは互換性がありません。

##MT4とMT5
メタトレーダーのMT5はMT4の上位互換プラットフォームです。
当然みんなMT5を使うと思いきや、いまだにMT4が根強い人気を誇ります。

理由は、EAプログラムがMT4のほうが豊富に存在するから。
以前よりMT4は長い間主流のプラットフォームだったため、MT4専用のEAが多く存在しています。前述の通りMT5に互換性がないためMT5では動作しません。

そのためMT4を選択するトレーダーがいまだに多いのです。

##MT5用のEAも増えてきた
現在はMT4の開発が止まっており、MT5は頻繁にアップデートが繰り返されどんどん使いやすくなっています。

裁量トレードをするかたは、当然MT5を選択します。テクニカル分析もMT5が優秀だからです。

また、EAの種類も現在はMT5用が増えてきました。

##MT4とMT5で動作するEAプログラム
MT4でもMT5でも動作するEAを作るプログラムがある。
しかし、まだあまりMT4/MT5共通プログラムで書かれたEAはありません。

また、MT4の開発が終わったことからMT4がMT5に統合される日は近いと思われます。
そこでメタトレーダー社はMT4用EAがMT5で動作するようにプログラム（コンバータ）も開発と発表しました。

ただ、機械的に変換するというものなのでEAが動作しなかったり、誤作動を起こす可能性が高いことから、結局自分でプログラムを書き直さないといけないようです。

##安心してEAを稼働させることができる海外FX業者
EAはMT4/MT5が使えなければ動作しません。
しかし、MT4/MT5は現在海外FX業者でしか使えません。

海外FX業者はちょっと不安というかた、信頼できる海外FX業者の見分け方について紹介します。海外FX業者の中で信頼できる業者・安心して利用できる業者は２社だけに絞られます。

はじめに結論を言ってしまうと信頼できる海外FX業者は、

「XMTrading（[XM口座開設](https://kaigaifxem.com/archives/341)）」
「Hotforex（[Hotforex口座開設](https://fuku6.com/archives/9106)）」

の２社になります。
理由は後述しますが、信頼できる海外FX業者の定義は下記。

- ある程度の運営期間があり運営実績があること
- 日本人トレーダーが利用している実績があること
- 入出金が確実にそして迅速に行われていること
- NDD方式採用
- **信頼ある金融ライセンスを取得していること**

みなさんどこを見ても「ハイレバレッジ」や「豪華なボーナスシステム」などを全面にアピールして勧めていますが、重要なことは別にあります。

まずは基本的に上記を満たしていない海外FX業者は選ぶのをやめましょう。

そして悲しいことに上記を満たしていないFX業者は多くあります。

#信頼ある金融ライセンス
下記うち上４つを満たす海外FX業者は結構あります。

- ある程度の運営期間があり運営実績があること
- 日本人トレーダーが利用している実績があること
- 入出金が確実にそして迅速に行われていること
- NDD方式採用
- **信頼ある金融ライセンスを取得していること**

しかし、信頼ある金融ライセンスを取得している海外FX業者は稀です。
私が知っている中では「XM」と「Hotforex」だけです。

##英国FCAライセンス
「XM」と「Hotforex」が取得している金融ライセンスが**英国FCAライセンス**というもの。

英国FCAライセンスは、金融ライセンスの中でもっとも取得困難といわれているほど厳格な取得制限が掛けられています。

英国FCAライセンスが信頼できる金融ライセンスである所以を解説します。

###信託保全
トレーダーの資産を安全に管理するために運用費と別管理で顧客の資産を分別して管理することを強く義務付けられています。

また、万が一FX業者が破綻したら最大8.5万ポンド（約1200万）を補償する規定があるので安心して資産を預けることができます。

###入出金管理
英国FCAライセンスが何よりも厳しいと言われているのが**入出金**に関することだと言われています。

特に出金に関してトラブルはないか遅延はないかなど厳格に管理されています。

たしかに海外FX業者を利用するにあたって不安な部分って、海外送金とか出金拒否はないかなどですよね。

#まとめ
MT4用のEAやインジケータを長く愛用していたかたはなかなかMT5に移行はできないですよね。
MT5用に自動変換ができるといっても残念ながらあまり使えないようです。

MT4が使えなくなる可能性もないとは限らないので今からMT5でお気に入りEAを見つけない物です。

海外FX業者でEAを使うなら信頼できる業者で利用しましょう。

「XMTrading（[XM口座開設](https://kaigaifxem.com/archives/341)）」
「Hotforex（[Hotforex口座開設](https://fuku6.com/archives/9106)）」
【Ruby on Rails】gem Pagy（ページネーション）を配列に適用させる書き方

railsのAPIモードでアプリケーションを作る際、ページネーションでPagyというgemを使用しました。
その際、記述の仕方に迷ったのでメモとしてここに残しておきます。

## 配列に適用させる記述
``` ruby
pagy, offices = pagy_array([])
```

## ふつうに適用させる方法
``` ruby
$ pagy, offices = pagy Office.where(city_id: params[:city_id])
```

``` ruby
pagy, offices = pagy(Office.all)
```

## HTTPヘッダーに関する記述
``` ruby
pagy_headers_merge(pagy)
```
これを上の記述の下に追記すると、HTTPヘッダーにページネーションの情報を持たせることができる。
Pythonで、日時と時間、秒単位を表すには

### Pythonで学習したこと
Python認定技術者に向けて勉強しています。
実際にコードがどのように役立つかについてですが、
使う人の側にたったコードを試したいです。
### 実践したコード
```python

import datetime

now = datetime.datetime.now()
print(now)
print(now.isoformat())
print(now.strftime('%d/%m/%y-%H%M%S%f'))

today = datetime.date.today()
print(today.isoformat('%d/%m/%y'))

t = datetime.time(hour=1, minute=0,second=5,microsecond=100)
print(t)
print(t.isoformat())
print(t.strftime('%H%_M_%S_%f'))

print(now)
d = datetime.timedelete(weeks=1)
#d = datetime.timedelete(days=1)
#d = datetime.timedelete(hours=1)
#d = datetime.timedelete(minutes=1)
#d = datetime.timedelete(second=1)
#d = datetime.timedelete(microsecond=1) //argumentを一つ選ぶ
print(now-d)

import time
#pair print('###')
#time.sleep(10)
#pair print('###')
 import os
 import shutil

 file_name = 'test.txt'

 if os.path.exists(file_name):
     shutil.copy(file_name, "{}.{}".format(
     file_name, now.strftime('%Y_%m_%d_%H__%M_%S')))

with open(file_name, 'w') as f:
    f.write('test')
```
エラーが出たコード

### 該当するソースコード
```python
print(now)
d = datetime.timedelete(weeks=1)

print(now-d)
```
### 今後の課題とします。
また、textを生成するコードも載せます。
NowでLINEBot作ってみる

# Now

## 概要

> node.jsで書かれたアプリケーションを超簡単にデプロイできるサービス。

### インストール

```bash:bash
npm install -g now
```

### 開発用サーバの立ち上げ

```bash:bash
now dev
```

### デプロイする

#### 登録

https://zeit.co にアクセスして登録

#### ログイン

```bash:bash
now login
```

登録したメールアドレスに認証URLが送られてくるのでクリック

#### デプロイ

```bash:bash
now
```

### URLを固定する

NowはデプロイのたびにランダムなURLが生成されるため、これを固定にしてあげる必要がある。
Package.json に設定を記述してあげる必要がある。

#### Package.jsonに追記

```json
"now": {
  "alias": {任意の文字列}
}
```

#### デプロイ

```bash
now --prod
```

`https://{任意の文字列}.now.sh`でアクセスすることができる。


# ngrok

## 概要

簡単にHttps化出来るトンネリングサービス。
LINEのWebhook URLはHttpsしか対応していないため、開発時にはこちらを利用すると便利。

### インストール

```bash
brew cask install ngrok
```

### 実行

```bash
ngrok http 3000
```

### Basic認証をかける

#### https://ngrok.com にアクセスして登録

#### ターミナルで認証する

```bash
ngrok authtoken {Authタブで確認したトークン}
```

#### 実行

```bash
ngrok -auth="{任意のユーザ名}:{任意のパスワード}" {ポート番号}
```

参考：[少しでも安全にngrokを使用する(Basic認証)](https://qiita.com/da-sugi/items/77f5b9bbbd32d8a79bf3)

# 備考

```bash:bash
# トークンなどをSECRETに入れておくことができるが何故かデプロイ時に毎回これを打たないとコケる
now -e CHANNEL_ACCESS_TOKEN=@line-token
```
共有制限付きのGoogleスプレッドシートをGCPサービスアカウントで読み込む方法

Googleスプレッドシートに共有制限がかかっている場合、そのままだとGCPのサービスアカウントは読み込み出来ません。

その場合は、 **サービスアカウントのメールアドレスをユーザとしてGoogleスプレッドシートに登録しましょう。**

手順は以下の通り。

① [Google Cloud Platform](https://console.cloud.google.com/) > IAMと管理 > サービスアカウントに移動し、サービスアカウントのメールアドレスをコピーします。

![スクリーンショット_2020-09-25_19_05_59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/339601/8288edce-c183-4188-bb2b-e6a2522bf2fb.png)

② 制限付き[Googleスプレッドシート](https://docs.google.com/spreadsheets/)に移動して、共有ボタンをクリックします。

![スクリーンショット_2020-09-25_19_13_50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/339601/8c4d73e5-c80d-5637-db3d-c394c923ac8b.png)

③ あとは、コピーしたメールアドレスを登録すれば完了です。

![スクリーンショット_2020-09-25_19_13_36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/339601/815c1f40-8f90-0e19-c81d-3a1990369087.png)

これで、 **制限付きGoogleスプレッドシートをサービスアカウントが読める様になります。**

あ、もちろんサービスアカウントの権限は閲覧者以上にしておいてくださいね。

こんな記事も書いています。

- [GASでQiita APIを叩いて結果をGoogleスプレッドシートに自動入力する手順を詳しくメモしておく](https://qiita.com/kurarararara/items/09c47ee536d8c0199034)
- [GoogleスプレッドシートとFastlaneでApp Store説明文を自動更新する方法](https://zenn.dev/kurarararara/articles/6d198bc9337edf)
AWS IAMでユーザーを作成しよう

[AWSのアカウントを作ろう](https://qiita.com/hagaji/items/31717950902c2d8477e4)でアカウント作成するとルートアカウントだけ作成されます。ここでは、作成したAWSアカウントのIAMでユーザーを作成してみましょう。

# IAMユーザーをなぜ作成するのか
別な記事にも書きましたが、ルートアカウントは、Administrator権限を有する非常に強力なアカウントであるため、開発や運用時には制限したIAMユーザーアカウントで操作することが推奨されます。
誤操作することを防ぐ目的があり、また、操作する人やプログラムへユーザーやロールを割り当てることで誰が操作をおこなったのか？という証跡を残す目的もあります。
（と書いたけど、少し雑な言い方かもしれない。あとで書き直す）

# この記事で行うこと
AWSのIAMユーザーを追加する。

# 事前に決めておくこと
AWSでは、ユーザーへ様々な権限を付与することができます。そのため、ユーザーへ付与する権限を事前に決めておく必要があります。

#### 権限付与でオススメする方法
IAMでグループを作成し、作成したグループに必要な権限を付与しておきます。
本記事の手順で権限を付与する部分がありますが、その時にグループを指定する方法をおすすめします。

# IAMユーザーを追加する手順
1. AWSコンソールへログイン
2. `IAM`へアクセスし、`ユーザー追加`をする
3. ユーザーのIDや詳細情報を登録する
4. ユーザーへ権限を設定する

## AWSコンソールへログイン
ルートアカウントへログインし、AWSコンソールを表示します

![スクリーンショット 2020-09-25 14.01.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703384/4871629c-a0f7-a6de-dfbf-cfdda6a77d43.png)

## `IAM`へアクセスし、`ユーザー追加`をする

![スクリーンショット 2020-09-25 14.02.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703384/82ae87de-7cd2-53bf-51d2-a0a86c86f7b3.png)

![スクリーンショット 2020-09-25 14.02.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703384/96174b09-3fc4-0222-eb6a-9b6be8cdc1a8.png)

## ユーザーのIDや詳細情報を登録する
まずはユーザ名を入力します。これは、ログインする際に利用するユーザーIDになります。そして、アクセスの種類を選択します。

**・プログラムによるアクセス:**
　コマンドラインやAPIなどプログラムからアクセスを許す場合にはチェックを付けましょう。
　アクセスキーとシークレットアクセスキーが払い出されます。
**・AWSマネジメントコンソール:**
　ルートアカウントと同じく、AWSコンソールを使用する場合にはチェックを付けましょう。
　AWSコンソールへアクセスするためのパスワードが払い出されます。

２つのチェックボックスは、ユーザーを**作成した後でも有効化することが可能**です。

![スクリーンショット 2020-09-25 14.02.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703384/47c4b240-f20f-0a07-e1d6-5759d40aaeaa.png)

![スクリーンショット 2020-09-25 14.03.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703384/8417d71a-bd67-66f1-fc80-b7ebd42d2457.png)

## ユーザーへ権限を設定する
作成するユーザーへ権限を設定してください。
グループを割り当てるか、それとも既存のポリシーを直接選択することも可能です。

![スクリーンショット 2020-09-25 14.04.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703384/4c3e2b5e-86cf-8785-a2f9-8520524df789.png)

### タグを追加する
AWSでは作成したリソースへタグをつけて管理することができます。

![スクリーンショット 2020-09-25 14.04.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703384/0498eec9-5f54-8ca4-f6d4-676b8b0504a4.png)

## 作成されるユーザーの確認

![スクリーンショット 2020-09-25 14.05.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703384/6c3ca6f0-0d3c-4d3e-fb99-01ab619b7979.png)

## 作成されたユーザーへの認証情報
ユーザー作成が成功した場合、ユーザーへアクセスするための認証情報が表示されます。
パスワードやシークレットアクセスキーは、本画面でしか表示されないため、コピペなどで保持するようにしてください。

![スクリーンショット 2020-09-25 14.05.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703384/00daa3cd-9562-d0a2-adf5-cb92b42fb9f6.png)

#### 補足
認証情報を紛失してしまってもルートアカウントにてIAMユーザーの認証情報を再発行することができます。

## 一覧で作成されたIAMユーザーを確認
IAMユーザーの一覧で、作成されたユーザーを確認できます。
また、この画面ではアクセスキーやパスワードがいつ設定されたのかを確認することができ、それらの認証情報がいつ使われたのかという`最後のアクティビティ`も確認することが可能です。

![スクリーンショット 2020-09-25 14.09.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703384/98c385fe-9926-8c89-f569-2f6ee21c6316.png)


# AWS公式ドキュメント
[AWS アカウントでの IAM ユーザーの作成](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_users_create.html)
12. 【Android/Kotlin】丸いイメージ（CircleImageView）

#はじめに
DreamHanksのMOONです。

前回はToastという通知メッセージについて説明ししました。
[11. 【Android/Kotlin】Toast](https://qiita.com/DreamHanks/items/f35807698c0456a69534)

今回は`CircleImageView`という外部ライブラリを使用していきます。

ライブラリを追加する方法については下記のリンクで確認してください。
[10. 【Android/Kotlin】ライブラリを追加](https://qiita.com/DreamHanks/items/b0326a6ede9c801a7137)

#CircleImageViewとは
皆さんはラインや他のアプリで丸い写真のイメージを見たことがあると思います。

それがCircleImageViewで変換されたイメージです。

CircleImageViewは原本のイメージを丸いイメージに変換してくれるImageViewのライブラリです。

#CircleImageView追加

・CircleImageViewのライブラリを追加
![3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/708649/9d3bcd70-48a0-c12a-7977-6498f570e086.png)
buile.gradleにのdependenciesに下記のコードを追加

```gradle
    implementation 'de.hdodenhof:circleimageview:3.1.0'
```

・Activityを作成

```kotlin:CircleImageViewActivity.kt
package com.example.practiceapplication

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.*

class CircleImageViewActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_circleimageview)

    }

}
```

・レイアウトのxmlファイルを作成
![1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/708649/678c9703-f3c6-3f7e-3ba4-40e327f96945.png)

```xml:activity_circleimageview.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".CircleImageViewActivity"
    android:gravity="center">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="原本のイメージ"/>

    <ImageView
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:id="@+id/org_iv"
        android:src="@drawable/dreamhanks"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="丸いイメージ"/>

    <de.hdodenhof.circleimageview.CircleImageView
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:src="@drawable/dreamhanks"
        android:id="@+id/circle_iv"/>
</LinearLayout>
```

CircleImageViewのViewタグを追加します。

#アプリ起動
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/708649/da50c489-b90d-6e30-1daf-3de933a1badd.jpeg" width=50%>

#終わりに
今回は`CircleImageView`という外部ライブラリを使用してみました。

次回はHandlerについて説明し、Handlerで画面遷移を遅延してみます。
[13. 【Android/Kotlin】Handler（画面遷移を遅延）](https://qiita.com/DreamHanks/items/a0a85f59e50e2e9308fe)

最新内容については下記のリンク（DreamHanksのブログ）で確認することができます。
[DreamHanksブログ（Android/Kotlinアプリ開発）](http://blog.dreamhanks.com/android-kotlin%e3%82%a2%e3%83%97%e3%83%aa%e9%96%8b%e7%99%ba/)
django PasswordChangeFormでエラーメッセージを日本語で出したい

# 問題

djangoにはでパスワード変更画面用のPasswordChangeFormがあって既定のチェック処理も入ってるが入力チェックエラーのメッセージや注釈をを日本語にしたかった。
メッセージの国際化や多言語化などで探したがいい方法に該当しなかったが、それもそのはずsettings.pyの言語設定を変えるだけだった。

うっかり。

というよりdjangoの言語設定すごいな。

同じ間違いに陥った人のために恥を晒しておく。

# 結論

言語設定が英語の場合

```python:settings.py
LANGUAGE_CODE = 'en-us'
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224453/11096feb-5796-d1a8-b7df-01ae50616ffa.png)

言語設定が日本語の場合

```python:setttings.py
LANGUAGE_CODE = 'ja'
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224453/8d17c866-ca59-c32e-e45e-d426cead10e1.png)

# 参考

https://simpleisbetterthancomplex.com/series/2017/09/25/a-complete-beginners-guide-to-django-part-4.html
CGAffineTransformを使ったアフィン変換で気をつけること

iOS DC2020のトークにあった
**CGAffineTransformはどう働いてるのか？〜Swiftエンジニアのための線形代数〜**[^1]
について、自分なりの理解も込めてこの場を借りてまとめてみました。

内容は、`CGAffineTransform`を使用する際に、
アフィン変換の説明に用いられる行列の形式とAppleのDocumentationの形式の違いによって、
CGAffineTransformの**ed APIを使用した際に、期待した動きにならない事象について説明されていました。

###アフィン変換の説明に用いられる形式
元々の座標(x,y)に対して、前から行列を掛け合わせて変換後の座標を取得する

```math
\begin{eqnarray}
\left(
\begin{array}{cccc}
x' \\
y' \\
1 \\
\end{array}
\right) = \left(
\begin{array}{cccc}
a & b & t_{ x }\\
c & d & t_{ y } \\
0 & 0 & 1 \\
\end{array}
\right)
\left(
\begin{array}{cccc}
x\\
y\\
1\\
\end{array}
\right)
\end{eqnarray}

```

```math
x' = ax + by + t_{ x } \\
y' = cx + dy + t_{ y }
```

###AppleのCGAffineTransformのDocumentationの形式
元々の座標(x,y)に対して、後から行列を掛け合わせて変換後の座標を取得する

```math
\begin{eqnarray}
\left(
\begin{array}{cccc}
x' & y' & 1\\
\end{array}
\right) = \left(
\begin{array}{cccc}
x & y & 1\\
\end{array}
\right)
\left(
\begin{array}{cccc}
a & b & 0\\
c & d & 0\\
t_{ x } & t_{ y } & 1 \\
\end{array}
\right)

\end{eqnarray}

```

```math
x' = ax + cy + t_{ x } \\
y' = bx + dy + t_{ y }
```

この違いによって、生まれた誤解について説明されていました。

###今回アフィン変換を使って想定する変更
CGAffineTransformを使用して、次の順番でアフィン変換を行った場合を考えてみました。

1.xを0.5倍、yを1.5倍のスケールに変換する
2.軸を90度傾ける

![期待.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368129/69a364d4-0514-9040-3fe9-3fc8ab5622bf.gif)



###想定する変更をCGAffineTransformの**ed APIを使用して実際に動かしてみる

```swift
UIView.animate(withDuration: 0.2) {
      self.view.transform = CGAffineTransform.identity.scaledBy(x: 0.5, y: 1.5)
                                                      .rotated(by: 90 * .pi / 180)
}
```

- `scaledBy(x:y:)` を使用してxを0.5倍、yを1.5倍のスケールに変換
- `rotated(by:)` を使用して軸を90度傾ける

という順番でアフィン変換をかけるように記述してみました。

実行結果
![実際.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368129/3d913c0f-ad92-23e5-1a09-60faef779dff.gif)


期待した状態と結果が異なるのは、CGAffineTransfoormでは、後ろから元の座標に対して演算するので、
rotateの変換、scaleの変換と処理を並べた場合は、
scaleの演算→rotateの演算の順とコードで記述した順番と逆で演算が行われる為、期待した状態と異なってしまいます。


###紹介された concatenating(_:) を使用して動かしてみる

```swift
let scale = CGAffineTransform(scaleX: 0.5, y: 1.5)
let rotate = CGAffineTransform(rotationAngle: 90 * .pi / 180)
let transform = scale.concatenating(rotate)
    
UIView.animate(withDuration: 0.2) {
      self.transView.transform = transform
}

```

実行結果
![別.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368129/c5ee7da3-ed63-c8af-aa69-7a8bac9b2aa3.gif)

`concatenating(_:)`では期待した結果を得ることができました。
concatenating(_:)については、ドキュメントにて

>**Return Value**
A new affine transformation matrix. That is, t’ = t1*t2.

と記載されています。[^2]
なのでこの場合は  `rotateの変換`→`scaleの演算`の順番でアフィン変換が行われる為、期待した状態になります。

[^1]: https://fortee.jp/iosdc-japan-2020/proposal/95413b51-d63a-4b82-b4fc-af808da6fc78
[^2]: https://github.com/nicklockwood/SwiftFormat/blob/master/README.md#config-file
Pythonで天気予報botもどきを作ってみた。

#Pythonで天気予報bot作ってみた.
タイトル通りPythonで天気予報botを作ってみました(厳密には全然botではないです)。
天気予報を確認することすらめんどくさがってしまう性格で「LINEで送れたらなー」と思っていた所、既に先人の方達がやっていたので、知恵を借りながら(ほぼパクリながら)作ってみました。
##やったこと
・スクレイピングでYahooの天気情報を取得
・スクレイピングで取得した情報をLINE Notifyで表示
##準備
###必要なライブラリのインストール
```
$pip install beautifulsoup4
$pip install requests
```
###トークンの取得
[LINENotify](https://notify-bot.line.me/ja/)でトークンを発行しておきます。
##コード
```Python
import urllib.request
import requests
from bs4 import BeautifulSoup

line_notify_token = 'xxxxxxxxxxxxxxxxxxxxx'#発行したトークンを使います。
line_notify_api = 'https://notify-api.line.me/api/notify'

rssurl = "https://rss-weather.yahoo.co.jp/rss/days/3410.xml"#このコードでは仙台の天気情報を取得します。

URL = "https://weather.yahoo.co.jp/weather/jp/8/3410/8201.html"

tenki = []
detail = []


def Parser(rssurl):
   with urllib.request.urlopen(rssurl) as res:
      xml = res.read()
      soup = BeautifulSoup(xml, "html.parser")
      for item in soup.find_all("item"):
         title = item.find("title").string
         description = item.find("description").string
         if title.find("[ PR ]") == -1:
            tenki.append(title)
            detail.append(description)

def Otenki():
    Parser(rssurl)
    for i in range(0,2):
        message = tenki[i]
        payload = {'message': "\n" + message}
        headers = {'Authorization': 'Bearer ' + line_notify_token}
        line_notify = requests.post(line_notify_api, data=payload, headers=headers)

Otenki()
```
##実行結果
![IMG_8243.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547761/979f7985-5c1b-d5d6-9a87-75c8f7b9540b.jpeg)
しっかり送られてきて嬉しい気持ちになりました。
##感想
本当はAWS,Herokuを使って自動化までやりたかったですが...。
知識が何も無い状態で飛び込んで高額請求がきたら対処出来ないので、今回はここまでにしておきました笑。

自分で動かしてみると分からないなりにも色々出来て楽しかったです。またスキルを身に付けていきながらこの記事も更新していきたいです。
##追記
Herokuで自動化することが出来たのでまた記事を書こうと思います。
###参考記事
[【Yahoo!天気リプレース版】LINE Notify + Pythonで天気情報を取得する方法](https://qiita.com/S_eki/items/259f5c1c2238810d6496)
[Pythonで天気予報をLINE通知する](https://qiita.com/kutsurogi194/items/6b9c8d37b2b83fc2ce87)
SQLの個人的備忘録

##データベースとは
テキストや数値などのデータを保存するためのツール。

##データベースの仕組み
データベースは表のことをテーブル、縦の列のことを「カラム」、横の行のことを「レコード」と呼ぶ。必要に応じて複数のテーブルを作成することが可能。

##クエリとは
データベースに送る命令。SQLはクエリを書くための言語。

##SELECT
どのカラムのデータを取得するか選ぶ。

```haml
-# 「name」カラムのデータを取得する。
SELECT name
```

##FROM
テーブルの指定。

```haml
-# 「purchases」テーブルの「name」カラムのデータを取得。最後には「;」をつける。
SELECT name
FROM purchases;
```
##複数のカラムのデータを取得

```haml
-# 「purchases」テーブルの「name」、「price」カラムのデータを取得。
SELECT name, price
FROM purchases;
```

##全てのカラムのデータの取得
```haml
-# 「purchases」テーブルの全てのカラムのデータを取得
SELECT *
FROM purchases;
```

##WHERE
特定のデータを取得するために使用。どこのレコードを取得するか選ぶ。

```haml
-# 「purchases」テーブルの全てのカラムのデータから、「category」が食費のものだけを取得
SELECT *
FROM purchases
WHERE category = “食費”;
```
なおテキストデータや日付データはクォーテーションが必要で、数値データは必要なし。

##LIKE演算子
ある文字を含むデータを取得する際に使用。また合わせて使われるのがワイルドカードで、どんな文字列にも一致することを指す記号。

```haml
-# 「purchases」テーブルの全てのカラムのデータから、nameがプリンを含むものだけを取得
SELECT *
FROM purchases
WHERE name LIKE "%プリン%";
```
“%プリン”でプリンで終わるnameを取得。
“プリン%”でプリンで始まるnameを取得。

##NOT演算子
条件に満たないデータの取得。

```haml
-# 「purchases」テーブルの全てのカラムのデータから、nameがプリンを含まないものだけを取得
SELECT *
FROM purchases
WHERE NOT name LIKE "%プリン%";
```

##NULL
データベースに何のデータも保存されていない場合「NULL」となる。

```haml
-# 「purchases」テーブルの全てのカラムのデータから、「price」が「NULL」のデータを取得
SELECT *
FROM purchases
WHERE price IS NULL;

-# 「purchases」テーブルの全てのカラムのデータから、「price」が「NULL」以外のデータを取得
SELECT *
FROM purchases
WHERE price IS NOT NULL;
```

##AND演算子
複数の条件を指定することができる。「WHERE 条件1 AND 条件2」のようにすることで複数の条件を満たすデータを取得することができる。

```haml
-# 「purchases」テーブルの全てのカラムのデータから、categoryが食費、尚且つcharacter_nameがコアラのデータを取得
SELECT *
FROM purchases
WHERE category = "食費"
AND character_name = “コアラ”;
```

##OR演算子
「WHERE 条件1 OR 条件2」とすることでどちらかの条件を満たすデータを取得することができる。

```haml
-# 「purchases」テーブルの全てのカラムのデータから、categoryが食費、若しくはcharacter_nameがコアラのデータを取得
SELECT *
FROM purchases
WHERE category = "食費"
OR character_name = “ラッコ”;
```
##ORDER BY
データを並び替えるのに使用。「ORDER BY 並び替えたいカラム名 並べ方」となる。並べ方ではASC(昇順)で数が小さい順に、DESCで数が大きい順になる。

```haml
-# 「purchases」テーブルの全てのカラムのデータから、priceが大きい順にデータを取得する。
SELECT *
FROM purchases
ORDER BY price DESC;
```

##LIMIT
最大何件取得するかを指定することができる。

```haml
-# 「purchases」テーブルの全てのカラムのデータから、5件のデータを取得
SELECT *
FROM purchases
LIMIT 5;
```
知って得するかも？私のおすすめ Webアプリ開発術！ (Azure x VS Code x LINE)

こんにちは！もっちゃんと申します。

突然ですが、皆さまはWebアプリを開発する時どのようなツールやサービスを使っていますでしょうか？

そこで本記事では、令和時代のおすすめっぽいWebアプリ開発をご紹介していきたいと思います。

## システム構成

だいたい下記のような感じです！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121860/ae2fd950-4145-c0e6-f9ba-300cfd5eca44.png)

## どのようなメリットあるのか？

どのようなメリットがありそうでしょうか。簡単に一つずつ見ていきましょう。

### Azure Static Web Apps

そもそもAzureがメリットだらけで上げていくと切りがないですので、ここでは新しいサービス **Azure Static Web Apps** のみをピンポイントで見ていきます。

* GitHubと強力に連携(Actionsによるリポジトリの変更検知で自動ビルド&デプロイなど)
* CORSの対応が不要!
* 自動的に更新される無料の SSL 証明書

などなどGitHubとの連携が良いですね！

### VS Code

* 各Azureサービス用の拡張機能を使ってVS Codeの画面からほぼ離れずに開発可能
* Visual Studio Codespacesを使えばWebブラウザでVS Codeライクな開発が可能

他にも **IntelliSense** や デバッグ機能など開発を強力に支援する機能が目白押しです！

※ Visual Studio CodespacesはGitHub Codespacesに統合されることになりました。詳細は[コチラ](https://devblogs.microsoft.com/visualstudio/visual-studio-codespaces-is-consolidating-into-github-codespaces/)をご覧ください。

### LINE

LINEはBotの開発が知名度が高いと思いますが、現在は **LIFF(LINE Front-end Framework)** と呼ばれるものが提供されていてWebアプリ開発とも親和性が高くなっています。LINEのプラットフォームを活用すると楽になる部分はあるかもしれません...

なお、LIFFは[LINEミニアプリ](https://developers.line.biz/ja/docs/line-mini-app/discover/introduction/)開発のベースとなる仕組みでもあります。昨年から今年にかけては**ミニアプリ**やOMOとかも盛り上がっていますね！
下記の参考情報も見ていただければと思います。

* https://developers.line.biz/ja/docs/liff/overview/
* https://note.com/unioce/n/n5f264f130dbc

## 続きはWebで！...
詳細な開発の流れの資料は別で用意しましたのでよろしければ下記をご覧ください！

[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121860/fe361e34-7007-6f0a-8d8c-910950cb1597.png)](https://speakerdeck.com/mochan_tk/azure-vscodejp-line-api-for-students-20200911)

* https://speakerdeck.com/mochan_tk/azure-vscodejp-line-api-for-students-20200911

## まとめ
簡単にですが以上になります！
ご一読いただきましてありがとうございました。

## ご注意
Azure Static Web Appsは現在プレビューの段階です。GA(正式リリース)された際に起こる差異や動作保証まではいたしかねます。あらかじめご了承ください。
OSX のtelnet でエラー

久々にルータのコンフィグをしようとし、mac からtelnet。しかし、見たことがないエラー。。。

```
[hogehoge@~]$ telnet 192.168.0.3
Password:
Trying 192.168.0.3...
Connected to 192.168.0.3.
Escape character is '^]'.
Illegal instruction: 4
```

そういえば、Catalina に上げてたので、ggrk しました。
https://qiita.com/9rq/items/cdd986dbb67886dd0b5b 参考にして、brew でインストール

```
[hogehoge@~]$ brew install telnet
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 1 tap (homebrew/cask).
==> New Casks
boost-note
==> Updated Casks
calibre ✔                     emby-server                   max                           openinterminal-lite
beyond-compare                lastpass                      openineditor-lite

Warning: telnet 63 is already installed and up-to-date
To reinstall 63, run `brew reinstall telnet`
```

再インストールしろとのことなので。

```
[yoshihiko@~]$ brew reinstall telnet
==> Downloading https://homebrew.bintray.com/bottles/telnet-63.catalina.bottle.tar.gz
######################################################################## 100.0%
==> Reinstalling telnet
Error: Could not symlink bin/telnet
Target /usr/local/bin/telnet
is a symlink belonging to inetutils. You can unlink it:
  brew unlink inetutils

To force the link and overwrite all conflicting files:
  brew link --overwrite telnet

To list all files that would be deleted:
  brew link --overwrite --dry-run telnet
[hogehoge@~]$ brew unlink inetutils
Unlinking /usr/local/Cellar/inetutils/1.9.4_2... 57 symlinks removed
[hogehoge@~]$ brew link --overwrite telnet
[hogehoge@~]$
[hogehoge@~]$
[hogehoge@~]$ telnet 192.168.0.3
Trying 192.168.0.3...
Connected to 192.168.0.3.
Escape character is '^]'.

login: operator
Password:

router>
```

成功
VisualStudioCode(vscode)のDefault Dark+テーマでPythonのユーザ関数呼び出しをハイライト表示する

#はじめに
VisualStudioCode(1.49.2)のデフォルトテーマ(Default Dark+)でPythonプログラム(*.py)のユーザ関数呼び出し時の関数名、引数名がハイライト表示されなかったため、「settings.json」に設定を追記する事で、表示可能としました。

#動作イメージ
##設定の追記前
ユーザ関数の呼び出し時の名前(例:print_debug)と引数がハイライト表示されません。
![20200925.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490699/f7e66d24-80b2-b7bb-60bd-ddbb918aa574.png)
##設定の追記後
ハイライト表示されます。
![20200925_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490699/9675d8d8-5e18-e13a-c946-baf7d4c63daf.png)

#設定の追記方法
1. VisualStudioCodeのメニュー「File」→「Preferences」→「Settings」を開く
2. ツリーメニュー「Workbench」→「Appearance」を開き、項目「Color Customizations」の「Edit in settings.json」を開く
![20200925_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490699/1b388003-9c57-9268-859b-80b5bcc5fead.png)
3. 開かれた「settings.json」に下記コードを追加します

```json:settings.json
    "editor.tokenColorCustomizations": {
        "textMateRules": [
            {
                "scope": [
                    "meta.function-call.python",
                ],
                "settings": {
                    "foreground": "#dcdcaa"
                }
            },{
                "scope": [
                    "meta.function-call.arguments.python",
                ],
                "settings": {
                    "foreground": "#9cdcfe"
                }
            },{
                "scope": [
                    "punctuation.definition.list.begin.python",
                    "punctuation.definition.list.end.python"
                ],
                "settings": {
                    "foreground": "#fff"
                }
            }
        ]
    }
```
4.「settings.json」上書き保存して、Pythonプログラムの表示を確認します。「settings.json」に既存の設定が書き込まれている場合は、設定がコンフリクト(競合)しないように注意します。

設定更新後もハイライト表示されない場合は、下記ポイントを確認します。
- 「settings.json」の追記誤り。JSON形式になっているか。既存の設定と競合していないか。
- 「Color Customizations」の「settings.json」を編集しているか。
- Pythonプログラムの拡張子が *.py になっているか。
- 拡張(Extensions)機能と競合していないか。

#ハイライト対象の変更
ハイライト表示する対象は "scope" で指定しています。
この "scope" に指定する値を変更する事で、ハイライト対象も変更されます。

1. "scope" に指定する値の調査<br>
コマンドパレット(Win:Ctrl+Shift+P, Mac:⌘ + Shift + P)を開き、「Developer: Inspect Editor Tokens and Scopes」を実行する。
![20200925_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490699/3d45c5af-f67b-1dc8-c712-50463e6b6e6c.png)
2. エディタのカーソルがあるテキストにミニウィンドウが表示され、ウィンドウ中「textmate scopes」に表示されている値を、「settings.json」の "scope" に指定します。
 ![20200925_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490699/2d430766-1400-ac14-64e3-fb05bcb120cf.png)
【Looker】dimensionを任意の表示順序でソートする

> 2020/9/28追記
> caseパラメータを用いた場合、記述した順序でexploreでもソートしてくれます。
> [公式リファレンス](https://docs.looker.com/ja/reference/field-params/case)
> ただし、
> ・ラベルのデータ型はstringで固定
> ・ラベルに変数を使えない
> 等の制約があるため、今回紹介するやり方を使うべきかはケースバイケースです。


# 例題

下記のデータが入ったSampleテーブルがあるとします。

| id | name |
| --: | :-- |
| 1 | aaa |
| 2 | bbb | 
| 3 | ccc |
| 4 | ddd |
| 5 | eee |

Exploreでnameを基準にソートさせたとき

| id | name |
| --: | :-- |
| 3 | ccc |
| 1 | aaa |
| 2 | bbb | 
| 5 | eee |
| 4 | ddd |

という順序で表示したい場合を考えてみましょう。

# 結論
ソート用のdimensionを定義し、[order_by_field](https://docs.looker.com/ja/reference/field-params/order_by_field)パラメーターに作成したソート用のdimensionを指定することで、任意の表示順序でソートさせることができます。


### sample.view
```
view: sample {
︙
︙
  dimension: id {
    primary_key: yes
    type: number
    sql: ${TABLE}."id"
  }

  dimension: name_sort {
    type: number
    sql:
      CASE ${id}
        WHEN 1 THEN 2
        WHEN 2 THEN 3
        WHEN 3 THEN 1
        WHEN 4 THEN 5
        WHEN 5 THEN 4
        ELSE NULL
      END;;
  }

  dimension: name {
    type: string
    sql: ${TABLE}."name"
    order_by_field: name_sort
  }
}
```
Python触ってみた（基本構文編）

# はじめに
[Python触ってみた（インストール編）](https://qiita.com/ok2/items/2964ebfb8254b465e77d)の続き

# 事前に確認＆やっておくといいこと
- 仮想マシンにSSHで接続すると日本語が文字化けしてしまいました。
- 調べたら以下の記事が困っていたことにドンピシャでした！
    - [SSH環境下のCentOSで文字化けした場合の対処法](https://qiita.com/Dakini/items/a9eb4546c38a6c8a9518)

```console:仮想マシン
# 状態確認　→　VC Keymapがusになっている
$ localectl status
   System Locale: LANG=ja_JP.utf8
       VC Keymap: us
      X11 Layout: n/a
# VC Keymapをjp106に更新(sudoつけて実行)
$ sudo localectl set-keymap jp106
# 再度状態確認　→　VC Keymapがjp106に更新
$ localectl status
   System Locale: LANG=ja_JP.utf8
       VC Keymap: jp106
      X11 Layout: jp
       X11 Model: jp106
     X11 Options: terminate:ctrl_alt_bksp
# 日本語のlocaleが使用可能か確認　→　そもそもjaがない！？
$ localectl list-locales | grep -i ja
# 日本語のlocaleを追加
$ sudo localedef -f UTF-8 -i ja_JP ja_JP
# 日本語のlocaleが使用可能になっていることを確認
$ localectl list-locales | grep -i ja
ja_JP
ja_JP.utf8
```

# 基本構文を学ぶ
## 正常系プログラムを実行
基本構文を学ぶために以下のプログラムを作成＆実行してみます。

```console:コマンド実行
# .pyファイルを作成
$ vi test02.py
```

```python:test02.py
print('モジュールのロード')

def test():
    print('関数：testを呼び出しました')

if __name__ == '__main__':

    print('python-izm')
#   print('パイソンイズム')
    test()
```

```console:コマンド実行
# Pythonコマンドを使用して作成した.pyファイルを実行
$ python test02.py
モジュールのロード
python-izm
関数：testを呼び出しました
```

3系の文字エンコードはデフォルトでUTF-8が適用されるので意識しなくてよいとのこと。
※2系の場合は1行目に明示的に宣言する必要があるらしいです。

## 異常系プログラム(インデント)を実行
Pythonはブロック構造にインデントを使用しています。
{ } を使用しないため、インデントの整合性が取れていないとエラーになります。

```console:コマンド実行
# .pyファイルを作成
$ vi test03.py
```

```py:test03.py
print('モジュールのロード')

def test():
        print('関数：testを呼び出しました')

# 対象プログラムをスクリプトとして起動したときのみ実行
# importなどの際は実行されない
if __name__ == '__main__':

      print('python-izm')
#   print('パイソンイズム')
    test()
```

```console:コマンド実行
# Pythonコマンドを使用して作成した.pyファイルを実行
$ python test03.py
  File "test03.py", line 10
    test()
         ^
IndentationError: unindent does not match any outer indentation level
```

> IndentationError: unindent does not match any outer indentation level
> IndentationError：unindentはどの外側のインデントレベルとも一致しません

google先生曰くエラーメッセージは上記とのことです。

# おわりに
インデントのブロック構造のみ気をつける必要がありますが、
以前GO言語を触れたことがあるのであまり違和感なかったですw

今後の流れとしては基礎編、応用編を実施後、何かものを作れたら記事にしようと思います！
（文字列とかif文とかは記事にするよりはプログラム作ったほうが覚えやすいので）
PyTorchのインストール

いい加減、何度もハマっているので、忘れないように記録を残しておくようにします。

# PyTorchをインストールするとき
- Anaconda NavigatorのGUIからPyTorchをインストールしないこと！
- 必ず https://pytorch.org/ を見ること！

そして、「INSTALL PYTORCH」のところで、自分の環境にあった選択をし、「Run this Command:」の文字列をコピペして実行すること。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130771/b2fdcab1-aea5-3d7a-983f-b2fcd3537ad2.png)

# 今までの失敗
- torchvisionがない
    - 直接condaでtorchvisionをインストールする
        - PyTorchとバージョンが合わない
        - PyTorchがCUDAでコンパイルされていない
            - 直接condaでcudatoolkitをインストールする
                - バージョンが合わない

# おまけ
- torchsummaryはpipでインストールする
iOS: Youtubeをアプリで再生する

自作のアプリでYoutubeを再生させます。

## ライブラリのインストール

- アプリのプロジェクトフォルダで、CocoaPodの初期化
- → Podfileが作成される

```bash
pod init
```

- Podfileに、youtube-ios-player-helperを追加

```
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'YoutubePlayer' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!

  # Pods for YoutubePlayer
  pod 'youtube-ios-player-helper', '~> 1.0.2' # 追加
end
```

- CocoaPodインストールコマンド実行

```
pod install
```

- Xcodeを「プロジェクト名.xcworkspace」ファイルをダブルクリックして起動する


## ViewにYoutube Playerを追加

- StoryBoardから、画面にView(UIView)を画面に設置
- ViewのクラスをYTPlayerViewに変更
- ViewControllerに、このYTPlayerViewを紐づける

```swift:ViewController
@IBOutlet weak var youtubeView: YTPlayerView!
```

## Youtubeを再生させる

- youtube_ios_player_helperをインポートする
- YTPlayerViewDelegateを実装する
- viewDidLoadでyoutubeViewの初期化

```swift:ViewController
import UIKit
import youtube_ios_player_helper

class ViewController: UIViewController, YTPlayerViewDelegate {

    @IBOutlet weak var youtubeView: YTPlayerView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        self.youtubeView.delegate = self
        self.youtubeView.load(withVideoId: "ec3_rjH_ymE")
    }

    func playerViewDidBecomeReady(_ playerView: YTPlayerView) {
        self.youtubeView.playVideo()
    }
}
```
[コントローラー]DBから特定のカラムの数値を取り出したい(自分メモ)


Aテーブル：user
Bテーブル：user_info

目的：
Bテーブルの特定カラム(ここではuser_main_id)の数値を返したい

やり方：
用意されているのは、Aテーブルの@user_sessionのみ。

1. Aテーブルの@user_sessionの中のidを探し出す。
2. Aテーブルのidと、Bテーブルのuser_idの数値を一致させる
3. Bテーブルの中でidで一致した後、目的のカラム(user_main_id)を取得する

```ruby:コントローラー
API表示名: user.find_by(user_id: @user_session.record.id).user_main_id 
```

@user_sessionの中身が何かが重要！


参考URL
https://qiita.com/tsuchinoko_run/items/f3926caaec461cfa1ca3
Python2のコードをPython3に書き換える（2to3）

<h1>なりゆき</h1>
ん？？これPython2のコードやんけ！？
Python3もよくわかっていないのに勘弁してや...

という感じでPythonクソ初心者が書いております。

<h1>環境</h1>
Windows10
Python 3.7.4

今回は全てコマンドプロンプトで行っている。

Python3がインストール済み前提とするため、
コマンドプロンプトで<code>py</code>と打ってみて、エラーが出ないか確認してみよう。
（<code>quit()</code>でPythonの対話モード終了）


<h1>2to3</h1>
どうやら2to3というPythonのライブラリのプログラムで、
Python2のコードをPython3のコードに自動変換してくれるらしい。


<h1>実践(ミス)</h1>
デスクトップ上に置いた、"Hello.py"を変換したいとする。

まず、変換したいファイルがある場所（ここではデスクトップ）に移動する。
<code>cd C:\Users\(ユーザー名)\Desktop</code>
次にいよいよPython2からPython3へ変換！！
<code>2to3 -w Hello.py</code>

これで、"Hello.py"はPyhon3のコードになり、
元のPython2のコードは"Hello.py.bak"になるはず!!　あれ？？

<pre>
'2to3' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。
</pre>
というエラーが...

どうやら、
Windows以外ではこれでOKらしいですがWindowsではエラーになります。

<h1>実践(成功)</h1>
上と同じくデスクトップ上に置いた、"Hello.py"を変換したいとする。
PythonがC:¥Python37へインストールされている場合は


<pre>
cd C:\Users\(ユーザー名)\Desktop
python C:\Python\Python37\Tools\scripts\2to3.py -w hello.py
</pre>

これでいけた！！

あなたが使う上で変更する必要のある箇所は、
<ul>
<li>変換したいファイルがある場所へのパス <code>C:\Users\(ユーザー名)\Desktop</code></li>
<li>2to3.pyへのパス <code>C:\Python\Python37\Tools\scripts\2to3.py</code></li>
<li>変換したいファイルのファイル名 <code>hello.py</code></li>
</ul>
といったところでしょうか

<h1>参考サイト</h1>
Windowsで2to3を使う（2系コードの3系コードへの変換）-メモの倉庫
https://woraise.com/2019/03/11/2to3/

2系から3系への変換ツール　-Python-izm　
https://www.python-izm.com/tips/2to3/

2to3 - Python2から3への自動コード変換 -Python
https://docs.python.org/ja/3/library/2to3.html
【Athena】既存データをPartition分割する

## 今使っているデータをPartition分割したい
Athenaで利用しているデータが拡大していき、費用削減・速度向上を狙ってPartitionでデータを分割したくなることがあると思います。
初期からデータを分けていた場合は問題がないのですが、何も考えていなかった場合、１ファイルまたは１ディレクトリ（S3にディレクトリはありませんが便宜上ディレクトリと表現します）に全てのデータが入っていることがあります。
この際、CTAS（CREATE TABLE AS SELECT）クエリで分割、というかデータを再構築します。

## 分割例
少し長いですが以下のようなデータを用意します。

| id | name | team_id |year|
|:-----------|:------------|:------------|:------------|
|1|佐藤|2|2019|
|2|高橋|2|2019|
|3|近藤|3|2019|
|4|田中|1|2019|
|5|山田|2|2019|
|6|野村|4|2019|
|7|河合|2|2019|
|8|五十嵐|1|2019|
|9|川端|4|2019|
|10|比屋根|3|2019|
|11|上田|2|2020|
|12|村上|4|2020|
|13|星|5|2020|
|14|歳内|3|2020|
|15|西浦|2|2020|
|16|西田|1|2020|
|17|中村|4|2020|
|18|畠山|5|2020|
|19|真中|3|2020|
|20|高津|2|2020|

このデータを元にAthenaテーブルを作成します。

```sql:create.sql
CREATE EXTERNAL TABLE IF NOT EXISTS db_name.partition_test (
  `id` int,
  `name` string,
  `team_id` int,
  `year` int 
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe'
WITH SERDEPROPERTIES (
  'serialization.format' = ',',
  'field.delim' = ','
) LOCATION 's3://example_bucket/partition_test/original/'
TBLPROPERTIES ('has_encrypted_data'='false');
```
これはCSVファイルをただ読み取るだけのcreate文です。
現在は`s3://example_bucket/partition_test/original/`ディレクトリに全テータを入れています。

このファイルを分割するCTAS文が

```sql:ctas.sql
CREATE TABLE db_name.partitioned_test 
WITH (
     format = 'PARQUET',  
     external_location = 's3://example_bucket/partition_test/partitioned/', 
     partitioned_by = ARRAY['team_id', 'year']
) 
AS SELECT id, name, team_id, year FROM partition_test;
```

これを実行することでlsコマンドでディレクトリ構造を見てみると…

```shell
$ aws s3 ls s3://example_bucket/partition_test/partitioned/
                           PRE team_id=1/
                           PRE team_id=2/
                           PRE team_id=3/
                           PRE team_id=4/
                           PRE team_id=5/
```
```shell
$ aws s3 ls s3://example_bucket/partition_test/partitioned/team_id=1/
                           PRE year=2019/
                           PRE year=2020/
```

このように`team_id`と`year`でデータが分割されています。これでwhere句で`team_id`か`year`を絞るとアクセスするファイルを減らせるため速度・費用の節約を図ることができます。

しかし、今回のようにデータ量が少ない場合は、where句で条件を指定しない場合逆にS3へのリクエスト量が増えるため費用は上がってしまいます。
Athenaはどのような読み取り量も最低でも10MBとなる点、S3の費用も考えてデータを構成する必要があります。
[ファイルサイズの最適化](https://qiita.com/YujiHamada3/items/fef3de57ef800af69cfe#%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%B5%E3%82%A4%E3%82%BA%E3%81%AE%E6%9C%80%E9%81%A9%E5%8C%96)でも書きましたが、1ファイルサイズは128MB程度になるのが一番オーバーヘッドが少なくなります。もちろんこのような調整は簡単でないことも多いのですが、気に留めておく必要あります。

## エラー

```
HIVE_COLUMN_ORDER_MISMATCH: Partition keys must be the last columns in the table and in the same order as the table properties: [team_id, year]. You may need to manually clean the data at location
```
CTAS文を実行した際にこのようなエラーが出る場合があります。これは読んでそのままなのですが、パーティションキーに指定したものはselect文の末尾に*順番通り*並べる必要があります。
なので今回の例でいうと

```sql
SELECT id, name, year, team_id FROM partition_test;
```
だと上記エラーが出ます。エラー文読めば問題なく対応できるのですが、直感的にこのようなエラーが出ることは予想できないので注意が必要です。
[OAuth]PKCEを用いた検証の目的と攻撃および防御の流れ

# PKCEの目的
認証コード窃取攻撃の軽減。
CSRF対策。

## PKCEの仕様自体が想定している攻撃
Public Clientとした場合に、認可コードを窃取されることで、公のClient Credentialとともにアクセストークンの取得を試みる攻撃。

### Public Clientとは
Client Credentialを秘匿に保てない前提にあるClient。

### Client Credential
Cleint認証情報。

# 攻撃内容
## 窃取対象
・認可コード

## 攻撃例

サービス：S
Sのバックエンドサービス：SB
攻撃ユーザー：X
対象者：Y

1~3までHTTPクライアントなどで実施する。
1. Sにおいて、XがSBの認可が必要なサービス（画面など）へアクセスする。
2. Sは、SBへXをリダイレクトさせる。
3. SBにおいて、Xが認証する。
4. SBにおいて、認可コードを発行し、XへSへのリダイレクトURLを返却する。
5. Xが認可コードを含むSへの**リダイレクトURLへの遷移を止める**。
6. SBは、Sからの認可コードによるアクセストークンの払い出しを受け付ける準備をする
7. 4.のリダイレクトURLをYへ何らかの方法で配布する。
8. YがリダイレクトURLにアクセスする。
9. **Yのセッション＋リダイレクトURL（に含まれるXの認可コード）**でSへアクセスする。
10. Sは、認可コードを用いて、SBからアクセストークンを得る。
11. Yは、SBの認可を受けたサービスを利用する。利用時におけるSBへの永続化情報（買い物かごとかストレージ情報とか）は、XのSBアカウントに反映される。


# 上記の防止例
## 攻撃防止の考え方
認可サーバにおいて、アクセストークンの取得に認可コードのみを必要としていた箇所を
認可コード要求時に認証済みクライアントから送信された使い捨ての`検証コード`も必要とするようにする。
これにより、攻撃者が知りえない`検証コード`が障壁となる。

## 攻撃防止の流れ
1. Sにおいて、XがSBの認可が必要なサービス（画面など）へアクセスする。
2. Sは、SBへXをリダイレクトさせる。
3. SBにおいて、Xが認証する。Sはこの認証リクエストに、`code_challenge`と`code_challenge_method`を送信する。`code_challenge`は`code_verifier`をもとに生成する。さらに、`code_verifier`はXのセッション情報に紐づけて保管する。
4. SBにおいて、認可コードを発行し、XへSへのリダイレクトURLを返却する。
5. Xが認可コードを含むSへの**リダイレクトURLへの遷移を止める**。
6. SBは、Sからの認可コードによるアクセストークンの払い出しを受け付ける準備をする
7. 4.のリダイレクトURLをYへ何らかの方法で配布する。
8. YがリダイレクトURLにアクセスする。
9. **YのリダイレクトURL（に含まれるXの認可コード）**でSへアクセスする。
10. Sは、認可コード**およびcode_verifierを用いて、SBからアクセストークンを要求しなくてはならない。攻撃者は、`code_verifier`を知りえないため、攻撃は成立しない。**

# 仕様（RFC7636）
## 英語
https://tools.ietf.org/html/rfc7636
## 邦訳
https://tex2e.github.io/rfc-translater/html/rfc7636.html