OmniAICreator/Qiita-1.07M huggingface dataset:
terraformのmoduleをprivate githubから使用する

## https

```
module "private_module" {
  source = "git::https://github.com/private-org/private-repo.git?ref=${branch or tag}"
  ...
}
```

CIでhttps経由でmoduleを使う場合はtokenが必要になるため,gitの設定でtokenを設定

```bash
$ git config --global url."https://${GITHUB_TOKEN}:x-oauth-basic@github.com/private-org".insteadOf "https://github.com/private-org"
```

## ssh

```
module "private_module" {
  source = "git::git@github.com:private-org/private-repo.git//backend?ref=${branch or tag}"
  ...
}
```

sshにしておきつつ、CIだけはtokenを使うようなケースではこうするとよい

```bash
$ git config --global url."https://${GITHUB_TOKEN}:x-oauth-basic@github.com/private-org".insteadOf "ssh://git@github.com/private-org"
```
Video Indexer で会議のキーフレーズを可視化したい

## はじめに
AIでなんかしたい。この Video Indexer っていろいろできそう！
くらいの感覚で触り始めたVideo Indexer に関する備忘録です。

## [Video Indexer](https://docs.microsoft.com/ja-jp/azure/media-services/video-indexer/)とは

Microsoftが提供しているAIソリューションである、Azure Cognitive Services ブランドの一部であり、動画をアップロードすることで、その動画に対しあらゆる分析を行うことができる。このvideo indexerには同じくAzure Cognitive Services のText Analytics や Face も内包されていおり、動画内の翻訳や文字認識や顔認識などの機能も行えるようになっていて、動画をベースとした幅広いソリューションに活用できる。

また、Video Indexer webサイトというものが用意されており、既存のAPIとは異なってグラフィカルに動画の分析を行うこともできるので誰でも扱いやすいのが特徴。もちろん、REST API も使用することができるの開発するシステムに組み込むことも可能。

## やりたいこと

録画していた会議内容のキーワードでワードクラウドを作成する

【背景】
リモートで行っていた全社向けMTGが、動画を撮っておくことで社員の好きなタイミングで視聴できるようになった。ゆっくり見る時間はないけど、とりあえず何が話されていたかはざっくり把握したい。

【使用するVideo Indexer api】

- POST : Upload Video
- GET : Get Account Access Token
- GET : List Videos (ビデオIDを知るために使用)
- GET : Get Video Index (解析結果)

ワードクラウドを生成するためのd3というライブラリのコードは以下の記事を参考にさせて頂きました。
[D3-cloud (d3-v5版) でワードクラウドを作成する](https://qiita.com/january108/items/5388799531c1ace8324e)

【Get Video Index APIの使用部分を抜粋】

```jsx
const request = require('request');
const fs = require('fs');
const url ='https://api.videoindexer.ai/{ location }/Accounts/{ accountId }/Videos/{ videoId }/Index?language=ja-JP&accessToken={ APIで取得したToken }'
var d = []
request.get({
    uri: url,
    headers: {
        'Ocp-Apim-Subscription-Key' : { Subscription key }
    }
}, function(err, req, data){
    var r = JSON.parse(data);
    var list = r.videos[0]['insights']['keywords'];
    for (li of list) {
        d.push({"word":`${li.text}`,"count":`${li.confidence}`});
    };
    fs.writeFile('words.json', JSON.stringify(d), (err, data) => {
        if(err) console.log(err);
        else console.log('write end');
    })
});
```

Get Video Index APIを使用すると、Video Indexerによって解析された結果が[JSON形式]((https://docs.microsoft.com/ja-jp/azure/media-services/video-indexer/video-indexer-output-json-v2))で出力されます。他のCognitive Services の機能の一部を使えるだけあって出力されるデータ量が多いなと感じました。

スクリプトを実行すると、参考にさせていただいたコードと同じくwords.jsonという名前のファイルに動画内のキーワードを書き出していきます。video indexer で検出できるキーワード認識の信頼度(confidenceプロパティ)を、ワードの頻出度とすることで文字サイズを変更します。つまり、認識したキーワードの信頼度が高いと判定されたものほど大きく表示されます。

## 結果

流石に多少手を加えただけでは、使い物にならなかったです笑
ワードクラウドは表示されますが、会議の要約というにはあまりも分かりづらすぎる、、

以下はテキスト化した際の所感になります。

- 言い淀みを拾い過ぎ

もちろん喋っている人の話し方にもよりますが、それでも「え〜」とか「これはまぁ」とかのノイズが多かったのが印象的でした。機械に読み込ませると、人間が普段無意識のうちに切り捨ててる言葉が顕著に現れて、これはこれで面白かったです。
→  COTOHA から言い淀み除去をするAPIが公開されています。抽出したテキストを一度このAPIに噛ませて使ってみると、かなりマシにになりました。(一度のリクエストで送れる文字数には制限があるので、長すぎると分割する必要があります)

- そもそも認識精度はあまり高くない？

今回取り込んだ動画内で喋っている方は、個人的には、かなり聞きやすい話し方をする方と思っていただけに、抽出結果を見て少し驚きました。この結果からキーワードが分析されると思うので、もちろんキーワードも期待できる結果ではありませんでした。
Video Indexer で生成されたテキストを Text Analytics API でキーフレーズ抽出をしたところ、大分結果が変わったので、何かしらの差異はあるのかもしれないですね。
AWSのEC2でrootになれなくなった場合の対処方法

ubuntuユーザーのsudoers設定を変更してしまい、スーパーユーザーになれなくなった場合の対処法

1. AWSマネジメントコンソールにログインする
2. EC2を開く
3. インスタンスを選択する
4. インスタンスを停止する（停止時に削除されないように注意）
5. 「アクションメニュー」の「インスタンスの設定」→「ユーザーデータの表示／変更」を選ぶ
6. ユーザーデータに下記を記入

#cloud-config
bootcmd:
- echo "ubuntu ALL=(ALL:ALL) NOPASSWD:ALL" >> /etc/sudoers
7. 「保存」を押した後、インスタンスを起動する
8. ubuntuユーザーで、パスワードなしで「sudo su -」が出来るか確認
9. 出来ることが確認出来たら、インスタンスを停止し、ユーザーデータに記述したものを削除
10. インスタンスを起動

以上。
Xcode12 'FirebaseCore/FirebaseCore.h' file not found　エラー解決

File
-Workspace settings
DerivedDataの削除

Xcodeを閉じる

ターミナルで
pod deintegrate
pod install

Xcodeを開く

PROJECT 
– build setting 
– Architectures 
– Excluded Architectures 

"arm64" を追加

参考にした記事
https://nsdev.jp/apple/ios/14581.html
https://github.com/firebase/firebase-ios-sdk/issues/2233#issuecomment-451357893
【ruby】ストロングパラメーター【require】【permit】【merge】使用方法　役割

# はじめに
　この記事は、学んだことを復習するために投稿者が理解できる言葉まで落とし込んで書いております。
# １.役割
　ストロングパラメーターとは、指定したキーを持つ、パラメーターのみ受け取るように制限をかけることができるものです。

# 2.使用する理由
　受け取るパラメーターのデータを制限することで、意図しないデータの保存。更新を避けるため。
今回は、商品出品を行うフリマアプリを想定した例で紹介します。


# 3.基本構成と使用方法

・基本構成は以下の通りです。

```ruby
# ・・・中略
 def new
    @item = Item.new
  end

 def create
   @item = Item.new(item_params)
 end

 private

 def item_params
   params.require(:item).permit(:name, :explanation, :category_id, :status_id, :delivery_fee_id, :shipping_region_id, :shipping_day_id, :selling_price, :image).merge(user_id: current_user.id)
 end
```

#### 使用方法
・ストロングパラメーターは、プライベートメゾットとして定義する。
・下記のように、<font color="Red">**item_params**</font>とすることで、可読性が向上する。<font color="Red">**createアクション**</font>で保存した後に、データを更新する<font color="Red">**updateアクション**</font>でも同様の箇所の変更を加えるので、記述をまとめられます！！

```ruby
 def create
   @item = Item.new(item_params)　←ここです
 end
```

# 4.制限する値

# 4-1.require（モデル名）

```ruby
# 使用例
params.require(:モデル名)

params.require(:item)

# itemモデルに入っている全てのデータが、保存される。
  指定したモデルの中でも、カラム名で保存したい値を制限したいときに、permitを使用する。
```

# 4-2.permit（:キー1,キー2...）
```ruby
# 使用例
params.permit(:キー1, :キー2....)

params.require(:item).permit(:name, :explanation, :category_id, :status_id, :delivery_fee_id, :shipping_region_id, :shipping_day_id, :selling_price, :image)

# 指定したモデルの中でも、保存したい値を制限したいときに、permitでカラム名を制限する。
```

# 4-3.merge（:結合させたい外部キー等）
```ruby
# 使用例：商品を出品したユーザーの情報を紐付けたい場合
params.merge(user_id: current_user.id)

params.require(:item).permit(:name, :explanation, :category_id, :status_id, :delivery_fee_id, :shipping_region_id, :shipping_day_id, :selling_price, :image).merge(user_id: current_user.id)
```
## 注意
<font color="Red">**current_user.id**を使用できるのは、**devise**を使っているからです。</font>
参考になる記事がありましたので、共有させていただきます。

 >Rails deviseで使えるようになるヘルパーメソッド一覧
https://qiita.com/tobita0000/items/866de191635e6d74e392

# 5.最後に
指摘事項などありましたら、勉強のために教えていただけると幸いです。
Chrome Custom Tabs で強制的に Chrome で表示する方法

# 概要

例えば AndroidManifest.xml の `<intent-filter>` に 

```xml:AndroidManifest.xml 
<intent-filter>
    <action android:name="android.intent.action.VIEW" />

    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />

    <data
        android:host="example.com"
        android:scheme="https" />
</intent-filter>
```

と定義していた場合、Chrome Custom Tabs で `https://example.com/` のページを表示しようとすると
intent-filter の条件に一致するため、

<img width="360" src ="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34926/03d63778-f4ac-d289-4660-22a0a570fdc9.png"/>


こんな感じで Chrome 以外の候補が表示されてしまいます。

この候補モーダルを表示させずに強制的に Chrome で表示する方法です。

# 方法

```kotlin:MainActivity.kt
val builder: CustomTabsIntent.Builder = CustomTabsIntent.Builder()
val customTabsIntent: CustomTabsIntent = builder.build()

if (packageManager.getLaunchIntentForPackage("com.android.chrome") != null) {
    customTabsIntent.intent.setPackage("com.android.chrome")
}

customTabsIntent.launchUrl(this, Uri.parse(url))
```

`setPackage()` で Chrome のパッケージ名を指定してあげるだけです。

念のため `getLaunchIntentForPackage()` で Chrome が存在しているかチェックしています。
↑ では存在しなかったときの処理はなにも行っていませんが本来であればエラーメッセージを表示するなどしてあげたほうが良いかと思います。

以上です。

# 参考
[[stackoverrun] android - Chromeのカスタムタブとインテントフィルタ](https://stackoverrun.com/ja/q/8996295#32656019)
複数チェックボックスを全選択した時のみ押せるボタン

```HTML

<!DOCTYPE html>
<head>
</head>
<body>
<p>確認ボタン</p>

  <p form="check">
    <input type="checkbox" onchange="change()" id="check1">
    <label for="check1">
    確認チェックボックス１
    </label>
  </p>

  <p form="check">
    <input type="checkbox" onchange="change()" id="check2">
    <label for="check2">
    確認チェックボックス2
    </label>
  </p>

  <p form="check">
    <input type="checkbox" onchange="change()" id="check3">
    <label for="check3">
    確認チェックボックス3
    </label>
  </p>

  <button type="submit" id="check-btn" disabled>
  承認 
  </button>


  <script type="text/javascript">
    function change() {
      if  ((document.getElementById("check1").checked)
        && (document.getElementById("check2").checked) 
        && (document.getElementById("check3").checked)) 
      {
        document.getElementById("check-btn").disabled = false;
      
      } else {
        document.getElementById("check-btn").disabled = true;
      }
    }
  </script>
</body>
</html>
```

##全てのチェックボックスをチェックする事によってボタンを押すことが出来る
![スクリーンショット 2020-09-25 18.00.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/515025/8ef98454-5562-bdab-e9d7-d79b91e5328c.png)
![スクリーンショット 2020-09-25 18.01.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/515025/416bce6b-0153-2282-60ac-f40089673afa.png)
![スクリーンショット 2020-09-25 18.00.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/515025/77feda61-c68f-0b83-8590-f331e1c593ea.png)
![スクリーンショット 2020-09-25 18.01.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/515025/7dfd2488-b326-2cde-f3cf-bde870cc5d37.png)
Pay.JP ローカルではできたのに本番環境では上手く動作しない時の解決法

1週間ほど悩んで解決した
Pay.PJがローカル環境ではしっかり動作するのに本番環境では決済ができない原因を忘れないうちに書いておきます。
Pay.JPの決済がうまくできない原因はエラー文が出ないのでかなり時間がかかりました…

動作環境
ruby 2.6.5
Rails 6.0.3.2
heroku 7.42.13

#エラーの原因
エラーが起こっていた原因は簡単にまとめると
**Herokuに設定した環境変数が本番環境に反映されていなかった**
ことが原因です

どういうことか説明していきます。
ターミナルにて
```heroku config:set PAYJP_PUBLIC_KEY='ご自身のテスト公開鍵'```
と
```heroku config:set PAYJP_SECRET_KEY='ご自身のテスト秘密鍵'```
を入力されるかと思います。
しっかり入力できているかどうかは
```heroku config```
で確認していただければ確認できます。
**確認するとしっかり入っているんです。**
**入っているんです！！**
これに騙されました…
Herokuの環境変数の中身を変えましたがこれまだ適応できていないのです。。

#Heroku環境変数の適応の仕方
結論から申します
```git push heroku master```
を入力してくださいこれでGitHubのマスターがプッシュされて環境変数が適応され本番環境でもしっかりと決済が行われます。
しかし、中には
```Everything up-to-date```
と、すでに最新の状態ですと帰ってくる方もいらっしゃると思います。自分もそうでした。
```git commit --allow-empty -m "空のcommit" ```
そんなときはこれを入力してGitHubのマスターをもう一度最新の状態にして
```git push heroku master```
してみてください！
きっと解決できると思います

ご高覧ありがとうございました。
画面の解像度で画像を切り替える

 画面の解像度で画像を切り替えられる　```srcset```
xが倍って意味　２xなら２倍　３xなら３倍、、、、
```<img src="xxxxx.png" srcset="xxxxxx.png 2x" alt="スマホ対応画像など">```
Python触ってみた（インストール編）

# はじめに
> SEとして一からプログラムを書く現場はほぼ経験したことがなく。。。
> 今回も前任者が開発したPythonのプログラムを改修してほしいとの依頼が。。。

上記のような状況のSEの方って意外と多くいるのではと思う今日この頃。
今回はPythonを読むのに最低限必要な知識を書き残しておこうと思います。

# 方針とゴール
- 今回は以下のサイトでお勉強していきます。
    - https://www.python-izm.com/
    - 参考サイトではPythonをPCに直接インストールしています。
    - PCは綺麗にしておきたいので仮想マシンを使用します。
- ゴールは「Hello World」相当のものを出力できればと思ってます。

# 前提
- 今回もVagrantを使って仮想マシン上にPython環境を用意します。
    - 以前の記事を参考（宣伝）：[Mac+Vagrant(CentOS7)+Docker+Jenkinsで優勝してみた](https://qiita.com/ok2/items/789430151e170768fe17)
- Pythonのバージョンは3系を使用します。
    - Pythonは2系と3系で互換性がありません。
    - プリインストールされているのはPython2です。

# Python3をインストール
Python3系を明示的にインストールします。

```sh:仮想マシン
# CentOSデフォルトのPythonバージョンを確認
## パス確認
$ which python
/usr/bin/python
# Pythonバージョン：2.7.5
$ /usr/bin/python -V
Python 2.7.5

# Python3をyumからインストール
$ yum -y install python3
~省略~
Installed:
  python3.x86_64 0:3.6.8-13.el7

Dependency Installed:
  python3-libs.x86_64 0:3.6.8-13.el7                      python3-pip.noarch 0:9.0.3-7.el7_7                      python3-setuptools.noarch 0:39.2.0-10.el7

Complete!

# インストールしたPython3のバージョン確認
## パス確認
$ which python3.6
/usr/bin/python3.6
## Pythonバージョン：3.6.8
$ python3.6 -V
Python 3.6.8

# Pythonコマンドを2系から3系に切り替え
## デフォルトのPythonコマンドの参照先確認：Python2
$ ls -l /usr/bin/python
lrwxrwxrwx. 1 root root 7 Jun  1  2019 /usr/bin/python -> python2
## デフォルトのシンボリックリンクを退避
$ sudo mv /usr/bin/python /usr/bin/python_bk
## 参照先がなくなったことを確認
$ ls -l /usr/bin/python
ls: cannot access /usr/bin/python: No such file or directory
## Python3.6のシンボリックリンクを作成
$ sudo ln -s python3.6 /usr/bin/python
## 変更したPythonコマンドの参照先確認：Python3.6
$ ls -l /usr/bin/python
lrwxrwxrwx. 1 root root 9 Sep 25 07:26 /usr/bin/python -> python3.6

# Pythonコマンド切り替え後の確認
## バス確認
$ which python
/usr/bin/python
## Pythonバージョン：3.6.8
$ python -V
Python 3.6.8

# pip(pkg管理システム)コマンドも使用可能
$ pip3 search ansible
ansible-stubs (0.1.dev1)                     - ansible-stubs aids in the development and testing of Ansible roles
~以下略~
```

# Pythonプログラム(.py)を実行
Python3をインストールしたのでプログラムを実行してみます。

```sh:仮想マシン
# .pyファイルを作成
$ vi test01.py
$ cat test01.py
print('python-izm')

# Pythonコマンドを使用して作成した.pyファイルを実行
$ python test01.py
python-izm
```

# 対話形式でPython実行
プログラムを用意しなくても対形式で実行することもできます。

```sh:仮想マシン
# 対話型シェル起動
$ python
Python 3.6.8 (default, Apr  2 2020, 13:34:55)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-39)] on linux
Type "help", "copyright", "credits" or "license" for more information.
```

```py:対話型シェル
# .pyファイルに記載したものと同じものを実行
>>> print('python-izm')
python-izm
# 終了する場合はquit()を実行
>>> quit()
```

# おわりに
インストールからプログラムの実行までは他の言語とそんなに遜色なくできました。
対話型シェルがあるのは動作確認などの際に便利そうで期待大です！
次回はソースの基本構文について勉強していこうと思います。
CCoE(Cloud Center of Excellence) は何をするのか

# はじめに

CCoE って初めて聞いたけど何だろう、何をするんだろうって思ったので調べて整理しました。

# CCoE の定義

クラウドセンターオブエクセレンス（CCoE）は、組織全体がクラウドを使用してビジネスを変革するために活用できるクラウド戦略、ガバナンス、ベストプラクティスの開発と管理を担当する、部門横断的なチームです。
CCoE は、クラウドの導入、移行、運用において組織全体をリードします。
クラウド・コンピテンシー・センター、クラウド・キャパシティ・センター、またはクラウド・ナレッジ・センターと呼ばれることもある。

参考: [CLOUD MANAGEMENT REPORT 2017](https://click.cloudcheckr.com/rs/222-ENM-584/images/CloudCheckr-Cloud-Management-Report.pdf)

# CCoE の具体的な仕事内容

-   クラウドの導入がスムーズに進む仕組みづくりを行う

## 1. クラウド活用のためのガイドラインの作成

- 標準化(ガイドライン)の作成
  - アカウント
  - ネットワーク
  - セキュリティ
  - 可用性
  - 監視
  - ログ
  - バックアップ・リストア
  - CI/CD
  - コスト管理

## 2. 情報の共有

- 成功事例(ベストプラクティス)、ノウハウの収集・共有

  - 開発
  - 運用
  - 自動化
  - セキュリティ

- 情報を共有する場を作ることが重要

## 3. 人材の育成

-  クラウド人材育成

# まとめ

組織のクラウド活用・導入を進めるために、部門横断的に存在し、リードを行うのがCCoE。
縦割り組織で部門間の連携がうまくいってないところに導入する場合、まずは活動を広く認識してもらうために情報の共有に力を入れる必要があるだろう。

# 参考リンク

-   [CLOUD MANAGEMENT REPORT 2017](https://click.cloudcheckr.com/rs/222-ENM-584/images/CloudCheckr-Cloud-Management-Report.pdf)

-   [クラウドのセンター オブ エクセレンス (CCoE) 機能](https://docs.microsoft.com/ja-jp/azure/cloud-adoption-framework/organize/cloud-center-of-excellence)

-   [CCoE(Cloud Center of Excellence)についてまとめてみた](https://dev.classmethod.jp/articles/about_ccoe/)

-   [クラウドの安全で積極的な活用のために](https://www.nri.com/-/media/Corporate/jp/Files/PDF/knowledge/publication/it_solution/2020/01/ITSF200103.pdf?la=ja-JP&hash=75CC393377AB628E62AE683957FF994ED4B318F3
)
-   [クラウド CoE とクラウド EA](https://www.accenture.com/jp-ja/blogs/cloud-diaries/japan-cloud-coe)

-   [DNP における CCoE の役割と AWS DeepRacer を活用した人材育成](https://pages.awscloud.com/rs/112-TZM-766/images/J1-04.pdf)

-   [Setting up a Cloud Center of Excellence (CCoE) for Enterprise Customers](https://www.slideshare.net/AliAsgarJuzer/setting-up-a-cloud-center-of-excellence-ccoe-for-enterprise-customers)
KotlinらしいAPIデザインにするには例外ではなくnullを返す

ある日仕事で日付操作のutility的な関数（プロジェクト全体でも使えるし、移植しようと思えばできそうな関数）を書いていて、その関数のAPIデザインについて議論があり、Kotlinらしいコードについて改めて意識するきっかけになったので、内容をメモがてら書いてみます。

# 作った関数

Javaの標準ライブラリの`java.time.LocalDate`の`LocalDate.parse(dateStr: String): LocalDate` メソッドは融通がきかなく、`2011-12-03`的な形式の日付文字列しかパースしてくれず、それ以外の形式の場合は例外を投げるような仕様になっています。

そこで様々な形式の日付文字列がパースできる以下のようなutility的なメソッドを作りました。
（`object DateUtil`というグローバルなオブジェクト内に定義しています）

```kotlin
fun parseLocalDate(dateStr: String): LocalDate? = TODO()
```

改善された点は2点です。
1. yyyy-MM-dd以外の形式の日付フォーマットでもパースできるようにした
2. パースできないフォーマットの場合は、例外を投げるのではなくnullを返すようにした

2つのメソッドの使い方は、以下のようになります。

```kotlin
// java.time.LocalDateのネイティブなメソッドを使う
// ※ld1, ld2の型はLocalDate
val ld1 = LocalDate.parse("2020-09-23") //OK
val ld2 = LocalDate.parse("2020/09/23") //例外を投げる

// 実装したメソッドを使う
// ※ld3, ld4, ld5の型はLocalDate?
val ld3 = DateUtil.parseLocalDate("2020-09-23") //OK。LocalDate.parse("2020-09-23")と同じ結果
val ld4 = DateUtil.parseLocalDate("2020/09/23") //OK。LocalDate.parse("2020-09-23")と同じ結果
val ld5 = DateUtil.parseLocalDate("invalid date") //null
```

# 議論内容

さて、このメソッドについて同僚にレビューを依頼した際に、
「`LocalDate.parse`が異常系において例外を投げているのに、`DateUtil.parseLocalDate`が異常系において例外を投げるのではなくnullを返しているのはなぜか」という質問がありました。

これについて以下のように理由を回答しました。

* 例外を返す必要性がないため
  * 日付形式が不正という事実は、コールスタックをさかのぼり伝播させる必要がない情報であるため
  * 異常系のケースは「形式が不正」というパターンだけなので、例外の種類により表現し分けなくてもnullで表現できる
* *Kotlinの標準ライブラリとかを見ててもこちらのほうがKotlinっぽいから*

ここでこの記事の主題でもある、*「Kotlinっぽいから」*という主観的な回答をしたことについて、何かもう少しきちんと説明できないかと感じていたところに、ちょうど自分の考えていたことと近い記事を見つけたのでそれについて内容紹介・整理したいと思います。

# 頭を整理する上で参考になった記事

この記事が参考になりました。 [Kotlin and Exceptions](https://medium.com/@elizarov/kotlin-and-exceptions-8062f589d07)
（執筆者はJetbrainsでKotlinライブラリのチームリードをしている方のようです）

要約としては **KotlinらしいメソッドのAPIデザインとしては、基本的にはメソッドの返り値をnullにするなり型を用意するなりでメソッドの振る舞いを表現すべき。例外は予期せぬ問題発生時に投げ、その例外はアプリケーションのルートレベル（大外）でHandlingすべき。** というものでした。

記事のポイントをまとめると、

* Javaには検査例外という仕組みがある
	* 例えばファイルI/O処理の場合、I/O途中にエラーが発生する可能性があるため、検査例外の仕組みにより例外ハンドリング（try catch）をすることを強制できる
	* この機能により異常系処理を書き忘れないというメリットが昔はあった
	* しかしその後メモリI/Oのようなエラーがほとんど発生しない処理にも検査例外が使われるようになり、例外チェックのボイラープレートコードが大量発生した
	* またJava8でLambda記法が登場したが、検査例外のせいで使いづらい面があった
* Kotlinも例外という仕組みを引き継いだ。そのおかげでJVMライブラリをシームレスに使える
	* しかし検査例外は前述の問題があるため言語仕様としては引き継がなかった
* Kotlinにおける例外の使い方
	* 例外はロジックのエラーに対して使う（例：『価格を表す引数は0以上でなければいけない』）
	* 例外は基本的にキャッチしない。トップレベルでキャッチされるようにする。
	* I/Oのエラーについてもキャッチせず、トップレベルでキャッチされるようにする。
	* **標準ライブラリも`OrNull`がついたものが多い。**異常系になりうるケースではそれらを使う（例：失敗しうるケースではString.toInt()ではなく、String.toIntOrNull()を使う）
	* 複数種類の失敗があり得る場合も例外ではなく、sealed classなどで各失敗を表現する型を定義すべき

※ Javaにそこまで詳しくないので、細かい点誤りあればすみません

ちょうど自分が感じていた「Kotlinっぽさ」というのは、`例外ではなく返り値（null等）でメソッドの振る舞いを表現する`ということであり、Jetbrainsで標準ライブラリを作っている人もまさにそういうことを考えていたことを知れました。
[paloalto]WEBUIのデバッグ取得方法

たまに、メーカからWEBデバッグの取得を依頼されることがあります。
WebGUI を含む問題のトラブルシューティングを行う場合に利用しますが、たぶん普段あんまり使うことはない。

英語のナレッジはありますが、一応日本語版覚書:point_up:

手順
-----------------------
1. WebUI にログイン   例)https://10.10.10.10/

2. 2.別のタブを開き、手順1と同じ URL にアクセスしますが、最後に/debug を追加します
　　　　　　　　  例)https://10.10.10.10/debug

3. 'Clear debug' ボタンをクリックし、すでに存在しているすべてのログをクリア

4.  'Minimize Javascript'のチェックを外す
5.  'Debug'にチェックし、デバッグを有効化

6.  1でログインした通常のWebUIタブに切替え、問題となる事象を再現させる

5.  'Debug'のチェックをはずし、デバッグを無効化
6.  'Minimize Javascript'にチェック

7.  デバッグ出力をテキストファイルにコピペ


WEBデバッグの取得方法は以下のナレッジを参考にしてください。
How to Run a PAN-OS Web UI Debug
-
https://knowledgebase.paloaltonetworks.com/KCSArticleDetail?id=kA10g000000CmA9CAK&lang=en_US
form_withによるname属性とid属性の自動付与

動作環境
Ruby 2.6.5
Rails 6.0.3.2

form_withを使った場合、name属性とid属性が自動で付与されていたことに気づかずにエラーをよく起こしていたので、投稿してみました。

##form_withにmodelを指定し、name属性とid属性が自動で付与される具体例
```ruby:new.html.erb
<%= form_with model: @hoge, local: true do |f| %>
  <%= f.text_field :fuga %>
  <%= f.submit "投稿する" %>
<% end %>
```
上記のように、modelを@hogeに指定し、検証ツールにてname属性とid属性を確認すると、**name="hoge[fuga]"、id="hoge_fuga"**となります。nameとidを指定していないのに、自動でname属性とid属性が付与されています。

先ほどのコードでは、name属性とid属性を指定しない場合は自動で付与されるという話でしたが、name属性とid属性を指定した場合はどうなるのかを見ていきましょう。

##form_withを使いname属性とid属性を指定した具体例
```ruby:new.html.erb
<%= form_with model: @hoge, local: true do |f| %>
  <%= f.text_field :fuga, name:"hogera", id:"piyo" %>
  <%= f.submit "投稿する" %>
<% end %>
```
先ほどと同様に、検証ツールにてname属性とid属性を確認すると、**name="hogera"、id="piyo"**となります。つまり、name属性とid属性は指定した通りになります。

次に、modelを指定するのではなく、urlを指定した場合はどうなるのかを見ていきましょう。

##form_withにurlを指定し、name属性とid属性が自動で付与される具体例
```ruby:new.html.erb
<%= form_with url: hoges_path, local: true do |f| %>
  <%= f.text_field :fuga %>
  <%= f.submit "投稿する" %>
<% end %>
```
先ほどと同様に、検証ツールにてname属性とid属性を確認すると、**name="fuga"、id="fuga"**となります。ここで気を付けたいのが、modelを指定した場合とname属性とid属性が異なっていることです。基本的に、controllerで行いたいactionが同じの場合、modelを指定してもurlを指定しても結果は変わらないのですが、name属性とid属性は異なります。

ちなみに、modelとurlの両方を指定すると、name属性とid属性はmodelを指定した場合と同じになります。

私はname属性とid属性は指定しないと付与されないものだと思っていたので、このことを知ったときには驚きました。また、JavaScriptを用いてname属性を取得することがあったのですが、その際に、modelを指定した時とurlを指定した時のname属性の違いに気づかずに何時間もエラーと闘ってしまうということがありました。

こういったエラーを防ぐために最初からname属性もid属性も指定してあげれば良いのでは？と考えたのですが、そもそも少しでも記述量を減らすために自動で付与しているので、自分で指定せずに自動で付与されたものを使うことが多いようです。
Rubyにおける○○.△△（ActiveRecordメソッド、インスタンスメソッド、データ取得）

#この記事を書いた背景
Rubyを学習している中で、○○.△△のパターンのコード（例： User.new）をたくさん見ました。
それぞれ使われ方が違うのではないかと思って調べたら、３つの使われ方のパターンが有りました。
ということで、今回は○○.△△のパターンをまとめました。

#対象読者
Rubyを学習中の駆け出しエンジニアさん

#実施環境
Ruby 2.6.5
Rails 6.0.3.3

#3つのパターンがありました
##①モデル（クラス）名.ActiveRecordメソッド名
モデルに対するテーブル操作で用いられます。
下の例では、『Tweet.all』、『Tweet.new』、『Tweet.find(params[:id])』の部分です。

~~~ruby
class TweetsController < ApplicationController
  def index
    #Tweetモデル（Tweetsテーブル）の全データ取得
    @tweet = Tweet.all
  end


  def new
    #Tweetモデルのインスタンス生成
    @tweet = Tweet.new
  end

  def edit
    #Tweetモデル（Tweetsテーブル）のある1つのデータ（1レコード）取得
    @tweet = Tweet.find(params[:id])
  end
end
~~~
ActiveRecordメソッドについては、こちらの記事をご覧ください。とても分かりやすかったです。
https://qiita.com/ryokky59/items/a1d0b4e86bacbd7ef6e8

##②インスタンス（変数）名.インスタンスメソッド名
インスタンスにメソッドをくっつけて使います。
インスタンスメソッドはインスタンスを生成しないと使えない。
下の例では、『number.calc(1,2)』の部分です。

~~~ruby
class Number
  def calc(a, b)
    puts a + b
  end
end

number = Number.new()
number.calc(1,2)
~~~

##③変数名.属性名
変数に格納された属性値を取得するときに用いられます。
下の例では、『user.nickname』の部分です。
Userテーブルのnicknameカラムのデータを取得します。

~~~ruby
class UsersController < ApplicationController
  def show
    #Userモデル（Usersテーブル）のある1つのデータ（1レコード）取得し、変数userに代入
    user = User.find(params[:id])
    #変数userのnicknameカラムの情報（属性値）を取得し、インスタンス変数@nicknameに代入
    @nickname = user.nickname
  end
end
~~~



以上になります。参考になれば幸いです。
Dcoker for windows起動時にNot enough memoryが出た時の対処法

# 状況
docker for windows 起動時にNot enough memory to start dockerと表示される。
再起動しても直らない。

![dockernotenough.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/612915/42e9a6d7-ef28-5681-9906-825d4c77f9dc.png)


# 対処法
①タスクバーのdockerアイコンを右クリックしsettingsを開く
②Resources内にあるADVANCEDを開く
③Memoryを最小の1.00GBに変更
④Apply&Restartをクリック
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/612915/ee98a020-57a5-8f9e-8ad0-11c08f9b20ea.png)




無事にDocker Desktop is runningになったら成功です。
【2D OD】Region ProposalからAnchor Boxへ

<h1>2stage detectorと1stage detector</h1>
R-CNN, Fast-RCNN, Faster-RCNNが遅かったのはRegion Proposalを用いた2stageのネットワークをだったから。
Region Proposalは多くの物体を提案してしまい処理速度が遅くなる。
それを解決すべく登場したのがYoloでも使われているAnchor Box。

<h1>Anchor Boxとは?</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/95d9d841-a89b-4d3b-0177-1aef180584cb.png)

様々なサイズや縦横比の長方形のBoxをAnchor Boxという。

<h1>Anchor Boxを用いた物体検出</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/9675adb1-2941-8819-dd67-e4cba20584af.png)

CNNによって画像を畳み込み、それぞれのAnchor Boxのサイズのオフセット、位置のオフセット等を学習する事で物体の位置を推測する。

上の画像を例にしてみる。まず2種類のAnchor Boxを16エリアに分けて定義する。右上の飛行機がいるエリアの緑色のAnchor Boxは得られたFeature Mapにより左にOffsetをするように学習してくれれば、飛行機の位置が検出出来る。サイズに関しても同じくオフセットを学習することで推測する事が出来る。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/3382a28c-c3fa-fd2b-2725-a92e5ada5c5e.png)

R-CNN系は物体の位置のRegion Proposalによって推定されたBounding Boxのオフセットを計算していたのに対してAnchorBoxでは定義されたAnchorBoxからのoffsetを計算するだけで良いので、計算コストを大幅に削減出来る。

<h1>結論</h1>
Feature MapからそれぞれのAnchor Boxのオフセットを最適化するように学習する事で学習が簡単になり、さらに計算コストも下がった

<h1>参考文献</h1>
アンカー ボックスによるオブジェクトの検出
https://jp.mathworks.com/help/vision/ug/anchor-boxes-for-object-detection.html
初めてのDialogflow 分岐編

# はじめに
[前回](https://qiita.com/ibukinson/items/16aba873701302c3a2e8)の続きです。
[前回](https://qiita.com/ibukinson/items/16aba873701302c3a2e8)をお読みで無い方は先に前回の入門編をご覧ください。

## 前回との変更点
今回はよりチャットボットらしく、聞き返しや分岐などの処理を前回の状態から追加していきたいと思います。
前回は

```
ユーザ「食べ物が欲しい」 → bot「はい、ハンバーガーです。」
```

だったのですが、今回は


```
ユーザ「食べ物が欲しい」 → bot「何が食べたいですか？」
ユーザ「うどん」 → bot「温かいのですか？ 冷たいのですか？」
ユーザ「温かいの」 → bot「はい、どうぞ温かいうどんです。」
```  
と言ったような聞き返しや分岐を行いたいと思います。
なお、うどんや蕎麦以外のピザなどの温冷の選択が無いものについては、分岐せずにそのまま「はい、どうぞ〇〇です。」と返すようにします。

# チャットボットの作成

## Entityの追加
Entityを新たに2つ作成します。
![Dialogflow 2020-09-25 13-33-34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/544661/1a27b143-3485-7fc9-cb8f-97d6c59894c5.png)
![Dialogflow 2020-09-25 13-51-54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/544661/57c00ce5-f153-d2cd-c516-86673938a9ec.png)

## follow-up intentの作成
このままだと、うどんと蕎麦の分岐の処理が出来ないので、follow-up intentの作成をしていきます。
Intentの一覧から「Add follow-up intent」をクリックします。

![スクリーンショット 2020-09-25 16.39.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/544661/4fef79d9-a274-77fa-da40-008f82e346ca.png)
その中からcustomを選択します。

![スクリーンショット 2020-09-28 10.42.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/544661/a8551669-8fa8-e4b4-63fe-2f2891f2bc0a.png)

それを２つ作ります。
![Dialogflow 2020-09-28 10-43-43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/544661/738de27c-8867-45f9-cfc7-f2e8388de8eb.png)

それぞれの名前を設定していきます。
そしてさらにfollow-up intentを作成します。
![Dialogflow 2020-09-28 12-10-18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/544661/68d726f2-93ba-27b9-426c-843cc9a34502.png)

## Intentの設定
まずは前回作成したfood-intentの修正からしていきましょう。
今回は聞き返しを行うので、ここでは何が食べたいのかを聞きましょう。
![Dialogflow 2020-10-18 15-19-33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/544661/45b76d94-d735-3f73-b399-11871421d191.png)

SAVEを行い、次に「food - intent - anser」intentの設定をしていきます。
ここでは「冷たい、暖かい」の選択肢が無い食べ物が回答された場合です。
Training phrasesには「寿司」と「ピザ」を入力。
![Dialogflow 2020-10-18 15-27-53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/544661/c60bd105-8867-d7e6-f6fa-91f1a66d80e6.png)

Responsesには「はい、どうぞ$typeです。」と入力します。
![Dialogflow 2020-10-18 15-28-07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/544661/96765fc8-3f8b-85c0-ff24-4206b6d7e58b.png)

ここの$typeというのは、ユーザが行った食べ物（）

# 確認
最後にちゃんと出来てるかどうかをマイクボタンから確認してみましょう。
下記の2パターンが確認出来たら成功です。

パターン1

```
ユーザ「食べ物が欲しい」 → bot「何が食べたいですか？」
ユーザ「うどん」 → bot「温かいのですか？ 冷たいのですか？」
ユーザ「温かいの」 → bot「はい、どうぞ温かいうどんです。」
``` 

パターン2

```
ユーザ「食べ物が欲しい」 → bot「何が食べたいですか？」
ユーザ「ピザ」 → bot「はい、どうぞピザです。」
``` 

# 最後に
今回は少し複雑な分岐や聞き返しの部分をやりました。
少し複雑ですが、一度理解すれば次回からは自分で出来るようなシンプルな作りになっているなと実感して頂けると思います。
他にも外部のファイルから取り込む方法や、FulfilIntentからwebhookを使い、外部のサービスやサーバーなどと連携なども行えるので、シンプルかつ出来ることが多いのがDialogflowの魅力だなと感じました。
最後までありがとうございました。
Xcodeで「DEVELOPER_DIR」に指定するパス

## はじめに

ターミナルでどのXcodeを使うか指定するとき、以下の2パターンを見かけますが、みなさんはどちらで指定しているでしょうか。
また、同じ挙動になるかご存知でしょうか。

```bash:DEVELOPER_DIRの指定パス
# 1
$ export DEVELOPER_DIR=/Applications/Xcode_12.app/Contents/Developer

# 2
$ export DEVELOPER_DIR=/Applications/Xcode_12.app
```

私は先日まで知りませんでした。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ときどき `DEVELOPER_DIR` で `/Applications/Xcode_11.6.app/Contents/Developer` でなく `/Applications/Xcode_11.6.app/` までしか指定していないのを見るんだけど、問題ないのかな？</p>&mdash; ウホーイ (@the_uhooi) <a href="https://twitter.com/the_uhooi/status/1309054170410950658?ref_src=twsrc%5Etfw">September 24, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 結論

結論から言うと、1も2も同様の挙動になるので、どちらで指定しても問題ありません。

`man xcode-select` で解説されています。

```shell-session:xcode-selectのmanualの抜粋
EXAMPLES
       xcode-select --switch /Applications/Xcode.app/Contents/Developer
          Select /Applications/Xcode.app/Contents/Developer as the active developer directory.

       xcode-select --switch /Applications/Xcode.app
          As above, selects /Applications/Xcode.app/Contents/Developer as the active developer directory. The Developer content directory is automatically inferred by xcode-select.
```

`DEVELOPER_DIR` の名前通り「Developer」フォルダを指定すべきですが、「Xcode.app」のパスを指定した場合は自動で「Developer」フォルダが推測されます。

## おまけ：「DEVELOPER_DIR」と「xcode-select」について

コマンドラインで使うXcodeを指定するには、 `DEVELOPER_DIR` 環境変数をエクスポートする方法と、 `xcode-select` コマンドで指定する方法の2通りあります。

以下の記事で取り上げた通り、私は前者の方法を使っています。
https://qiita.com/uhooi/items/29664ecf0254eb637951#xcodeの選択不要

## おまけ：XcodeのCLIツールの説明はmanが詳しい

`xcode-select` コマンド以外にも、 `xcrun` や `xcodebuild` などのコマンドはWeb上に情報が多くありません。
`man` コマンドによる説明が一番詳しい公式ドキュメントといっても過言ではないので、覚えておくと有用です。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">xcodebuildとかもそうなんですけど、Xcode関係はだいたいmanが一番詳しい（それがいいことなのかどうかは分からないけど）。</p>&mdash; kishikawa katsumi (@k_katsumi) <a href="https://twitter.com/k_katsumi/status/1309059266939154433?ref_src=twsrc%5Etfw">September 24, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## おわりに

「DEVELOPER_DIR」に指定するパスは、「Developer」フォルダと「Xcode.app」のパスのどちらでもいいことがわかりました。
つまりどちらを指定するかは好みです。

私は1で指定していましたが、短いほうがスッキリするので最近は2で指定することが多いです。
EBSのファーストタッチペナルティをくらったときに反省したこと

小ネタ。

久々に[ファーストタッチペナルティ](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ebs-initialize.html#ebs-initialize-linux)をくらって反省したので、
ポストモーテム的なものをまとめます。
出せる部分だけ。

## 発生事象

#### 概要

ファーストタッチペナルティによるレスポンスの遅延及びエラーの発生

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143313/c2cea9c9-c2d8-9ff7-c026-bb4b95c6071e.png)

ELBの平均レスポンスタイムとパーセンタイルのグラフ。
紫の線がレスポンスタイム。
ほとんどのリクエストのレスポンスタイムが悪化している。

#### 詳細

1. あるwebサーバのネットワークの帯域が不足し始めたので、スケールアウトすることで対処しようとした。
2. ディスクの高IOが必要で、オートスケールは設定していないサーバだった。
3. EC2で作成されており、定期的に取得しているAMIから復元しようとしていた。
4. EBSに800GB程度のデータを保持していた。
5. AMIからインスタンス構築し、追加した台数分ロードバランサの配下に登録した。
6. 登録したインスタンスにバランシングされだしたタイミングからレスポンスタイム及びエラー率が上昇した。
7. 登録したインスタンスのログからエラー等は未検出だった。
8. 調査したところディスクのIOPSが既存環境の1/7程度の性能となっていた。
9. ロードバランサから切り離し回復した。

## 原因

#### 直接原因

* ファーストタッチペナルティにより、ファイル読み込みに遅延、結果レスポンスが遅延した

正常時のCPUの状態
※緑色の部分がiowait、それ以外はsystemやuser、stealなど。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143313/efa15484-f8bc-e4a8-b9cc-04c55b9c14df.png)

問題発生当時のCPUの状態
※system,userなども本来含まれているが、iowaitが占めていて他の値が見えないほどになっている
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143313/769bf5e0-83d0-ac47-209b-0d5e9e8e5e14.png)

#### 対策が必要そうな項目

* ファーストタッチペナルティが起こることを認識できていなかった
* 事前の動作確認でIOの性能の確認は含まれていなかった
* 復旧手順を参考に復旧するも、実際に復旧させたときに発覚するたぐいの問題だった

## 対応

* `grep hoge -r /hoge` で、既存ファイル読み込むことでブロックにアクセスした。※公式はddやfioをお勧めしてる
* IOPSが正常時動作と同等程度出ることを確認した。
* 再度ロードバランサに接続し問題ないことを確認した。

## 再発防止策

* AMIからの復旧が必要な場合
  * Fast snapshot restoreを利用する
  * https://aws.amazon.com/jp/blogs/news/new-amazon-ebs-fast-snapshot-restore-fsr/
* 高IOが必要なディスクに対して
  * スナップショットから復元するような運用をやめる
  * EBSを作り直しデータを他からダウンロードするなどの仕組みにする
  * 作成時にディスクを確保(新規作成)するようにする

## 見送った再発防止策

* 復旧訓練
  * 一回同じことをやったことがあり、その際は運よく問題にならなかった
  * 定期的な運用見直しで、定期的にファーストタッチペナルティのことを思い出すよう訓練を行うことは、人員と工数とコストの兼ね合いから難しい
* 高IOの復元だけ必ずFSRを利用するよう自動化する
  * こういう自動化やアラートがないとFSRを使うというノウハウが忘れ去られ再発するリスクは免れない
  * 同じような条件をどう判定するか、判定にかかる部分の自動化が困難と思われる

## 感想

再発防止策と書きましたが、防止策というより、再発したときに何をやるのかという内容で、反省としてはあまり良くないかもしれません。
何か良さそうな防止策があれば教えていただきたいところです。

そもそもファーストタッチペナルティがどういう時に起きるか知ってても、実際の事象と結び付けられないのが良くないです。
こういうことが起きると気をつけなきゃってなるけど、しばらくしたら忘れると思うのであまり意味がないです。
起きないために気づく方法は現状テストしかないけど、テストの観点にも無ければテストもできない。
テストの観点に含めるためには経験を積まないといけないしでデッドロック。
どうしたらいいんだろ・・・？一律リリース時にディスクパフォーマンスを計測する？
みんなしてるのかなあ。
VSCodeの「Draw.io Integration」拡張でファイルをエクスポートする方法

# エクスポート方法

F1キー押下 > Draw.io: Export To...

![スクリーンショット 2020-09-25 15.45.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9875/f1ae458c-7718-5d0f-213e-8bf38ef52113.png)

# 参考
- [Can not export file #113](https://github.com/hediet/vscode-drawio/issues/113)
[Rails]simple_calendarの導入方法

#はじめに
アプリ開発でカレンダーを用いた実装をしたかったので簡単にまとめました。

###simple_calendarとは
simple_calendarとは、簡単にカレンダー機能を付け加えれるgemです。
月間カレンダー、週間カレンダーなど日付指定をしてカレンダーを作成することができます。
今回は月間カレンダーを用いた方法となっております。

#目次
1. simple_calendarのインストール
2. simple_calendarのビューの生成
3. カレンダーを表示
4. カレンダーのレイアウトの変更
5. おまけ

#1. simple_calendarのインストール
gemファイルに以下を追記し、アプリケーションのディレクトリで「bundle install」を実行します。

``` gem.file
gem "simple_calendar", "~> 2.0"
```
#2. simple_calendarのビューの生成
simple_calendarのビューファイルを生成するために、以下のコマンドを実行します。
レイアウトをカスタマイズしたいときはこのコマンドでファイルを生成することで編集ができるようになります。

#####ターミナル 
``` 
rails g simple_calendar:views
```

#3. カレンダーを表示
###モデルの編集
カレンダーにイベントを表示させるために以下をモデルに追記します。
「date」の部分はカラム名を記述します。

```ruby:model.rb
def start_time
  self.date
end
```

###ビューファイルの編集
カレンダーを表示させるために、以下を記述します。
「events」の部分は、コントローラーで設定したインスタンス変数を置くことでデータを引っ張ってきます。
これでカレンダー上にイベントを表示させることができます。

```ruby:view.html.erb
<%= month_calendar events: @all do |date, all| %>
  <%= date.day %>　//カレンダー上の日程の表示の仕方
  <% all.each do |i| %>
    <div>
      <%= i.price %>
    </div>
  <% end %>
<% end %>
```

<%= date %>だと2020-01-01のように出力されます。
今回は日付だけを表示させたいので<%= date.day %>と記述しています。

###その他ファイルの編集
simple_calendarのCSSを適用させるために、application.cssに「*= require simple_calendar」を追記します。

```ruby:/app/assets/stylesheets/application.css
/*
 *= require simple_calendar #ここに追記します
 *= require_tree .
 *= require_self
 */
```


#4. カレンダーのレイアウトの変更
以下のようにファイルを作成しCSSを自分で記述することで、カレンダーのデザインをカスタマイズすることができます。

```ruby:/app/assets/stylesheets/_simple_calendar.scss
.simple-calendar {
  .day {}

  .wday-0 {}
  .wday-1 {}
  .wday-2 {}
  .wday-3 {}
  .wday-4 {}
  .wday-5 {}
  .wday-6 {}

  .today {}
  .past {}
  .future {}

  .start-date {}

  .prev-month {}
  .next-month { }
  .current-month {}

  .has-events {}
}
```

#5. おまけ
inputタグでカレンダーを使いたいときは以下のように 「f.date_field」で表示させることができます。

```ruby:view.html.erb
<%= form_with model: @income, local: true do |f| %>
  <%= f.date_field :date, id:"date" %>
<% end %>
```

#参考リンク
https://qiita.com/isaatsu0131/items/ad1d0a6130fe4fd339d0
https://github.com/excid3/simple_calendar
Boost Spirit V2のSpirit.Qiについて少し調べた

Spirit V2は、Spirit.Qi, Spirit.Karma, Spirit.Lexの三つ巴で紹介されることが多いが、Spirit.Karma, Spirit.Lexは使ったことがないので、Spirit.Qiを調べることにする。

Spirit.Qiは、単純に言うとパーサーである。

さらに端的には、qi::parseとqi::phrase_parseの２つがある。

qi::phrase_parseは、qi::ruleやqi::grammerで拡張可能であり、この時になると、EBNF然にかけるSpirit.Qiが本領を発揮するらしい。(-ω- )o< 

+```c++
qi::parse(it, str.end(), int_ % ',', result) && it==str.end();
+```

↑ 1文字（この場合は整数）のパース

+```c++
qi::phrase_parse(it, str.end(), +( "x:" >> double_ >> "y:" >> double_ ),
+```

↑ 2文字以上のパース
+(...) の「+」は、一文字以上の文字の繰り返しという意味。

コードを見てみる。。。

+```c++
qi::parse(it, str.end(), int_ % ',', result) && it==str.end();
+```

     1#include <iostream>
     2#include <string>
     3#include <vector>
     4#include <boost/fusion/tuple.hpp>
     5#include <boost/spirit/include/qi.hpp>
     6#include <boost/spirit/include/phoenix.hpp>
     7using namespace std;
     8using namespace boost;
     9using namespace boost::spirit;
    10
    11bool parse_csv( const string& str, std::vector<int>& result )
    12{
    13  string::const_iterator it = str.begin();
    14  return qi::parse(it, str.end(), int_ % ',', result) && it==str.end();
    15}
    16
    17int main()
    18{
    19  {
    20    std::vector<int> result;
    21    if( parse_csv( "4,2,7", result ) )
    22      cout << result.size() << " integers parsed" << endl;
    23    else
    24      cout << "error" << endl;
    25  }
    26  {
    27    std::vector<int> result;
    28    if( parse_csv( "9 6 5", result ) ) 
    29      cout << result.size() << " integers parsed" << endl;
    30    else
    31      cout << "error" << endl;
    32  }
    33}

実行してみる。。。

<pre>
$ ./a.out 
3 integers parsed
error
</pre>

+```c++
qi::phrase_parse(it, str.end(), +( "x:" >> double_ >> "y:" >> double_ ),
+```

コードを見てみる。。。

     1#include <iostream>
     2#include <string>
     3#include <vector>
     4#include <boost/fusion/tuple.hpp>
     5#include <boost/spirit/include/qi.hpp>
     6#include <boost/spirit/include/phoenix.hpp>
     7using namespace std;
     8using namespace boost;
     9using namespace boost::spirit;
    10
    11bool parse_points( const string& str, std::vector< fusion::tuple<double,double> >& result )
    12{
    13  string::const_iterator it = str.begin();
    14  return qi::phrase_parse(it, str.end(),
    15                          +( "x:" >> double_ >> "y:" >> double_ ),
    16                          ascii::space,
    17                          result
    18                          ) && it==str.end();
    19}
    20
    21int main()
    22{
    23  std::vector<int> result;
    24  {
    25    std::vector< fusion::tuple<double,double> > result;
    26    if( parse_points( "x: 1 y: 2.0 x: 3 y: -4.5", result ) )
    27      cout << result.size() << " points parsed" << endl;
    28    else
    29      cout << "error" << endl;
    30  }
    31}

実行してみる。。。

<pre>
$ ./a.out 
2 points parsed
</pre>
pythonプログラム起動時に「ValueError: Unable to configure handler 'file_output_handler'」

# 事象
コード自体は問題なさそうなのだが、なぜかエラーになる。

``` py
.
..
...
LOG_CONFIG = {
    'version': 1,
    ...
    ..
    .
    'handlers': {
        'console': {
            'formatter': 'default',
            'class': 'logging.StreamHandler',
            'stream': 'ext://sys.stderr',
        },
        'output': {
            'level': 'DEBUG',
            'class': 'logging.handlers.TimedRotatingFileHandler',
            'formatter': 'default',
            'filename': '/path/to/application.log',
            'when': 'MIDNIGHT',
            'interval': 1,
            'backupCount': 5,
        },
    },
    ...
    ..
    .
}
...
..
.
```

``` shell
.
..
...
  File "./main.py", line 7, in <module>
    load_log_config()
  File "./configs/log_config.py", line 41, in load_log_config
    dictConfig(LOG_CONFIG)
  File "/root/local/python-3.8.5/lib/python3.8/logging/config.py", line 808, in dictConfig
    dictConfigClass(config).configure()
  File "/root/local/python-3.8.5/lib/python3.8/logging/config.py", line 570, in configure
    raise ValueError('Unable to configure handler '
ValueError: Unable to configure handler 'file_output_handler'
```

# 原因
`filename`に指定したディレクトリが存在しない（または誤っている）のが原因
エラーメッセージがわかりづらくて少しハマった・・・

``` py
.
..
...
LOG_CONFIG = {
    'version': 1,
    ...
    ..
    .
    'handlers': {
        'console': {
            'formatter': 'default',
            'class': 'logging.StreamHandler',
            'stream': 'ext://sys.stderr',
        },
        'output': {
            'level': 'DEBUG',
            'class': 'logging.handlers.TimedRotatingFileHandler',
            'formatter': 'default',
            'filename': '/path/to/application.log',　←　コレ
            'when': 'MIDNIGHT',
            'interval': 1,
            'backupCount': 5,
        },
    },
    ...
    ..
    .
}
...
..
.
```
QRコードを読み取ってアプリが開く機能をKonyで作ってみた Part①

##目次
1. はじめに
2. 実装方法
3. まとめ

##はじめに
今回は、Konyに標準搭載されているdeeplinkの機能を使って、
QRコードを読み取って特定のアプリを起動するための方法をご紹介します。

利用者がたくさんのアプリから該当アプリを探して開く手間を省くために、
deeplinkの機能はよく利用されます。

Konyでは簡単に実装ができるので、是非活用してみてくださいね:ok_hand:


##実装方法

###①アプリを準備
deeplinkで開きたいアプリをKonyで作成します。
今回は、こちら（[Camera Widgetを使って画像取り込みアプリを作ってみた](https://qiita.com/Kony_Team/items/df8aa2cf8d6e197c3105)）で作成した
Imaga Uploaderのアプリを使って説明していきます。

###②deeplinkのURLを指定
アプリが完成したら、
KonyのProject Settingsを開き、Native->iPhone/iPad/Watchを開きます。
下の方をスクロールすると、「deeplink URL Scheme」が現れますので、
こちらにアプリのリンク名を指定します。

今回は、サンプルとして「imageuploader」と設定をしました。
![スクリーンショット 2020-09-25 14.59.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/d15aec51-b64b-6bae-5662-3a2b8ebdfd54.png)

これでKony Visualizerでの設定は完了です！

ここまで完了したら、アプリのBuildを行います。
Product->Run as->Emulator名->Nativeを選択すると、アプリのBuildができます。

![スクリーンショット 2020-09-25 15.02.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/9c1635dc-47de-f23c-c04a-4f3daef84856.png)

Buildがうまく行かない場合は、
詳しいBuild方法を別記事で紹介していますので、参考にしてみてください。
:point_right:[Kony Mobility PlatformでのアプリBuild実行手順](https://qiita.com/Kony_Team/items/748881071e6f1e4b3c9d)

###③Xcodeでの設定
Buildが完了しましたら、Xcodeを開きます。
XcodeのInfoタブを開いたら、「URL Type」にKony Visualizerで指定した
deeplinkが反映されているかどうかチェックしてください。

![スクリーンショット 2020-09-25 15.10.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/73f74e3d-3eb6-6955-3501-d70126ab6a5c.png)
URL SchemesにVisualizerで指定した「imageuploader」が反映されていますね！

上記のようになっていれば、OKです！
アプリを作成し実機にインストールをしてください。

###④リンクの作成
最後にアプリを開くためのリンクを作成します。
deeplinkを「imageuploader」と指定したので、
以下のようなURLリンクを作成すればアプリが開くようになります。

サンプル： `imageuploader://`

今回はこちらのリンクを元にQRコードを作成します。
同様にQRでアプリを開くようにしたい場合は、無料でQRコードを作成できるサイトがありますので
そちらをご利用ください。

では、アプリとアプリを起動するためのリンクが作成できましたので、
実際の動作をチェックしてみましょう:grinning:！
<blockquote class="twitter-tweet"><p lang="und" dir="ltr"><a href="https://t.co/LJtUL4Q61b">pic.twitter.com/LJtUL4Q61b</a></p>&mdash; Kony (@Kony12763790) <a href="https://twitter.com/Kony12763790/status/1309385502726922242?ref_src=twsrc%5Etfw">September 25, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

QRコードをiPhoneのカメラで読み取ると、
ポップアップが表示され「（アプリ名）で開く」をタップすると
Image Uploaderアプリを開くことができました！


今回はアプリのリンクのみの指定でしたが、
リンクの末尾にパラメータを指定することにより、
遷移先のフォーム等を指定することができますので、次回その方法について説明したいと思います:wave_tone2:

##まとめ
今回はKoyのdeeplinkの機能を使って、
URLリンクからアプリにジャンプさせる方法をご説明しました。

次回、リンクから取ってきた値によってアプリの遷移先を変える方法もご紹介しますので、
是非そちらも参考にしてみてくださいね！

##参考
https://docs.kony.com/konyonpremises/Subsystems/Studio_User_Guide/Default.htm#Deeplink_Function.htm
【Markdown】VSCodeで快適にQiita用記事の下書きをするための簡易ガイド

Webサービスに文章を投稿するときにローカルで下書きしてからコピペするタイプの人が書いたQiita用記事の下書き簡易ガイド
（最終更新：2020.09.25）

## 書いた人の環境

- OS：macOS Catalina バージョン10.15.6

## VSCodeのインストール

下記リンクからインストーラをダウンロードしてよろしくやります（詳細省略）。
[Visual Studio Code](https://azure.microsoft.com/ja-jp/products/visual-studio-code)

## VSCodeの設定

Markdown的に正しい文書を書くためにLint（文法チェック的なもの）を入れます。

```txt
VSCode左のExtensionsをクリック
検索窓に"markdown"と打つ
"markdownlint"というエクステンションをインストール
```

正式なMarkdownとQiita版Markdownで改行の扱いに違いがあるので、設定でQiita版に合わせます（改行を無視せず改行として扱われるようになる）。

```txt
VSCodeの Code > Preferences > Settings を開く
検索窓に"markdown"と打つ
"Markdown > Preview: Breaks"の項目にチェックをつける
```

あとは、拡張子「.md」でファイルを作成してエディタ右上のプレビューマークをクリックすればプレビューを見ながらMarkdownで下書きしていけます。

## よく使う記法集

### 「# 」ヘッダ（見出し）

- #を増やすことで見出しの階層を指定可能

### 「- 」順序なしリスト

- インデントすることでリストの階層を指定可能

### 「1. 」順序付きリスト

- インデントすることでリストの階層を指定可能

### 「\[表示用テキスト](URL)」リンク

- "表示用テキスト"の文字でURLへのリンクを貼れる

### 「\`\`\`code:file.ext 〜 \`\`\`」ソースコード

- バッククォート３つで挟んでソースコードを記述するとハイライトされる（Qiita上）
- コードの種類、ファイル名を指定可能

### 「> 」引用

- 記号の数によって引用の階層を指定可能

### 「\」エスケープ

- 記法自体を文字として記述することが可能

## あとがき

ひとまず私がよく使うかつ忘れそうな最小限の知識をまとめてみました。
詳しい記法については公式の記事を参照するとよいでしょう。
[Markdown記法 チートシート](https://qiita.com/Qiita/items/c686397e4a0f4f11683d)

※厳密にいうとこの記事がQiitaのガイドラインにある「プログラミングに関する知識」にあたるか微妙かもしれませんが、プログラミング上のドキュメントに関する知識の共有ということで適切だと判断した、とビビリな私は注釈を添えておきます。
［Laravel8］ログイン機能付きでプロジェクトを作成するまで


1. [composerでプロジェクトを作成する](#1-composerでプロジェクトを作成する)
2. [Jetstreamをインストールする](#2-Jetstreamをインストールする)
3. [LivewireかInertiaのどっちかをインストールする](#3-LivewireかInertiaのどっちかをインストールする)
4. [ビルドする](#4-ビルドする)
5. [データベースを作る](#5-データベースを作る)
6. [.envファイルでデータベースを変更する](#6-.envファイルでデータベースを変更する)
7. [マイグレーションする](#7-マイグレーションする)

環境：XAMPP for Windows, Laravel Framework 8.6.0

###1. composerでプロジェクトを作成する

まずはcomposerを使ってプロジェクトを作成します。
以下のコードの場合、『your-project』という名前のプロジェクトを作成します。

```
composer create-project --prefer-dist laravel/laravel your-project
```

###2. Jetstreamをインストールする

<b><font color="Red">cdコマンドでプロジェクト内に移動したら</font></b>、Jetstreamをインストールします。

```
composer require laravel/jetstream
```

###3. LivewireかInertiaのどっちかをインストールする

LivewireかInertiaのどっちかを選択してインストールします。
`--teams` は、チーム機能を付ける為のオプションです。必要なければ取って良し。

```
php artisan jetstream:install livewire --teams
```

もしくは、

```
php artisan jetstream:install inertia --teams
```

###4. ビルドする

ビルドします。

```
npm install && npm run dev
```

###5. データベースを作る

私の場合、今回XAMPPを使っているので、XAMPPでサクッとデータベースを作っておきます。

###6. .envファイルでデータベースを変更する

.envファイルのデータベース名を忘れずに変更しておきます。

```php:.env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=your_project　←ここ。
DB_USERNAME=root
DB_PASSWORD=
```

###7. マイグレーションする
マイグレーションします。

```
php artisan migrate
```

すると、以下画像のように８個のテーブルが入った状態で出来上がります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235741/9ee6f2d3-7ab5-4272-de25-4c7399bc81ed.png)

artisanコマンドでサーバ起動後にトップページを確認すると、以下画像のように右上にLoginとRegisterが表示されます。

```
php artisan serve
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235741/bdc1db09-aaff-10dd-e15c-05ffa2623a66.png)

以上です。

参考サイト：
https://jetstream.laravel.com/1.x/installation.html
https://blog.capilano-fw.com/?p=7827
HTMLで文字化けを直す方法（UTF-8、Shift_JIS）

#はじめに
ソースコードなどのテキストファイルを他のエンコードタイプでブラウザ表示させると文字化けしてしまいます。
HTMLで文字エンコーディングを指定し、文字化けを直す方法を説明していきます。

#目次
1.文字エンコードって何？
2.エンコードタイプとは、コードと文字の対応表
3.HTMLでエンコードタイプを指定する
4.エンコーディングを変換する

#1.文字エンコードって何？
一言でいうと、「文字データを数値へ変換させること」です。
コンピューターはデータを「数値」でしか理解できません。そのため、「文字」を扱う場合には、「数値」に変換して処理を行います。この変換のことを文字エンコードと言います。

#2.エンコードタイプとは、数値と文字の対応表
コンピューターに「文字」を理解させるためには、「数字」と「文字」の対応表が必要です。
この対応表にはいくつかの種類があって、OSの種類によって、扱う対応表も異なります。例えば、WindowsはShift_JIS、UNIXやMacはUTF-８など異なった対応表でテキストを扱います。
この対応表のことをエンコードタイプといい、アルファベットはどの種類のエンコードタイプでも同じ数値データが割り当てられています。なので、英語で書かれたテキストファイルはそれを作成したコンピューターと違うコンピューターで表示しても文字化けはしません。
ところが、ひらがなや漢字などはエンコードタイプによって、割り当てられている数値データが異なります。
そうするとWindowsでテキストファイルを作って、Macでそれを表示すると文字化けが発生して読めません。
どのOSも全てのエンコードタイプを扱えるようにはなっていますが、デフォルトで扱うエンコードタイプが異なるため文字化けが発生してしまいます。

#3.HTMLでエンコードタイプを指定する
まず表示するページで使われるエンコードタイプをHTMLファイルに指定しなければいけません。もし指定しないと、コンテンツ内の文字が誤って解釈されてしまいます。
そのためには、ソースコードが書かれたHTMLファイル内のmeta要素でcharset属性を使います。
また、文字化けしてしまうことを想定しているため、言語は日本語としています（lang="ja"）。
#####UTF-8で表示させたい場合
```
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
・・・
```
#####Shift_JISで表示させたい場合
```
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="Shift_JIS">
・・・
```


このcharset属性はHTML5から追加された属性の為、HTML5より前のバージョンのHTMLでは下記の方法で記述します。

#####HTML5より前の文字コードの指定方法
```
<meta http-equiv="content-type" content="text/html; charset=文字コード">
```
#####HTML5より前のバージョンでShift_JISで表示させたい場合
```
<meta http-equiv="content-type" content="text/html; charset=Shift_JIS">
```

#4.エンコーディングを変換する
HTMLファイルを表示するにはエディタを使います。
現在ではテキストのエンコードタイプを自動で判別して表示してくれるものが多いですが、自動で判別してくれないときはエンコードタイプを設定から自分で切り替える必要があります。
今回はVScodeを用いてShift_JISでの表示を行っていきます。

VSCodeのデフォルトのエンコードタイプはUTF-８になっています。そのため、Shift_JISで作成したテキストファイルを表示すると文字化けしてしまいます。
VSCodeにはデフォルトでエンコードタイプを変換する機能が備わっているため、変換に拡張機能はいりません。

___
VSCode画面下に表示されているエンコードタイプ（デフォルトはUTF-8）をクリック
↓
表示されたメニューの「エンコード付きで再度開く」を選択
↓
「Japanese (Shift JIS)」を選択
↓
文字化けがなくなりShift_JISで表示される
___

#参考
[Shift JISやEUCなどからUTF-8へ変換する方法](https://codeaid.jp/blog/exchange-utf8/#i-2)
[文字コードと文字化け対策](https://creatorquest.jp/lessons/html/meta-character/)
[http-equiv 属性
](https://reference.hyper-text.org/html5/attribute/http-equiv/)
Rustの関数について


# まえがき

この記事はRUSTチュートリアルをZerobillbank社内メンバー（有志）で勉強がてら、可能な限りわかりやすく内容を書き出す企画の一部です。

なお、初学者のため（略）という免責を打ちつつ間違いなどあればコメントで教えていただけますと一同嬉しく思います！

本項は関数について記載します。
https://doc.rust-jp.rs/book/second-edition/ch03-03-how-functions-work.html

# 関数の動作法

## 関数の命名規則

Rustの関数と変数の命名規則は、スネークケースを使うのが慣例です。

```
fn my_function() {
    println!("My Function.");
}
```

## 関数の引数

関数定義では引数の型注釈が必須です。

```
fn my_function(x: i32) {
    println!("The value of x is: {}", x);
}
```

## 戻り値のある関数


"->"の後に型を書きます。

```
fn five() -> i32 {
    5
}
```

上記の関数では"return"が記述されていません。
Rustではブロックの最後の式の値が暗黙的に返却されるため、"return"の記述が必要ありません。

"return"で戻り値の値を指定することもできますが、上記の書き方が一般的なようです。

また、下記のように5の後ろにセミコロンを付けたらどうなるでしょう？

```
fn five() -> i32 {
    5;
}

error[E0308]: mismatched types
 --> src/main.rs:6:14
  |
6 | fn five() -> i32 {
  |    ----      ^^^ expected `i32`, found `()`
  |    |
  |    implicitly returns `()` as its body has no tail or `return` expression
7 |     5;
  |      - help: consider removing this semicolon

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.
error: could not compile `playground`.

To learn more, run the command again with --verbose.
```

上記のようなエラーになります。
行末にセミコロンを付けた場合に式は文に変換され、値を返却しなくなることが原因です。

では、式と文とはどういうものでしょう？

- 文
   - なんらかの動作をして値を返さない命令
- 式
   - 結果が値に評価される


文の例

```
let y = 6;  // let y = 6; はyに6を代入している。結果として値を返さない命令となる
```

式の例

```
{
    let x = 3;
    x + 1 // 式となり4を返す
}
```

このように、他の言語だとあまり見られない;の使い分けがあるので注意が必要です。

## さいごに

ZEROBILLBANKでは一緒に働く仲間を募集中です。
[ZEROBILLBANK JAPAN Inc.](https://zerobillbank.com/%e3%81%8a%e5%95%8f%e3%81%84%e5%90%88%e3%82%8f%e3%81%9b/)
tech camp 卒業


#祝　卒業しました！
今日はテックキャンプで最終課題発表会がありました

ここにも感想をまとめておきます
最終課題ではフリマアプリの実装、追加実装をしました。

#最終課題を終えての学び

最終課題を通じて、自分でエラーを解決する力が身についたと感じでいます。カリキュラム通りにやっている時は深く考えなかったメゾッドや変数などがどこに対応しているかなど自身で深く考えて理解しなければ進められなかったからです。コードを自分で考えて打ったのは最終課題からが初めてだったので不安も募りましたが、qiitaやrailsガイドを調べて自分でコードを書いて自分の思う挙動が成功した時はとても達成感がありました。


#プログラミングスクールを通っての感想

私はプログラミングを知って１ヶ月ほどでスクールに入ったので、コードの仕組みも何もわからずすごく不安でしたが、難解なコードの羅列を理解できた時はすごく嬉しく、楽しく学習できました。初めて自ら楽しいと思って始めた勉強でしたので、スクールで学んだこの学習に対する姿勢を忘れず、これからもペースを乱さずに学習を続けていきたいです。今はオリジナルアプリを作っている最終ですが、全て自分で調べて作ると、すごく技術不足であることを感じます。これからたくさん知識を増やしてみんなに便利だと思ってもらえるようなアプリを開発していきたいです。


#最後に
　知識が増えてできることが増えるということはすごく楽しいです。
　新しいことを挑戦したい方にとってプログラミングはすごくおすすめです☺️
PHP Laravel 6 おすすめ映画投稿サイト作成過程 8:ジャンルタグ追加編（後編）

##controllerとviewファイルの作成

recommendsのviewファイルを複製して使用しました。
他のviewファイルも同様です。

```recommend/resources/views/tags/create.blade.php
@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">{{ __('Login') }}</div>

                <div class="card-body">
                    <form method="POST" action="{{route('tags.store')}}">
                        @csrf
                        <table>
                            <thead>
                                <tr>
                                    <th>タグ</th>
                                </tr>
                                <tr>
                                    <th><input type="text" name='title'></th>
                                </tr>
                            </thead>
                        </table>
                        <button type="submit">登録</button>
                        <a href="{{route('recommends.index')}}">一覧に戻る</a>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection
```