OmniAICreator/Qiita-1.07M huggingface dataset:
railsのコントローラーでAPIの必須項目の入力チェックする

railsのコントローラーでAPIの必須項目が入力されているかチェックする方法です。
どんなケースで使うのか具体的な使い方を書いていきます。
rails guideには以下の説明がされています。

> In addition, parameters can be marked as required and will flow through a predefined raise/rescue flow that will result in a 400 Bad Request being returned if not all required parameters are passed in.

https://guides.rubyonrails.org/action_controller_overview.html#strong-parameters

## サンプルコード

```ruby
class UserController < ApplicationController
  rescue_from ActionController::ParameterMissing, with: :handle_parameter_missing

  def index
    @users = User.search(user_search_params)
  end

  private

  def user_search_params
    params.require(:name, :email)
    params.permit(:name, :email)
  end

  def handle_parameter_missing(e)
    render json: { message: e.original_message }, status: 400
  end
end
```

## コードの説明

1. `index`アクションではユーザの入力値を使ってユーザ情報の検索を行う。
1. ユーザの入力値は`require`メソッドを使用して必須項目の存在確認を行う。
1. 必須項目が存在しない場合は例外`ActionController::ParameterMissing`が発生するので`rescue_from`で捕捉する。
1. `rescue_from`で例外を捕捉した後`handle_parameter_missing`内でエラーメッセージを抽出しレスポンスのjsonを返却する。

## コードの詳細な説明

### 1. actionの定義

ユーザの検索アクションです。`User.search`引数にユーザの入力値を検証したパラメーターを指定します。

```ruby
def index
  @users = User.search(user_search_params)
end
```

### 2. 入力値の検証

```ruby
def user_search_params
  params.require(:name, :email)
  params.permit(:name, :email)
end
```

`require`メソッドを使ってパラメータを検証します。
`require`メソッドは引数に指定したkeyが存在しない場合、例外`ActionController::ParameterMissing`を発生させます。

### 3. 例外`ActionController::ParameterMissing`の捕捉

```ruby
  rescue_from ActionController::ParameterMissing, with: :handle_parameter_missing

  def handle_parameter_missing(e)
    render json: { message: e.original_message }, status: 400
  end
```

`rescue_from`で`ActionController::ParameterMissing`を捕捉してエラー処理を行います。

エラー処理では`message`keyに`original_message`で取り出したエラーメッセージを格納します。
また、status codeに400を指定します。

#### エラーメッセージの抽出について

`original_message`メソッドを使用して簡潔なエラーメッセージのみを取り出す事ができます。

```ruby
$ e.original_message
=> "param is missing or the value is empty: name"
```

`message` メソッドだとkeyのサジェストが出てしまいます。

```ruby
 e.message
=> "param is missing or the value is empty: name\nDid you mean?  target_date\n               rate\n               controller\n               format"
```


`e.full_message`だとスタックとレースが表示されます。

## 参考
rails guide

https://guides.rubyonrails.org/action_controller_overview.html#strong-parameters
【AWS】Amazon Route53について

# はじめに
AWS認定試験取得に向けてAWSの知識を整理するためのまとめです。
今回はRoute53についてまとめます。

# Amazon Route53とは
可用性と拡張性に優れたクラウドのDNS（ドメインネームシステム）サービスです。
DNSというのはドメイン名（例：www.example.com）を、IPアドレス(例：192.0.2.2)へ変換し、
ルーティングする仕組みです。

#Amazon Route53の特徴

## ホストゾーン
ホストゾーンとはレコードのコンテナであり、レコードには example.com や
そのサブドメインのトラフィックをどのようにルーティングするかに関する情報を保持します。
ホストゾーンの名前と対応するドメインの名前は同じです。
ホストゾーンは２種類あります。

| ホストゾーン | 詳細 |
|:--|:--|
|パブリックホストゾーン|トラフィックをインターネット上でどのようにルーティングするか指定するレコードが含まれています。|
|プライベートホストゾーン|トラフィックをVPCでどのようにルーティングするかを指定するレコードが含まれています。|

##ルーティングポリシー
ルーティングポリシーとはクエリに対してどう応答するかを決めるポリシーです。
レコードを作成するときにルーティングポリシーを選択します。

|ルーティングポリシー|詳細|
|:--|:--|
|シンプルルーティング|一つのリソース（1つのウェブサーバなど）に対して、ルーティングするとき（スタンダード）|
|フェイルオーバールーティング|アクティブ/パッシブフェイルオーバー構成の時に使用します<br>プライマリリソースとセカンダリリソースを用意し、プライマリリソースで異常が発生した場合、セカンダリリソースへ切り替えます。|
|位置情報ルーティング|ユーザの位置情報に基づいてルーティングする場合に使用します。<br>具体的にはクライアントのIPアドレスをもとに、国、地域にローカライズされたコンテンツを表示する場合に使用します。|
|地理的接近ルーティング|ユーザに物理的に近い場所にあるリソースを提供する場合に使用します。|
|レイテンシールーティング|複数のAWSリージョンにリソースがあり、より少ない往復時間で最良のレイテンシーを実現するリージョンにルーティングする場合に使用します。|
|複数値回答ルーティング（マルチバリュー）|複数のリソースにDNSレスポンスを分散する場合に使用します。<br>ヘルスチェックも同時にされて、正常なところへルーティングされる。|
|加重ルーティング|指定した比率で複数のリソースにルーティングする場合に使用します。|

##DNSレコードタイプ
レコードタイプとは
Route53でサポートされるレコードタイプは下記の通りです。

| レコードタイプ | 詳細 |
|:--|:--|
|A レコードタイプ|ホスト名とIPアドレス（IPv4）を関連付けます。|
|AAAA レコードタイプ|ホスト名とIPアドレス（IPv6）を関連付けます。|
|CAA レコードタイプ|ドメインの証明書を発行する認証機関を指定します。<br>第三者が勝手にサーバ証明書を発行することを防止できます。|
|CNAME レコードタイプ|ホスト名とドメインを関連付けます。<br>例えばtest.example.comに対して、　別のドメインsample.example.comなどを関連づけることができます。|
|DS レコードタイプ|DNSSECを利用するためのレコードです。<br> DNSSECとはDNSキャッシュポイズニングのような攻撃を防ぐ仕組みで、それを利用する場合はこのレコードを設定します。|
|MX レコードタイプ|メールサーバーの名前を指定します。|
|NAPTR レコードタイプ|名前付け権限ポインタ (NAPTR) は、動的委任発見システム (DDDS) アプリケーションで、1 つの値を別の値に変換または置き換えるために使用されるレコードのタイプです。<br>例えば、1 つの一般的な用途は、電話番号を SIP URI に変換する場合です。|
|NS レコードタイプ|ホストゾーンのネームサーバーを設定します。|
|PTR レコードタイプ|IPアドレスに対応するドメイン名を設定します。<br>IPアドレスからホスト名を割り出す「逆引き」時に利用されます。|
|SOA レコードタイプ|ゾーンを管理するための情報などを設定します。|
|SPF レコードタイプ|メールの送信者の身元を確認するために使用されていましたが、運用性の問題から現在はTXTレコードで作成することが推奨されています。|
|SRV レコードタイプ|負荷分散サービスの提供/冗長性の確保/サービスポート番号の通知を可能にするレコードです。|
|TXT レコードタイプ|ホスト名に関連付けるテキスト情報（文字列）を定義するレコードです。送信ドメイン認証の認証情報などを記述します。（SPFレコードの設定も可能です）|


#他のサービスとの連携
## CloudTrail
Route53に対して発行されたリクエストの種類、リクエストの発行元IPアドレスなどを記録できます。

## CloudWatch
CloudWatchを使用する事でRoute５３のヘルスチェックの状態を監視できます。
なんらか異常が発生したときは、異常を検知してメールなどで通知することも可能です。

他にも様々なサービスと連携可能です。

#料金
基本的には従量課金制となります。

## ホストゾーンの管理
Route53で管理しているホストゾーンごとに月額料金が発生します。

## DNSクエリへの応答
クエリの内容ごとに日割り計算で料金が発生します。

他にも様々な要素で料金が発生します。

#参考サイト
https://aws.amazon.com/jp/route53/
https://dev.classmethod.jp/articles/route53-resolver/
https://aws-community.com/aws-services-route-53/
https://www.nic.ad.jp/ja/basics/terms/dnssec.html
https://help.onamae.com/answer/7883
【Git】チームから学ぶGitの使い方　プルリクエスト作成編

####My Profile
プログラミング学習歴②ヶ月目のアカウントです！
プログラミングスクールで学んだ内容や自分が躓いた箇所等のアウトプットの為に発信しています。
また、プログラミング初学者の方にわかりやすく、簡潔にまとめて情報共有できればと考えています。
もし、投稿した記事の中に誤り等ございましたら、コメント欄でご教授いただけると幸いです。　



#対象者

* pull request(プルリクエスト)の使い方を知りたい方


#目的

* プルリクを出してからマージまでの流れを抑える

#実際の手順と実例
###0.前回までの流れ

https://qiita.com/nao0725/items/7f431f81cbe60abe5931


###1.プルリクとは、、、、？
pull request(プルリクエスト)の略称です。
他のメンバーに変更点を通知する際にこの機能を使います。


###2.実際のプルリクの流れを解説

#####1. プルリク作成
![スクリーンショット 2021-07-26 7.45.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1681213/7fe96243-9626-89e7-f01a-95ef8c7d12d6.png)

#####2. 作成後は作業していたブランチから統合ブランチをマージできるようにします。
下記の図の①がトピックブランチで②が統合ブランチです。
そして画像③をクリックすればプルリク作成完了です。
![スクリーンショット 2021-07-26 7.49.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1681213/74cf5d39-07fe-2cda-4d8a-48da1d6f311c.png)

⚠画像①②の右にAble to mergeと表示されていますが、このように表示されていれば、問題なくプルリク作成できます。しかし、コンフリクトが起きていると、赤文字で表示されますがそのままプルリク作成しても問題ありません。

#####3. コミットメッセージを残す

どのように変更したかを具体的に書いていくと見て下さるメンバーに伝わりやすいです。

![スクリーンショット 2021-07-26 8.02.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1681213/97c6c189-0bd5-ae5e-d1de-3636a3a45d90.png)


###3.プルリクエスト完了後

#####1.コメントする
プルリクが作成完了後は、変更点に問題がなければ、プルリクをみた他の開発メンバーがコメントを残します。

⚠**必ず他のメンバーがプルリクを承認してください。**理由としては、自分でプルリクを確認してしまうと、どこを変更したかメンバーがわからないまま開発が進んでしまうからです。

#####2.マージする
問題がなければ、**Merge Pull Request**を押せばマージまで完了です。Terminal上でマージしなくてもここで実行されます。

#####3.最新の状態をPullする
最後に、自分の作業ブランチに戻って、最新状態になった統合ブランチをpullすると変更内容が反映されます。
（ここで自分の作業ブランチでコミットしていない箇所があるとエラーが起きるので、先にコミットしてからpullしましょう）

````
$ git checkout 自分の作業していたブランチ
````
````
$ git pull origin develop
````
Before starting UiPath:回数が分かっている繰り返し（For）発展

## 皆もすなるQiitaといふものを、儂もしてみむとてするなり。

と言う訳で、こん＊＊は！はなっち！です。

★★★この記事はUiPathブログ発信チャレンジ2021サマー、7/26の記事です。★★★

今回は、ちょっとしたシリーズです。UiPathを使うに当たって、UiPathの機能ではなく、コンピュータ言語を使う上での基礎知識を展開していこうと思います。

#回数が分かっている繰り返し（For）発展

お財布の中の10円玉を積み上げてみてください。その中に、令和に発行された硬貨は何枚あるでしょうか？
さて、どうやりますか？積み上げた、すべての硬貨を、一枚一枚、確認していきますね？

と言うのは「繰り返し（For）」で読んだよって思った方もいらっしゃるでしょう。前振りです<m(__)m>

お財布の中の10円玉と100円玉を積み上げてみてください。その中に、令和に発行された10円硬貨は何枚あるでしょうか？
さて、どうやりますか？積み上げた、すべての硬貨を、一枚一枚、確認していきますね？

と言うお話です。

「繰り返し」は、以下のようなフローチャートになります。

　　　　積み上げた硬貨【すべてを確認しおわるまで】、以下の動作を行う。
　　　　　　１）硬貨を手に取る
　　　　　　２）10円玉だったら、2-1）～2-3）の処理をする
　　　　　　　　2-1）発行年が見える面にする
　　　　　　　　2-2）令和ならカウントアップ
　　　　　　　　2-3）確認した硬貨を脇に置く
　　　　    ３）１）に戻る

この「繰り返し」の中で、途中で次の硬貨の確認をするシーンがあります。
無論、IF文の「True」で制御するのも手ですが、「continue」と言う考え方があります。

IF文で100円玉だったら、「continue」で制御すると、次の反復処理の先頭に制御が移動します。

　　　　積み上げた硬貨【すべてを確認しおわるまで】、以下の動作を行う。
　　　　　　１）硬貨を手に取る
　　　　　　２）100円玉だったら、３）～５）をやらない  ← ここが新しい
　　　　　　３）発行年が見える面にする
　　　　　　４）令和ならカウントアップ
　　　　　　５）確認した硬貨を脇に置く
　　　　　　６）１）に戻る

このように、反復処理の中で制御を変えていく命令文を「ジャンプステートメント」と言うようです。

「ジャンプステートメント」には、「Break」と言うのもあります。

お財布の中の10円玉と100円玉を積み上げてみてください。100円硬貨が出てくるまでの10円玉に、
令和に発行された10円硬貨は何枚あるでしょうか？

IF文で100円玉だったら、「Break」で制御すると、反復処理を終了させます。 終了した後ろに次にステートメントがある場合は、そこに制御が移動します。

　　　　積み上げた硬貨【すべてを確認しおわるまで】、以下の動作を行う。
　　　　　　１）硬貨を手に取る
　　　　　　２）100円玉だったら、繰り返しを止める  ← ここが新しい
　　　　　　３）発行年が見える面にする
　　　　　　４）令和ならカウントアップ
　　　　　　５）確認した硬貨を脇に置く
　　　　　　６）１）に戻る

##おわりに
いかがでした？

処理の制御、面倒ですねぇ。はなっち！的にはBoolean変数で処理するしないを制御しています。これは改造、改版の際に、可視性を高めるためと考えているのですが。。。どうでしょうね。

是非UiPathでのロボ開発の一助になればと思っています。

ありがとうございました！
[GitHub Actions]Environmentsを利用した自動push

- 普段CIとしてGithub Actionを利用しているが、環境変数の取扱いには色々な手法がある。
- その中で最近利用可能になった機能がEnvironmentsであり、各用途毎に分けて定義が可能。
- 今回はそのEnvironmentsの利用を覚えるため、データ更新及び自動pushを例としたサンプル利用を記録する。

## 環境
- Mac OS X 10.15.6

## 手順

### 要件整理
- 今回利用するサンプルのディレクトリ構成は以下。
  - **※.githubディレクト以下はこれから作成**
  - **※data(あるAPIから取得して整理したCSVデータ)・script(APIからの取得及び整理処理)**

```
.
├── .github
│   ├── worlflows
│   │   ├── main.yml
├── data
│   ├── ***.csv
├── script
│   ├── update.sh
```

- 今回CIで毎日12時に自動で実現したい要件は以下。
  - あるAPIから取得したdataディレクトリ内のファイルを更新するscriptディレクトリ内の`update.sh`を起動
  - Environmentsで定義したgit環境情報で自動push

### Environments定義
1. [Github](https://github.com/)上のサンプルディレクトリ内のsettings内のEnvironments欄に遷移して、`New environment`をクリック。
2. 任意のNameを入力して追加。
3. 作成したenvironmentを押下して「Configure update」欄の`Add Secret`を押下。
    - **※本来は「Environment protection rules」でレビュアーの設定等を行うが、今回は割愛。**
4. `GIT_EMAIL`としてgit情報の任意のemailを定義。
5. 完了

![image](https://user-images.githubusercontent.com/44114228/126892273-d16598de-769a-4322-8cf0-652120ddbdbc.png)

![image](https://user-images.githubusercontent.com/44114228/126892427-1f503f70-c9c2-403a-a7e3-1442f75e48b1.png)

![image](https://user-images.githubusercontent.com/44114228/126892630-6b58852b-b1ea-4f91-bf0e-43b682eca0e2.png)

### ファイル用意
- サンプルディレクトリにワークフローを定義するための必要なディレクトリ及びファイルを以下のように作成する

```shell
# 任意
cd work/sample
# workflowsディレクトリ作成
mkdir -p .github/workflows
# workflowsファイル作成
touch .github/workflows/main.yml
```

- 作成後、中身を以下のように記述する。

```yaml:.github/workflows/main.yml
name: "dataUpdate"

on:
  schedule:
    - cron: '00 3 * * *'

jobs:
  build:
    runs-on: ubuntu-latest
    environment: update
    steps:
    - uses: actions/checkout@v2
    - name: Update Data
      run: sh ./script/update.sh
    - name: setting git
      run: |
        git config --local user.email ${{ secrets.GIT_EMAIL }}
        git config --local user.name "アカウント名"
        git add .
        git commit -m "update current_data $(date '+%Y%m%d')"
        git push origin master
```

- 記述後、githubにpushすれば完了。

## 結果
- 指定した時間にワークフローのコミットメッセージ通りに以下のようにpushされていることを確認。

![image](https://user-images.githubusercontent.com/44114228/126892927-3b485165-a39a-49f0-b342-18d2f8b7b93c.png)

## まとめ
- GitHub Actionsのスケジュールと環境変数を利用すれば、サーバー不要で自動pushやデータ整理が可能であることが分かった。
- ただ環境変数の取扱いには注意が必要。

## 参考
- [公式](https://docs.github.com/ja/actions/reference/environments)
CSSを書くときは、プロパティや値の意味が自然になるものを選ぼう

## これは何

- CSSでは同じUIを表現するにしてもたくさんの書き方があります
- 最終的な見た目は同じになるとしても、プロパティや値の意味が不自然なものを選ぶと後から困りがち……
- 自然な書き方の例をいくつかまとめた記事です

## 中央揃え

何かの要素を左右中央に揃えたいとき、`text-align: center;`でも`display: flex; justify-content: center;`でも、どちらでも同じ見た目になる場合が多いです。

しかし`text-align`はあくまで`文章の行揃え`に関するプロパティ。
そもそもがレイアウトをするために存在するプロパティではありません。

なんとなくで`text-align`を使っていると、子要素にブロック要素を配置したときに上手く中央揃えにならなくて困っている……なんて人もときどき見かけます。

## 横並び

2021年現在、恐らく横並びを実現するのにfloatを使っている人は多くないと思いますが、`display: inline-block;`を手癖で書いているであろう人はたまに見かけます。

`float`はあくまで後続を回り込ませるためのプロパティ。
`display: inline-block;`は、あくまで要素の幅ピッタリになるだけで横並びにさせる意図はない。

などなどから`display: flex;`を使うのが良いでしょう。
横1列ではなく、縦にもレイアウトしたいなら`display: grid;`も便利です。

## marginとpadding

どちらも和訳すると「余白」になってしまいがちで、混同している人も多い気がします。
`margin`は「外側の余白」で`padding`は「内側の余白」と考えてください。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/90431c76-f3ff-4716-dd07-62813e6b5662.png)

2つのボタンが横並びで存在するとして、ボタン同士の余白は外側の余白なので`margin`でとる。
対してボタンの背景色とテキストの距離は内側の余白なので`padding`でとる。

もちろんマークアップの内容によって変わってくるのですが、自分が関心を寄せている対象の外側に距離をとりたいのか、内側に距離をとりたいのかを考えてください。

全てをmarginでとると相殺が大量に発生して計算が難しくなり、逆に全てをpaddingでとるとマークアップのネストが深くなりすぎます。

## マジックナンバーを使わない

CSSに限った話ではありませんね。

文章とアイコンの位置を揃えたいとか、ドロップダウンメニューの表示位置を調整したいとかで`margin-top: -14.4px;`のような記載になっているのをときどき目にします。
どこから出てきたのか分からない値が入っていると、レビュワーも困りますし、後から変更したいときも大変ですよね。

例えば1文字分ずらしたいなら`margin-top: -1em;`と書いた方が意図を伝えやすいはず。

また、目視で指定するのではなくちゃんと計算して、式もコメントか何かで書いておきましょう。
`/* font-size: 16px * line-height: 1.8 / 2 = 14.4 */`とでも書いてあれば後から見ても一目瞭然です。
更に言えばSass VariablesやCSS Custom Propertiesがちゃんと設定されていれば`margin-top: calc($font-size * $line-height / 2)`のようにコメントを書かずとも内容が分かります。

## z-indexの数値

[@tokumitu](https://qiita.com/tokumitu)さんから質問をいただいたので記載します。
コメントありがとうございます :pray: 

z-indexはいくつか流派があるような気がしますが、私の場合は「数値の大小で重なり順を制御せず、0と1をboolとして扱う」ようにしています。

どういうことかというと、仮に`z-index: 9999;`が指定された要素があったとしても、親要素の指定や`transform`指定などによっては1番上に配置されないのです。

逆に`z-index`を指定せずともコードとして後の行に書かれた要素であれば上に配置されます。
そのため、モーダルウィンドウなどをJavaScriptから追加/削除する場合などでも、マークアップの最後に追加すれば割と勝手に1番手前に要素が描画されます。

できるだけマークアップ側で要素の重なりを制御することで、`z-index`は0か1だけのboolのようなつもりで扱える……という寸法。
CSSをトレースして重なり順をシミュレートするのは大変なので、私はよくこのような手法をとります。

## こういう場面で迷った、があったら

コメント頂けたらこの記事に追記するかもしれません。
全てにお答えできる保証はありませんが、もし疑問があればお気軽にどうぞ。
[Rails]値オブジェクトとは？〜使い方と注意点を押さえる〜

# はじめに
開発の規模が大きくなればなるほど、モデルが肥大化するFat Modelという問題が発生しやすくなります。そこで、`値(Value)オブジェクト`という設計手法を利用することでこの問題が解決出来ますので、利用方法と注意点をしっかり押さえて導入を検討してみましょう！

# 値オブジェクトとは？
値オブジェクトとは、読んで字の如く、「値」を表すオブジェクトなのですが、この値とはドメイン駆動設計という設計手法に登場する概念で、同一性を判断できない情報のことを指します。
値オブジェクトを利用することで、コードを綺麗に保ち見通しが良くなることで、テストが書きやすくなり、Fat Modelの問題を解消できます。また、**オープン・クローズドの原則**という、`あるクラスを修正したとき、他のクラスに影響が出ない設計`を実装できます。

## 例
山田さんと田中さんがいるとします。この2人の血液型はどちらもA型です。血液型が同じだからといって、同一人物となるわけではありません。
こういった、値が同じでも同一だと断定できない情報のことを値オブジェクトと呼びます。
※住所や名前なども同様です

# 前提条件
- ユーザー(User)、管理者(Admin)という2つのクラスがあるとする
- それぞれ名前として姓と名を持つ
- 姓と名からフルネームを取得できる

# 使い方
それぞれのユーザーの名前を値オブジェクトにします。

1.名前を切り出したNameクラスを実装する。

```app/values/name.rb
class Name
  attr_reader :first_name, :last_name

  def initialize(first_name, last_name)
    @first_name = first_name
    @last_name = last_name
  end

  def full_name
    "#{first_name} #{last_name}"
  end
end
```

2.それぞれのユーザーのクラスに値オブジェクトを使えるように設定する。

```app/models/user.rb
class User < ApplicationRecord
  # 第一引数に値オブジェクト名、第二引数には属性のマッピング
  composed_of :name, mapping: [%w(first_name first_name), %w(last_name last_name)]
end
```

```app/models/admin.rb
class Admin < ApplicationRecord
  # 第一引数に値オブジェクト名、第二引数には属性のマッピング
  composed_of :name, mapping: [%w(first_name first_name), %w(last_name last_name)]
end
```

## 利用例
### Valueオブジェクトを用いた検索

```ruby
users = User.where(name: Name.new('Taro', 'Yamada'))
```

## ユースケース
- 複数の値を組み合わせてひとつの値を算出するもの
    - 名前(姓・名・ミドルネーム)
    - 住所(国や県・市区町村など)

- 値の表現や比較を行うもの
    - 日付
    - 通貨
    - 気温
    - 商品レビューにおける星の数


## 注意点
- 導入タイミングは、値オブジェクトを複数のクラスから利用することになったとき

- `app/values`下に配置

- ファイル名はValueオブジェクトの名前にする
    - name.rb
    - address.rb

- 必要最低限のインタフェースのみを公開する
    - 公開したインタフェースに対するユニットテストを書く

# 終わりに
上記の通り、何もかも切り出して値オブジェクトとしても良いわけではないようですね。注意点をしっかり押さえることで、見通しが良いコードを実装出来るので、これからタイミングを見て使っていきましょう！

# 参考
[Rails: Value Objectを検討してみよう（翻訳）]
(https://techracho.bpsinc.jp/hachi8833/2020_10_27/82304)

[Railsのデザインパターン: Valueオブジェクト]
(https://applis.io/posts/rails-design-pattern-value-objects)

[composed_of を使って Rails で値オブジェクトを扱う]
(https://buildersbox.corp-sansan.com/entry/2020/04/08/110000)
Python で開平法の手順を使った平方根の近似値を求める処理を作成してみた

バージョン

- Python 3.8.3

# 開平法

筆算で正の数の平方根を任意の桁まで求められる方法

今回はあえてプログラムで同じ手順で平方根を求めてみました

- 参考
    - [開平法の手順|思考力を鍛える数学](http://www.mathlion.jp/article/ar124.html)

# `math.sqrt` で一発で平方根は出せるのでこんな処理は必要はない

```py
from math import sqrt

print(sqrt(3)) # 1.7320508075688772
print(sqrt(100)) # 10.0
print(sqrt(111)) # 10.535653752852738
print(sqrt(277729)) # 527.0
print(sqrt(23480.352289)) # 153.233
```

<font color="Red">**このように簡単に平方根の値は出せるので今回のようにわざわざ作る必要はありません。**</font>

私が python と数学の勉強のために作ってみた処理になります。

何か間違いなどありましたら教えていただけるとありがたいです。

# 作ってみた開平法の処理

```py
from sympy import Symbol, solve
from sys import argv
from math import sqrt, floor, ceil

_, num, digit = argv

result = ''
cnt = added_num = minused_num = 0
x = Symbol('x')

# 整数部分と小数点数部分で２回ループする
for i in range(2):

    if int(digit) <= cnt:
        break

    split_num = num.split('.')[i] if i == 0 or '.' in num else ''

    if i == 0:
        # 1週目は整数部分なので最初を0埋め
        formatted_num = ('0' if len(split_num) % 2 else '') + split_num
    else:
        # 2週目は小数点数部分なので最後を0埋め
        formatted_num = split_num + ('0' if len(split_num) % 2 else '')
        result += '.'

    two_num_list = [int(v + formatted_num[i + 1]) for i, v in enumerate(formatted_num) if i % 2 == 0]

    # 2桁ごとに分割した数字単位でループ
    j = 0
    while int(digit) > cnt:

        if i == 0 and len(two_num_list) <= j:
            # 整数部分を計算したので小数点部分へ行く
            break

        target_num = int(str(minused_num) + (str(two_num_list[j]) if len(two_num_list) > j else '00'))

        if cnt == 0:
            # 最初の1回だけべき根以下の最大の自然数を取得
            calc_stacking_num = result_num = floor(sqrt(target_num))
        else:
            # 2週目以降
            #   x*(added_num*10+x) が target_num 以下の最大の自然数を取得
            result_num = [floor(v) for v in solve(x * (added_num * 10 + x) - target_num, x) if v >= 0][0]
            calc_stacking_num = int(str(added_num) + str(result_num))

        result += str(result_num)

        # calc_stacking_num と下一桁を足す
        last_num = int(str(calc_stacking_num)[-1])
        added_num = calc_stacking_num + last_num

        # 次の two_digit と合わせるために引いた数を取得しておく
        minused_num = target_num - result_num * calc_stacking_num

        cnt += 1
        j += 1

print(result)
```

```console
$ # python kaiheihou.py [平方根を求めたい数字] [処理を繰り返す桁数]
$ python kaiheihou.py 3 10
1.732050807
$ python kaiheihou.py 100 5
10.000
$ python kaiheihou.py 111 20
10.535653752852738848
$ python kaiheihou.py 277729 5
527.00
$ python kaiheihou.py 23480.352289 10 # 小数点数もいける！
153.2330000
```
2021/07/24開催 Connpassイベントランキング

# 申込数TOP5

|順位|イベント名|グループ|申込数|定員|
|:---:|:---|:---|:---:|:---:|
|:one:|[Rによるオープンデータ前処理勉強会（医療データ）](https://connpass.com/event/219249/)||403||
|:two:|[AWSの基礎を学ぼう 特別編　最新サービスをみんなで触ってみる はじめての元帳データベース](https://awsbasics.connpass.com/event/216055/)|[AWS エバンジェリストシリーズ　AWSの基礎を学ぼう](https://awsbasics.connpass.com/)|313||
|:three:|[【無料】機械学習・データサイエンス基礎講座（６）](https://datascienceteam.connpass.com/event/217258/)|[異業種データサイエンス研究会](https://datascienceteam.connpass.com/)|231|350|
|:four:|[今宵はゆるりと情シストークしよう！6回目！](https://infosys-talk.connpass.com/event/218773/)|[情シストークしようぜ！](https://infosys-talk.connpass.com/)|77|77|
|:five:|[【オンライン】スマホでAzure IoT！『ifLink』マイクロサービス開発入門ハンズオン](https://algyan.connpass.com/event/217486/)|[ALGYAN(あるじゃん)主催 公式イベント！](https://algyan.connpass.com/)|62||
【R】接続

library(readr)
library(XML)
library(stringr)

xmlToDataFrame("text.xml")

xml<-read_csv("text.xml",col_names =FALSE)
colnames(xml)<-("xml")

vin<-xml[grep("VIN",xml$xml),]

file_txt<-read_csv("filelist.txt",col_names = FALSE)
colnames(file_txt)<-("file_list")

list<-file_txt$file_list

for (tar_txt in list) {
  xml<-read_csv(tar_txt,col_names =FALSE)
  colnames(xml)<-("xml")
  vn<-xml[grep("vn",xml$xml),]
  print(vn)
}

file_list<-dir("./data/")
for (tar_txt in file_list) {
  xml<-read_csv(tar_txt,col_names =FALSE)
  colnames(xml)<-("xml")
  vn<-xml[grep("vn",xml$xml),]
  # 文字列抽出
  pick_vn<-str_sub(vn,start = 6,end = -7)

  
    
  data.frame(pick_vn,pick_system,pick_dtc,file_path)

}


###############wt#####
library(readr)

file_list<-dir("./wt_data")
setwd("./wt_data/")

wt_table<-data.frame()
col_list<-c("flag","CL_NUM","CL_NUM_H","CL_NUM_RO","PRO_CD","DATA_CD","WR_CD","RO_CD","Cont_CD","RO_CD_3","RO_CD_O","Cont_CD_O","ST_CD","DL_CD","PRO_div_CD","PRO_CD_D","MK_CD","CA_CD","PUR_CD","SIT_CD","DIS_CD_R","UNI_KEY","UNI_KEY_ORI","NU_CD","FR_CD","FR_NUM","MO_CD","MO_NAME","SER_CD","REG_DAY","WO_DAY","DISTA_CD","KM_DATA","MI_DATA","HOU_DATS","PA_DIST_CD","PAR_DIST_KM","PAR_DIST_MI","PAR_DIST_HO","BRA_CD","COS_CDS","CLA_DIST_CD","CH_DATE_RO","CH_DATE_H","BAN_DATE","ACC_DATE","ACCO_DATE","SS_DIST","WT_CD_RO","WT_CD_RO_RPA","WT_CD_RO_PA","WT_CD_BASE","RAT_WO","ARR_CO","CRE_DE_CD","MAK_R","PN_5","PN_3_1","PN_3_2","PN_EX","ALL_PN","CATE_CD","WT_CD_PA","PA_ER_CD","REP_REG_DATE","REP_DO_DATE","CONT_CD","SY_CD_1","SY_CD_2","PU_R_CD","TR_CD","QI_CD","DIST_SE_CD","DIST_SE_CD_RA","DAYS","PAR_COU_NUM","PAR_RA_CD","SUM_F","MY_CD","FA_CD","WR_CD_MA","ORI_DATE_CD","ORI_M_CD","EV_CD")
pick_col<-c("UNI_KEY")
for (wt_txt in file_list) {
  wt<-read_csv(wt_txt,col_names =FALSE)
  colnames(wt)<-(col_list)
  pick_wt<-wt[,pick_col]
  wt_table<-rbind(wt_table,pick_wt)
  
}
tmp<-read_csv("../list.txt",col_names = FALSE)
fix<-read_csv("../fix.txt",col_names=FALSE)
new_txt<-cbind(fix,tmp)
write.csv(new_txt,"../new.csv")
【初心者向け】RESTfulAPIを作るには？

# RESTful APIとは？
`REpresentational State Transfer` の略です。
よくRESTと言われます。

***

## APIとは？
`アプリケーションプログラミングインタフェース`と言われます。
ざっくり言うと、外部向けに機能を公開したものです。
有名なものといえばGoogle Maps APIでしょうか。

***

## RESTful APIを作る際に必要なもの
大雑把に言ってしまうと

- Request(送信するデータ、送信先URL等)は何か
- Response(返却するデータ、ステータスコード等)は何か

の２つです。

***

## データの送受信
基本的にはJSONで送受信します。
（xmlで通信する場合もあるかもしれません）
URLに何らかのIDをパラメーターとして埋め込む場合も多々あります。

***

## MIME TYPE
基本的に

- Application/json
- Application/xml

のどちらかで通信します。

***

# REST APIの設計
ExcelでAPI設計書等を作る必要があるかと思いますが
`Swagger`を利用すると開発中にも試せて色々便利です。

https://editor.swagger.io/

***

# swaggerの書き方
- OpenAPI v3系
- Swagger v2系

の書き方が可能です。

***

## OpenAPI v3にするメリット
書き方がSwagger v2と変わるので、好き嫌いは分かれるかもしれませんが…
host（通信先）が複数定義できます。
AWSで送信先のAPI Gatewayが違う場合、いちいち送信先を書き換える必要が無くなるのでこちらが便利です。


***

## ドキュメント生成
Swagger UI等でHTMLドキュメントとして出力することも可能です。
自社サービスであれば、こちらの方が色々と楽です。

***

# REST APIの実行方法

基本的には非同期通信処理で実行します。

- jQuery等のクライアントサイドでは`Ajax`や`axios`
- PHP等のサーバーサイドでは`cURL`
- Swift等では`URLSessionDataTask`

などを利用して通信することが多いです。
（もちろん上記以外もあると思います。）

***

## Method

| METHOD | 詳細 |
|-:|:-|
| GET | データやコンテンツの取得 |
| POST | データの新規追加 |
| PUT | 既存データの更新 |
| DELETE | 既存データの削除 |

:::note warn
preflightでOPTIONSが送信される場合もあります。
:::

***

### MethodによってCRUD処理を分ける
例えばユーザーを削除したい場合は
`～～/user/{userId}/delete`のようなURLを定義するのではなく
`～～/user/{userId}`に対して、MethodをDELETEで送信する。

情報を取得したい場合は
`～～/user/{userId}`に対して、MethodをGETで送信する。

上記のように、同じURLに対してどう操作するかをMethodで決めること。

***

## 注意事項

:::note warn
API側はセッションを利用しないこと
:::

REST APIは原則`ステートレスであること`とします。
そのため、セッション等でサーバー側に情報を保持しておくことはしません。

***

# 参考
https://qiita.com/geshi/items/5275cc9d089105625c5f
https://qiita.com/NagaokaKenichi/items/0647c30ef596cedf4bf2
https://qiita.com/TakahiRoyte/items/949f4e88caecb02119aa
https://qiita.com/godgarden/items/be420a8c165f4a0f3ad8
https://qiita.com/sakuraya/items/6f1030279a747bcce648#%E3%81%9D%E3%81%AE-delete-%E6%9C%AC%E5%BD%93%E3%81%AB%E5%89%8A%E9%99%A4%E3%81%A7%E3%81%99%E3%81%8B
https://qiita.com/mtakehara21/items/efcbbc3ba58a62c10eb6
https://qiita.com/lamp7800/items/1e7612026dd2c9c818b3
RSpec の基本構文

# RSpecとは 　　
***Ruby用のテストフレームワーク***です。

# Modelのテストとspecファイル構文
yテストの内容は基本的にはこの構文です。他のもありますが基本はこの形です。

```user_spec.rb
describe “テストの対象”　do
     context “テストの条件” do
        it “期待する結果” do 
            expect(target).to eq xxx
  #targetはテストの対象　eqはmatcher  xxxはテストの対象
        end
    end
end
```

# matcherとは　　
期待値と実際の値を比較して、一致した（もしくは一致しなかった）という
結果を返すオブジェクト。
eq は、左右のものが等しいことをテストするものです。

# expectとmatcher
「テストの対象に対して、どのようなことを期待し、結果どうなるのか」 を記述してテストしていきます。
WEB版ETロボコンシミュレータについて（導入編）

![スクリーンショット 2021-07-26 2.16.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1804036/f35cbfd7-5f63-11db-f6f8-b2a325069a48.png)
https://webglsim.etrobo.jp

# はじめに
私はETロボコン実行委員の一員として、2020年にUnityによる[ETロボコン](https://www.etrobo.jp)シミュレータを開発しました。どんなものかは[ETロボコン 2021 プロモーションビデオ](https://www.youtube.com/watch?v=W4U41Jk_b38)を見ていただけると雰囲気がわかると思います。Youtubeには私の[技術的な解説動画](https://www.youtube.com/watch?v=XJ3cE9BqdO8)も公開されています。

# ETロボコンシミュレータの課題
[ETロボコン環境](https://github.com/ETrobocon/etrobo/)は参加者の間口を広げるために、WindowsだけでなくMacやLinuxにも対応しています。これは[棚橋先生の凄まじい努力](https://www.youtube.com/watch?v=lNX-QjdOMnA)によるものですが、一方で、環境構築のための時間がかかる問題や、不具合発生時の問題切り分けが非常に難しい問題を抱えることになりました。（売っぱらう予定だったiMac2014がデバッグ用に大活躍しています...）

また、TOPPERS/箱庭WGが開発した組込みCPUシミュレータAthrillとの連携も良い面と悪い面がありました。良い面は、実機向けのビルド環境と共通化できることです。シミュレータである程度確認したソフトウェアをロボットで動かそうと思えば動かせる、と言うところが素晴らしいです。悪い面は、Athrillの性能不足及び、UnityとAthrill間のUDP通信の遅さです。ゲーミングマシンであれば60fps以上で快適に動くものの、廉価PCでの動作はかなり厳しいものがあります。

その他にも、参加料を払っていただいている参加者の方々以外にはETロボコンシミュレータを提供することができず、教育用途で使ってみたいという方々からのご要望に応えることができませんでした。

# WebGLによるETロボコンシミュレータのビルド
気まぐれでUnityのWebGLビルドをやってみたところ、ETロボコンシミュレータが意外に動きそうな感触を得ました。そこで、プロモーションや2022年大会での利用をめざして、WEB版ETロボコンシミュレータを開発することにしました。

[UnityのWebGLでの開発](https://docs.unity3d.com/ja/2020.1/Manual/webgl-gettingstarted.html)は通常の開発よりも大変で、C#のソースコードを変更するとビルドに数分かかるような状況です。しかも、Unityエディタ上で動いたとしても、ちょっとしたことでブラウザ上で動かなくなるので、githubに少しづつコミットしながら動作確認をする必要がありました。

# ロボット制御用スクリプト MiniScript
Unity部分の目処が立ち、次の課題はロボット制御のスクリプトをどうするかでした。個人的にはPythonでやりたかったのですがいいソリューションが見つからず。Unityの中で軽量に動くスクリプト言語を探したところ、[MiniScript](https://miniscript.org)が良さそうだと思いました。Unityとのマイグレーション方法が明確であり、言語仕様がシンプルなので、初心者でも簡単にロボットを制御できそうです。

# WEBエディタAce
MiniScriptをどこで記述するかが問題になりました。最初はUnityのInputFieldを用いてエディタを実装したのですが、マウスをクリックするとテキストが全選択される問題や、WebGLのInputFieldがコピペに対応していない問題が発覚し、この解決にとても時間がかかった挙句、出来上がった機能(Script Panel)のあまりの使いづらさに、自分用のデバッグ機能として将来は闇に葬ることにしました。

MiniScript関係の情報を漁っていると、[Aceを用いてUnityを制御する例](https://forum.unity.com/threads/miniscript-lightweight-scripting-language-for-your-game.373853/page-2)を発見しました。と言うことで、これを参考にして作りました。

# WEB版ETロボコンシミュレータの公開
最初は自分のアカウントのAzureStaticAppsに置いていたのですが、勤め先の環境ではプロキシさんが邪魔をして動かないことが判明しました。そこで、ETロボコンのサブドメインを設定していただき、無事公開となりました。ETロボコンのホームページのAboutの一番下からも行けますし、下記URLからでも行けます。

https://webglsim.etrobo.jp

スマートフォンでは動作せず、PCの最近のWEBブラウザで動きます。

# 遊び方

WEB版ETロボコンシミュレータのAPIのページを見ると、サンプルコードやAPIが見れます。とりあえず走らせてみたい場合は下記コードをRun Scriptボタンで実行してください。Debug logをオンにすると実行ログが見れます。ブラウザのデバッグ機能(F12)でもみれます。GPU非搭載のPCの場合は、HackEVをHackEV(Simple)に変えると良いでしょう。

```
// P制御で走る。
v=50 // まっすぐの時の速度指令値
for i in range(0,10000) // 10000周期分動かす。
    ref=ev3_color_sensor_get_reflect // カラーセンサから反射光の強さを取得する。
    p=(ref-18)*2 // 目標値18からの差分に係数2をかける。
    ev3_motor_set_power_left (v-p)  // 右エッジの場合、目標値より暗い場合は右に曲がるように制御する。
    ev3_motor_set_power_right (v+p) // 右エッジの場合、目標値より暗い場合は右に曲がるように制御する。
    yield // 次の制御周期まで待つ
end for         
```

# 最後に
本稿ではWEB版ETロボコンシミュレータの開発経緯について説明しました。次回以降は、二輪倒立ロボット(EV3way)による倒立振子制御など、このシミュレータでできることを説明したいと思います。

# おまけ
投稿しようと思ったら、タグは０より大きい値にしてください、と言うエラーが出て焦りました。初投稿あるあるなんでしょうか。
Raspberry Piの初期設定からssh接続まで

#はじめに
まず、raspberrypiを使うために、キーボード、モニター、マウス、microSD、PC、USB電源アダプター、microUSBケーブル、HDMIケーブル、インターネット（有線orWifi)を用意する必要がある。
作業の流れとしては、OSダウンロード、SDカードのフォーマット、OSインストール、初期設定、sshの設定の順に行います。ssh接続ができるところまで進めば、キーボード、マウス、モニターがなくても操作できるようになります。

#OSダウンロード
OSをインストールする方法はいくつかあるが、
今回は[Raspberry Pi Imager](https://www.raspberrypi.org/software/)を用いて入れる。
[こちら](https://www.youtube.com/watch?v=J024soVgEeM&t=25s)を見ると英語で解説されている。
まとめると、
1.Raspberry Pi Imagerを起動する
2.CHOOSE OSを押して、Raspberry Pi OS(32bit)を選択する
3.CHOOSE SD CARDを押して、挿入したSDカードを選択する
4.WRITEを押して実行する。
数十分程度時間がかかる。

#Raspberry Piの起動
さきほど書き込みをしたmicroSDカードをRaspberry piに挿入する。
電源に接続すると起動が開始される。
キーボード、マウス、モニターをつけ、初期設定を始める。

#初期設定

### Set Country
今回は
Country:Japan
Language:Japanese
Timezone:Tokyo
と設定

### Change Password
ここではパスワードの設定を行う。パスワードを設定しない場合は空欄のままNextで次へすすむ。デフォルトのパスワードは```raspberry```となっている

### Set Up Screen
ディスプレイに写っている画面がフルスクリーンでなく、黒枠が出ている場合はチェックボックスにチェックを入れる。

###Select WiFi Network
ここではWifiの設定を行う。しばらく待つとWiFiネットワークのリストが出てくるので、そこから自分のルータに接続する。

###Update Software
ここではソフトウェアの設定が行われる。最新になるので、ここではNextボタンを押して更新を行うことにする。System is up to dateという画面が出てきたら完了。しばらく時間がかかる時がある。
###まとめ
いまのラズパイには日本語フォント、日本語入力、VNCサーバーなどが最初から入っているようだ。

#SSH接続
###はじめに
筆者の環境はmacを想定しています。
RaspberrypiのSSHはデフォルトで無効化されているため、有効にする必要がある。
Terminalで```$ sudo raspi-config```と入力して、```3 Interface Options```から```P2 SSH```を選択するか、メニュー⇨設定⇨Raspberry pi⇨インターフェースからSSHにチェックを入れ、OKを押す。どちらの手順とも再起動が必要なので、terminalで```$ sudo reboot```で再起動。
また、raspberrypiではパスワード認証方式が利用されている。
###接続する（Mac)
macでターミナルを開き、```$ ssh Raspberry piのユーザ名@xx.xx.xx.xx```(xx.xx.xx.xxにはラズパイのIPアドレスを入れる)
このあとにRaspberrypiのパスワードを聞かれるので入力（設定してない場合は ```raspberry```となっている。
RaspberrypiのIPアドレスは ```$ ifconfig```を実行することで調べることができる。
###公開鍵認証方式でのssh接続
macのターミナルで ```$ ssh-keygen -t rsa```と入力し、鍵の作成をすると、保存ファイル名が聞かれるので、保存されるファイルを指定する。```鍵名```と```鍵名.pub```が作成される。.pubがついている方が公開鍵となっている。
次に、公開鍵(鍵名.pub)をraspberrypiへ転送する
```$ scp [公開鍵へのパス][Raspberrypiのユーザ名]@raspberrypi.local;```を実行することでRaspberrypiの/home/piディレクトリに公開鍵が転送される。Raspberrypiのターミナルで```$ mkdir .ssh```を実行し、/.sshディレクトリを作成する。/.sshの中にさっきの公開鍵を移動させる。```$ mv 鍵名.pub .ssh/authorized_keys```とし、ファイル名を変更し、```$ chomd 600 .ssh/authorized_keys```としてパーミッションの変更、次に/etc/ssh/sshd_configの```#PubkeyAuthentication yes```のコメントアウトを外す。これで公開鍵認証の設定が完了する。
```$ sudo /etc/inti.d/ssh restart```でSSHサーバを再起動し、Macのターミナルで```$ ssh -i [秘密鍵へのパス][ユーザ名]@raspberrypi.local```をし、SSH接続をする。
これにより、パスワードの入力なしにssh接続を利用できるようになる。
#最後に
キーボード、モニタ、マウス等の準備が難しいときは[こちら](https://qiita.com/murs313/items/81757bf8bc74b6b76cdf)の記事を参考にするとできるかも。。。
SSH接続で操作できるようになると、わざわざキーボード、マウス、モニタの場所をとらなくても、ラズパイを操作できるようになるので結構楽です。
高校生の時にNOOBSを使ってRaspberrypiの初期設定などを行っていましたが、最近はだいぶ便利になったようです。


#参考文献
[ssh接続] (https://www.fenet.jp/beginner/column/%E9%96%8B%E7%99%BA%E7%92%B0%E5%A2%83/1031/#Mac%E3%81%8B%E3%82%89Raspberry_pi_%E3%81%AB_SSH%E6%8E%A5%E7%B6%9A%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95)

[初期設定](https://www.indoorcorgielec.com/resources/raspberry-pi/raspberry-pi-setup/)
"Warning: Received `true` for a non-boolean attribute"が出たときの対策

### エラーメッセージ
```.log
Warning: Received `true` for a non-boolean attribute
```
上記の様なエラーが発生。

### 対策
propsに$をつける

### 参考
https://github.com/styled-components/styled-components/issues/1198
https://styled-components.com/docs/api#transient-props
いいね機能実装　[Ruby on Rails]

##完成品
![いいね機能1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798471/bd7523ee-bcc5-d2c2-3703-abc613176059.gif)

投稿にいいね機能を実装する。
テーブルは、Users,Booksに加えFavoritesを追加する。
##実装の手順
①モデルの作成
②ルーティングを追加
③それぞれのモデルに関連付けを追加
④コントローラを作成
⑤Viewを作成する
###①モデルの作成
```ruby:terminal
$rails g model Favorite user_id:integer book_id:integer
```
**user_id**：userとの紐づけ
**book_id**：book投稿との紐づけ
**integer**:データ型の整数

###②ルーティングを追加
```ruby:routes.rb
resources :books do
    resource :favorites , only: [:create , :destroy]
  end
```
favoritesのshowページが不要で、idの受け渡しも必要ないので、resourceとなっています。
今回は、resources :booksにネストします。
resources :booksの中にresource :favorites , only: [:create , :destroy]を入れるという意味です。
ネストする理由は、ルートパスにあります。

```ruby:routes.rb 
#ネストしない場合
resources :books 
resource :favorites , only: [:create , :destroy]
```

ネストしないとルートパスが、下図になります。実はこのままだと、どの投稿(book_id)にいいねを付けたか特定することができません。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798471/5234d44a-0fdd-ac15-096d-1538a140eb8e.png)
ネストすることでルートパスが下図になります。投稿(book_id)を特定することができますね。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798471/5e8c3d70-dfa7-5d73-6554-a7629111a70b.png)

###③それぞれのモデルに関連付けを追加

```ruby:app/model/user.rb
has_many :favorites, dependent: :destroy
```

```ruby:app/model/book.rb
has_many :favorites, dependent: :destroy
def favorited_by?(user)
   favorites.where(user_id: user.id).exists?
end
```

```ruby:app/model/favorite.rb
belongs_to :user
belongs_to :book
```
アソリエーション
※ user : favorite = 1 : 多　
※ book : favorite = 1 : 多

１つのuserからみて、いいねは多数あるのでhas_many
１つのbook（投稿）からみて、いいねは多数あるのでhas_many
１つのいいねからみて、user・book（投稿）は１つしかないのでbelongs_to
has_manyの後にはdependent: :destroyを付けましょう。

**favorited_by?**メソッドを作成します。
このメソッドで、引数で渡されたユーザidがFavoritesテーブル内に存在（exists?）するかどうかを調べます。


###④コントローラを作成

```ruby:terminal
rails g controller Favorites
```
```ruby:app/controllers/favorites_controller.rb
class FavoritesController < ApplicationController
  def create
 　 book = Book.find(params[:book_id])
    favorite = current_user.favorites.new(book_id: book.id)
    favorite.save
    redirect_to request.referer
  end
  def destroy
    book = Book.find(params[:book_id])
    favorite = current_user.favorites.find_by(book_id: book.id)
    favorite.destroy
    redirect_to request.referer
  end
end
#必要に応じてインスタンス変数を付けましょう。（book => @book）
```
**current_user**はログイン中のユーザーです。
**request.referer**は、元のviewに戻ってきます。いいねをクリック→いいねされたviewに戻ります。
なぜparamsの中が**:book_id**なのか？恐らくusr_idと混同するからと推測

###⑤Viewを作成する
```ruby:terminal
#<% books.each do |book| %>
<% if book.favorited_by?(current_user) %>
  <%= link_to book_favorites_path(book), method: :delete do %>♥<%= book.favorites.count %>
  <% end %>
<% else %>
  <%= link_to book_favorites_path(book), method: :post do %>♡<%= book.favorites.count %>
  <% end %>
<% end %>
#<% end %>
#book/indexで投稿を全て表示しているので今回はインスタンス変数なし
```
**<% if book.favorited_by?(current_user) %>**
いいねがクリックされている状態と、されていない状態で表示を変えます。

**<%= book.favorites.count %>**
いいねされた数を表示しています。

以上で実装完了となります。
【Android Kotlin】Installed Build Tools revision 31.0.0 is corruptedの対処法

# 環境
- Android Studio 4.2.2

# エラー内容
新規プロジェクトを作成した時，あるいは`Run 'app'`をした時に，以下のエラーが発生する場合があります．

```
Installed Build Tools revision 31.0.0 is corrupted.
Remove and install again using the SDK Manager.
```

# 対処法
以下のように`app/build.gradle`を書き換えることでエラーを解決できます．

`変更前`

```app/build.gradle
android {
    compileSdkVersion 31
    buildToolsVersion "31.0.0"

    defaultConfig {
        applicationId "app.myouji.nickname.myapplication"
        minSdkVersion 21
        targetSdkVersion 31
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    ~ 省略 ~

}
```

`変更後`

```app/build.gradle
android {
    compileSdkVersion 31
    buildToolsVersion "30.0.3" //変更

    defaultConfig {
        applicationId "app.myouji.nickname.myapplication"
        minSdkVersion 21
        targetSdkVersion 30 //変更
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    ~ 省略 ~

}
```

# 参考記事
- [Android Studio error “Installed Build Tools revision 31.0.0 is corrupted”](https://stackoverflow.com/questions/68387270/android-studio-error-installed-build-tools-revision-31-0-0-is-corrupted)
- [Installed Build Tools revision 31.0.0 is corrupted. Remove and install again using the SDK Manager. が表示され、ビルドが失敗する](https://se.yuttar-ixm.com/androidstudio-error-01/)
Unityを使った映像配信方法

Unityを使って映像配信をしてみたかったので、方法を調べてみました。


# 1.OBS Studioに出力
Unity内の映像をOBSに出力し、HTTPサーバから映像を取得する方法

### UnityCapture
UnityCamを基に作られたUnity内のカメラをノートPCの内側カメラとして扱えるようになるUnityプラグイン
4kも対応可能

https://github.com/schellingb/UnityCapture


# 2.NDI（ネットワークデバイスインターフェイス）
LANを介してビデオを共有することができる
NDIホストを自動検出可能
ロイヤリティフリー

https://www.youtube.com/watch?v=739e2ie67IM


### KlakNDI
NDIを使用してコンピューター間でビデオフレームを送受信できるようにするUnityプラグイン

https://github.com/keijiro/KlakNDI

# 3.SPOUT
同一PC内のアプリ間高で速映像共有ができる

### KlakSpoutUnity
SPOUTを使用してコンピューター間でビデオフレームを送受信できるようにするUnityプラグイン

https://github.com/keijiro/KlakSpout


# 4.WebRTC(Web Real-Time Communication)
ウェブブラウザやモバイルアプリケーション間でのリアルタイム通信で、Web会議システム等で利用されている。

### WebRTC for Unity
WebRTCを使用するためのUnityプラグイン
Unity Render Streamingで同時に 複数の端末のブラウザに対して映像のストリーミング配信することができる。

https://github.com/Unity-Technologies/com.unity.webrtc


Unity間での配信の参考記事

https://qiita.com/namiwavess/items/b911f4798cf35e2f735d


Sora Unity SDK
1:1,1:多で映像配信できるプラグイン

https://github.com/shiguredo/sora-unity-sdk


# 5.HLS(HTTP Live Streaming)

ライブ配信、VOD(Video On Demand)配信に対応している通信規格
Abema TV等で使用されている

Unityの配信用プラグインは配布されていない？

受信は以下のアセットで可能

https://assetstore.unity.com/packages/tools/video/easy-movie-texture-video-texture-10032?aid=1011lGbg&utm_source=aff

https://assetstore.unity.com/packages/tools/video/ump-android-ios-56044
【Python】進化する関数

# What's this?
あと付けで機能を足せる関数です。使い道は思いつきません。
何か思いついたらコメントで教えていただけると嬉しいです。

```python 
def evolvableFunc(*keys):
    for name, f in evolvableFunc.__dict__.items():
        if callable(f):
            evolvableFunc.__dict__[name] = f(**f.__dict__)
    return tuple([evolvableFunc.__dict__[key] for key in keys])
```
`evolvableFunc.関数名 = 関数`で持たせた関数を順に実行します。
関数に渡す引数は`evolvableFunc.関数名.引数名 = 引数`で定義します。
実行結果は関数名のローカル変数に保存されます。
`evolvableFunc`呼び出し時に引数として文字列で関数名を渡せば、タプルで実行結果を受け取れます。

Python3.6から辞書の順番は保持されるらしいので、恐らく定義順で実行されるはず。
### 例１

```python 
evolvableFunc.f1 = lambda a: a*a
evolvableFunc.f1.a = 6
evolvableFunc.f2 = lambda: evolvableFunc.f1+5
print(evolvableFunc('f2'))  # -> (41,)
```
### 例２

```python 
evolvableFunc.f3 = lambda : not any([evolvableFunc.f2%i==0 for i in range(2, int(evolvableFunc.f1**.5)+1)])
evolvableFunc('f1', 'f2', 'f3')  # -> (36, 41, True)
```
### 例３

```python
def f4(x):
    for i in range(x):
        print(i)
    return i>5
evolvableFunc.f4 = f4
evolvableFunc.f4.x = 6
evolvableFunc('f4')  # -> (False,)
'''stdout
0
1
2
3
4
5
'''
```
[05] PowerShell実践例 ... デバッグ情報を充実させる


|本シリーズのトップページ|
|:--|
|https://qiita.com/robozushi10/items/0b0605257ad39bc22895|

# はじめに

前項で、例外発生のコードを記したが、このとき例外発生元の関数情報などをハードコーディングしていた.

これを C言語の `__FILE__` や `__LINE__` のような感じで埋め込めるようにしてみる.

　

# 環境

```
Windows 10 Pro
PowerShell バージョン 6系
```


# プログラムについて

## 処理概要

次の 1〜5 の処理をする

```
1. module.ps1 を作成して __FILE__ , __LINE__ , __PATH__ を実装する.
　　なお、__PATH__ は絶対パスを表示する機能を持つ.

2. 実処理をする sample.ps1 の中から 1 の module.ps1 をインクルードする.

3. sample.ps1 の中で __FUNC__ 相当（関数表示）を実装する.
   
4. sample.ps1 の中で __FILE__ , __LINE__ , __PATH__ を呼び出す

5. sample.ps1 を実行する.
```

## module.ps1

```powershell
# 本スクリプト置き場
$BATDIR = $PSScriptRoot

# デバッグログ設定 ... ここを切り替えると Write-Debug によるログが表示されなくなる
$DebugPreference = 'Continue'

# ファイル名を返す関数
function Get-ScriptBaseName { return (Split-Path  $MyInvocation.ScriptName -Leaf) }

# ファイル絶対パスを返す関数
function Get-ScriptFullName { return $MyInvocation.ScriptName }

# 行番号を返す関数
function Get-ScriptLineNumber { return $MyInvocation.ScriptLineNumber }

# 関数を変数として扱うための定義
new-item alias:__FILE__ -value Get-ScriptBaseName | Out-Null
new-item alias:__PATH__ -value Get-ScriptFullName | Out-Null
new-item alias:__LINE__ -value Get-ScriptLineNumber | Out-Null


```

## sample.ps1

下記は [前回のコード](https://qiita.com/robozushi10/items/71bdcbcfda44acb7ea11)にデバッグログを埋め込んだものである.

```perl
# module.ps1 を読み込む
. .\module.ps1

function sub($workdir)
{
  # デバッグログ
  Write-Debug "[$(__FILE__):$(__LINE__):$($MyInvocation.MyCommand)]"

  # 引数 $workdir で指示されたディレクトリが存在しなければエラー終了させる
  if(!(Test-Path -Type Container $workdir))
  {
     # 例外ログを強化した
     throw "<$workdir> was not found: no such directory [$(__PATH__):$(__LINE__):$($MyInvocation.MyCommand)]"
  }
}

function main()
{
  # デバッグログ
  Write-Debug "[$(__FILE__):$(__LINE__):$($MyInvocation.MyCommand)]"
  # 引数 workdir に ".\work" を指定して呼び出す
  sub -workdir ".\work"  
}

try
{
  # デバッグログ
  Write-Debug "[$(__FILE__):$(__LINE__):$($MyInvocation.MyCommand)]"
  # main 関数を呼び出す
  main
}
catch
{
  Write-Host "異常発生: $($error[0])"
  # ここに確実に終了させたい処理を書けば良い
}

```

## 実行結果

次のようにデバッグ情報がより詳細になった

```
DEBUG: [sample.ps1:23:a.ps1]
DEBUG: [sample.ps1:16:main]
DEBUG: [sample.ps1:5:sub]
異常発生: <.\work> was not found: no such directory [c:\work\sample.ps1:10:sub]
```

　

# 参考にしたサイト

|URL|
|:--|
|https://www.shiftwiki.nl/spls|
|https://forsenergy.com/ja-jp/windowspowershellhelp/html/64517b77-a2a7-4890-8482-f393fa555fd2.htm|
|https://stackoverflow.com/questions/817198/how-can-i-get-the-current-powershell-executing-file|
InoreaderのPythonラッパーの紹介

# 概要
InoreaderをPythonで使用した場合に便利なライブラリがあったので紹介

## 内容
- [python-inoreader](https://github.com/Linusp/python-inoreader)
    - Inoreader APIのPythonラッパー

## 便利な点
- インストールが簡単
    - pipコマンドを実行するだけ
- 重複記事の削除を無料ユーザーでも可能
    - 重複記事の削除は有料ユーザでないと画面上からは出来ないが、インストール後は下記コマンドで実行可能
        - `inoreader dedupe`
- 未読記事を一括で取得可能
    - `inoreader fetch-unread `

### 使用方法
- 下記コマンドでインストール
    - `pip install git+https://github.com/Linusp/python-inoreader.git`
- 設定ファイルを環境変数$HOME配下に下記の通り作成

```.inoreader
[auth]
appid = your_app_id
appkey = your_app_key
```
- 下記コマンドを実行しログイン
    - inoreader login
- コンソールにOAuth認証用のURLが出力されるため、アクセスして許可を設定する

## 注意点
- 事前にInoreaderでAPIIDを取得しておく必要がある。
- 設定ファイル格納場所を環境変数[HOME]を参照している為、Windows環境などでHOMEがない場合、起動しない

## 参考サイト
- [python-inoreader](https://github.com/Linusp/python-inoreader)
Cloud Functions(Node.js)でberglasのsm://形式の秘密情報を展開する方法

# 本文
Cloud Runでは `sm://<project_id>/<secret_name>` の形式で環境変数をセットして起動すれば自動的にSecretManagerから秘密情報を取得して展開してくれます。(言語不問)

同様の機能がCloud Functionsにもあったらいいなと思ったんですが、Go言語版のみしかサポートされていなかったので、Node.js版を作成しました。

```js
const { SecretManagerServiceClient } = require('@google-cloud/secret-manager');

async function resolveSecret(element) {
  const client = new SecretManagerServiceClient();
  const [, , projectId, secretName] = element.split('/');
  const name = `projects/${projectId}/secrets/${secretName}/versions/latest`;

  const [version] = await client.accessSecretVersion({
    name: name,
  });
  return version.payload.data.toString();
}

async function substituteSecrets() {
  const resolved = await Promise.all(
    Object.entries(process.env)
      .filter(([_, element]) => element.startsWith('sm://'))
      .map(async ([key, element]) => [key, await resolveSecret(element)])
  );

  for (const [key, element] of resolved) {
    process.env[key] = element;
  }
}
```

# 参考
https://github.com/GoogleCloudPlatform/berglas
https://www.npmjs.com/package/@google-cloud/secret-manager
[GitHub]修正方法について

# はじめに
本記事は、GitHubにてLGTMにならず、`修正となった場合`の対処方法となります。
私が理解していなかった部分で、そのためかなりの時間の要してしまいましたので
アウトプット、備忘録として記録いたします。

### 何を理解していなかったのか
レビュアーからLGTMが貰えず、こちらで修正し、
再度レビュアーに確認依頼する流れです。


# そもそものGitHubのルールに沿った開発の流れ
```ruby
①masterブランチから`ブランチを切る`。

②コードを記述し、都度`commit`する。

③commit後、`push`する。

④`pull requestを作成`する。

⑤レビュアーへ`確認`依頼する。

⑥レビュアーが作業者に対して`修正`依頼をする。

`⑦作業者にてコードを修正する。`

⑧修正後、無事に`LGTM`となる。

⑨`merge`する。

⑩リモートリポジトリからローカルリポジトリへ`pull`する。
```

#何を理解していなかったか
当時の私の話です。
⑦にてLGTMとならなかったため、修正が必要になりました。
その際に、修正後はどうやってレビュアーに確認依頼すればいいのか、
全くわからず、`再度①から実行しなければならないと勘違い`しており、
レビュアーに確認依頼するところまで辿り着けず、
モヤモヤしていました。

#結論
【⑦にて修正となった場合】

```ruby
①コードを`修正`

②修正箇所について、`再度commit`する。
この時、commit名は「修正」などと分かり易く。

③`再度push`する。

④`再度確認依頼`をする。
```

これで以上です。
`pull requestは既に作成されている`ため、
再度pull requestを作成する必要があるという認識が全くできていなかったことが原因でした。
こんなことに何度もエラーが出てしまったりしていました。

#終わり
私含めて初学者の方は、
GitHubを使いこなすのに少々手こずってしまい、
同じような悩みを抱えてしまう方もいると感じています。

しかし、GitHubという機能は、
働く上で、必ず身につけなければならないものだと確信しています。

今、失敗できたことをプラスに捉え、
引き続き頑張りましょう！！
voidメソッドのユニットテストを書く戦略

先日参加したCodeZine Academy[TDD実践講座](https://event.shoeisha.jp/cza/tdd)に参加した際に、今までモヤッていたことを質問して答えていただいた内容。

## 質問の内容

> テスト結果をpublicメソッドから確認しづらいときはどうすればよいか。オブジェクトの内部状態を変更するメソッドで戻り値がvoidのものなど。

> 例："スイッチ"クラスに"オンにする()"メソッドがあるとき、内部状態としてはオン・オフを管理するフィールドを持っているが、それを直接返すようなgetterメソッドを公開していない場合

以下のようなクラスを想定しています。

``` Switch.java
/**
 * スイッチクラス。スイッチはオン・オフを切り替えることができる。
 */
public class Switch {

	/** オン・オフの内部状態 */
	private SwitchStatus status;
	
	/**
	 * スイッチをオンにする。
	 */
	public void turnOn() {
		this.status = SwitchStatus.ON;
	}
}
```

## 結論
以下の3戦略のうちのどれかを選択する
1. 副作用のない、テスト容易性を高めるメソッドを追加する(getterなど)
2. リフレクションを利用する
3. 内部状態によって振る舞いが変わる公開メソッドで観測する

説明用に作成したサンプルソースは[こちら](https://github.com/acnaman/how-to-test-void-method)。

### 1. 副作用のない、テスト容易性を高めるメソッドを追加する(getterなど)

そもそも戻り値がvoidで内部状態を確かめることができないということは、テスト容易性が低いということ。テスト容易性が低いのはTDDでは不利に働くため、純粋にテスト容易性を上げるためにテストを観測可能にするための、副作用がないメソッド(例えばgetterメソッド等)を追加し、それ経由でテストします。

``` SwitchTest.java
	// 「1. 副作用の無いテスト容易性を高めるメソッドを追加する」経由のテスト
	@Test
	public void turnOnTest1() {
		// 実行
		_switch.turnOn();
		// 検証
		assertEquals(_switch.getStatus(), SwitchStatus.ON);
	}
```

ここからは私の解釈ですが、この戦略を取る場合はpackage privateとかで宣言して必要最小限の可視性にとどめておくのが良さそうです。テストのためにgetterを無闇矢鱈と開放するのは良くないので。

### 2. リフレクションを利用する
Javaの場合リフレクション経由でprivate変数にアクセスできるので、それを利用してテストを書くことができます。

``` SwitchTest.java
	// 「2. リフレクションを利用する」経由のテスト
	@Test
	public void turnOnTest2() throws ClassNotFoundException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
		// 実行
		_switch.turnOn();
		Field field = _switch.getClass().getDeclaredField("status");
        field.setAccessible(true);
		// 検証
		assertEquals(field.get(_switch), SwitchStatus.ON);
	}
```

個人的には、リフレクション経由でのテストはできれば避けるべきかと思います。例えば内部変数名を変えただけでテストが失敗してするようになってしまいますので。

### 3. 内部状態によって振る舞いが変わる公開メソッドで観測する
既存のメソッドの中で、内部状態によって振る舞いが変わるメソッドがあれば、それ経由で結果を確認することができます。

``` SwitchTest.java
	// 「3. 内部状態によって振る舞いが変わる公開メソッドで観測する」経由のテスト
	@Test
	public void turnOnTest3() {
		// 実行
		_switch.turnOn();
		// 検証
		assertEquals(_switch.displayName(), "オン");
	}
```

1の方法と比べるとクラスの実装を変える必要がないのは良い点です。反面、そもそも内部状態によって振る舞いが変わるメソッドがなければこの戦略を採用することは出来ませんし、テストに使用した公開メソッドの実装が変わってしまった場合や、公開メソッド自体にバグがあった場合にテスト対象のメソッドのバグを検出しづらいという欠点がありそうです。

## どれを採用するかはケースバイケース
3つの戦略のうち、どれを採用するべきか、というのはケースバイケースだと思います。
開発チーム内で、どういう場合にどの戦略を採用するのか、などを認識合わせしておくと良いかなーと思いました。
RailsでJaveScriptが動かないときの原因と対処法

## はじめに
Railsでアプリケーション製作中、jsを思うように動かせず苦労したため、躓いたポイントをまとめました。
初学者のため基礎的な内容かと思いますが、どなたかの参考になると嬉しいです！

## 前提条件
Rails 5.x.x
jQuery 3.x.x
app/assets/javascripts/　以下のファイルにjsを記述していることを前提とします。

## 原因1
####そもそもJavaScript、jQueryが読み込まれていない
まずは基本的なところを確認します。

* ビューにスクリプトを読み込むための記述があるか

```application.html.erb
<head>
   〜省略〜
   <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
</head>

```

* gemが追加されているか
 
```ruby:Gemfile
gem 'jquery-rails'
```
→ `bundle install`を実行

* application.jsファイルにJQueryを読み込むための記述があるか

```application.js
//= require jquery3
//= require jquery_ujs
//= require_tree .
```
`//= require jquery` と `//= require jquery_ujs` は `//= require_tree .`
より上に書く必要があります。
`//= require_tree .`は javascriptsディレクトリ配下のjsファイルを出力に含めるという記述なので、順番を逆にしてしまうとjQueryを読み込む前にjsファイルに記述した内容が読み込まれてしまいます。

##原因２
####turbolinksの影響
turbolinksとは、高速化を目的としたライブラリで、rails4以上ではデフォルトで入っています。
ページ遷移をAjaxに置き換え、画面の一部だけを更新することで高速化しようとするため、ページ読み込みを起点としたjsのイベントが発火しなくなってしまいます。

リンクを経ずに直接ページにアクセスしたり、ページをリロードした場合にはturbolinksの影響を受けないため、正常に動作します。

リンクを踏んでページ遷移した際にもjsを動作させるには下記の方法で記述します。
`turbolinks:load`とすることで初回読み込み、リロード、ページ切り替えの全てで処理を実行できるようになります。

```javascript:xxxx.js
$(document).on('turbolinks:load', function() {
  実行したい処理
});
```
また、リンクに下記記述をすることで特定のリンクのみturbolinksを無効化することができますが、ユーザビリティを考えるとあまり多用しない方が良いのかな...？

```erb
<%= link_to "turbolinksの無効化", root_path, 'data-turbolinks': false %>
```
##原因３
####エラーが出て処理が止まっている
記述は上から順に読み込まれ、エラーが出た時点で止まってしまうため、該当部分の記述が正しくても、それより上に記述した部分でエラーが出ていると処理が実行されません。
エラー部分を修正することで正常に動作するようになります。

##原因4
####指定した要素を見つけられていない

 `getElementById('hoge')`などで要素を取得し、その要素に対しての処理を記述していた場合、`#hoge`を取得できないと当然その後の処理は実行できません。

考えられる原因としては

* HTMLより先にJSが読み込まれている
* そもそもそのページに指定した要素がない

などがあるかと思います。

前者の場合、処理を下記関数内に入れてあげるとページを読み込んでから処理を実行できるようになります。

```javascript:xxxx.js
window.onload = function () {
  実行したい処理;
};
```
後者の場合は、スペルミスの他、意図しないページでイベントが発火していることも考えられます。
`//= require_tree .` の記述をしているため、処理を実行させたいページ以外でもjsの記述が読み込まれています。
ページ読み込みをトリガーとしている場合などはイベントが発火してしまい、指定した要素を探しに行ってしまいます。

対処法は色々あると思いますが、一つの例として「要素がない場合は処理を終了する」という条件文を追加することで、続く処理でのエラーを防ぐことができます。

```javascript:xxxx.js
function(){
  if (!document.getElementById("hoge")) return //この文を追加
  '#hoge'に対する処理;
};
```

##まとめ
####RailsでJaveScriptが動かないときの原因と対処法

* そもそもJavaScript、jQueryが読み込まれていない
* turbolinksの影響
* エラーが出て処理が止まっている
* 指定した要素を見つけられていない

Railsでjsを動作させるにあたって躓いたところ、調べたことをアウトプットさせていただきました。間違っている箇所がありましたらご指摘いただけると嬉しいです🙇‍♀️

##参考
[Rails5でjqueryを動かす方法](https://qiita.com/hiroyayamamo/items/b258acbaa089d9482c8a)
[04] PowerShell実践例 ... エラー終了させたい場合は素直に例外を使う


|本シリーズのトップページ|
|:--|
|https://qiita.com/robozushi10/items/0b0605257ad39bc22895|


# はじめに

PowerShell の戻り値の扱いは難しく、個人的にはあまり使わない方が良いと思っている.
特に、呼び出し元にエラー値を返す場合などは難しい. (正直なところ至難である)

それでもエラー分岐に進んでしまった場合に、呼び出し元へエラー値を返して、適切な後始末をしてから終了させないといけない場合もある.

例: シリアルポートのクローズや、USBメモリなどのアンマウントなど

このような場合、try 〜 catch による例外捕捉の準備をしたうえで、エラーシーケンスに進んだ際に throw を実行する方が楽で且つ確実であった.
さらに throw の際にエラーログを埋め込んでおくとデバッグも捗った.

これらは Python における自作 Exception に該当する.

このときの対応例を記しておく.

　

# 環境

```
Windows 10 Pro
PowerShell バージョン 6系
```


# プログラムについて

## 処理概要

次の 1〜5 の処理をする

```
1. 例外捕捉の準備をする
2. main 関数を呼び出す
3. main 関数から sub 関数を呼び出す
4. sub 関数の中でエラー分岐に進み、例外を発生させる.
5. main 関数の呼び出し元で例外をキャッチして各種後始末をする.
```

## sample.ps1

```powershell
function sub($workdir)
{
  # 引数 $workdir で指示されたディレクトリが存在しなければエラー終了させる
  if(!(Test-Path -Type Container $workdir))
  {
     # 🛑終了させたい場合は下手に戻り値を返さずに例外を発生させてしまう.
     # このときデバッグ情報を書いておくと便利である.
     throw "<$workdir> was not found: no such directory [at sub]"
  }
}

function main()
{
  # 引数 workdir に ".\work" を指定して呼び出す
  sub -workdir ".\work"  
}

# 以下、実処理開始

try
{
  # 例外捕捉の準備をしてから main 関数を呼び出す
  main
}
catch
{
  # 上記 🛑 で発生した例外を捕捉できる
  Write-Host "異常発生: $($error[0])"
  # ここに確実に終了させたい処理を書けば良い
}


```

## 実行結果

次のようにデバッグ情報と共に終了させることができる.

```
異常発生: <.\work> was not found: no such directory [at sub]
```
Typescriptでcsvtojsonを使い２つのcsv文字列をjsonに変換する

Typescriptで2つのcsv形式の文字列をいい感じにjsonに変換したいのだが
https://www.npmjs.com/package/csvtojson
とかを見てもいい感じの例を見つけられなかったので記載します。

# 例
以下のような２つのcsv形式の文字列があった場合にjsonに変換したい場合
## 文字列A
```
hoge,fuga
```

## 文字列B
```
1,2
```

## 変換後の文字列
```
{ hoge: '1', fuga: '2' }
```

# やり方
もちろんやり方はいくつもあると思うのですが以下で実現できました

```convert_csv_to_json.ts
const csv = require('csvtojson')

const n = "hoge,fuga"
const s = "1,2"
const csvStr = n + "\n" + s

csv({flatKeys:true})
.fromString(csvStr)
.subscribe((jsonObj:string)=>{
		console.log(jsonObj)
});
```

また関数から呼び出したい場合は以下でできました。
https://stackoverflow.com/questions/50990456/node-js-csvtojson-return-result-outside-of-function
よりcsvtojsonはPromise objectを返すので値の取り出し方もPromise内で行います

```convert_csv_to_json.ts
const csv = require('csvtojson')

const n = "hoge,fuga"
const s = "1,2"
const csvStr = n + "\n" + s

function fugafunc(csvStr:String):Promise<String>{
  return csv().fromString(csvStr);
}

const result = fugafunc(csvStr)
result.then((data: String) => {console.log(data) })