OmniAICreator/Qiita-1.07M huggingface dataset:
Reduxt-toolkitで`A non-serializable value was detected in the state`

# 環境
React-toolkit 1.4.0

# 原因
公式サイトに書いてあるけど、ReduxにSerializable不可能なclassを渡すと該当エラーが出る。
今回ひっかかった例だと他言語の感覚でclassをnewして渡すとNG。
いわゆるオブジェクトリテラル(`{}`)で表現できるものを渡さなければならないみたい。

## OK
``` typescript
type A = {
    member: string
}
const a: A = {member: 'member'};    
```

## NG
``` typescript
class A {
    constructor(public member: string) {}
}
const a = new A("member");
```


参考
https://redux.js.org/style-guide/style-guide#do-not-put-non-serializable-values-in-state-or-actions
[herokuデプロイ手順①]heroku CLIのインストールからログインまで

## はじめに
個人アプリ開発において本番環境を**heroku**に指定し、デプロイを行いました。
公式リファレンスを参考にするとすんなりデプロイできたので、これから段階ごとに分けてアウトプットします。


## 環境
Rails 5.0系
macOS catalina 10.15
herokuアカウント作成済み（まだ作成していない方は下記URLからそちらを先にお願いします）
https://dashboard.heroku.com/apps

## heroku CLIのインストール
まずホームディレクトリにて**heroku CLI(コマンドラインインターフェース）**をインストールします。

```ターミナル.
$ brew install heroku/brew/heroku
```

インストールしたらターミナルでherokuコマンドを使用できます。

## herokuにログイン
次に下記コマンドを実行してheroku CLIにログインします。herokuアカウントのメールアドレスとパスワードを使用してログインしましょう。

```ターミナル.
$ heroku: Enter your Heroku credentials
Email: schneems@example.com
Password:
Could not find an existing public key.
Would you like to generate one? [Yn]
Generating new SSH public key.
Uploading ssh public key /Users/adam/.ssh/id_rsa.pub
```

## 最後に
次回は引き続きherokuデプロイ編②をアウトプットしていくので参考にして下さい。
https://qiita.com/nkekisasa222/items/6954937cc5c968909401
Rubyでちょっとずつポーカーを実装する その3

#前回の記事
[その1](https://qiita.com/paraizo2424/items/23f5ab031dbda184ce9d)→[その2](https://qiita.com/paraizo2424/items/10c4a2576a53e655aef9)

#役の判定
役は、
ロイヤルストレート＞ストレートフラッシュ＞フォーカード＞フルハウス＞フラッシュ＞ストレート＞スリーカード＞ツーペア＞ワンペア＞ハイカード（役なし、通称豚）
の順番の強さになる。
例えば、役がフォーカードだった場合、それ以下の役（スリーカード、ワンペア）は判定する必要がない。
なので、強い役から判定していく。

###弱い役から判定する方がいいのか??
[役の確率](https://ja.wikipedia.org/wiki/%E3%83%9D%E3%83%BC%E3%82%AB%E3%83%BC%E3%83%BB%E3%83%8F%E3%83%B3%E3%83%89%E3%81%AE%E4%B8%80%E8%A6%A7#5%E6%9E%9A%E3%81%AE%E3%81%A8%E3%81%8D%E3%81%AE%E7%A2%BA%E7%8E%87)
ワンペアかハイカードが出る確率を合わせると約92%になる。"動くこと重視"なので後に検討しよう。


#役を判定するのは誰の振る舞いか??
麻雀なら自分で役の判定と点数計算するので、ポーカーも自分で役を判定するとしよう。

#その3流れ
プレイヤーは自分の役が何か判定する player.judge
(手札がすべて同じマークかどうか）same_suit?
（手札が並びになっているか）count_up?
（手札にペア、スリーカード、フォーカードがいくつあるか)count_pair
プレイヤーは自分の役を発表する　player.show
ゲーム終了

#コード
https://github.com/paraizo2424/poker_game/commit/0342813bd1fccd3183e1111ad48bf9b00106e2ef

#次回
[その4](https://qiita.com/paraizo2424/items/4806a724879b0cc8d6c5)
Python 3エンジニア認定データ分析試験（2020年6月8日から開催した奴）

2020年6月20日(土)にPython 3エンジニア認定データ分析試験を受けました。
一応、合格したので記事を書いておきます。
少しでも次受ける方の参考になれば幸いです。

## 受験理由
■１ Pythonを用いたデータ分析手法に興味があったから。
■２ 業務でPython（データ分析）を使う可能性があったから。

## 感想
■１ 比較的簡単です。[プライム・ストラテジーの模擬試験](https://study.prime-strategy.co.jp/)の方が難しいですので、この模擬試験で「なぜ正解か」「なぜ間違っているか」を完璧に理解できれば、おそらく合格すると思います。とはいえ、主教材『Pythonによるあたらしいデータ分析の教科書（寺田ら, 2018, 翔泳社）』は一度読むべきです。
■２ 主教材の全ページからでるわけではありません（5章はでません）。[Python3 エンジニア認定データ分析試験の公式ページ](https://www.pythonic-exam.com/exam/analyist)から試験範囲を確認することをお勧めします。
■３ 試験時に電卓、ペンは使えませんが、計算問題が２、３題でます。
	
## 学習教材
■１ Pythonによるあたらしいデータ分析の教科書（寺田ら, 2018, 翔泳社）
・・・ 主教材：ここから問題がでるようですので、これで学習しましょう。
■２ [プライム・ストラテジーの模擬試験](https://study.prime-strategy.co.jp/)
・・・ 私の時は本番の試験より難しかった：自分の時は模擬テストが２つだけしかありませんでしたが、2020年7月19日時点で模擬テストが３つになっています。模擬試験を完璧に理解してから本番に臨むのがよいです。

## 学習方法
■１ 主教材を読む。
・・・一度読み、そのあと、苦手な箇所を試験直前まで何度も読みました。
■２ プライム・ストラテジーの模擬試験を解く
・・・問題を印刷して、紙になぜ正解か、なぜ間違えたかを書き込みました。試験前日と、当日にも読み返しました。

## 反省点
■１ 特になし。

## 試験前にやっておいてよかったこと等
■１ 試験直前に模擬試験でカバーしていない範囲を、チェックしておいたこと。
正規表現入門 第一回 オプション

# 学習する契機
1. 正規表現が苦手で、何かある都度、Google検索してサンプルをコピーして使用している自分が嫌になった。
2. 本記事では第一弾として、正規表現のオプションについて記載する

# 正規表現とは
- 一言で言うならば、「文字列をパターンで表すルール」です。

# オプション
- JavaScriptでは、以下の検索オプションが利用可能です。

| オプション | 意味 |
|:------------------:|:------------------|
| g | グロバール検索 |
| i | 大文字と小文字を区別しない検索 |
| m | 複数行検索 |
| y | 特定の位置からの検索 |

## オプションの使用例
1. オプション指定なし
2. gオプション指定
3. iオプション指定
4. mオプション指定
5. yオプション指定
6. オプションの複数指定

``` 1-2(オプション指定なし).js
console.log('ABC_ABC_ABC'.match(/ABC/));
```
> 実行結果
[ 'ABC', index: 0, input: 'ABC_ABC_ABC', groups: undefined ]

``` 1-2(gオプション指定).js
console.log('ABC_ABC_ABC'.match(/ABC/g));
```
> 実行結果
[ 'ABC', 'ABC', 'ABC' ]

``` 1-2(iオプション).js
console.log('ABC'.match(/abc/));
console.log('ABC'.match(/abc/i));
```
> 実行結果
null
[ 'ABC', index: 0, input: 'ABC', groups: undefined ]

``` 1-2(mオプション).js
console.log("ABC\nDEF".match(/^D/));
console.log("ABC\nDEF".match(/^D/m));
```
> 実行結果
null
[ 'D', index: 4, input: 'ABC\nDEF', groups: undefined ]

``` 1-2(yオプション).js
var exp = /ABC/y;
console.log(exp.lastIndex);
console.log(exp.test('ABC'));

exp.lastIndex = 1;
console.log(exp.test('ABC'));
console.log('ABC'.match(exp));
```
> 実行結果
0
true
false
[ 'ABC', index: 0, input: 'ABC', groups: undefined ]
yオプションを指定すると、検索を任意の位置から始めることが出来ます。
なお、検索位置はRegExpオブジェクトのlastIndexプロパティで指定します。
例を見てわかる通り、yオプションはStringオブジェクトのメソッドでは有効にならない点に注意してくだ
さい。

``` 1-2(gオプションとiオプションの組み合わせ).js
console.log('ABC_abc_ABC'.match(/ABC/gi));
```
> 実行結果
[ 'ABC', 'abc', 'ABC' ]

# 参考URL
- [Github サンプルソース](https://github.com/shusuke-nakamura/regular_expression/blob/master/src/1-3.js)

# 次回予告
- [メタ文字を用いた検索](https://qiita.com/shuchan/items/21cdfc76e5f22bf42120)
Set-Location（cd）を履歴として残し、過去に移動したディレクトリへ簡単にアクセスできるようにするスクリプトを書いた

# TL; DL

- `cd`でディレクトリ移動した際に、移動後のパスを配列に格納
- インデックスを指定して過去に移動したディレクトリへアクセスする


# 作業環境

```powershell
❯ $PSVersionTable

Name                           Value
----                           -----
PSVersion                      7.0.3
OS                             Microsoft Windows 10.0.18363
```

# やりたいこと・やったこと

## やりたいこと

- 過去に行き来したディレクトリへの移動を簡単にしたい

## やったこと

1. `cd`でディレクトリ移動後、`pwd`の値を配列に格納
2. 格納した配列の中身をインデックスと一緒に出力
3. `cd`の引数として2で出力した値を指定することで、ディレクトリを移動する


## 書いたコード

```powershell
$Script:cdj_arr = @()
function Set-Location-History {
	Param(
		[String]$path
	)
	Set-Location $path
	$Script:cdj_arr += Get-Location
}

function Get-Location-History {
	Write-Host '値を参照するには$cdj_arr[i]を利用します。'		
	Write-Host "`r`n"		
	for ($i = 0; $i -lt $cdj_arr.Count; $i++) {
		Write-Output('Index ' + $i + '： ' + $cdj_arr[$i])
	}
}
```

## 使用方法

`cd`と同じように使う。

```powershell
> Set-Location-History .\Desktop\HTML5LV1_ver2_mogitest\
```

`Get-History`から`cd`の履歴のみを取得しているような感じ。

```powershell
❯ Get-Location-History
値を参照するには$cdj_arr[i]を利用します。

Index 0： C:\Users\mirumo\Desktop\HTML5LV1_ver2_mogitest
Index 1： C:\Users\mirumo\Desktop
Index 2： C:\Users\mirumo
```

```powershell
> cd $cdj_arr[0]
❯ pwd

Path
----
C:\Users\mirumo\Desktop\HTML5LV1_ver2_mogitest
```

# コードを書く中で初めて知ったこと

## 変数のスコープを明示的に設定することができる

コード内に出てくる`$Script:cdj_arr`は、スクリプト内で参照可能な変数`$cdj_arr`を意味する
これを使った意図は、異なる関数間で同じ変数へのアクセスを可能にするため

参考：[変数のスコープ](http://suyamasoft.blue.coocan.jp/PowerShell/Tutorial/Scope/index.html#Script)


# 今後やりたいこと

値を配列に入れて、インデックスを使ってそれを参照するよりも、
オブジェクトを作成して、Idの値を`Where-Object`で指定して値を参照するやり方に変えたい

おわり
Jetson Yolo USBカメラで物体を認識させる

###Jetson Yolo USBカメラで物体を認識させる

darknetフォルダの中にpythonで書かれた物体認識のサンプルプログラムがあり、USBカメラを接続した状態で実行するとUSBカメラの画面が立ち上がり、写ったものを物体認識が働きます。

<img width="400" alt="スクリーンショット 2020-07-19 19.50.27.pn#g" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674266/0fc084f1-2830-0e2f-1614-eef55da3964c.png">

100円ショップで買ったコップが認識されました。


学習済みのデータで実行する

```
$ wget https://pjreddie.com/media/files/yolov3.weights

$ ./darknet detector demo cfg/coco.data cfg/yolov3.cfg yolov3.weights
```
FPS1.0
データが重いのかカクカクでした

最小限の学習済みデーターで実行

```
$ wget https://pjreddie.com/media/files/yolov3-tiny.weights

$ ./darknet detector demo cfg/coco.data cfg/yolov3-tiny.cfg yolov3-tiny.weights
```

FPS 5.0 少し早くなりました。

今後このdarknetのサンプルプログラムを改造し、開発していくことになると思います。

[参考](https://www.nakasha.co.jp/future/ai/yolov3_pre-trained_model.html)

####感想
こんなに楽に物体認識ができるとはJetson Nano JetPackとYoloはすごい。
Jetpack ISOファイルをインストールするだけでここまで簡単にできるのがいい
私も機械学習エンジニアとしてデビューする可能性が高まりました。
UdemyでPython講座を学ぼうと思います。

**[Jetson NanoでYoloをすぐ利用する](https://qiita.com/aqzihb/items/b3ce30228eb056615a96)**

<a href="https://px.a8.net/svt/ejp?a8mat=3HA5YE+3SXPWY+3L4M+BW8O2&a8ejpredirect=https%3A%2F%2Fwww.udemy.com%2Fcourse%2Fpython-beginner%2F" rel="nofollow"><img width="350" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674266/4706654b-9785-84d2-ee97-17ce9f7e4b11.jpeg"></a>
<a href="https://px.a8.net/svt/ejp?a8mat=3HA5YE+3SXPWY+3L4M+BW8O2&a8ejpredirect=https%3A%2F%2Fwww.udemy.com%2Fcourse%2Fpython-beginner%2F" rel="nofollow">現役シリコンバレーエンジニアが教えるPython 3 入門 + 応用 +アメリカのシリコンバレー流コードスタイル</a>
Pythonを学ぶ際にとても役に立ちました！

<a target="_blank"  href="https://www.amazon.co.jp/gp/product/B08MZFQWDP/ref=as_li_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=B08MZFQWDP&linkCode=as2&tag=iotana-22&linkId=37b7556bf63c7b4bb3652296b3e8cc7a"><img width="300" alt="NVIDIA Jetson Nano 2GB 開発者キット" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674266/7370d26c-43d1-3a68-c233-5167e1df46e4.jpeg"></a>
<a target="_blank"  href="https://www.amazon.co.jp/gp/product/B08MZFQWDP/ref=as_li_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=B08MZFQWDP&linkCode=as2&tag=iotana-22&linkId=37b7556bf63c7b4bb3652296b3e8cc7a">NVIDIA Jetson Nano 2GB 開発者キットを購入する</a>
アジャイルソフトウエア開発技術者検定試験Lv.1

2020年7月19日にアジャイルソフトウエア開発技術者検定試験Lv.1を受験しました。
一応、合格したので記事を書いておきます。
少しでも次受ける方の参考になれば幸いです。
興味のある方は[アジャイルソフトウエア開発技術者検定試験の公式サイト](http://agilecert.org/)を見てください。

## 受験理由
■１ アジャイル開発に興味があったから。
■２ もしかしたら今後使うかもしれないと思ったから。

## 感想
■１ そこまで難しくないですが、公式テキストである『アジャイル検定公式テキスト アジャイルソフトウエア開発技術者検定試験 レベル1対応（アジャイルソフトウェア, 2017, リックテレコム）』に書かれている用語とは異なる用語が試験で使われるので、最初は混乱します。が、そのまま文章を読み進めると、これはチームリーダーのことを言っていて、これはプロダクトオーナーのことをいっているのだなと、問題文全体の文脈から予測がつくので、とりあえず、最後まで解いてそのあと、微調整をすればOKです。
■２ 公式テキストだけだと、頭の整理がつかないかもしれないので、「アジャイル　用語」などで、ネット上で検索して自分の足りない箇所を学ぶのがいいです。また、文字だけでは理解できない方は、アジャイルで画像検索して、視覚的に理解するのがよいかもしれません。

## 学習教材
■１ アジャイル検定公式テキスト アジャイルソフトウエア開発技術者検定試験 レベル1対応（アジャイルソフトウェア, 2017, リックテレコム）
・・・公式テキスト：とりあえず、これを読みましょう。
■２ アジャイルサムライ――達人開発者への道（Jonathan, 西村・角谷信太郎（監訳）, 近藤・角掛（訳） 2011, オーム社）
・・・ 余裕があれば読んだ方がよい奴：私は試験前日に80ページほど読んだだけですので、全て読み切れない状態で試験を受けました。
■３ とにかく「アジャイル」でググる
・・・ 通勤時には携帯でググって頭の整理：異なる言い回しなどはググった方が身に付きますのでググって学習するのは有益です。

## 学習方法
■１ 公式テキストを読む。
・・・1回読んで、2回目は流す程度に読む。
■２ 「アジャイル開発宣言」と「アジャイル宣言の背後にある原則」をとにかく覚える。
・・・公式テキストにもありますし、ググっても出てきます。とにかくこれを覚えた方がよいです。毎日、「朝、昼、晩」と何度か頭の中で復唱して、ほぼ完ぺきに覚えます。
■３ 隙間時間にググってアジャイルに関してを調べる。私は通勤時間だけググってました。

## 反省点
■１ 『アジャイルサムライ――達人開発者への道』を全部読んでおきたかった。

## 試験前にやっておいてよかったこと等
■１ 「アジャイル開発宣言」と「アジャイル宣言の背後にある原則」を試験直前まで読んでおいたこと。
StoryBoardの簡素化

#View数が増えてきたときの対処法


下記のように、開発が進んでいくとViewの数が増えていき全体が少しごちゃごちゃしてきてしまうことがあります。
StoryBoard Referenceを使用し、StoryBoardをシンプルにする方法をやっていきます。
<img width="1246" alt="スクリーンショット 2020-07-19 19.15.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562721/ad0a0684-c808-2011-904d-a0faf116a1d8.png">
##　StoryBoard　ファイルを作り分岐

NewFile　→　StoryBoardを選択肢
<img width="727" alt="スクリーンショット 2020-07-19 19.16.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562721/09eeda40-84e0-6001-5ee3-72e80cd380c6.png">

作ったStoryBoard（今回はBlue .StoryBoardと名付けました。）に、Main.StoryBoardから切り取って貼り付け。
貼り付けたら、NavigationControllerをクリックし、　「is initial ViewController」にチェックを入れます。
<img width="262" alt="スクリーンショット 2020-07-19 19.17.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562721/20503614-19ef-d530-ec0f-c0f0366a6015.png">
storyBoardをBlue.storyBoardと接続。
<img width="260" alt="スクリーンショット 2020-07-19 19.19.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562721/2183c86c-a465-d7d7-e33f-570bc8e512a6.png">
このままだとTagBarが表示されていないので、
右上の「+」ボタンからTab Bar Itemを選択。Navigation Controllerに貼り付けます。

<img width="679" alt="スクリーンショット 2020-07-19 20.01.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562721/73f1702e-5b16-3fc8-4fdd-ae968b34a0b9.png">

Blue.storyBoardはこんな感じ。
<img width="1049" alt="スクリーンショット 2020-07-19 19.49.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562721/ccd35ea7-b80c-9d7e-6659-f9e819e79c43.png">

main.StoryBoardに戻ったら右上の「＋」ボタンから「StoryBoar Reference」を選択。<img width="677" alt="スクリーンショット 2020-07-19 19.17.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562721/fa6f4212-e5c1-65d4-89af-2b269aa68124.png">
TagBarControllerとRelationship Segue の　view controllers　でつなげます。
<img width="431" alt="スクリーンショット 2020-07-19 19.18.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562721/a0b04acf-88f1-5311-5fe7-d2061c3ca4d0.png">
そうすると、こんな感じ！
<img width="1188" alt="スクリーンショット 2020-07-19 19.38.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562721/75a763ec-4f8e-94df-039e-0e5ec9c2387c.png">
他、２つのTabbarも同様に行うと・・・
こんな感じでMain.StoryBoardがシンプルになりました！
<img width="574" alt="スクリーンショット 2020-07-19 19.28.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562721/7fafc2c7-0660-4417-b0c2-5b5570c06a37.png">
いまさらですが、AmazonLinux2 で yum できなくて困った話

久しぶりに AWS で VPC を構築する機会があり、コンソールを開いたが、色々変わっていた。
Multi AZ, 4Subnet(public x2, Private x2) の NAT@Public, WORKER@Private な一般的な構成で、WORKER サーバから yum 出来なくて困った。

## Amazon Linux(2) の yum リポジトリは S3

とのことで、エンドポイントの設定をすれば良いと、あちこちに書いてあったので、設定。（したが、それだけではつながらなかった）

### Endpoint の Policy 設定

```VPC > エンドポイント > ポリシー```

```json
{
    "Version": "2008-10-17",
    "Statement": [
        {
            "Sid": "AmazonLinux2AMIRepositoryAccess",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::amazonlinux.*.amazonaws.com/*"
        }
    ]
}
```
こいつを作成して、Private 側の Route Table にくっつける。

### Sub Route Table

しばらくすると、勝手に追加される。

|      Source      |  Target   |               Note               |
| :--------------: | :-------: | :------------------------------: |
|    x.x.x.0/xx    |   local   |           default set            |
| xxxx:xx....::/xx |   local   |           default set            |
| pl-xxxx.s3, ...  | vpce-xxxx | これが追加される |
|    0.0.0.0/0     | eni-xxxx  |         Instance of NAT          |
|       ::/0       | eni-xxxx  |         Instance of NAT          |

yum のリポジトリのある S3 には、NAT インスタンスを通らずに、直接アクセスする。
ただし、私の環境では、これだけではつながらなかった。


## Security Group（or NACL） の設定

Security Group なり Network ACL の設定で、Private Subnet にあるサーバが直接 S3 にアクセスできないと、yum できない。当たり前。S3 の IP Range は、

```VPC > マネージドプレフィックスリスト```

から見つけることができる。S3 と Dynamo が用意されていた。
私の場合は、NACL は緩く、SG で締める方針にしていたので、SG の Outbound に S3 のマネージドプレフィックスリストを追加したところ、yum が通るようになった。

## おわりに

ネット上では、ポリシーの追加の話はたくさん見かけるが、SG の話が見当たらなかったのは、そもそも S3 に接続する設定があった上で、yum のリポジトリが変更になったからだろうか？よく分からないが、何か出来ない場合は、ネットを検索して一発解決策を探したくなるが、どういう経路でどんな通信を許可/拒否したくて、それに必要な設定がなされているかを、1つずつ潰していけば解決する。と再確認。
[git]ローカルのディレクトリをリモートに登録する

公式の手順踏んでみるだけです。何気にやったことなかったのでメモ書き
https://docs.github.com/ja/github/importing-your-projects-to-github/adding-an-existing-project-to-github-using-the-command-line

以下の `ruby_test` ディレクトリ配下をgithubに登録してみます

```
ruby_test
├── README.md
├── sample.rb
├── sample_test.rb
└── test
    └── fizz_buzz_test.rb
```

#### 1. ローカルディレクトリをGitリポジトリに登録する

```
$ git init
Initialized empty Git repository in /yourdirectory/ruby_test/.git/
```

#### 2. ローカルファイルを全てgitに登録する
```
$ git add .
$ git commit -m "1"
```

#### 3. github上でリポジトリを作る
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178351/64f4b981-75b8-431f-e212-53db99f30a57.png)

* Repository name : リポジトリ名。ローカルのディレクトリ名と同じで良いが自由
* その他そのまま

#### 4. ローカルディレクトリをリモートに関連付けする
![キャプチャ1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178351/6019c306-20fc-24e6-305d-04491595ff02.png)

* このURLをコピーしておく

```
# リモートに登録する
$ git remote add origin https://github.com/mikenekoko/ruby_test.git

# リモートにpushする。UsernameとPasswordを聞かれるので答える
$ git push -u origin master
Username for 'https://github.com': *********
Password for 'https://*********@github.com':
Counting objects: 8, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (8/8), done.
Writing objects: 100% (8/8), 1.50 KiB | 383.00 KiB/s, done.
Total 8 (delta 0), reused 0 (delta 0)
To https://github.com/mikenekoko/ruby_test.git
 * [new branch]      master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.
```

リモートで確認したら、すでにファイルが登録できている

![キャプチャ3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178351/7f2c2b23-322a-dba6-9287-65a15242bf28.png)
Macで「ダウンロード」フォルダを一発で開く小技

Macのデフォルト設定では

- デスクトップのどこにいても`cmd+option+space`でFinderが開く（「検索」にフォーカスされた状態で）
- Finderでは`cmd+option+L`で「ダウンロード」フォルダが開く

ようになっているので、`cmd+option+space` `cmd+option+L`と続けて打てば「ダウンロード」フォルダを一発で開くことができる。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79394/ccc26eed-b7e9-8e1b-1f83-8dc5b908660d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79394/7f217430-4063-3b41-18ec-714cc961860d.png)

https://support.apple.com/ja-jp/HT201236
書評：クリーンアーキテクチャ　達人に学ぶソフトウェアの構造と設計

# はじめに
クリーンアーキテクチャというと「あの図のもの」とか「ちゃんとやるには難しそう（難しいのですが）」
というイメージが先行してなかなか手を付けれていなかったですが、
以下の動画がすごくわかりやすく解説してくれていて、
[なるセミ 【プログラミング】実践クリーンアーキテクチャ 音ズレ修正Ver.](https://www.youtube.com/watch?v=BvzjpAe3d4g)

[Qiita](https://qiita.com/nrslib/items/a5f902c4defc83bd46b8)もあります。

ちゃんと学習してみようかと思い、本を手にとってみました。

# 印象に残った部分
1日1章以下くらいのペースで読んだので、結構うろ覚えが多いのですが...
（読書ってどう読むのが記憶の定着と応用につながりやすいのだろうか...
 モチベーションがバラバラで読むのが気分次第になりやすい...）

本全体の流れとしては
・設計やアーキテクチャの歴史
・各部分ごとのアーキテクチャについての解説（コンポーネントとかサービスとか）
・クリーンアーキテクチャの提案

みたいな感じです。

クリーンアーキテクチャという単語自体は後半(22章）になってから登場します。
クリーンアーキテクチャも殊更これだ！という主張をするというよりも
今までの歴史とポイントを考えるとクリーンアーキテクチャという一つの解がありうる。
みたいな感じで、クリーンアーキテクチャまでの章をじっくり読んで、
自分の経験と照らし合わせて考えることが自分にとっては意義深かったです。

ちょっと地味ですが、一番印象に残ったのは、
15章 アーキテクチャとは？
の「デバイス非依存」というセクションです。

今はカードもテープも使ったプログラムに携わることはおそらく無いですが、
デバイスを変更しても何も変更することなく動くプログラムというのは
自分的にはアーキテクチャが求められることを実現している状態だと思いました。

アーキテクトという役割にはビジネスをシステムで実現することと
継続的に開発することを実現する役割があると思いますが（個人の見解です..）、
ビジネスルールとの分割だけではなくデバイスやOSとも分離した状態
（今だとOSが変わってもとかバックエンドのDBがオンプレミスからクラウドになるとかあるいはRDBがKVSになるとかでしょうか）を作るのはアーキテクトの理想の成果だと思いました。
（これは実際難しいことだと思いますが..）

印象に残ったところとはちょっと違いますが、
1章~11章 はプログラム設計の学習や入り口にすごくいいかと思いました。
（リーダブルコードはどうだったか記憶が曖昧..）だけど、
設計の原則にページを割いてる本ってあまりなかったので..
ワークショップ「炭素年代測定値の分析と可視化」その1

7月19日に行われたワークショップ「炭素年代測定値の分析と可視化」の復習です。

当日資料はこちらのGitHubからダウンロードできます。
[https://github.com/benmarwick/Analysing-Archaeological-Radiocabon-Ages-Using-R.git](https://github.com/benmarwick/Analysing-Archaeological-Radiocabon-Ages-Using-R.git)

# 単一年代の較正年代

厚真町厚幌2遺跡のデータを使用しました。
単一資料について較正年代を可視化します。
![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60438/0473df9d-5649-48a2-662c-75b788b21f63.png)


```{r}
library(rcarbon)

x <- 
  calibrate(x = 4750,  # 1300BP
            errors = 30, # 誤差（標準偏差）
            calCurves = 'intcal13')  
# calCurvesは北半球、南半球、海産物などに応じて選択
# とりあえず"intcal13"を選択しておけば良い。
```

変数xはリスト形式のデータで、`x$grids$1`に較正年代とその密度が格納されています。

```{r}
head(x$grids$"1")

      calBP       PrDens
44404  5597 1.431645e-05
44405  5596 2.038797e-05
44406  5595 2.874464e-05
44407  5594 4.010891e-05
44408  5593 5.550909e-05
44409  5592 7.618120e-05
```

```{r}
plot(x,
     HPD=TRUE,
     credMass=0.95)
```
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60438/01efe31e-fc7c-cc20-64aa-1b9ec299da52.png)


# 複数資料の較正年代

複数資料の較正年代も方法は上記と一緒です。
測定年代と誤差をベクトルで与えます。

```{r}
xx <- 
  calibrate(x=c(4750,4910, 4950, 4960),
            errors=c(30,30, 30 ,30),
            calCurves='intcal13')
```

この場合、可視化手法は用意されていないので、`summary()`で概要を把握します。

```{r}
summary(xx)

  DateID MedianBP OneSigma_BP_1 OneSigma_BP_2 TwoSigma_BP_1 TwoSigma_BP_2
1      1     5519  5580 to 5508  5486 to 5470  5585 to 5459  5373 to 5331
2      2     5632  5650 to 5605      NA to NA  5711 to 5687  5683 to 5674
3      3     5674  5716 to 5644  5625 to 5622  5733 to 5606      NA to NA
4      4     5684  5721 to 5652      NA to NA  5741 to 5609      NA to NA
  TwoSigma_BP_3
1      NA to NA
2  5663 to 5592
3      NA to NA
4      NA to NA
```

# Bchronパッケージを利用した複数資料の分析と可視化

```{r}
library(Bchron)
```

Bchronパッケージを使用して複数資料の年代の可視化を行います。

```{r}
ages2 <- 
  BchronCalibrate(ages=c(4750,4910, 4950, 4960), # 測定年代
                  ageSds = c(30,30, 30 ,30),　# 誤差
                  calCurves= c('intcal13','intcal13','intcal13','intcal13')　# 較正方法
  )
```

```{r}
plot(ages2)
```

![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60438/0b21f25d-e92e-da03-c66e-ed3f7a394e9e.png)


# ノンパラメトリックフェーズ推定

炭素年代から推定される、当該資料群採取遺跡（あるいは地域）の活動段階を推定する手法です。


```{r}
# 引数はBchronCaribrate()と同じです
Dens <- 
  BchronDensity(ages=c(4750,4910, 4950, 4960), # 測定年代
                ageSds = c(30,30, 30 ,30),　# 誤差
                calCurves= c('intcal13','intcal13','intcal13','intcal13')　# 較正方法
  )
```

引数probの値を小さくするとより多くのphaseを検出します。phaseが多すぎると解釈が難しくなりそうです。

```{r}
summary(Dens, prob = 0.95)
```

6つのフェーズが検出されました。

```
At probability level 0.95 there were 6 phases found.
Phase 1 
From 5317 to 5408 
Phase 2 
From 5411 to 5584 
Phase 3 
From 5596 to 5740 
Phase 4 
From 5757 to 5783 
Phase 5 
From 5787 to 5833 
Phase 6 
From 5837 to 5850 
```

この結果を較正年代とともに可視化します。

```{r}
plot(Dens ,
     xlim = c(5300,5900) # x軸の範囲を指定
     )
```
![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60438/d0915c3c-0dbd-61af-54d7-317798e3591d.png)
プログラミング上達講座1：星を描いてみる

プログラム言語の文法を覚えても
どうやって書いたら良いか
まだまだ解らないよーって人多いと思います。 

そんな方のためのプログラミング上達講座です。 
考えたい方は動画を止めて
プログラムを考えてみてください。 

解説動画はこちら

[![表示されなかったらすみません](https://img.youtube.com/vi/n62CvpTAJZU/0.jpg)](https://youtu.be/n62CvpTAJZU)


## 星を書いてみる

今回のテーマは`星を書いてみる`です。
次のような星を描く関数を作成してみましょう。

```python

条件： 
n = 行数 
def star(n):
    処理 
```

※星や口は全角

### 初級の問題

`n段目にn個の星を描く`

例えば

```python
star(5)
```

と実行したら、次のように感じに
表示されるような関数を作りましょう。

★
★★
★★★
★★★★
★★★★★


### 中級の問題

`n段に三角形になるように星を描く`

```python
star(5) 
```

口口口口★口口口口
口口口★★★口口口
口口★★★★★口口
口★★★★★★★口
★★★★★★★★★


### 上級の問題

`n段にダイヤを描くように星を描く`

```python
star(9)
```

口口口口★口口口口
口口口★口★口口口
口口★口口口★口口
口★口口口口口★口
★口口口口口口口★
口★口口口口口★口
口口★口口口★口口
口口口★口★口口口
口口口口★口口口口

```python
star(10)
```

口口口口★★口口口口
口口口★口口★口口口
口口★口口口口★口口
口★口口口口口口★口
★口口口口口口口口★
★口口口口口口口口★
口★口口口口口口★口
口口★口口口口★口口
口口口★口口★口口口
口口口口★★口口口口

※偶数個と奇数個の時で処理が変わり
真ん中からは折り返す


さあ、考えてみましょう。






### 初級編回答

まず`print`関数で文字を出力できます。

n段目にn個の星ということで
毎回個数が変わりますので

このような繰り返しを行うには
`for`文を用います。

```python
def star(n):
    for i in range(n):
        print('★'*(i+1))
star(5)
```

`range`関数を用いると
数値の代わりになるものを生成できます。

数値は0から始まるので1を足してあげます。

Pythonでは文字に関しては
`*`で繰り返しを表現できるので
`print`関数で文字を`n`段分だけ
表示するようにすれば完成です。




### 中級編回答

まず、引数で入力された行数で総量を求めておきます。
ピラミッド型に星を出力する個数は`行数 x 2 -1`個になります。

次に出力を

`星の左側の口`
`★`
`星の右側の口`

というように3分割しそれぞれの個数を計算します。

星の個数が決まれば全体から引いて
2で割れば外側の口の個数になります。

このような関数になりました。

```python
def star(n):
    tmp = n*2-1
    for i in range(n):
        s = ((i+1)*2-1)
        k = (tmp - s)//2
        res = '口'*k + '★'*s + '口'*k
        print(res)
        
star(5)
```

### 上級編回答

上級は解くのに時間がかかると思います。

まず入力された行数が奇数の時と
偶数の時で処理が変わります。

ひし形の上部と下部では
処理が変わることに注意が必要です。

`ひし形の左の口`
`ひし形に描くための★の外枠と口`
`ひし形の右の口`

と分けて考えて
各部分の個数を計算して繋げれば
正解にたどり着けます。

if文の条件分岐で個数を先に考え
出力する1行分の文字を考えます。

こんな感じのコードで星を描けます。


```python

def star(n):
    for i in range(n):
        s = (i+1)*2-1        
        k = (i-n//2) if (i+1>n//2) else (n - s)//2
        w = (n-(k*2)-2) if (i+1>n//2) else (i*2 if n%2==0 else i*2-1) 
        res = '口'*k
        if (i+1)==1 or (i+1)==n:
            res += '★★' if n%2==0 else '★'
        else:
            res += '★' + '口'*w + '★'
        res +='口'*k
        print(res)
```

参考例なので結果があっていれば正解です。

## まとめ

さていかがだったでしょうか？

プログラミングの考え方が
身についてきましたでしょうか。

引き続きやっていきたいと思いますので
プログラミングを上達したい方は
解いてみてください。

それでは。

## 作者の情報

乙pyのHP：
http://www.otupy.net/

Youtube：
https://www.youtube.com/channel/UCaT7xpeq8n1G_HcJKKSOXMw

Twitter：
https://twitter.com/otupython
Azure Functions の環境変数から値を取得する方法

# TL;DR

**ConfigurationManager** を利用した方法では値を取得できなくなっていたため, **Environment** を利用した。



# はじめに

Azure Functions 開発をしている際に環境変数を利用することは多くあると思います。
その取得方法については **ConfigurationManager** クラスをオススメするものが日本語・英語の記事を問わずほとんどだと思います。
しかし, 今回 v3 で開発をし始めてみるとうまく取得できなかったため, 初心に戻って **[Microsoft Docs](https://docs.microsoft.com/en-us/azure/azure-functions/functions-dotnet-class-library#environment-variables)** を参考に開発をしたらすんなりできたので, それの備忘録となります。



# 方法

## 事前条件

以下のような環境変数設定がされている前提で話を進めていきます。

```json:json
{
  "IsEncrypted": false,
  "Values": {
    "SAMPLE_VALUE": "This is Sample Value"
  },
  "ConnectionStrings": {
    "DB_CONNECTION_STRING": {
      "ConnectionString": "This is Connection string",
      "ProviderName": "System.Data.SqlClient"
    }
  }
}
```


## Values: 環境変数の取得

環境変数の取得はとてもシンプルで, **Environment.GetEnvironmentVariable(string, EnvironmentVariableTarget)** にキーを渡してあげるだけで簡単に取得できます。

```cs:sample.cs
namespace Sample
{
    public static class SampleFunction
    {
        [FunctionName("sample")]
        public static async Task<IActionResult> Run (
            [HttpTrigger(AuthorizationLevel.Function, "get", Route = null)] HttpRequest req,
            ILogger log )
        {
            var x = Environment.GetEnvironmentVariable("SAMPLE_VALUE", EnvironmentVariableTarget.Process);
            return new OkObjectResult($"### { x }");
        }
    }
}
```

上記の Functions を起動し, ブラウザでアクセスすると以下のような出力がされると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125601/b7756aad-7fb8-9ce2-cad1-b6136cdbaf89.png)


## ConnectionStrings: 接続文字列の取得

では, 接続文字列の場合はどのように取得するのでしょうか？
これも非常にシンプルに解決でき, キーの前に **ConnectionStrings:** というプレフィクスを付けてあげるだけで取得できます。

```cs:sample.cs
namespace Sample
{
    public static class SampleFunction
    {
        [FunctionName("sample")]
        public static async Task<IActionResult> Run (
            [HttpTrigger(AuthorizationLevel.Function, "get", Route = null)] HttpRequest req,
            ILogger log )
        {
            var x = Environment.GetEnvironmentVariable("ConnectionStrings:DB_CONNECTION_STRING", EnvironmentVariableTarget.Process);
            return new OkObjectResult($"### { x }");
        }
    }
}
```

上記の Functions を起動し, ブラウザでアクセスすると以下のような出力がされると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125601/3d5130ca-d3ef-aab8-128a-91e098e5abb7.png)



# おわりに

2020/07/20 現在の公式ドキュメントでは **Environment.GetEnvironmentVariable(string, EnvironmentVariableTarget)** を利用するように勧めているので, 素直にこれに従っておくのが良いでしょう。
【プログラミング初心者】ローカル開発環境でrails sがエラーになる時の対処法

### 状況

ターミナルでいつも通り、railsサーバーを立ち上げようとしたところ、

```ruby:terminal
user@usernoMacBook-Air app名 % rails s
Traceback (most recent call last):
	5: from bin/rails:3:in `<main>'
	4: from bin/rails:3:in `load'
	3: from /Users/user/app名bin/spring:10:in `<top (required)>'
	2: from /Users/user/app名/bin/spring:10:in `new'
	1: from /System/Library/Frameworks/Ruby.framework/Versions/
2.6/usr/lib/ruby/2.6.0/bundler/lockfile_parser.rb:95:in `initialize'
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby
/2.6.0/bundler/
lockfile_parser.rb:108:in `warn_for_outdated_bundler_version'
: You must use Bundler 2 or greater with this lockfile. (Bundler::LockfileError)
```
上記のエラーが出て、サーバーが急に立ち上がらなくなってしまいました。

###環境

```ruby:terminal

■ruby -v
ruby 2.5.3p105 (2018-10-18 revision 65156) [x86_64-darwin19]

■bundler -v
Bundler version 1.7.4

```
### 行ったこと

bundlerはすでにインストールされている為

```ruby:terminal
sudo gem update bundler
```
を行うと、

```ruby:terminal
Your Ruby version is 2.6.3, but your Gemfile specified 2.5.3
```
と出てしまう。
開発しているアプリのrubyのバージョンが2.5.3だが
なぜかMacのローカルの開発環境のrubyのバージョンが2.6.3になってしまっており、
（自分で自覚がなくアップグレードしてしまったのかもしれません）
バージョンが違う為、上記が表示されていました。

既にAWSにデプロイ様の本番環境を作っており、本番環境でのrubyのバージョンが
2.5.3だった為バージョンは2.5.3で統一したく、

```ruby:terminal
rbenv local 2.5.3
（今後、railsを用いて他のアプリをローカルで開発する可能性を考えて
rbenv globalではなく、あえてlocalでこのプロジェクトだけ2.5.3を使うよう指定しました）
```

```ruby:terminal
source ~/.bash_profile
```
これで、無事サーバーが立ち上がりました！


###今後

なぜローカルのrubyのバージョンが上がってしまったのかを
調査したいと思います。。。
2020年 第2回 G検定

2020年7月4日13～15時開催のG検定を受験しました。
一応、合格したので記事を書いておきます。
少しでも次受ける方の参考になれば幸いです。
[twitter](https://twitter.com/hashtag/g%E6%A4%9C%E5%AE%9A?f=live)みるとどんな感じであったかわかります。


## 受験理由
■１ AI、機械学習、深層学習に興味があったのでその延長線上で受験。
■２ 受験料半額であったのも大きい。

## 感想
■１ 問題数が200問といつもより少なかったようです。[twitter](https://twitter.com/hashtag/g%E6%A4%9C%E5%AE%9A?f=live)などで、受験者のコメントをみていると全体的に難化した感じのコメントがみられましたが、[一般社団法人日本ディープラーニング協会のページ](https://www.jdla.org/)をみると、合格率は前回よりも少しあがっています（66.66％ → 68.96%）。
■２ 全体の問題数が減って、法律関係が増えたみたいなので（本当かな？）、それで難しく感じたのかもしれないです。法律関係の問題は最初にでるので、ここで心折れるらしいです。それを知っていればギリギリ踏みとどまれます。ちなみに、twitter情報ですが、法律関係の問題は60問ほどあったようです。
■３ 個人的には強化学習に関して「踏み込みすぎだろ」と思いながら解いていました（私の勉強不足なのかもしれませんが）。
■４ 主観ですが、強化学習と法律関係以外はそこまで難しくなかったような気がしました。
■５ 下記の学習教材１の公式テキスト、定番の黒い本からはほぼ出なかったです。
■６ 新しい問題集が出版されていたので、解いたのですが、新しい方の問題集に似た問題が結構でいていました。
	
## 学習教材
※ 学習教材の3と4は基本的に問題しか解いていないですが、4はp. 188からは全部読みました。
■１ 深層学習教科書 ディープラーニング G検定（ジェネラリスト） 公式テキスト（浅川ら, 2018, 翔泳社）
・・・ 定番の白本！：今回はあまり役に立たなかった。とはいえ、ここからやった方がいいです。
■２ 徹底攻略 ディープラーニングG検定 ジェネラリスト 問題集 徹底攻略シリーズ（明松・田原, 2019, インプレス）
・・・ 定番の黒い本！：今回はあまり役に立たなかった。とはいえ、ここからやった方がいいです。
■３ スッキリわかる　ディープラーニングG検定（ジェネラリスト） テキスト＆問題演習 （株式会社クロノス, 2020, TAC出版）
・・・ 新しい奴１：よくまとまっているけど、あまり使用しなかった。
■４ これ1冊で最短合格 ディープラーニングG検定ジェネラリスト要点整理テキスト＆問題集（山下ら, 2020, 秀和システム）
・・・新しい奴２：似た問題が結構出た気がしますが、なぜかネットの評判はあまりよくないです。網羅的だからだろうか・・・。
■５ G検定 ～最短合格指南書～(著者：yuki）
・・・用語がまとまっている本（Kindle Unlimitedで読める）：学習教材６の用語がまとまっています。
■６ G検定 ～予測問題集～ Kindle版（著者：yuki）
・・・問題集１（ Kindle Unlimitedで読める）：似たような問題が結構出ました。
■７ 実践で理解する G検定 ディープラーニング教本: G検定合格者が教える最短で合格する秘法（著者：神草）
・・・この本からweb模擬試験受けれます（Kindle Unlimitedで読める）：たくさん問題を解きたい人は使用した方がよいです。
■８ [Study-AIの模擬試験](URL: http://study-ai.com/generalist/)
・・・おなじみの模擬試験！：今回はあまり役に立たなかった。
■９ AI白書2020（独立行政法人情報処理推進機構 AI白書編集委員会（編）, 2020,  株式会社角川アスキー総合研究所）
・・・多くの人が読むのを諦める奴：例にもれず挫折しました（ほぼ読んでいません）

## 学習方法
※基本的には問題を手当たり次第解きまくるというスタンスで勉強しました。
■１ 定番の白い本（公式テキスト）を読む。
・・・私は2019年12月に1回読んだので、二回目は流す程度に読みました。
■２ 定番の黒い本（スキルアップAIの奴）を読む。
・・・こちらも2019年12月に1回読んだので二回目は流す程度に読みました。
■３ 学習教材の3-8の問題をだいたい試験日の一週間前くらいから解き始めて、全て解き終えました。
・・・学習教材の6、7は試験前日（夜）に始めて解きました。

## 試験
■１ 13時00分から開始ですが、12時50分にログイン（なかなかログインできないこともあるようなので、10分前に入る方がよいらしい）
■２ ポップアップブロック解除してと書かれていたので解除して12時55分から試験開始
■３ 試験開始（※法律問題と強化学習が出た箇所はあまり正確ではなく、体感です）
・・・30分で60問ほど終了（法律問題がでて心折れかける）
・・・60分で130問ほど終了（簡単なのが出たのでサクサクと進める）
・・・90分で170問ほど終了（踏み込んだ強化学習の問題が何問かでて心折れかける）
・・・110分で全問終了（難しいのも何問か出て予想より時間を消費）
・・・残った10分で見直し（見直ししたが解答にほとんど変更なし）
■４ 試験終了
■５ アンケート

## 反省点
■１ AI白書を読んでおきたかった。あまり意味ないとよく言われますが。
■２ 強化学習に関しての知識不足を痛感した。
■３ 学習教材３、４は問題ばかり解いていたので、問題以外の箇所もじっくり読んでおきたかった。

## 試験前にやっておいてよかったこと等
■１ 問題集によって言い回しが結構違うので、その点に慣れておきたかったため、多く問題を解いておいてよかった。
■２ 古い問題集だと、内容が古い気がしたので新しいのを試しに買って解いてみたところ、実際に試験に出た問題は新しい問題集寄りのものであった。やはり、情報は更新していかないとダメなのだと思う。
■３ 定番の白い本や黒い本を2019年に趣味で読んでいたので、内容はだいたい把握しており、多くの問題を解くことができた。
■４ 『ゼロから作るディープラーニング』の１と２を読んだことがあったので、多少深いことも把握していた。
Perl: ImageMagick で背景色の変更

入力画像のサンプル
![input_jul19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/634243f3-6290-e44b-83cb-ab4d02610b75.png)


出力画像のサンプル
![out_jul19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/ee8b09e7-dcf5-5207-b340-71b08504cacf.png)

```pl:back_white.pl
#! /usr/bin/perl
#
#	back_white.pl
#
#					Jul/19/2020
# ----------------------------------------------------------------
use strict;
use warnings;
use utf8;

use Image::Magick;
# ----------------------------------------------------------------
print STDERR "*** start ***\n";

my $file_in = $ARGV[0];
my $file_out = $ARGV[1];

&back_white_proc($file_in,$file_out);

print STDERR "*** end ***\n";

# ----------------------------------------------------------------
sub back_white_proc()
{
	my ($file_in,$file_out) = @_;

	print STDERR $file_in . "\n";
	print STDERR $file_out . "\n";

	my $Image=Image::Magick->new;
	$Image->Read($file_in);
	my ($width, $height)	= $Image->Get('width', 'height');
#
	$Image->Transparent(color=>'white');
	my $Base=Image::Magick->new;
	$Base->Set(size=> $width . 'x' . $height);
	$Base->Read("gradient:white-#DDDDDD");
	$Base->Composite(image=>$Image, compose=>'over', gravity=>'center');
	$Image	= $Base->Clone();
	$Image->Write($file_out);
}

# ----------------------------------------------------------------
```

実行コマンド

```bash
./back_white.pl linux_logo.png out01.png
```
【AWS】【ECR】【CircleCI】ECRにイメージをプッシュするときにハマったとこ

# circleciのログはSUCCESSなのにECRにイメージがない

以下、nginxイメージをプッシュするコード

```yaml:.circleci/config.yml
version: 2.1 
orbs:
  aws-ecr: circleci/aws-ecr@6.10.0
workflows:
  build_and_push_image_nginx:
    jobs:
      - aws-ecr/build-and-push-image:
          account-url: AWS_ECR_ACCOUNT_URL_ENV_VAR_NAME_NGINX
          aws-access-key-id: ACCESS_KEY_ID_ENV_VAR_NAME
          aws-secret-access-key: SECRET_ACCESS_KEY_ENV_VAR_NAME
          dockerfile: Dockerfile
          no-output-timeout: 20m
          path: ./nginx
          region: AWS_REGION_ENV_VAR_NAME
          repo: 'nginx' 
          tag: $CIRCLE_SHA1 # <- これが原因だった "${CIRCLE_SHA1}"と書いていたため、中身がなくecrに認めてもらえなかった
          filters:
            branches:
              ignore:
                - master
```

CIRCLE_SHA1の中身は次の通り。
<img width="850" alt="スクリーンショット 2020-07-19 19.06.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630802/c84c0299-6976-4fd4-0f1a-707d547678f6.png">
`tag: $CIRCLE_SHA1`とすると、CircleCIで定義済みの環境変数があたるので、問題なし。
![スクリーンショット 2020-07-19 19.04.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630802/ac3c57d3-d9c9-93e0-e16c-fdfe6a67503c.png)

[Circleciの環境変数の使い方](https://circleci.com/docs/ja/2.0/env-vars/)
[Amazon ECR リポジトリのタグ付け](https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/ecr-using-tags.html#tag-resources)
attiny85

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/250209/53e3c8c8-ca38-5564-a3b7-d011f96a4d4e.png)

### データシート略語
https://techdocs.altium.com/sites/default/files/wiki_attachments/296759/PinAbbreviations.pdf

### PWM
http://okiraku-camera.tokyo/blog/?p=7480

CS0-CS2
http://kcnotebook.web.fc2.com/avr/timer.html
CS02 CS01 CS00
0	0	0	停止(タイマ/カウンタ動作停止)
0	0	1	Fclk(分周無し)
0	1	0	Fclk / 8(8分周)
0	1	1	Fclk / 64(64分周)
1	0	0	Fclk / 256(256分周)
1	0	1	Fclk / 1024(1024分周)
1	1	0	T0ﾋﾟﾝの下降端 (外部ｸﾛｯｸ)
1	1	1	T0ﾋﾟﾝの上昇端 (外部ｸﾛｯｸ)

### マクロ一覧
http://startelc.com/AVR/Avr_100macroMemo.html

### ポート
ポートB方向レジスタ DDRB　　(ポートAならDDRA) 0ならINPUT 1ならOUTPUT
ポートB出力レジスタ PORTB　(ポートAならPORTA) OUTPUTにHigh/Lowをセット
ポートB入力レジスタ PINB　　(ポートAならPINA)　INPUTがHigh/Lowかチェック

### servo
```
#include <avr/wdt.h>
#define OUTPUT_PIN  _BV(1)

void init_pwm() {
  OCR0A = 156;  // TOP value :  64us * 156 = 9984us = 10ms = 100Hz. SG92R works on 50Hz. but set 100Hz for degree subdivide.
  OCR0B = 1;  //  H period  : 256us x 10 / 2 = 128us
  TCCR0A = B00100011; // COM0A: 00, COM0B: 10, WGM01-00: 11. TCCR0A(TimeCountControlRegister 0A)
  //TCCR0B = B00001001; // FOC:00, WGM02:1, CS02-01: 001 (system clock x1)
  TCCR0B = B00001011; // FOC:00, WGM02:1, CS02-01: 011 (system clock x64)
  TCNT0 = OCR0A;// init count. if(TCNT0 == OCR0A) ic reset count and reload new OCR0A and OCR0B.
}

void set_pwm(int a) {
  OCR0B = a;
}

void setup() {
  cli();
  DDRB = OUTPUT_PIN; // inputは0
  PORTB = 0;  // 他は0
  ACSR |= 0x80;    // アナログコンパレータ禁止
  ADCSRA &= 0x7f;  // disable ADC
  wdt_disable();
  TIMSK = 0;  // disable Timer0/1 overflow interrupt.
  sei();
  
  pinMode(0, INPUT);
  init_pwm();
}

void trigger_on(int a){
  set_pwm(a);
}

void trigger_off(){
  TCCR0A = 0;
  TCCR0B = 0;
}

int wait = 100;
int count = 8 * wait; //64us x 8 = 512 us.
void loop() {
  if(digitalRead(0) == LOW){
    trigger_on(count/wait);
    ++count;
    if(count > 37*wait) count = 8*wait;
  }else{
    trigger_off();
  }
  delay(1);
}
```
【初心者】NO FILEの削除方法

マイグレーションファイルを間違えて作り、慌てて手動で削除してしまいその後rails db:migrateするとエラーが出てしまいました。そのときに出てきたのがNO FILEです。

###削除方法
①マイグレーションファイルの確認
$ rails db:migration:statusで現状の確認とマイグレーションファイルのIDを調べる。

```
$ rails db:migration:status

Status   Migration ID    Migration Name
--------------------------------------------------
   up     20200518132414  Devise create users
   up     20200521083405  Add name to users
   up     20200525013751  Create posts
   up     20200527010431  Add picture to posts
   up     20200528232616  ********** NO FILE **********
   up     20200531083300  Create comments
```
NO FILEとなっているIDは20200528232616と確認

②ダミーのファイル作成
あとでファイルは消してしまうのでhogeの部分はなんでも大丈夫です。

```
touch db/migrate/20200528232616_hoge.rb
```

```20200528232616_hoge.rb
 class Hoge < ActiveRecord::Migrattion[5.3] #5.3の部分はrailsのバージョンに合わせてください
   def change
   end
 end
```
③マイグレーションファイルを削除

現状の確認

```
$ rails db:migrate:status

Status   Migration ID    Migration Name
--------------------------------------------------
   up     20200518132414  Devise create users
   up     20200521083405  Add name to users
   up     20200525013751  Create posts
   up     20200527010431  Add picture to posts
   up     20200528232616  Hoge　
   up     20200531083300  Create comments
```
現状はこのようにMigration Nameがちゃんとついている状態になっています。
ここからマイグレーションファイルをupからdownの状態にします。

```
$ rails db:migration:down VERSION=2020052823261
```

```
$ rails db:migrate:status

Status   Migration ID    Migration Name
--------------------------------------------------
   up     20200518132414  Devise create users
   up     20200521083405  Add name to users
   up     20200525013751  Create posts
   up     20200527010431  Add picture to posts
  down    20200528232616  Hoge　
   up     20200531083300  Create comments
```

downの状態になったことを確認したあと、削除します。

```
$ rm db/migrate/db/migrate/20200528232616_hoge.rb
```
再度確認してみると、

```
$ rails db:migrate:status

Status   Migration ID    Migration Name
--------------------------------------------------
   up     20200518132414  Devise create users
   up     20200521083405  Add name to users
   up     20200525013751  Create posts
   up     20200527010431  Add picture to posts
   up     20200531083300  Create comments
```

ちゃんと消えているはずです！！


###まとめ
まずはマイグレーションファイルを間違えて作ってしまっても、慌ててupの状態で削除をしないことが大切です。
FileMakerから4Dに保存されているデータをJSON経由で取得して同期する

# [FileMaker](https://www.claris.com/filemaker/)と[4D](https://jp.4d.com/product-download/Feature-Release)を同期したい

---
### 使えるJSON

[FileMaker](https://www.claris.com/filemaker/)も[4D](https://jp.4d.com/product-download/Feature-Release)もJSONがまぁ使える様になった。
[4D](https://jp.4d.com/product-download/Feature-Release)側は、選択されているレコードを、テーブル構造のフィールド名と値のセットにしたレコード数分のJSON配列に１命令で変換してくれる。（これ便利。なんと逆も可能でJSONをレコード情報に一発で復元できる）

[FileMaker](https://www.claris.com/filemaker/)側はJSONの属性名を変数に取り出して、その変数名に合致するフィールドに値をセットする事ができる。この時[FileMaker](https://www.claris.com/filemaker/)らしいのはフィールド属性（テキスト、数値）だか無視して値を設定しても良きに計らってくれるのだ。


---
### 先ずは、[4D](https://jp.4d.com/product-download/Feature-Release)側のデータ取り出しAPIを整備する。

```
$s:=get_WFValue_by_name ("dt")  //
If ($s#"")
	$dt:=Date($s)
Else 
	$dt:=Current date(*)
End if 
QUERY([Fax];[Fax]DATE=$dt)
$s:=Selection to JSON([Fax])
WEB SEND TEXT($s;"application/json")
```
http://[hostname]/4DCGI/fm/FAX/list?dt=2020/1/1

てな具合にアクセスすると、JSON配列の文字列を取得できるようになる。
特筆すべきは[4D](https://jp.4d.com/product-download/Feature-Release)側の処理の簡単さで、アクセス制御したりエラー処理したりといった周辺を除いていくと・・・

- レコードをクエリ
- 検索結果をJSON文字列に変換
- 文字列をMIME type指定して送出

という３行の命令で完了してしまう。超ラクチン。
ただしWebデータ送出を使うためには、[4D](https://jp.4d.com/product-download/Feature-Release)にウェブ公開できる要するためのライセンスを追加する必要があるので注意。デバッグ検証だけなら小一時間稼働できるモードがあったりする。

---
### [FileMaker](https://www.claris.com/filemaker/)側でデータをパースしてレコードに置き換える。

テーブル定義はこんな感じ。同期したい[4D](https://jp.4d.com/product-download/Feature-Release)側の定義と全く同じ名前にしておく。

![FAX_struct.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207772/a808d876-d95e-14fc-610c-3c14aac31bc7.png)

そして、同期が発生するアクションで下記スクリプトを実行する。
![FAX_sync.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207772/f49e2b83-dead-0ebf-097e-140526834063.png)

赤枠の部分がポイントで、JSONの属性名がそのままフィールド名になり、値を良きに計らって保存してくれる。IDについては毎回設定する必要なく、場合によっては更新させたいので検索キーとしても使っている。

こういう節操のない動きに抵抗がなければ、ほんとファイルメーカーは簡単なソリューション構築の選択肢になってくる。

---
### [4D](https://jp.4d.com/product-download/Feature-Release) -> [FileMaker](https://www.claris.com/filemaker/)の同期が完成だ。

いわゆるPull型というか、[FileMaker](https://www.claris.com/filemaker/)のGUIで某かのアクションが発生した時必要に応じてデータを引っ張ってくるタイプの同期ができるようになったのである。

実は、[FileMaker](https://www.claris.com/filemaker/)がクライアントになるタイプでのJSON活用は、そのままのコードがFileMaker Goでも動作する。つまり、API提供するサーバー側は何でもOKで、iPadをクライアントにしたソリューションがいろいろと作れてしまうのです。

---
次は、逆方向か。[FileMaker](https://www.claris.com/filemaker/)のデータを外部から取り出しできるようにしてみる・・・
webpack + vueの遅延ローディングでチャンクファイル名がうまく生成されないときにチェックすること

# やりたいこと

以下の書き方で `index.js` とは別に遅延ローディング用の `home.bundle.js` を生成する。
概要としては、公式Doc https://webpack.js.org/configuration/output/#output-chunkfilename をやりたい。

詰まったのでメモ。

```ts:index.ts
const router = new Router({
  routes: [
    {
       path: "/home",
       component: () =>
          import(/* webpackChunkName: "home" */ "./view/home/Home.vue"),
    },
  ]
});
```

`webpack.config.js` の概要は以下の通り。（関係あるところだけ）
依存ファイルたちを `vendors.bundle.js` として出力する設定になっている。

```js:webpack.config.js
module.exports = {
  target: "web",
  mode: "production",
  entry: "./src/index.ts",
  output: {
    path: path.join(__dirname, destDir),
    filename: "index.js",
    chunkFilename: `[name].bundle.js`,
  },

  module: {
     // ...
  },

  //  ...

  optimization: {
    splitChunks: {
      cacheGroups: {
        commons: {
          test: /[\\/]node_modules[\\/]/,
          name: "vendors",
          chunks: "all",
        },
      },
    },
  },

  // ...

}

```

# 問題

`home.bundle.js` みたいに出力されてほしいのに `1.bundle.js` のように数値が入ってくる。
`vendor.bundle.js` は直接指定しているので問題ない。


# チェックすべきこと

https://github.com/webpack/webpack/issues/4861
ここで皆さんが熱心に議論されていました。

## チェック1: .babelrc
babelを使っている場合は `.babelrc` にコメントを削除する記述がないかチェック

```:.babelrc
{
    // ...
    "comments": false <= ここをtrueに 
}
```

## チェック２: tsconfig.json

関係あるところだけ抜粋。
`removeComments` が `true` になっている場合は `false` にする。

また、上の議論の中では `module` を `esnext` にすればいけると言っている人もいる。
一応試すと良いかも。

```json:tsconfig.json
{
  "compilerOptions": {
    "module": "esnext",
    "removeComments": true,
  }
}
```

## その他
### エイリアスは使わないほうが無難説
`@` で `/src` を表す系のものはやめたほうがいいと言っている人もいる。

### そもそも `chunkFileName` が指定されているかどうか確認
さんざん騒いだ後に「指定してなかったわ。。。orz」みたいなのは避けたい。
Tencent CloudのRTCを使って、ビデオチャットサービスをつくる

### TRTCの紹介
Tencent Real-Time Communication（TRTC）はTencentが21年間に蓄積したネットワーク及び音声ビデオ技術に基づいて、複数人の音声ビデオ通話と低遅延のインタラクティブライブストリーミングソリューションを提供します。Tencent Cloudサービスを通じて開発者に開放します。TRTCの詳細は[こちら](https://intl.cloud.tencent.com/jp/product/trtc)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/633185/7995bf92-c90c-b604-45a1-e068ac9fcc74.png)

この記事では主に、Tencent Cloud TRTC Demo（Android）をすばやく実行する方法を紹介します。
Demoを1分以内に実行し、30分で音声通話、ビデオ通話、インタラクティブストリーミングソリューションを構築できます。

### 前提条件
- テンセントクラウドのアカウントを持っていること
- クラウドの営業担当に連絡した上、TRTCの機能を有効していること

### 環境要件
- 少なくともAndroid 4.1（SDK APIレベル16）と互換性があり、Android 5.0（SDK APIレベル21）以上を使用することをお勧めします
- Android Studio 3.5以降
- APPにはAndroid 4.1以上のデバイスが必要です



### コンソールでアプリを作成
TRTCのコンソールをアクセスして、下の図のようにアプリを作成します。
Demo名前は適当な英字でOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/633185/0549139c-1628-6f7d-6c28-f7989c73efcf.png)

### SDKとDemoのソースコードをダウンロード
Android、iOS、Webなどの多くのプラットフォームのSDKがありますので、開発にはとても便利です。
今回のAndroidのSDKを使って、説明します。Githubからあるいは直接にZipファイルのダウンロードはOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/633185/2767ece9-af18-0a56-3ff2-b53d87d994b8.png)

### Demoのソースコードの設定
下の図のように、SDKApIDとSecret Keyを```/liteav/debug/GenerateTestUserSig.java ```に設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/633185/6707412c-3a2e-04c7-2271-ae469a310309.png)

*ちょっと注意してもらいたい：今回のdemoがSecret Key(クラウドの認証する為の秘密鍵)をアプリに設定しましたが、実際の運用の時にサーバに設定します。なぜかと言うと、アプリをデコンパイルしてしまうと、第三者にクラウドの認証する為の秘密鍵が漏れてしまいます。Secret Keyを使ってUserSigの生成でクラウドの認証の仕組み及びサーバの設定方法は[こちら](https://qiita.com/hiSirius/items/3c6fdb19ae8e428f9dbb)*

### コンパイル＆実行
コンパイルをすると、実行できます。

### 実行の結果
- 友達と通話してみました。音質と画質も非常に高いレベルでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/633185/7af42f2a-8daf-a084-6aed-fdfc5aabeccc.png)
- 遅延について
二台のスマホでこのStop watch(https://www.estopwatch.net) を同時に映って測ってみました。
遅延は58ms、16msでした。
<img width="859" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/633185/33d6ab42-05a0-a38e-1e2a-c11970e6e4a7.png">
<img width="946" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/633185/38a43e9a-1ebb-680f-f132-08b9ff663b90.png">

- コンソールで通話の使用量の確認。
音声通話：27分, 標準画質ビデオ通話：39分。　一目瞭然ですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/633185/602d9d78-3fbf-b396-1b31-ee0edd9301ec.png)





### 良くある質問
【Vue.js】slot で HTMLタグやデータを渡す

# はじめに
slot を学習したので備忘録的に書きます。

# slot とは
子コンポーネントにコンテンツ（HTMLタグやdata, props など）を渡すことができるもの。

と解釈。

[参考資料（リファレンス）](https://jp.vuejs.org/v2/guide/components-slots.html)
# HTMLタグを渡す


```Childe.vue
<template>
  <div>
    <slot></slot>
  </div>
</template>
```


```Parent.vue
<template>
  <div>
    <Childe>
      <p>スロットだよ</p> <!-- ここの記述をタグごと渡す -->
    </Childe>
  </div>
</template>

<script>
import Childe from "./Childe.vue";

export default {
  components: {
    Childe,
  }
}
</script>
```

# propsのデータも一緒に渡す

```Childe.vue
<template>
  <div>
    <slot></slot>
    <p>{{ propsText }}</p> <!-- 受け取ったpropsを表示 -->
  </div>
</template>

<script>
export default {
  props: ['propsText'],
}
</script>
```

```Parent.vue
<template>
  <div>
    <Childe props-text="プロップステキスト"> <!-- propsの渡し口 -->
      <p>スロットだよ</p>
    </Childe>
  </div>
</template>

<script>
import Childe from "./Childe.vue";

export default {
  components: {
    Childe,
  }
}
</script>
```

# 親dataを渡す

```Childe.vue
<template>
  <div>
    <slot></slot>
    <p>{{ propsText }}</p>
  </div>
</template>

<script>
export default {
  props: ['propsText'],
}
</script>
```

```Parent.vue
<template>
  <div>
    <Childe props-text="プロップステキスト">
      <p>スロットだよ</p>
      <p>{{ data }}</p> <!-- data を受け取る -->
    </Childe>
  </div>
</template>

<script>
import Childe from "./Childe.vue";

export default {
  data() {
    return {
      data: "データ",
    }
  },
  components: {
    Childe,
  }
}
</script>
```

# 複数slotに個別に名前をつけて使い分ける
```Childe.vue
<template>
  <div>
    <slot name="text"></slot> <!-- slotに名前をつける -->
    <slot name="data"></slot> <!-- slotに名前をつける -->
    <p>{{ propsText }}</p>
  </div>
</template>

<script>
export default {
  props: ['propsText'],
}
</script>
```

```Parent.vue
<template>
  <div>
    <Childe props-text="プロップステキスト">
      <template v-slot:text> <!-- 名前を付けたslotに対応させるコンテンツを指定 -->
        <p>スロットだよ</p>
      </template>
      <template v-slot:data> <!-- 名前を付けたslotに対応させるコンテンツを指定 -->
        <p>{{ data }}</p>
      </template>
    </Childe>
  </div>
</template>

<script>
import Childe from "./Childe.vue";

export default {
  data() {
    return {
      data: "データ",
    }
  },
  components: {
    Childe,
  }
}
</script>
```
Zendesk API よく使うものまとめ

Zendeskを使ってアプリ開発を行っている方、あるいはこれから使おうと考えている方むけに
よく使うAPIをまとめました。
少しでもZendeskで苦しんでいる人の助けになれば幸いです。
詳しいことは[公式](https://developer.zendesk.com/rest_api/docs/zendesk-apis/resources)に記載されているため、困ったときは是非参照してみてください。

# User関連

Zendeskにユーザーを作成したり、ユーザー情報を取得する場合に使用するAPIを記載します。

- **ユーザー情報取得**
  - ユーザのIDを使用してユーザー情報を取得します。 

```
GET /api/v2/users/{id}.json
``` 
<br/>

- **複数のユーザー情報取得**
  - ユーザのIDを使用して複数のユーザー情報を取得します。 
  - 例：　`〜 ids=1,2,3` 

```
GET /api/v2/users/show_many.json?ids={ids}
```

<br/>

- **ユーザー作成**
  - パラメーターを渡して、ユーザを作成します。 

```
POST /api/v2/users.json
```

　↓パラメーターの例

```
user: {
  name: "test",
  email: "test@test.com",
  phone: "0001112222",
  ...
}
``` 

　

- **ユーザー更新**
  - パラメーターを渡して、ユーザ情報を更新します。 

```
PUT /api/v2/users/{id}.json
```

　↓パラメーターの例

```
user: {
  id: 1111111,
  email: "update@test.com",
  ...
}
``` 


# チケット関連

Zendesk上でチケット周りを操作するAPIを記載します。


- **チケット作成**
  - パラメーターを渡して、チケットを作成します。 

```
POST /api/v2/tickets.json
```

　↓パラメーターの例

```
ticket: {
  subject: "チケットのタイトル",
  comment: {
    body: "チケットの内容",
  },
  priority": "urgent",
  ...
}
``` 

　　
- **チケット更新**
  - パラメーターを渡して、特定のチケット情報を更新します。 

```
PUT /api/v2/tickets/{id}.json
```

　↓パラメーターの例

```
ticket: {
  id: 1234567,
  subject: "タイトル変更",
  comment: {
    body: "チケットの内容変更",
  },
  ...
}
``` 
  
# 記事関連

Zendeskでは記事を作成できるため、その記事を操作するAPIを記載します。


- **記事の取得**
  - 記事情報を取得します。 

```
GET /api/v2/help_center/ja/articles.json
```

　↑基本はこの形ですが、これだとすべての記事が取得されてしまいます。
　　それだと実用性に欠けるので、条件を絞っていきます。


- **カテゴリで取得**
  - Zendeskの記事を作成し、分類する上でカテゴリという概念が存在します。
  - 該当するカテゴリの中にある記事のみを取得したい場合は以下になります。

```
GET /api/v2/help_center/ja/categories/{カテゴリのid}/articles.json
```


- **セクションで取得**
  - カテゴリの中に、さらに小さい単位でセクションと言うものが存在します。
  - 該当するセクションの中にある記事のみを取得したい場合は以下になります。

```
GET /api/v2/help_center/ja/sections/{セクションのid}/articles.json
```

- **特定の記事をIDで取得**
  - 記事のIDを使用して、特定の記事のみを取得できます。

```
GET /api/v2/help_center/ja/ja/articles/${記事のid}.json`;
```

- **クエリで絞る**
  - 様々なクエリ条件を指定して、取得結果を操作することも可能です。

　↓条件別にソートする

```
　記事の更新日でソート
　〜？sort_by=updated_at;

　Zendesk画面上の表示順でソート
　〜？sort_by=position;

  上記でソートしたものを昇順or降順で並べる
  〜？sort_by=updated_at＆sort_order=asc　（降順ならdesc）

　etc
```

　↓ページングして取得する

```
　?per_page=5&page=1；
```
per_pageで記事を何個単位でページングするか指定し
pageで何ページめを取得するか指定する。
例えば全部で８つの記事があった場合、per_pageが５なら
page=1で５つの記事、page=２で残りの3つの記事が取得される。


##参考
冒頭にも記載しましたが[公式](https://developer.zendesk.com/rest_api/docs/zendesk-apis/resources)に詳しく記載されていますので困ったときは是非ご参照ください。