OmniAICreator/Qiita-1.07M huggingface dataset:
【DynamoDB】updateItemで新規項目を追加しないようにする 〜条件付き書き込み（ConditionExpression）を使って〜

DynamoDBのupdate処理で、テーブルに存在しない項目を指定すると、新規項目としてテーブルに追加されてしまいます（[UpdateItem](https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/WorkingWithItems.html#WorkingWithItems.WritingData.UpdateItem)）。
条件付き書き込み（ConditionExpression）を使用し、updateで存在しない項目を指定した時に、テーブルへの追加を防ぎ、何も変化しない状態になるよう実装します。


# 環境
- macOS
- AWS Cloud9
- Node.js 12

# AWS.DynamoDB.DocumentClient
JavascriptでDynamoDBを操作するとき、**AWS.DynamoDB**を使う方法と**AWS.DynamoDB.DocumentClient**を使う方法の2パターンがあるのですが、**AWS.DynamoDB.DocumentClient**を使う方が、DBを操作するときにデータの型を指定せずにコードを書くことができて便利なので、今回はこちらを使用しています。
**AWS.DynamoDB**との違いは、データ型の指定が不要な点と、メソッド名がやや異なる（〇〇Itemが〇〇になる）くらいで、メソッドの具体的な仕様は全く同じと考えて良さそうです（[AWS.DynamoDB.DocumentClient 公式ドキュメント](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB/DocumentClient.html)）。

# 実行コード

```javascript
const AWS = require('aws-sdk');
const DB = new AWS.DynamoDB.DocumentClient();

exports.handler = async(event, context) => {
    const dbParams = {
        TableName: "tableName",
        Key:{
            timestamp: XXXXXX                                
            message: "message"
        },
        ExpressionAttributeNames: {
            '#s': 'status'
        },
        ExpressionAttributeValues: {
            ':status': true
        },
        ReturnValues: 'ALL_NEW', 
        UpdateExpression: 'SET #s = :status',
        ConditionExpression: 'attribute_exists(#s)' // ここで条件を指定
    };
    const data = await DB.update(dbParams).promise();
    return data
}
```

ここで、

```javascript
ConditionExpression: 'attribute_exists(#s)' 
```
によって、「`timestamp`属性の値がXXXXXX、`message`属性の値が"message"である項目のうち、statusという属性を持つ項目が存在している場合」のみ、updateが実行されるようになります。
つまり、そもそも指定した`timestamp`や`message`を持つ項目が存在しなければ、何も実行されずに済むということです。

## ConditionExpression

**ConditionExpression**に使用できる演算子・関数は、
比較演算子： = | <> | < | > | <= | >= | BETWEEN | IN
論理演算子： AND | OR | NOT
関数： attribute_exists | attribute_not_exists | attribute_type | contains | begins_with | size
となっています。（[参考：公式ドキュメント](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB.html)）

各関数について簡単に説明しておくと、

- attribute_exists(path)：キーで指定した項目にpathという属性が存在する場合に実行
- attribute_not_exists(path)：キーで指定した項目にpathという属性が存在しない場合に実行
- attribute_type(path, type)：pathという属性の値がtypeで指定したデータ型であれば実行
- begins_with(path, substr)：pathという属性の値がsubstrで指定した文字列で始まる場合に実行
- contains(path, operand)：pathという属性の値がoperandを含んでいれば実行
- size(path)：pathで指定した属性のサイズを返す。例えば、`size(path) < 3`のようにして使う

となっております。
各演算子や関数に関する詳細は、[こちらのリファレンス](https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions)をご覧ください。

## 実行に失敗したとき
指定したDBの操作がConditionExpressionの制約に反し、実行されなかった場合には、**ConditionExpression**という例外が吐かれます。
例外時に何か処理を施したい場合は、try~catchで**ConditionExpression**をcatchしてあげると良さそうです。

ご参考までに。
初心者によるプログラミング学習ログ 333日目

#100日チャレンジの333日目
twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。
100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。
333日目は、
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>333日目　1.5h<br>・ポートフォリオ作成<br>モーダルウインドウに挑戦<a href="https://twitter.com/hashtag/%E6%97%A9%E8%B5%B7%E3%81%8D%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8?src=hash&amp;ref_src=twsrc%5Etfw">#早起きチャレンジ</a><a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアと繋がりたい</a><a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a></p>&mdash; ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) <a href="https://twitter.com/yudapinokio/status/1267897090870439936?ref_src=twsrc%5Etfw">June 2, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
エクセルのCSV化マクロ

- 複数ファイル同時に変換

```vb
Sub csv()
     Dim OpenFileName As Variant
     Dim target As Variant
     Dim Findpos As Long

     Application.screenUpdating = False

     OpenFileName = Application.GetOpenFilename(FileFilter:="Microsoft Excelブック,*.xls?", MultiSelect:=True)
     If IsArray(OpenFileName) Then
         For Each target In OpenFileName
            Workbooks.Open target
            
            'ドットの位置取得　ファイル名取得用
            Findpos = InStrRev(ActiveWorkbook.Name, ".")

            '元のブックと同じ階層に出力
            ActiveWorkbook.SaveAs _
            Filename:=ActiveWorkbook.Path & "\" & Left(ActiveWorkbook.Name, Findpos - 1) & ".csv", _
               FileFormat:=xlCSV
       
            ActiveWorkbook.Close SaveChanges:=False
         Next target
     Else
        MsgBox "キャンセルされました"
     End If
　　　Application.ScreenUpdating = True
End Sub
```

 - 指定フォルダ以下を再帰的に変換
 - Microsoft Scripting Runtime参照設定が必要
 https://blog.goo.ne.jp/office_y/e/da9389b88ab88de9a92150e78544313e

```vb

'再帰
Sub saiki()
    Dim objFSO As FileSystemObject
  
    Dim Selectfolder As Variant

    With Application.FileDialog(msoFileDialogFolderPicker)
        If .Show = True Then
        Selectfolder = .SelectedItems(1)
        End If
    End With
    
    
    'FileSystemObjectのインスタンスの生成
    Set objFSO = New FileSystemObject
    Call GetDirFiles(objFSO.GetFolder(Selectfolder))
    'オブジェクトの解放
    Set objFSO = Nothing
End Sub

Sub GetDirFiles(ByVal objFolder As Folder)
    Dim objFolderSub As Folder
    Dim objFile As File
    Dim Findpos As Long
    
    
    'サブフォルダの取得
    For Each objFolderSub In objFolder.SubFolders
        Call GetDirFiles(objFolderSub)
    Next
    'ファイルの取得
    For Each objFile In objFolder.Files
            Workbooks.Open objFile.Path
            
            'ドットの位置取得　ファイル名取得用
            Findpos = InStrRev(ActiveWorkbook.Name, ".")
            
                '元のブックと同じ階層に出力
                ActiveWorkbook.SaveAs _
                Filename:=ActiveWorkbook.Path & "\" & Left(ActiveWorkbook.Name, Findpos - 1) & ".csv", _
                   FileFormat:=xlCSV
          
            ActiveWorkbook.Close SaveChanges:=False
            
    Next
    'オブジェクトの解放
    Set objFolderSub = Nothing
    Set objFile = Nothing
End Sub


```
FileSystemObject
「ツール」→「参照設定」「Microsoft Scripting Runtime」にチェック。

参照設定しない場合、
Dim objFSO As Object
Set objFSO = CreateObject("Scripting.FileSystemObject")

ADODB.Stream
参照設定で、「Microsoft ActiveX Data Objects 2.8 Library」にチェック。

参照設定しない場合、
Dim adoSt As Object
Set adoSt = CreateObject(ADODB.Stream)
QUARTUSでBRAM(Block Ram)を生成する

# QUARTUSでBRAM(Block Ram)を生成する
初めてQUARTUSで回路設計をしました．Quartusは公式ドキュメントが充実してるし，日本語版もあるし素晴らしいと思ったらドキュメントが2007，2011とかで全然仕様が変わっていて却って混乱を招くように感じました．

##BRAM生成方法
QUARTUSではbramの生成に2種類方法があるようです．
一つはverilogコード内で
`(* ramstyle = "M-RAM" *) reg [7:0] b_memory[0:127]; `
のように宣言する方法．
また下記のように種類がいくつかあるようです．
M-RAM : ブロックRAM
M4K : M4KブロックRAM
M512 : M512ブロック
logic : 通常のロジックセル
等々...
(http://cpu-labs.com/verilog_synth_technic)

この種類に関しても曲者で，公式のドキュメントを参照すると，対応しているデバイスファミリとそうでないものがあります．仕様上，ここら辺を参照しながらでないと論理合成時にエラーが起きてBRAMができてくれません．(エラーメッセージは忘れました．)
![bram_info.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539495/ed9e1771-fc83-96f7-9aa5-4ce92872c9e1.png)
(https://www.intel.co.jp/content/dam/altera-www/global/ja_JP/pdfs/literature/ug/ug_ram_rom_j.pdf)



二つ目のBRAM生成の方法としてQUARTUS内の標準機能IPカタログを利用することです．
IPカタログ>Library>Basic Function > On Chip Memory>RAM:~
を選択することでUI上ではBRAMのコードを生成できるようです．
設定の際に参考にしたページ(http://japanese.sugawara-systems.com/tutorial/tutorial/sram.htm)


紛らわしいことにドキュメントが古いせいか(20200529現在)MEGAFUNCTIONWIZARDという謎の言葉が，どのドキュメントを見ても出てくるので注意．


###　反省
自分はMAX10というデバイスファミリを利用予定だったのでblock memoryが載っていることを下記公式ページで確認したうえで一つ目の方法でBRAM生成を行おうとしたのですがデバイスファミリが非対応であるというエラーメッセージが出続け発狂しそうでした．
(https://www.intel.co.jp/content/dam/www/programmable/us/en/pdfs/literature/pt/max-10-product-table.pdf) 
下記ドキュメントからはM9K式のブロックメモリを搭載していること等も確認できました．しかし以下のコマンドでも非対応ですのエラーが出るのです．
`(* ramstyle = "M9K" *) reg [7:0] b_memory[0:127]; `
(https://www.intel.co.jp/content/dam/altera-www/global/ja_JP/pdfs/literature/hb/max-10/ug_m10_memory_j.pdf)
理由はわかりませんでいたが結局IP catalogからM9K BRAMを生成できました，やはり公式以外の文献が少なくて苦労しました．

追記：HW初心者でQUARTUSも初めて触ったので，ちぐはぐなことを言っていたらご指摘ください．
よくあるset HTTP_PROXY=~に苦労した話

# はじめに
私の会社は認証プロキシを経由して外部ネットワークに接続するようになっています。
数か月ぶりにWindows10のマシンでpythonを使うことになり、コマンドプロンプトからpipを実行しようとして認証プロキシ設定にハマってしまったので、自分用メモとして残します。

# 例のコマンド
いろんなサイトに出てる例のコマンドです。

~~~
set HTTP_PROXY=http://<UserName>:<Password>@<HostName>:<PortNo> 
set HTTPS_PROXY=http://<UserName>:<Password>@<HostName>:<PortNo> 
~~~

※以下は自分の環境に置き換えが必要です。<>は不要です。
　\<UserName\>：認証プロキシのユーザー名
　\<Passwrd\>：認証プロキシのパスワード
　\<HostName\>：認証プロキシサーバのホスト名
　\<PortNo\>：認証プロキシサーバのポート番号
サイトによって=の後を""で括っているものもありますが、自分の環境では(結果的に)無くて問題ありませんでした。

このコマンドはpythonを触るたびに使っているので、余裕と思い、pipしてみると、407エラー…。括弧で括ってみたり、「http://」の部分を外してみたり、何度もプロキシサーバのアドレスの入力ミスを確認してみたりしたけど、一向に治る気配なし…・

久々に使うといいことありません。

# 原因は怠け癖
そういえば数か月前にpythonを使ったときになんかいじったな…ということを思い出しましたが、実際に何をいじったのかは思い出せず。毎度メモを取ろうと思いつつも取らない自分の怠け癖のせいで今回ダメージを喰らいました。
結局、pipにブレークポイントを張って、proxy関連のところまで戻ってみたところ、プロキシのパスワードが古いもの(私の会社では3か月に一度変更が必要)であることが発覚しました。さらにコードを辿ってみたところ、requestsのclient.pyのソースコードに直接プロキシ情報が書き込まれていました(誰かがやったみたいに書いていますが、やったのは自分)！
恐らく前回いじっていた際に、何度もプロキシ情報を入力するのが面倒でやったんだと思います。覚えていないけど。
そもそもこんなことやるべきではないんだけど、やるんだったらせめてメモとれよと思い、教訓として今回初めてQiitaに書いてみました。
大きな機能開発を細かくレビューしてもらうときに使いたいGitHubのSquash Merge

チーム開発において、大きな機能開発をいきなり大きなPull Request（以下PR）を作るとレビューが大変です。
また、レビューの段階で設計的に良くない点が見つかって大きな書き直しに迫られることもあるかと思います。
このようなことはある程度規模の大きくなってきたアプリケーションに、複数の機能を並行して開発している経験があるならイメージが付きやすいと思います。

そんな作業途中のコミットログやレビューでの指摘事項の修正が、すべてmasterブランチのコミットログに残ってしまうのは格好わるいような気がします。
そんなときに今の会社に入って運用されているマージのルールがとても良かったのでメモしておきます。

# Squash Mergeとは
GitHubには3つのマージ方法がある、ということを意識したことがある人はどれぐらいいるでしょうか？
<img width="361" alt="スクリーンショット 2020-06-03 2.16.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122390/5837c793-70d3-82b9-5fcb-b719b67a27b0.png">
▼をクリックすると、このようなメニューが開いてマージの方法を選択することができます。
そのうちの1つがSquash Mergeというもので、マージする際に途中のコミットログが消えて1つのコミットに集約されなおされます。

詳しくはこちらのGitHub公式ドキュメントやQiitaが参考になると思います。

- [プルリクエストのマージについて \- GitHub ヘルプ](https://help.github.com/ja/github/collaborating-with-issues-and-pull-requests/about-pull-request-merges)
- [GitHubの3種類のマージを理解する \- Qiita](https://qiita.com/wataash/items/ab7828a1bc452b665f94)

# ブランチの運用ルール

- master 
  - masterブランチ。本番へデプロイされる
- develop/XXXX
  - 機能ブランチ。 **masterへは「Create merge commit」** する
- work/XXXX/YYYY
  - 作業ブランチ。 develop/XXXXから派生ブランチとして切る。 **develop/XXXXへ「Squash and Merge** する

workブランチではPRを作るとき派生元の積極的にコミットを積んでいってかまいません。レビューの指摘内容とかもここで積んでいくのが主です。PRを作るとき、ベースブランチは develop/XXXX を選びます。
最終的に、developにマージするとき、「Squash and Merge」を選ぶと **developブランチの1つのコミットになります。**

developブランチはmasterへマージされる前の最終確認的な運用をします。
このブランチのPRで指摘があった場合は、別途workブランチを切り直して修正したほうがコミットログがきれいでしょう。
最後に「Create merge commit」すると、 **workブランチのPR単位のコミットログが並びます。**

コミットグラフっぽいものを書いていくとこんな感じでしょうか。

```
◯[master]
|＼
|　◯[develop/X] （まだコミットが積まれてないので本当は枝分かれしてないけどイメージ
|　|＼
|　|　◯[work/X/Y1] wip
|　|　◯ feat: 機能1のwork1
|　|　◯ fix: 機能1のレビュー指摘事項の修正
```

developブランチとworkブランチを切って、workブランチで作業します。
develop/Xブランチに向かってPRを切り、workブランチをsquashマージします。

```
◯[master]
|＼
|　◯ [develop/X] work1 (#1)

```

squashマージすると、develop/XブランチにPR1個分のコミットが1つのコミットとして積まれます。
次のworkブランチも切りましょう。

```
◯[master]
|＼
|　◯[develop/X] work1 (#1)
|　|＼
|　|　◯[work/X/Y2] feat: 機能1のwork2

```

work2のブランチもdevelop/XブランチにSquashマージします。

```
◯[master]
|＼
|　◯[develop/X]
|　|
|　◯ work1 (#1)
|　|
|　◯ work2 (#2)
```

develop/Xブランチにwork2の作業内容が1コミットにまとめられて積まれます。

```
◯[master]
|＼
|　◯[develop/X]
|　|
|　◯ work1 (#1)
|　|
|　◯ work2 (#2)
|／
◯[master] Merge pull request #3 from develop/X

```
最後にCreate commit and mergeすると、PR単位のコミットログだけが残ります！
コミットログが作業中のようなコメントではなく、PRに紐付いた1つのまとまりとしてコミットされるので、とても見通しがよいのではないでしょうか！

Squash Mergeなんて知らなかったよ、という私なので、とても感動したという話でした。

# 余談
マージ方法の選択は完全なる手動オペです。最後に選択してマージした方法が記録されるようです。
自動的に選択してもらう方法はないっぽい？なのでしばしば間違いが起こりますが、それについては特に気にしてない感じで運用してます。
うまいことやるとコミットログが綺麗になって気持ちいい、くらいですね。
間違えたからといって目くじらを立てているとつらくなってしまうかもしれません。

## 常に squash merge したいなら
>常に squash merge でいいのであれば、リポジトリの設定でそれ以外のマージ方法を無効にしてしまう方法はありますね。
> [プルリクエストにコミットの squash を設定する \- GitHub ヘルプ](https://help.github.com/ja/github/administering-a-repository/configuring-commit-squashing-for-pull-requests) 
> @unarist

補足ありがとうございました！
【開発環境としてのChromebook】Lenovo Chromebook Duetその３

# はじめに
Lenovo Chromebook Duetを使い始めて１週間が経過しました。
とても普段使いの使い勝手がよい端末だなと改めて思います。
いよいよ日本での発売が正式発表され、コアなChromebookファンだけではなく新たな客層にどのように受け入れられていくのかが今からとても楽しみです。

# Crostiniについて
現在ChromebookのLinux機能としてCrostiniが準備されています。
ここでは以下のバージョンのLinuxイメージが利用できます。
・Debian 9 strech
・Debian 10 buster
※DuetはARM64アーキテクチャ

双方利用してみましたがDuet的には一長一短あるように感じました。


|version|良い点|気になる点|
|:-:|:-:|:-:|
|strech|busterより安定している気がする|fcitx-mozcがリポジトリにないため、日本語入力環境の設定が面倒くさい|
|buster|fcitx-mozcが簡単にインストールできる|ARMに対応したパッケージがない場合がある<br>若干安定度に欠ける|

基本的にDuetはARMアーキテクチャであるため提供されているバイナリが少なめです。
Dockerはインストールできますが、起動できないイメージが多々あります。
VS CodeはOSS版かついわゆる[headmelted版](https://github.com/headmelted/codebuilds/releases)になります。Remoteなどの便利な機能が使えなかったりします。
この辺はわりきった上で開発環境を作っていく必要がありますね。

# ベンチマーク
Linuxのsysbenchを利用してCPU、メモリ、ファイルIOを計測してみました。
今回も対象は以下の端末になります。
・Lenovo Duet
・ASUS C101
・ASUS C425

## CPU
実行コマンドは以下の通りです。条件はデフォルトです。
`$>sysbench --test=cpu run`

|DUET|C101|C425|
|:-:|:-:|:-:|
|![DUET-CPU.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96398/8f1cc15d-9835-e1e8-218a-0e3b040ff018.png)|![C101-cpu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96398/03a75079-3ae4-7ca8-b6f3-1da0cc33a4ca.png)|![C425-CPU.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96398/2e410bae-fd0b-5e48-42ff-0dd19c9e3d1f.png)|
|5.6208 Sec|5.0693 Sec|10.3156 Sec|

・やはりC101の方がDUETより少し速い。
・C425が大幅に時間を要しているのはCISCとRISCの特性の違い？

## メモリ
実行コマンドは以下の通りです。条件はデフォルトです。
`$>sysbench --test=memory run`

|DUET|C101|C425|
|:-:|:-:|:-:|
|![DUET-memory.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96398/1d20fa6b-8c87-81ab-f629-073748786906.png)|![C101-memory.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96398/63b9b54c-cc0a-a462-0e1a-f8f90570be29.png)|![C425-memory.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96398/20e189b2-56a2-9c6c-aed1-c4f000dcac8d.png)|
|282.56MB/Sec|1443.38MB/Sec|3108.81MB/Sec|

・ここでもC101の方がDUETより好成績を収めています。

## ファイルIO
実行コマンドは以下の通りです。条件はシーケンシャルファイルの読み書きです。
`$>sysbench --test=fileio --file-test-mode=deqwr run`

|DUET|C101|C425|
|:-:|:-:|:-:|
|![DUET-fileio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96398/544df77b-f677-eb79-1f8b-73626cfb2181.png)|![C101-fileio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96398/08dea3ea-93d8-b9f9-9320-726f7e06a884.png)|![C425-fileio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96398/16807dab-7a2b-c3b9-04e7-f82b06abfc1f.png)|
|76.855MB/Sec|5.9379MB/Sec|36.982 MB/Sec|

・ファイルIOについてはDUETが他の２つに比べて圧勝となります。
・C101についてはそもそもディスクの空きがなくテスト終盤には限りになくディスクフルの状態となるので、別の処理が割り込んでいる可能性も否めません。（それでもDUETのファイルIOは圧倒しているかもしれません）


# 最後に
DUETとC101の処理性能的にはsysbenchを利用したベンチマークにおいてもさほど大差がなさそうなことがわかりました。
ただしストレージは容量が大きいだけではなく速度的にもDUETの方がC101よりアドバンテージがあり、開発作業の観点においては取り回しが良くなるのではないかと期待します。
Font Awesomeの色とサイズを変える方法

# プログラミングの勉強日記
2020年6月3日　Progate Lv.83
ウェブページ制作中

##Font Awesomeのサイズの変更

#####HTMLファイルにコードを書き足してサイズを変更する

| コード | 大きさ | 
|:---:|:---:|
|fa-xs | 0.75倍 |
|fa-lg | 1.33倍 |
|fa-2x | 2倍 |
|fa-3x | 3倍 |
|fa-4x | 5倍 |
|fa-5x | 7倍 |

```html:使用例
<i class="fab fa-twitter fa-xs"></i>
```

#####CSSを用いてサイズを変更する
　新しくクラスを作り、そのクラスをCSSで大きさ変更する。

```html:使用例
<i class="fab fa-twitter size"></i>
```

```css:使用例
.size{
  font-size:1.5em; /*1.5倍にする*/
}
```


##Font Awesomeの色を変更

#####CSSを用いて色を変更する
　サイズの変更と同様に、新しいクラスを作ってそのクラスをCSSで色を変更する。

```html:使用例
<i class="fab fa-twitter size"></i>
```

```css:使用例
.size{
  color:#1da1f2; /*青色にする*/
}
```
[Java] 天パの人による適当な入門 Java編 その0 (コードの決まり事)

##コードの決まり
その0は、番外編というか、なんとなくわかっていくだろうけどめっちゃ大切なことを書いています。
本編はその１からです。シリーズの説明なども書いています。
https://qiita.com/Shodai-Kurasaki/items/99cf6b0ec1a8e80640b1
###　{　}　について

```java:Sample1.java
class Sample1
{
		public static void main(String[] args)
		{
			System.out.println("Hello World!");
		}
}
```
このようにコード内には{ }が存在しています。たくさんコードをうつしていくと大体どこにあるかがわかってきますが、覚えてほしいのは、
**{と} の数が必ず同じになるようにする**
ということです(例外：文字としての { は数えません)。すぐにこのセットをたくさん使うプログラムを書くことになるとおもいますが、その時１つでも足りなければもう動きません。
**それの防止のために{ }のセットごとに階段状にしています。
tabキーを一回押すのが普通です。**

###　;　について
System.out.println("Hello World!")**;**←これ
**ひとつの文の終わりには基本的に必ずつけます。**例外は直後に{ }がついてるものです。

```
class Sample1
{ ←このように{}がうしろについてくるやつ以外は　;　をつけます。
```
これがないと動きません。
因みに、これの後ろに改行を入れないと動かないわけではなく、

```
System.out.println("Hello World!"); System.out.println("Hello World! 2");
```
としても問題ありません。ただ、基本的にはみにくくなるので改行しちゃってください。

###　ファイル名とクラス名

```java:Sample1.java
class Sample1 ←これがクラス名
{
		public static void main(String[] args)
		{
			System.out.println("Hello World!");
		}
}
```
**クラス名はファイル名と同じ**にしてください。違うものにすることもあるのですが、最初は何も考えずに同じにしてください。ちなみにファイルの拡張子は.javaで保存するようにします。

###　コメント文
プログラム内で、だんだんメモを残したいところが出てくるようになります。「この文はHello World!と表示するための文だ」などです。
そういう時は　**//**　をかいてそのあとにメモを書きます。//　のあとはプログラム実行時には完全に無視されるので好きにかいて構いません。しかし、//　はその行の//以降の内容しかメモにしません。
複数行にわたってメモをしたい場合は**/*　 */**でメモをはさみます。

```java:Sample1.java
class Sample1
{
		public static void main(String[] args)
		{
			System.out.println("Hello World!"); //ここはメモ

            /*ここも~~~~~~~~~~~~~~~~~~~~~~~~~~~
                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~メモ*/
		}
}
```

####おわり

もし訂正すべき点などありましたらご指摘よろしくお願い致します。
Windowsの仮想オーディオデバイスを使って音声認識でオンラインミーティングの自動文字起こし作成

英語でのオンラインミーティングの機会が多く、リアルタイム自動字幕生成があると便利だと考えて環境をセットアップしてみました。
使用OSはWindowsになります。

Macの方は、既に投稿された記事があるのでそちらを参照してください。
[Macの仮想音声デバイスを使って音声認識でオンラインミーティングの自動字幕作成]
(https://qiita.com/tttamaki/items/a6cf6e9d88c121a91c70)

# 概要
[otter.ai](https://otter.ai)にアカウントを作成しブラウザでアクセスすることで、オーディオ入力からリアルタイムで文字起こしをすることが可能です。
(下図参照)
<img width="429" alt="micin.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57937/3b1d361a-6053-8619-c5f9-ef2c542c616f.png">

そこで、オーディオ出力を分岐させ、片方を通常出力し、もう片方をオーディオ入力に接続することで、otter.aiの機能を使ってリアルタイム文字起こしを実現できます。(下図参照)
<img width="421" alt="audio_connection.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57937/f37f7cc2-9ce8-f377-c1b4-a306d4daaf56.png">

なお、補足情報ですがotter.aiは１カ月で600分まで無料で利用できるとのことです。
[Otter Plans](https://otter.ai/pricing)


# 準備
- 仮想オーディオミキサーVoiceMeeterBananaのインストール  
https://www.vb-audio.com/Voicemeeter/banana.htm
- 仮想オーディオデバイスVB-CABLEのインストール  
https://www.vb-audio.com/Cable/
- 自動英語字幕作成サービス otter.ai  
アカウント作成しておく

# 仮想オーディオミキサーVoice Meteer Bananaの設定
- サウンドの出力を仮想オーディオミキサーVoice Meeter Bananaに設定  
出力デバイスを下記の図のように**VoiceMeeter Input(VB-Audio VoiceMeeter VAIO）**に設定してください。  
(VoiceMeeter Aux Input(VB-Audio VoiceMeeter AUX VAIO）もあるので注意してください。)

<img width="358" alt="soundoutput.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57937/0795ca8c-abaa-6bbf-34c9-f35cc40d2d58.png">

- Voice Meeter Bananaの起動と設定  
Voice Meeter Bananaを起動して、青色の枠で囲われた左側のVIRTUAL INPUTSの設定のA1,A2を有効にしてA1とA2に出力します。
また、右上のA1,A2を選択して、A1を通常のオーディオ出力デバイス、A2をCABLE Input(VB-Audio Virtual Cable)に設定してください。(下図参照)
こうすることで、オーディオ出力を分岐させ、片方を通常出力し、もう片方を仮想オーディオデバイスVB-CABLEに接続できました。  
なお、Voice Meeter Bananaの設定が終わっても、Voice Meeter Bananaは終了させないでください。Voice Meeter Bananaを終了させてしまうとどこからも音が出力されなくなってしまいます。  
<img width="482" alt="vmbanana02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57937/23b16873-eb4c-4fa2-6b5c-24649fbc3243.png">


# 仮想音声デバイスVB-CABLEの設定
- VB-CABLEの出力設定  
上記Voice Meteer Bananaの設定で、既にVB-CABLEとオーディオ出力が接続されていますので、下図のようにサウンドの入力にCABLE Output（VB-Audio Virtual Cable）を設定することでVB-CABLEとオーディオ入力が接続されます。

<img width="371" alt="soundinput.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57937/231d0437-86bf-3146-7cb7-6af84a952f0a.png">

# otter.aiで書き起こし
otter.aiでの書き起こしは、otter.aiにブラウザでアクセスし、オーディオ入力からのリアルタイム書き起こしをスタートさせるだけで下記の図のように書き起こしが可能になります。下記は、Youtubeの動画の書き起こしをしていますが、他のアプリでも同様の処理が可能です。
<img width="1906" alt="jobs.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57937/e0e26874-8051-a4e6-e189-0b204f7613fc.png">


# 参考ページ
[Windowsで writer-app + VB-Audio Virtual Cableを使った完全自動文字起こしの方法]
(https://popcorns.jp/blog/writerapp/auto-transcription-with-windows/)
WSL デフォルトのOSの変更

VSCodeでもターミナルのシェルの選択肢にwslが増えていて感動しました。
デフォルトのosがdockerのもの(dockerが入っているわけではなかった笑)になっていたのでUbuntuに変更しました。

以下のコマンドでかなり簡単に変更できたので共有します。

![](https://pbs.twimg.com/media/EZhayIuUMAAJ-Ai?format=jpg&name=medium)
[TCPDF requires the Imagick or GD extension to handle PNG images with alpha channel. ] が出たとき

* phpでPDFを生成する機能を動かした際、白画面に表題のエラーが返ってきた。
* phpinfo() で確認したらGDライブラリが入ってなかったので入れた。

```shell
sudo apt-get install php7.3-gd
```

* インストール時、選択肢を聞かれたところはデフォルト、紫の画面は current keep 的なものを選択。


---

* おまけ
* phpのバージョン毎にgdがあったので検索してどれを使うか判断する

```
apt-cache search gd | grep php
```
AWS Cloud9の環境構築 Rubyを最新の安定版にアップデートする

Cloud9の環境でプリインストールされている「RVM」を使っています。

## 現在のRubyの最新の安定版のバージョンを確認する
公式サイトで確認できます。
[Rubyのダウンロードページ](https://www.ruby-lang.org/ja/downloads/)
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538652/d77d0f11-fbb3-3209-585d-ee98a9c6476d.png)
2020/6/3時点で最新の安定版は2.7.1でした。

## Cloud9の環境でインストールされているRubyのバージョンを確認する
listコマンドでインストールされている(切り替えることができる)Rubyのバージョンの一覧を表示します。
`rvm list`
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538652/38bdf273-3c07-0266-780f-b30bcb61298b.png)
デフォルトで入っているバージョンが2.7.1ではなかったので追加でインストールします。

## RVMでインストール可能なRubyのバージョンの一覧を表示する
`rvm list known`
インストール可能なRubyのバージョンの一覧が表示されます。
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538652/2c0d0aa7-3cc6-a9f2-a92f-5462d0cd53e8.png)
[ ]で囲まれた部分はバージョンを指定するときに省略できる部分です。
MRI の一覧にインストールしたいRubyのバージョン「2.7」が含まれていませんでした。この場合、RVMの更新が必要です。
[AWS Cloud9でRVMのアップデートをする - Qiita](https://qiita.com/mocotan/items/b14548b376a5957763ea)

メモ：
MRI (Matz’ Ruby Implementation)は最も一般的なRubyの処理系。


## バージョンをゆるく指定してRubyをインストールする
バージョン2.7をインストールする場合は以下のようにコマンドを入力します。
`rvm install 2.7`

処理が終わったらインストールができたか確認します。
`rvm list`
でインストールされているRubyのバージョンの一覧を表示します。
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538652/5cf72bee-4868-d862-d190-ee9bdaab1f9f.png)
インストール完了です。

rubyコマンドでも現在のバージョンを確認できます。
`ruby -v`
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538652/7a8cbc0f-e6cb-befd-1d09-111ebb258430.png)

## バージョンを細かく指定してRubyをインストールする
書き方はゆるく指定するときと同じです。
バージョン2.3.1をインストールする場合は以下のようにコマンドを入力します。
`rvm install 2.3.1`
エンターキーを押すとインストールが開始されます。


インストールできたか確認します。
`rvm list`
2.3.1が追加されたことが確認できます。
<img width="241" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538652/72c93533-39e3-bdeb-e839-1423baccfca4.png">

### 記号の意味
=> - current(現在使用中のRubyのバージョン)
=* - current && default(現在使用中かつデフォルトのバージョン)
 * - default(デフォルトのバージョン)

## 使用中のRubyのバージョンを切り替える
`rvm use <バージョン>`

例えば2.7.0を使用するには以下のコマンドを実行します。
`rvm use 2.7.0`

切り替わったかどうかの確認は`rvm list`です。
現在使用中のバージョンは「=>」か「=*」で選択されます。

rubyコマンドでも現在のバージョンを確認できます。
`ruby -v`

## デフォルトで使うRubyのバージョンを設定する
2.7.0をデフォルトに設定する場合のコマンド
`rvm --default use 2.7.0`

`rvm list` で確認
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538652/fe900eb5-eb3f-40f6-56d4-a2014daaca3f.png)
「*」が付いているのがデフォルトの印。


## インストールしたRubyを削除する
`rvm remove <version>`

削除するバージョンを入力してコマンドを実行します。
`rvm remove 2.3.8`

処理が終わったら
`rvm ls`
で一覧から消えていれば、削除されたことが確認できます。
「アーキテクチャ」って、何を指すの？

「アーキテクチャ」という言葉はソフトウェアエンジニアとして働いているとよく聞きますが、そういえば曖昧に、漠然としたイメージだけで捉えていたので、整理するために書きました。
# 「アーキテクチャ」という言葉は何を意味するのか？
## 辞書を参照すると
「アーキテクチャ」じゃなくて「アーキテクチャー」で入ってましたが、この記事では「アーキテクチャ」で統一します。
### 新明解国語辞典 第7版
> ①建築物。建築術。建築学。
②コンピューターシステム全体の設計思想・構成方式。

### 大辞林 第4版
> ①建築。建築学。建築様式。構造。
②構造。構成。組織。
③コンピューターを機能面から見たときの構成方式。記憶装置のアドレス方式、入出力装置の構成方式などをさす。一般に、同じアーキテクチャーのコンピューターには、ソフトウエアの互換性がある。

**「構成方式」**という言葉がどちらにも入っています。新明解の方がより具体的ですね。
少し抽象的な意味を取ると、**既に組み上がった具体的な何かではなく、その組み合わせ方、組み立て方というような抽象的なものを指す言葉**だと言えそうです。
その中でも、特定の事物としては建築やコンピュータが挙げられるようですね。
## Wikipediaを参照すると
辞書だけでなく、一般的にはどういう定義や理解なのか、という意味でWikipediaも見てみます。

[Architecture](https://en.wikipedia.org/wiki/Architecture)に対応する日本語版のWikiページは、[建築](https://ja.wikipedia.org/wiki/%E5%BB%BA%E7%AF%89)でした。
ここに記載されているのは`「人間が活動するための空間を内部に持った構造物を、計画、設計、施工そして使用するに至るまでの行為の過程全体、あるいは一部のこと」`。辞書の①の定義ですかね。

では②③の定義は、というと、[コンピュータ・アーキテクチャ](https://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF%E3%83%BB%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3)の項目にありました。`コンピュータ（特にハードウェア）における基本設計や設計思想などを意味する`とのこと。

辞書とWikipediaを合わせて考えると、まず、「アーキテクチャ」という言葉は、具体的には「建築」と「コンピュータ・アーキテクチャ」を指す。加えて、抽象的には「構成方式」を意味する言葉ということになるでしょうか。

また、[建築](https://ja.wikipedia.org/wiki/%E5%BB%BA%E7%AF%89)の項には存在しませんが、英語版の[Architecture](https://en.wikipedia.org/wiki/Architecture)の項には[Other types of architecture](https://en.wikipedia.org/wiki/Architecture#Other_types_of_architecture)という項目があり、どんなアーキテクチャがあるのかという点で参考になりそうです。ソフトウェアエンジニアに関係がありそうな項目を抜粋します。

* Business architecture（ビジネス・アーキテクチャ）
* Computer architecture（コンピュータ・アーキテクチャ）
* Enterprise architecture（エンタープライズ・アーキテクチャ）
* Network architecture（ネットワーク・アーキテクチャ）
* Software architecture（ソフトウェア・アーキテクチャ）
* System architecture（システム・アーキテクチャ）

ビジネス、コンピュータ、エンタープライズ、ネットワーク、ソフトウェア、システムと、どれもある程度複雑なものが挙がってますね。こうしたある程度複雑な物事を指す単語と組み合わせると、それらの「構成方式」を意味すると言えそうです。

## まとめ
- 「アーキテクチャ」という言葉は、具体的に「建築」や「コンピュータ・アーキテクチャ」を意味したり、抽象的に「構成方式」を意味したりする  
- ビジネス・アーキテクチャ、ソフトウェア・アーキテクチャのように、ある程度複雑な物事の構成方式を指す時に使われる

----
アーキテクチャという言葉の定義っぽい部分を整理してみました。
「アーキテクチャってそもそも何なんだっけ？」と思って、記事を探したり本を読もうとしても、「アーキテクチャとは何か？」というタイトルで中身はソフトウェア・アーキテクチャの記事だったりして、「そもそも何なんだっけ？」という点がなかなかクリアにならなかったので。

もっとシンプルに定義されてるよ、などあれば、コメントいただけると嬉しいです。
NITICNoobsによるGit/GitHub講座 第7回 〜fetch/pull〜

## 自己紹介
どうも、isso0424です。又の名をいっそうです。
高専2年生でぷよぐやみんぐを趣味でやっています。
何やってるかは以下のtwitterやGitHub見てもらえればわかると思います。
[twitter](https://twitter.com/kousou4129)
[GitHub](https://github.com/isso0424)
今回は僕がGit&GitHub解説を進めていきます。
## お目次
- fetch
- pull

## お説明
## fetch
fetchが今回最初に説明するコマンドになります。
これはリモートリポジトリから変更を引っ張ってくるコマンドです。
### 使い方
```text
git fetch [リモートリポジトリ]
```
これで終わりって言えば終わりなんですけど、具体的な例を見てみましょう。
### 例
もともと以下のようなファイルがあったとします。

```text:demo.txt
I'm genius.

yes
```

そこに、origin/masterにAさんが変更をpushします。
変更内容は以下の通りです。

```text:demo.txt
I'm genius.

no
```

そして、この状態であなたが

```text:demo.txt
I`m noob.

yes
```

という変更を加えようとします。

しかしまだ待ってください。
この状態でファイルを変更しようとすると***CONFLICT***します。
なぜなら、リモートの変更とローカルの変更が矛盾して衝突してしまうからです。
`は?CONFLICT?しらねえよ`って人は今すぐ
[第五回](https://qiita.com/ko_5/items/c0c45c80f12e0072e51e)を見てきてください。

このときに,前述のfetchを使います。
というわけで編集前に

```
git fetch origin
```
を実行します。
これによりリモートの変更がローカルに適用され、以下のようなログが出ます。

```
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Total 3 (delta 0), reused 3 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 223 bytes | 223.00 KiB/s, done.
From URL
  hoge..fuga master    -> origin/master
```
これは`リモートの変更取ってきたぞ!`というGit君からの喜びの叫びです。

さて、変更は取ってきただけでは**意味がありません**。
これをローカルに適用するためマージしましょう。

```
git merge origin/master

origin/master: remoteリポジトリ"origin"のmasterブランチ
```

これで、リモートの更新にローカルが追いついたため、pushできるようになります。
この状態で前述の変更を行い、pushすることができます。

```
git push origin master
```

これで世界に平和が訪れました。

## pull
前回と合わせてmerge,fetchについて学んできました。
毎回fetchしてからmergeしても良いのですが段々面倒になってきます。

そんなワガママな希望にも答えてくれるのがgit君です。
gitにはpullというコマンドがあります。
### 使い方
```
git pull [リモートリポジトリ名] [リモートリポジトリのブランチ名]
```
これにより現在作業しているブランチにリモートリポジトリのブランチをマージすることができます。

つまり、pullはfetchとマージを組み合わせたコマンドと考える事ができます。
### 例
先程の例を流用します。
先程の例でfetchをしたタイミングで

```
git pull origin master
```
を実行します

この時点で、origin/masterがmasterに対してマージされます。
そのため、この時点でファイルの編集に入ることができます。

あとは先程の例のマージ後と同じです。

## おまとめ
- リモートの変更内容を取ってくる時はfetch
- リモートのあるブランチの最新状態と同期させたい時はpull

次回はGitHubの**PullRequest/Issue**について説明します。

## おリンク
[1回目〜〜インストール編〜〜](https://qiita.com/Colk-tech/items/e75c61146cabc887ad29)
[2回目〜〜設定編〜〜](https://qiita.com/Colk-tech/items/f0817df7c6fdc9a7f283)
[3回目〜〜基本技能編〜〜](https://qiita.com/Colk-tech/items/8d4b28b9001b862eeb99)
[4回目〜〜平行世界編-1〜〜](https://qiita.com/Flisan/items/e6398225905e0ed906dc)
[5回目〜〜平行世界編-2〜〜](https://qiita.com/flisan/items/6afd47345fdca42f1c3c)
[6回目〜〜GitHub編〜〜](https://qiita.com/ko_5/items/c0c45c80f12e0072e51e)
7回目〜〜fetch/pull編〜〜 ←イマココ
[8回目〜〜Issue/PR編〜〜](https://qiita.com/isso0424/items/6fc09a68bf0011dfc922)

## 執筆者
- [いっそう](https://twitter.com/kousou4129)
- [こ](https://twitter.com/ko_CottonLove)
- [こるく](https://twitter.com/Colk_)
- [フライさん](https://twitter.com/loxygenK)
RedshiftのJDBCの依存関係をSBTで追加する


RedshiftにJDBCで接続したい場合、JDBCのライブラリはMavenCentralにUpされていないため、シンプルに依存関係を書くだけでは追加が出来ないため、その設定方法を説明します。

### 1. 最新バージョンの検索

[Redshift Jdbc42](https://mvnrepository.com/artifact/com.amazon.redshift/redshift-jdbc42)
から最新(or 安定バージョン)を探す

### 2. LibraryDependenciesに追加

```scala:build.sbt
libraryDependencies += "com.amazon.redshift" % "redshift-jdbc42" % "1.2.41.1065"
```
ここまでは普通に設定します。

### 3. Resolverの追加

MavenCentralにアップされていないため、このjarがデプロイされているMaven RepositoryをResolverに追加する必要があります。
RepositoryのURLは下のスクショの赤いラインのところで確認出来ます。
![Redshift_maven_repository.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12647/d3845990-492c-19b1-acaa-2cd81b003997.png)

こちらのURLをResolverとして追加します。

```scala:build.sbt
resolvers += "Mulesoft" at "https://repository.mulesoft.org/nexus/content/repositories/public/"
```

以上で直接JarをダウンロードしてこなくてもRedshiftのJDBCを依存に追加可能です。
【Unity 2019】画面が激しくテアリング（波打ち）する問題の回避方法

## Unity 2017.2 から Unity 2019.2 に乗り換えました

プレハブの編集機能が神です。
しかし、Windows ビルドでフルスクリーンモードの時に**「テアリング」**という画面が波打つ現象がやたらと気になるようになりました。

## VSync がオフだからでは？

いや、VSync は両バージョンでオフだったんですけど、Unity 2017 の時はこんなに酷くなかった。
何かあったに違いない…。

## 原因と対策

Unity 2019 からはフルスクリーンモード時のデフォルトの画面転送方式が変わったようです。
（BitBlt → DXGI flip model swapchain）

https://issuetracker.unity3d.com/issues/screen-tearing-occurs-when-running-standalone-build-in-fullscreen-mode

どうもこの DXGI flip model swapchain でテアリングが起きてしまっているようです。

![00497.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321683/dcf22e02-03b2-e051-3181-861c1bc82531.png)
Player 設定をよく見たら以前の BitBlt 方式に戻すオプションが追加されていました。
ここをオフにしたらテアリングはなくなりました。めでたしめでたし。


## VSync をオンにするのではダメ？

自分は2Dアクションゲームを作っていますが、VSync がオンだと**びびるほど操作感がもっさりします。**
もっさり感は静止画や動画の比較では伝わらないのが残念…。

今回の対策でテアリングも気にならなくなったので、個人的にはゲーム側の VSync 設定はオフ一択です。
（ただ、念のためオン・オフを切り替えるオプションは実装しようと思います）
三角関数の合成

三角関数の合成の公式が覚えられないっていう人の参考になればいいかなと思うが。
俺も覚えておらず（覚えられず）、その都度導いてるので。

三角関数の値だけは知っておこう。単位円を頭に描くのは重要だと思う。
覚えるというよりはイメージすることが大事な気がする。
次の表の値も詳しく覚えてることはなくて、$\frac{1}{\sqrt{2}}$の箇所以外で
$\frac{\sqrt{3}}{2}$と$\frac12$は単位円で長い方が$\frac{\sqrt{3}}{2}$だねくらいにしか覚えていないので（出てくる数字は5種類しかないし）。

|$\theta$|$\sin\theta$|$\cos\theta$|| $\theta$|$\sin\theta$|$\cos\theta$|
|:---:|:---:|:---:|---|:---:|:---:|:---:|
|$0$|$0$|$1$||$\pi$|0|$-1$|
|$\frac{\pi}{6}$|$\frac{1}{2}$|$\frac{\sqrt{3}}{2}$||$\frac{7\pi}{6}(=-\frac{5\pi}{6})$|$-\frac{1}{2}$|$-\frac{\sqrt{3}}{2}$|
|$\frac{\pi}{4}$|$\frac{1}{\sqrt{2}}$|$\frac{1}{\sqrt{2}}$||$\frac{5\pi}{4}(=-\frac{3\pi}{4})$|$-\frac{1}{\sqrt{2}}$|$-\frac{1}{\sqrt{2}}$|
|$\frac{\pi}{3}$|$\frac{\sqrt{3}}{2}$|$\frac{1}{2}$||$\frac{4\pi}{3}(=-\frac{2\pi}{3})$|$-\frac{\sqrt{3}}{2}$|$-\frac12$|
|$\frac{\pi}{2}$|$1$|$0$||$\frac{3\pi}{2}(=-\frac{\pi}{2})$|$-1$|$0$|
|$\frac{2\pi}{3}$|$\frac{\sqrt{3}}{2}$|$-\frac{1}{2}$||$\frac{5\pi}{3}(=-\frac{\pi}{3})$|$-\frac{\sqrt{3}}{2}$|$\frac{1}{2}$|
|$\frac{3\pi}{4}$|$\frac{1}{\sqrt{2}}$|$-\frac{1}{\sqrt{2}}$||$\frac{7\pi}{4}(=-\frac{\pi}{4})$|$-\frac{1}{\sqrt{2}}$|$\frac{1}{\sqrt{2}}$|
|$\frac{5\pi}{6}$|$\frac{1}{2}$|$-\frac{\sqrt{3}}{2}$||$\frac{11\pi}{6}(=-\frac{\pi}{6})$|$-\frac{1}{2}$|$\frac{\sqrt{3}}{2}$|

例えば、$\sin x +\cos x$を考えると、見方によれば(無理やりだけど)、
**加法定理を使える形に**持っていけば、

```math
\begin{align*}
\sin x +\cos x &= \sqrt{2} \Big(\sin x\cdot \frac{1}{\sqrt{2}} +\cos x\cdot \frac{1}{\sqrt{2}}\Big) \\
&= \sqrt{2}(\sin x \cos \frac{\pi}{4} + \cos x\sin\frac{\pi}{4})\\
&= \sqrt{2}\sin (x+\frac{\pi}{4})
\end{align*}
```
のように変形することができるがこれが三角関数の合成。上のは$\sin$の加法定理を意識したから、$\sin \cos + \cos \sin$の形にした。式中の$\sqrt{2}$で括りだしている部分はその結果出てくる数字の2乗和が1になるように調整しているだけ。$\boldsymbol{\sin^2 x + \cos^2 x=1}$という性質あるでしょ。それはつかえるようにしないと。
だからこれは別にこれ一つが答えではなくて、次のように$\cos$の加法定理を軸にしてもよい。

```math
\begin{align}
\sin x +\cos x &= 
\sqrt{2} \Big(\cos x \cdot \frac{1}{\sqrt{2}} - \sin x\cdot  \Big(-\frac{1}{\sqrt{2}}\Big)\Big) \\
&= \sqrt{2} \Big(\cos x \cos \Big(-\frac{\pi}{4}\Big)
- \sin x \sin \Big(-\frac{\pi}{4}\Big)\Big) \\
&= \sqrt{2} \cos \Big(x - \frac{\pi}{4}\Big)
\end{align}
```
こちらは$\cos$の加法定理を意識して合成した例。この2つの結果を見比べてみると多分新しい公式得られていて、$\sin x = \cos (x-\pi/2)$ってのが成り立つんじゃないかな、この公式覚えてないから合ってるかわからんけど。

このように合成で得られる結果は一意に定まらない。コツとしては見えない部分に先ほどの表中にある同じ行の三角関数の値を入れてみて加法定理使えないかなぁと考えてみるとやりやすいのかもしれない（俺は公式覚えられないから、いつもこうやってる）。大体表中の値しか使えないし、それ以外でも頭使えるようになるし。
Web ComponentsでTheme Providerを実装する

Web ComponentsでReactの`ThemeProvider`のようなものを実装したい。

[@ionic/coreのtheme](https://github.com/ionic-team/ionic/blob/master/core/src/utils/theme.ts)の実装を読んだら感銘を受けたのでメモ

## まとめ

- Element.closest(selector)でDOM treeを逆向きに検索する
- 実装に困ったら[@ionic/core](https://github.com/ionic-team/ionic/tree/master/core)を読む


## 実装

### `theme-provider`

attribute変更の際にthemeの変更を適用したいという要求が無いなら、空のコンポーネントで良い

``` html
<template id="theme_provider">
  <slot></slot>
</template>
```

``` js
customElements.define(
  "theme-provider",
  class extends HTMLElement {
    constructor() {
      super();
      const template = document.getElementById("theme-provider");
      this.template = template.content;

      const shadowRoot = this.attachShadow({
        mode: "open"
      }).appendChild(template.content.cloneNode(true));
    }
  }
);
```

### 子コンポーネント

子コンポーネントは何でもいいですが、各テーマのstylesを用意しておきます

``` html
<template id="heading_level1">
  <style>
    h1.default {
      color: #333;
    }

    h1.christmas {
      color: green;
    }
  </style>
  <h1>
    <slot></slot>
  </h1>
</template>
```

``` js

customElements.define(
  "heading-level1",
  class extends HTMLElement {
    constructor() {
      super();
      const template = document.getElementById("heading_level1");
      this.template = template.content;

      const shadowRoot = this.attachShadow({
        mode: "open"
      }).appendChild(template.content.cloneNode(true));

      // theme-providerを探してthemeを登録する
      this.themeElement = this.closest('theme-provider');
      const theme = this.themeElement ? themeElement.getAttribute('theme') : '';
      this.shadowRoot.querySelector("h1").className = theme;
    }
  }
);
```

### DOMツリーを親の方向に検索してThemeを取得する

DOMツリーの親方向に探索する場合は`Element.closest(selector)`

``` js
const theme = this.closest('theme-provider').getAttribute('theme');
this.shadowRoot.querySelector("h1").className = theme;
```

classNameをプログラマブルにしたい場合は[clsx](https://www.npmjs.com/package/clsx)とかを使うと良いと思う

### `theme-provider`が変更された場合に反映したい

動的にthemeを入れ替える必要がある場合は、その変更を子コンポーネントに通知したい。

`theme-provider`側：変更を外に通知するために`CustomEvent`を使う必要がある。

子コンポーネント側：初回のtheme取得と同じく、親Nodeを遡って`theme-provider`を見つけ、event listenerを登録しておく。

というdemoは[Codepen](https://codepen.io/nekobato/pen/xxZxKVE)に置きました。
MySQL 5.7で文字列末尾から特定の文字列が出現するまでの文字列を抽出する

## TL;DR
とある案件で、`URLを含む本文`から`本文末尾に出現するURL`のみ抽出して本文とURLを分割してほしいと依頼が来たので、`文字列末尾から特定の文字列が出現するまでの文字列を抽出するクエリ`を作成しました。

```sql
SELECT RIGHT(body, INSTR(REVERSE(body), REVERSE('http://')) + CHAR_LENGTH('http://') - 1) AS url FROM articles;
```


## 環境
- MySQL 5.7


## 使用する関数
|名前|説明|
|:---|:---|
|INSTR|部分文字列が最初に出現する位置のインデックスを返します|
|REVERSE|文字列内の文字を逆順に並べ替えます|
|RIGHT|右端から指定された数の文字を返します|

引用元: [MySQL 5.6 リファレンスマニュアル  /  関数と演算子  /  文字列関数][functions] [^1]


## クエリ解説
### サンプルのテーブル
```
mysql> SELECT * FROM articles;
+----+---------------------------------------------------+
| id | body                                              |
+----+---------------------------------------------------+
|  1 | 本文http://example.com 本文http://example.com      |
+----+---------------------------------------------------+
1 row in set (0.00 sec)
```

### 検索したい文字列が1文字の場合
1. REVERSE関数で`本文の文字列`を逆順に並べ替え、INSTR関数で`検索文字列`が最初に出現する位置のインデックスを取得
2. `1.で取得したインデックス`＝`本文の文字列末尾から検索文字列が出現するまでの文字列の長さ`になるので、そのままRIGHT関数に渡す

```
mysql> SELECT INSTR(REVERSE(body), 'h') AS `index` FROM articles;
+-------+
| index |
+-------+
|    18 |
+-------+
1 row in set (0.00 sec)

mysql> SELECT RIGHT(body, INSTR(REVERSE(body), 'h')) AS url FROM articles;
+--------------------+
| url                |
+--------------------+
| http://example.com |
+--------------------+
1 row in set (0.01 sec)
```

### 検索したい文字列が2文字以上の場合
1. REVERSE関数で`本文の文字列`と`検索したい文字列`を逆順に並べ替え、INSTR関数で`検索文字列`が最初に出現する位置のインデックスを取得
2. `1.で取得したインデックス`＝`本文の文字列末尾から検索文字列の末尾が出現するまでの文字列の長さ`になるので、`検索文字列の長さ`を足して1引いてからRIGHT関数に渡す

```
mysql> SELECT INSTR(REVERSE(body), REVERSE('http://')) AS `index` FROM articles;
+-------+
| index |
+-------+
|    12 |
+-------+
1 row in set (0.00 sec)

mysql> SELECT RIGHT(body, INSTR(REVERSE(body), REVERSE('http://')) + CHAR_LENGTH('http://') - 1) AS url FROM articles;
+--------------------+
| url                |
+--------------------+
| http://example.com |
+--------------------+
1 row in set (0.01 sec)
```

## まとめ
実際に使ったときはCASE式とサブクエリを使って、本文とURLを分割して別々のカラムに保存しました。
開発や運用の都合で、ときどきこの手の泥臭いクエリが必要になることがあるので、文字列操作の関数は一通り目を通しておこうと思いました。


## 追記(2020/06/03)
とある先輩エンジニアに今回のケースならSUBSTRING_INDEX関数で取得できるとアドバイスを貰ったので追記します。

```sql
SELECT CONCAT('http://', SUBSTRING_INDEX(body, 'http://', -1)) AS url FROM articles;
```

SUBSTRING_INDEX関数は区切り文字が指定された回数出現する前の部分文字列を返しますが、第3引数に負の数を指定すると文字列の末尾から検索します。

```
mysql> SELECT SUBSTRING_INDEX(body, 'http://', -1) FROM articles;
+--------------------------------------+
| SUBSTRING_INDEX(body, 'http://', -1) |
+--------------------------------------+
| example.com                          |
+--------------------------------------+
1 row in set (0.00 sec)
```

あとはCONCAT関数で区切り文字列と結合するだけですね。

```
mysql> SELECT CONCAT('http://', SUBSTRING_INDEX(body, 'http://', -1)) AS url FROM articles;
+--------------------+
| url                |
+--------------------+
| http://example.com |
+--------------------+
1 row in set (0.01 sec)
```



[functions]:https://dev.mysql.com/doc/refman/5.6/ja/string-functions.html
[^1]: MySQL 5.7のリファレンスは日本語化されていなかったので5.6にしておきました。
【AWS SAP】WorkSpacesとAppStream 2.0の違い【頻出】

##AWS SAP取得に向けて勉強する中で覚えてよかったもの 第3弾
以下の違いについて覚えておいて損はありません。

・WorkSpaces
・AppStream 2.0

##WorkSpacesとは
デスクトップを提供するサービス。

(公式サイトより引用)
> Amazon WorkSpaces は、マネージド型でセキュアなサービスとしてのデスクトップ (DaaS) ソリューションです。Amazon WorkSpaces を使うと、Windows または Linux のデスクトップが数分でセットアップでき、すばやくスケールすることで世界中のたくさんの従業員にデスクトップを提供できます。自分が起動した WorkSpaces に対してのみ、月単位または時間単位のいずれかで支払うことができるため、従来のデスクトップやオンプレミスの VDI ソリューションに比べて、費用を削減できます。Amazon WorkSpaces では、ハードウェアのインベントリ、OS バージョンとパッチ、仮想デスクトップインフラストラクチャ (VDI) の複雑な管理作業をなくして、デスクトップ提供戦略を簡素化します。Amazon WorkSpaces では、高速で応答性の高いデスクトップをユーザーが選択し、サポートされているデバイスを使用していつでも、どこからでもアクセスできます。

##AppStream 2.0とは
Windowsで動くデスクトップのアプリケーションを任意のコンピュータのブラウザに配信する。

(公式サイトより引用)
> Amazon AppStream 2.0 は、完全マネージド型のアプリケーションストリーミングサービスです。デスクトップアプリケーションを AppStream 2.0 で集中管理し、任意のコンピュータのブラウザへ安全に配信できます。ユーザー数無制限で世界中に簡単にスケールでき、ハードウェアやインフラストラクチャの調達、プロビジョニング、運用は不要です。AppStream 2.0 は AWS 上に構築されているため、最も厳しいセキュリティが要求される企業向けに設計されたデータセンターとネットワークアーキテクチャを利用できます。アプリケーションは特定のユースケース向けに最適化された仮想マシン (VM) で実行され、それぞれのストリーミングセッションがネットワーク条件に合わせて自動的に調整されるため、GPU 負荷の高い 3D デザインやエンジニアリングのようなアプリケーションであっても、各ユーザーが応答性の高いスムーズな操作を行えます。

##WorkSpacesとAppStream 2.0の違いは？

デスクトップ環境を提供したい場合はWorkSpaces。

特定のアプリケーションの実行環境が必要でデスクトップ環境を提供しないという場合は、AppStream 2.0 を利用する。
画像の中心を基準に表示させる方法【CSS】

#Webサイトに画像を載せるときに、画像の中心を基準に表示させる方法

Webサイトを作成するときに、指定した要素の大きさと画像の大きさが異なる場合、普通は

```css:css
  background-size: cover;
```
を使って画像の大きさを要素の大きさに揃えるんですけど、これだと画像の表示される部分が左にずれる。
じゃあ画像の中心を基準にサイト上に表示させたいときはどうしたら良いか。それは次のように書けばよい。

```css:css
  background-position: center center;
```

こう書くことで画像の中心を基準に表示させることができる。1つ目のcenterが左右を表し、2つ目のcenterが上下を表している。
これは、

```css:css
  background-position: center;
```
と省略して書くことも可能。

参考リンク：[background-positionについて](http://www.tohoho-web.com/css/prop/background-position.htm)
[React Practice] External API communication with React

# [React Practice] External API communication with React

## Data download & construction

```bash
$ git clone https://github.com/dai-570415/react-getapi.git

$ cd react-getapi

$ npm install

$ npm start
```

## Put each API key in "YourKey"

```js
// components/News/Index.js
// NEWS API(https://newsapi.org/) 
const URL = `https://newsapi.org/v2/top-headlines?country=jp&apiKey=YourKey`;
```

```js
// components/Gourmet/Index.js
// ぐるなび API(https://api.gnavi.co.jp/api/)
const keyId = 'YourKey';
```
PHP環境設定 

#環境の準備
下記サイトから、ウェブサーバーをダウンロードする。
https://bitnami.com/stacks
Mac -> MAMP
Windows -> WAMP

インストール時にMySQLのパスワードを聞かれるが、一旦適当に入力でOK。
インストール完了画面の[Open Application Folder]をクリックする。
[Application Folder] > apache2 > htdocs > ココにindex.phpを配置することで、このファイルを動作させることができる。

#PHP設定

これを設定することで、ウェブサーバーに設置した、phpファイルを変更した際に、
即時に変更が反映されることができる。

キャッシュを無効にするには、下記iniファイルを開いて、opcache.enable=0に変更する。
[Application Folder] > php > etc > ini.php

#PHP基本
###変数とは
- あらゆるデータを格納できる箱のようなもの
- データを何度も入れ替えできる
- 必ず利用前に宣言する必要はない
- 変数名の大文字小文字は区別される
- 変数にアクセスできる範囲が決まっている

###変数宣言のルール
先頭は$を付ける。
変数名の先頭は、_(アンダースコア)または文字
セミコロンで終了する。
(例)
```$hoge;```

初期値を入れる場合
```$hoge = 'abc';```



###定数とは
- 型や配列を格納できる箱のようなもの
- 中に格納したデータは固定化（入れ替えできない）
- 利用する前に宣言が必要
- 定数名はすべて大文字で書く
- PHPのどこからでもアクセスできる
Reactの人気を超えたASP.NET Coreとは？

## 2020 Web Developer Survey
StackOverflowの[2020 Web Developer Survey](https://insights.stackoverflow.com/survey/2020)の「最も愛されるWebフレームワーク」分野で、ASP.NETがReactを超えて１位になりました。なんとなく聞いたことはあるのですが、実際にどのようなものかを調べてみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375274/e3db76eb-19f1-93f4-1aae-cef93874adac.png)

**ASP.NETを普段から使ってるわけではないので、間違った内容があればご訂正して頂ければと思います。**


## Fullstack Web Framework
ASP.NETは、**Microsoftが開発した開発者プラットフォーム**で、C#、F#、Visual Basicを利用して様々なアプリケーションを開発できるようにしたものです。

iOS・AndroidアプリをXamarinで開発でき、*IoT・デスクトップ・機械学習*なども作れます。
その中でもASP.NET Coreは、Webの**フロントエンド・バックエンド開発**が可能です。

## 使用している会社
ASP.NET Coreは、テンセントやStackOverflow、GoDaddyなど、巨大なWebサイトで使用されてます。
理由としては、エンタープライズが使いやすい仕様であることと、**パフォーマンスがとても早い**からです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375274/f860b4ed-02b1-e962-fc83-fb75c15e8847.png)

Node.jsやJavaのバックエンドが一秒に80万回程度のリクエストを処理できる反面、**.NETでは約700万（7.33 million）リクエスト**を処理できます。なので、高いパフォーマンスが求められるサービスに適していると思われます。

## Blazor
Reactを超えた人気を誇るようになった理由としては、**Blazor**が挙げられると思われます。
Blazorを使えば、フロントエンドをC#でビルドできます。


```cshtml
<h1>counter</h1>
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
  private int currentCount = 0;
  private void IncrementCount() 
  {
    currentCount++;
  }
}
```

Node.jsが人気になった理由同様、**バックエンドもフロントエンドもC#で開発できるのは大きいメリット**です。コードはC#で書き、コンパイルはWeb Assemblyを利用、必要なJSのAPIやライブラリーはJavaScript Interopで呼び出せます。

また、Blazorを利用すれば、**クライアントロジックをサーバーで処理**することもできます。つまり、クライアントサイドとサーバーサイドのインタラクティブさのみならず、SSRレベルのセキュリティも持てるようになります。

## JavaScriptのエコシステムとの差
ASP.NET CoreはJS同様、同じ言語でフルスタックな開発ができるのにメリットがありますが、JSのエコシステムとの決定的な差は、**JSは開発者の力量に頼りがち**という点です。

JSの場合、**開発環境の構築のために様々なオープンソースライブラリーをダウンロードし、自分なりの設定**をしていかなければなりません。ASP.NET CoreはMSが多くのリソースを投資して誕生した**「ビジネスプロダクト」**なので、完成度が高く、すべてがフレームワーク内に用意されています。

[チュートリアル](https://dotnet.microsoft.com/learn/aspnet/hello-world-tutorial/intro)

## 最後に
いかがだったでしょうか。*普段からC#を触ってらっしゃる方々には嬉しい調査結果*かもしれません。
ちなみに2019年の同じ調査では、ASP.NETは5位を記録していたので、**早いスピードで人気を獲得**しているのがわかりますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375274/056a2f08-1f37-8dfb-05ed-a790e10bf3d8.png)

それにしても、最近コードエディターはVS Code、コードベースはGithub、フレームワークはASP.NETと、**Microsoftの進撃**が止まらないですね…


**追記（20/06/04）**
@unsignedint さんから補足頂いたので、本文に追記させてもらいました。
>表題では合っていますが、文中のASP.NETはASP.NET Coreですね。この両者、かなり別物ですので……。グラフにも出ていますが、ASP.NETの方は環境を選ぶこともあるのか、13位にとどまっています。ASP.NET Coreはプラットフォームの自由度が非常に高くなったので一定のブレイクが見られたということかと思います。

>この結果は非常に面白いと思います。というのも、Blazorは比較的新しい技術（サーバー版は去年の後半、WebAssemblyは今年の5月にGM）であり、中にはプレビュー版を試用していた回答者もいるかと思いますが、Blazorがどの程度の影響を与えたのかは興味深いところです。（ASP.NET Core自体は、Blazorを使わなくてもウェブアプリが開発できますので……現時点ではまだそちらが主流かと思います。）

>また、ASP.NET Coreの人気度が高い一方、Wantedの方ではReactが依然と高くなっているため、使用者からみてASP.NET Coreの満足度が高い一方、他のフレームワークの使用者から引き寄せる力がまだまだ低い、ということなのではないかと解釈しています。

>先月、Blazorサーバー・WebAssemblyが出揃い、また、今後のリリースでパフォーマンスの向上等が予定されていることを考えると、今後、更に飛躍する可能性が高そうですし、また、Wantedの方も伸びていくかもしれません。（伸びればいいな、と思っています。Blazor非常に快適なので……。）

> @unsignedint
サイトの右側にできる余白を消す方法【HTML/CSS】

#サイトを作っているときに画面右側にできる謎の余白を消したい

```html:html
  <body>
    <div id="wrapper">この中に全てのソースコードをつっこむ</div>
  </body>
```

```css:css
  #wrapper {
    width:100%;
    overflow:hidden;
  }
```


と書くことでサイトの右端にできていた謎の余白を消すことができた。

参考リンク：[サイトの右にできる余白の解決方法がわかりません](https://teratail.com/questions/55255)
【AWS】LambdaとSNSでスマホにSMSを送る

## 概要

- 電話番号でメッセージを送るSMSを使いたいなと思って調べてみたらAmazonSNSで実現できると分かったので試してみました
- API Gateway - Lambda - SNS を連携させてAPI化させてみました
- 当然ですが指定した電話番号に本当にSMSを送れてしまうので、**悪用しない/されないようにご注意ください**
- ちなみに日本の場合は一通辺り$0.07451のようです
    - https://aws.amazon.com/jp/sns/sms-pricing/

## 構成

- 今回作る構成です

<img width="799" alt="スクリーンショット 2020-06-03 0.02.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175213/5ad3dcea-7e4c-eb69-79ef-31809ef3d46e.png">

## 雛形生成

- 今回はServerlessFrameworkを使います
- Lambdaのコードだけ見たい人はスキップしてください

```zsh
mkdir sms-sample
cd sms-sample
sls create -t aws-nodejs-typescript
npm i
```

- 一式作成できました

```
tree -I node_modules
.
├── handler.ts
├── package-lock.json
├── package.json
├── serverless.yml
├── tsconfig.json
├── vscode
│   └── launch.json
└── webpack.config.js
```

## Lambda関数の作成

- AWS SDKを使うのでインストールしておきます

```zsh
npm i -D aws-sdk
```

- handler.tsを修正します
    - Lambda関数の中でSNSのpublishを呼んでSMSを送信します
    - 電話番号とメッセージはパラメータとして受け取ります

```ts:handler.ts
import { SNS } from 'aws-sdk';
import { APIGatewayProxyHandler } from 'aws-lambda';

const sns = new SNS();

export const sendSMS: APIGatewayProxyHandler = async event => {
  const body = JSON.parse(event.body);
  const { message, phoneNumber } = body;
  try {
    // 電話番号とメッセージを設定
    const params: SNS.Types.PublishInput = {
      // 先頭の0を削って+81をつける
      PhoneNumber: phoneNumber.replace(/^0*/, '+81'),
      Message: message,
    };
    // メッセージを送信
    await sns.publish(params).promise();
    return { statusCode: 200, body: 'success' };
  } catch (e) {
    console.log(e);
    return { statusCode: 500, body: JSON.stringify(e) };
  }
};
```

## Serverless.ymlの設定

- API Gatewayの設定やiamの設定などしていきます

```yml:serverless.yml
service:
  name: sms-sample
custom:
  webpack:
    webpackConfig: ./webpack.config.js
    includeModules: true
plugins:
  - serverless-webpack
provider:
  name: aws
  runtime: nodejs12.x
  region: ap-northeast-1
  apiGateway:
    minimumCompressionSize: 1024
  environment:
    AWS_NODEJS_CONNECTION_REUSE_ENABLED: 1
  # iamの設定
  iamRoleStatements:
    - Effect: Allow
      Action:
        - 'sns:Publish' # SNSのPublishの権限を付与
      Resource: '*'
functions:
  sendSMS:
    handler: handler.sendSMS
    # API Gatewayの設定(POST:/sendSMS)
    events:
      - http:
          method: post
          path: sendSMS
```

## 動作確認

- デプロイします

```zsh
sls deploy
```

- エンドポイントにアクセスしてみます

<img width="831" alt="スクリーンショット 2020-06-03 0.24.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175213/d3c97ef0-90bb-68eb-382b-e2efd3af5038.png">

- ちゃんと届きました！

![Screenshot_20200603-002459.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175213/19d4294b-b7cf-97e8-6b1b-033c8482f2ec.png)

## まとめ

- 思ったよりも簡単にSMS送信を実現できました
- ServerlessFrameworkでどこでもすぐに再現できるのがいいですね
Django で factory_boy のシード値を固定する

## 結論
`TestCase` を継承したカスタムクラスを作成して `setUp()` にシード値を設定する。
各アプリではカスタムクラスを継承してテストを書く。

## 背景
Djangoで `factory_boy` を使う際に、テストの再現性を担保したかった。

## 手順

### 環境

```text
factory-boy==2.12.0
```

### `BaseTestCase` クラスの定義

シード値を固定する `BaseTestCase` クラスを定義する。
自分は `base` アプリケーションを作成して、抽象クラスはそこに書くようにしている。

```python:./base/tests.py
from django.test import TestCase
import factory.random


class BaseTestCase(TestCase):
    def setUp(self):
        factory.random.reseed_random(0)
        return super().setUp()
```



### 個別の `TestCase` クラスの継承

`BaseTestCase` クラスを継承して各テストケースを定義していく。

```python:./user/tests.py
from base.tests import BaseTestCase

from .models import User
from .factories import UserFactory


class UserTestCase(BaseTestCase):
    def test_create_user(self):
        user = UserFactory()
        actual_user = User.objects.get(pk=user.pk)
        self.assertEqual(user, actual_user)
```

もちろん `setUp()` を定義する際は親クラスのメソッドも呼んでおく。

```python:./user/tests.py
class UserTestCase(BaseTestCase):
    def setUp(self):
        super().setUp()
        print("initialize")

    def test_create_user(self):
        user = UserFactory()
        actual_user = User.objects.get(pk=user.pk)
        self.assertEqual(user, actual_user)
```

## まとめ
シード値の固定により再現性を担保した状態でテストが実行できるようになった。
Djangoを前提の記事だが、Djangoに限らず通用するはず。