OmniAICreator/Qiita-1.07M huggingface dataset:
インフラ領域の自動化について学ぶ

## 目標
インフラ領域におけるパワーワードでもある「自動化」について実際にどのような事例があるのか学びたい

## サーバー構築
Infrastructure as Code
つまりコードを書いてインフラ構築
サーバー構築を自動化する、その心は

- コードを記述すればサーバー構築ができるため、とにかく素早く構築をしたい
- スキルの標準化
- 人的ミスの予防

https://www.rworks.jp/system/system-column/sys-entry/21725/

メリットとしては

- 一度構築をしたものを再利用することができる
- バージョン管理ができる
- コード化されているため、レビューができる

https://www.imagazine.co.jp/infrastructure-as-code%E3%81%AE%E7%95%99%E6%84%8F%E7%82%B9%E3%81%A8%E3%83%A1%E3%83%AA%E3%83%83%E3%83%88%E3%80%80%EF%BD%9E%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E6%9B%B4%E6%94%B9%E3%83%97%E3%83%AD/

よく使用されるツールとしてはTerraformやAnsibleがある

https://dev.classmethod.jp/articles/akiba-aws-iac-failure-cases/

### ARM
Azure の環境構築をコード化して実行するためのテンプレート。
json形式。

### サーバー構築における自動化を行う上での必要スキル

- ARM(jsonの取扱・記述)
- AWS CloudFormation(jsonの取扱・記述)
- Terraform・Ansible
- これらにGitを適切に組み込み管理する

## SaaSの管理者業務
### Teamsの自動化
MS製品のTeamsの自動化事例を学ぶ

<b>課題</b>

- チームの乱立を避けるため、ユーザー自身のチーム作成を制限することが一般的
- チーム作成を申請制にし、IT部門が一元管理する運用となる場合、以下の問題に直面する
    - 棚卸しをしないことによるサイトやチームの乱立​
    - 退職や異動による​管理者不在のチーム​
    - 手動のポリシー適用により、​設定漏れが発生する​
    - 退職や異動による​責任の所在が不明確​
    - 申請毎にチーム作成する​運用工数が増加​
    - 管理タスクのミスや漏れ​
    - SPOサイトの容量圧迫​
    - ゲスト参加チームの棚卸し​

これらの運用課題を自動化で解決しようということ。
![スクリーンショット 2021-10-28 18.00.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1603537/eb98d890-3752-a0bf-b663-79071a8d56f6.png)
![スクリーンショット 2021-10-28 18.00.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1603537/8ea9934e-9eae-f2af-5376-51d67375d1a7.png)
異なるプロジェクト間のBigQueryデータ同期アプリ構築時のハマりポイントまとめ 【BigQuery・GCS編】 


## はじめに
「プロジェクトAにあるBigQueryのデータをプロジェクトBに週次で同期を取ってほしい」という要望が発生しました。
手作業で毎週行うのはキツいため、自動化できないか検証を行いこのデータ移行アプリを作成しました。

本記事では備忘も兼ねて、対応した内容・ハマったポイントなどを記載します。
事前に知っておけば調査の手間が減る内容もあるため、参考になればと思います。

## 本記事で主に扱うGCPサービス
- BigQuery
- Google Cloud Storage(GCS)
- Google App Engine(GAE)

本記事ではBigQueryとGCSについてがメインになります。

## その他サービスでの対応内容
他のサービスで対応した内容については、以下の記事にまとめています。
[異なるプロジェクト間のBigQueryデータ同期アプリ構築時のハマりポイントまとめ  【GAE編】](https://qiita.com/nakazawaw/private/5602ee2337e8d3f92bff)

## 要件
- プロジェクトAのBigQueryテーブルデータをプロジェクトBに定期的に同期したい
- 対象のテーブル数は30弱

プロジェクトAには外部システムから数分間隔でファイル連携され、毎日大量のデータが新しくBigQueryに取り込まれる仕様でした。
「プロジェクトBでプロジェクトAと同等のデータを扱いたい」という要望がありこのような仕組みが必要になりました。
ただし、プロジェクトAほどリアルタイム性は求められないため、週次での更新としました。

## 制約
- プロジェクトAとプロジェクトBではVPCが異なるため、直接テーブルのコピー操作はできない
- 新規に専用インスタンスは立てられない

BigQueryにはGCPコンソールの操作でテーブルをコピーする機能があるのですが、VPCが異なる場合はエラーとなりました。
おそらくアクセス権限周りの制御により発生するエラーだと思います。
また、案件都合で専用のGCEインスタンスの作成にはNGが出たため、今回は新規GCEインスタンスを作らずに実現する必要がありました。

これらの問題を突破しつつ、テーブルデータを移行しなければいけませんでした。

## できあがった構成
プロジェクトAとB両方にアクセスできる中間環境を用意して、最終的には下記のような構成と処理になりました。

- 処理内容
  1. プロジェクトAのAirflowサーバー内シェルでbq extractコマンドを実行(cron実行)
  2. 中間環境のGAEでファイル移動処理を実行(GAEのcron実行)
  3. プロジェクトBのAirflowサーバー内シェルでbq load処理を実行(cron実行)
![001_gcpアーキ図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1476851/3f320784-5df2-31fd-9100-2dc666ecaa78.png)


## BigQueryでの対応内容・注意点
### bqコマンドでのインポート・エクスポート操作
BigQueryはテーブルの内容をjsonファイル等にエクスポート(bq extract)、逆にファイルからインポート(bq load)する処理がコマンドで実行できます。
以下のコマンドはgzip形式でテーブルデータのエクスポートとインポートを実行するコマンドです。

```
bq extract --compression GZIP --destination_format NEWLINE_DELIMITED_JSON sample_dataset_a.sample_table gs://sample-backet-a/sample_table_*.gz

bq load --replace --source_format NEWLINE_DELIMITED_JSON --encoding=UTF-8 sample_dataset_a.sample_table gs://sample-backet-a/sample_table_*.gz
```

bq load では --replace オプションを付与し、テーブルの中身を洗い替えするようにしています。
指定したテーブルが数億のレコードを持っていても、コマンド実行は5分以内には完了しました。

これと同等の動きをするGAE向けの書き方がありますが、課題にぶつかったため採用できませんでした。

### パーティション設定が有効なテーブルのbq extract結果

bq extract で出力されるファイル数と1ファイルごとのサイズには毎回差異がありました。
今回対象としたテーブルはパーティーション設定が有効だったため、パーティーション単位で区切られ出力されるようです。 

### コマンド実行をshell化

プロジェクトAとBにはそれぞれにAirflow(バッチ処理管理ツール)用のGCEインスタンスが存在したため、
エクスポートとインポートはそこにbqコマンドを実行するシェルを作成し配置することにしました。
（Airflowについてもいろいろ苦労させられたため、そちらについては別途記事にしたいと思います。。。）

## GCSでの対応内容・注意点
### GCSの利用用途
BigQueryデータのエクスポート先と、環境間のファイル移動の保存先としてGCSを利用しました。
また対象テーブルは後で追加されることが想定できたため、テーブルの一覧をjson形式の定義ファイルとしてGCSに配置し、GAEアプリが参照する構成としました。

### ライフサイクルポリシーの設定
bq extractが実行毎に結果ファイル件数が異なる関係で前回実行時のファイルが残っていると邪魔なので、今回はGCSバケットのライフサイクルポリシーを「1日経過でファイルを削除」するように設定し、次回処理起動時にはバケット内が空になるようにしました。
![002_gcsバケット設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1476851/3f17088e-1f07-28ab-c4a6-038ef97f602e.png)

## 最後に
bq extractの結果ファイル数が毎回違っていたのは想定外でした。
ライフサイクルポリシーの設定ができたお陰で、かなり運用の手間が省けたのは良かったです。

GCPについては日本語の記事が少ないなと感じるので、この記事が少しでもGCPについて困っている方の役にたてば幸いです。
LIFE WILL Emodiversity APIのemotion_mapを使ってみたメモ

# これはなに
LIFULLさんから出ている年月から地域の感情を分析結果を取得するAPIのメモです。

※[emotion_analyzeについてのメモはこちら](https://qiita.com/wakasamasao/items/4cafcd75cfa2b8a821d0)

どんなものかのデモはこちらで体験できます。
https://lab.lifull.com/lifewill/emodiversity/map/

tokenの申請は以下のページを見てください。
https://lab.lifull.com/lifewill/emodiversity/api-docs/index.html

今回利用するemotion_mapのドキュメントはこちら
https://lab.lifull.com/lifewill/emodiversity/api-docs/reference/emotion_map.html

# APIの呼び方
## Node.js
```
const request = require("request");
request.post({
    url: "https://lab.lifull.com/lifewill/api/v1/emotion_map",
    headers: {
        "token": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
    },
    form: { year: 2021, month: 5 },
    json: true
}, function (error, response, body) {
    const emoMaps = body.emotions;
    if (!error) {
        const emoList = ["ドキドキ", "ワクワク", "キュンキュン", "ニコニコ", "ホノボノ", "ユルユル", "ウトウト", "シクシク", "モヤモヤ", "ツンツン", "ピリピリ", "ソワソワ"];
        for (let emo of emoMaps) {
            emo.emotion_text = emoList[emo.emotion - 1];
        }
    }
    console.log(emoMaps);
});
```
※既存のデータではemotionの番号(1-12)しかこないので、テキストを追加するプログラムが追加しています。

# 取得できるデータ
## 実際のサンプル
```
{
  emotions: [
    { emotion: 3, jis_code: 11002, name: '札幌市' },
    { emotion: 3, jis_code: 12025, name: '函館市' },
    { emotion: 3, jis_code: 12033, name: '小樽市' },
    { emotion: 8, jis_code: 12041, name: '旭川市' },
    { emotion: 11, jis_code: 12050, name: '室蘭市' },
    { emotion: 11, jis_code: 12068, name: '釧路市' },
    { emotion: 3, jis_code: 12076, name: '帯広市' },
    { emotion: 9, jis_code: 12084, name: '北見市' },
    { emotion: 6, jis_code: 12092, name: '夕張市' },
    { emotion: 2, jis_code: 12106, name: '岩見沢市' },
    { emotion: 2, jis_code: 12114, name: '網走市' },
    { emotion: 9, jis_code: 12122, name: '留萌市' },
    { emotion: 11, jis_code: 12131, name: '苫小牧市' },
    { emotion: 9, jis_code: 12149, name: '稚内市' },
    { emotion: 7, jis_code: 12157, name: '美唄市' },
    { emotion: 1, jis_code: 12165, name: '芦別市' },
    { emotion: 1, jis_code: 12173, name: '江別市' },
    { emotion: 11, jis_code: 12181, name: '赤平市' },
    { emotion: 2, jis_code: 12190, name: '紋別市' },
    { emotion: 8, jis_code: 12203, name: '士別市' },
    { emotion: 6, jis_code: 12211, name: '名寄市' },
    { emotion: 11, jis_code: 12220, name: '三笠市' },
    { emotion: 6, jis_code: 12238, name: '根室市' },
...(略)...
  ],
  result: 'success',
  update: '2021-05-31 03:41:18.9311'
}
```
取得すると全市町村分が来ますのでデータ量が非常に多いです。
※2021年10月現在で1709
jis_codeに関してはこちらを参考にしてください。
https://www.soumu.go.jp/denshijiti/code.html
What are the types of Enterprise Web Development?


No matter how many tasks we undertake, our principal goal is to satisfy the needs of our clients. One of the markets which are in serious require of digital change is large-scale enterprises. Every time we share our own special software experiences, we know our real mission.

The growth rate is rapid in the enterprise mobile app development market. According to the global statistics on mobile app revenues, the market will grow to $365 billion in 2023. Absolutely incredible!
Let us provide an in-depth guide on the process of developing enterprise apps and the various types of Enterprise Mobile Applications.
    
<b>Types of Enterprise Mobile Applications</b>

There are three main types of enterprise mobile applications: departmental, employee, and company level.

Let's talk about the differences and similarities between the different types independently:

<b>Employee level:</b>

This kind of <a href="https://www.techavidus.com/blogs/enterprise-web-application-development">enterprise application</a> is only for internal employee communications and assigning assigninggeneral, they are designed to assist in the smooth process the internal processes. Consider it an application with a brief list of features that can aid managers in tracking the progress of their project and to identify any possibility of problems with timing to avoid any delays. The app for employees ensures the smooth running of your workflow, provides continuous performance checks in real-time and keeps employees informed of any related actions.

<b>Department level:</b>

Like any other large corporation that has multiple departments responsible for specific tasks. Departmental applications focus on the needs and procedures within the specific department, such as marketing, sales and finance, for example. With the help of departmental apps employees are able to completeto  different tasks that are are specific to their teams as well as stay in contact with customers, and take care of their feedback in a timely manner.


<b>Company level:

When your internal workflows of every individual employee and employeesre department are improved the company-wide enterprise applications come into the picture. These applications aim to link every department to a single corporate network. It allows you to share documents from the enterprise and databases for employees as well as executives. In the end, an uninterrupted connection can help 
ensure consistency and also helps in commhelption.     

It is evident that every kind of enterprise mobile app has a distinct purpose. Beginning with an employee-level application type, you could develop an enterprise mobile application that is the best fit for your needs at the moment.
If you want to make your company more durable forward-looking, ambitious, and aspired just contact us to get a free consultation.
Slackのワークフローで、送信日時をスプレッドに入力する

Slackのワークフローからスプレッドシートにデータを集積させる時に、送信日時のデータを入力したい場合のTipsです。

こんな感じのスプレッドがあったとして、送信日時の所に、ワークフロー動作時の日時を挿入します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260763/3995f115-ac9d-7b0a-e241-01a00b65b313.png)


1. スプレッドにAddする時、`=now()`と関数を入力する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260763/048a9b07-3fee-32c7-dc60-51843d28fe11.png)

2. Addした行をselectする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260763/b6a73e74-01bf-26a5-1d34-903413c2a4ca.png)

3.selectした内容（変数を挿入する＞select~＞送信日時）でupdateする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260763/c2a286d5-9dd0-4f53-e352-245a2d958d5c.png)

※add~ ではなく select~ の方を選んでください！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260763/8b9e41ac-d1ac-2955-aff7-fe9cbef682ff.png)

以上！

ワークフローで送信日時を入力できるようになりました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260763/47d3da8a-c2d5-2964-3414-b4b8323e7317.png)


## now()を入れた時点で日付が表示されたよ。updateはしないといけない？

now()は常に現在時刻を表示するので、時間経過で勝手に変わってしまう…
updateによって、「now()関数」を「送信日時」で上書きしている。

## selectをするのは何故？addしたときの値でupdateではダメ？

selectすると、「now()関数によって画面に表示されている現在時刻」を取得できる。
≒「送信日時」
HTTP Proxy 経由で Azure Storage にアクセスする (v12 バージョン) (.NET Core)

# HTTP Proxy 経由で Azure Storage にアクセスする (v12 バージョン) (.NET Core)

\# 以下の記事が書かれた時の版数は .NET Core 3.1 (3.1.412), Azure.Storage.Blobs 12.10.0 となります.

.NET 用 Azure Blob Storage クライアント ライブラリ v12 でまたマイクロソフトがオーバーホールをして、プロキシの設定方法が変わっていたので調査した. 9.4.1 から使えた .NET 用 Azure Blob Storage クライアント ライブラリ v11 で使える設定方法は [HTTP Proxy 経由で Azure Storage にアクセスする (.NET Core)](https://qiita.com/c-yan/items/0d86259bc3be8304e8b5) をご確認ください.

v12 は async 強制がなくなって先祖返りした感. v11 より v12 のほうが良い気がする.

```csharp
using Azure.Core;
using Azure.Core.Pipeline;
using Azure.Storage.Blobs;
using System;
using System.Net;
using System.Net.Http;

namespace ConsoleApp
{
    class Program
    {
        static readonly string ConnectionString = "...";
        static readonly string ProxyUrl = "...";
        static readonly string ProxyUserId = "...";
        static readonly string ProxyPassword = "...";

        static void Main(string[] args)
        {
            var serviceClient = new BlobServiceClient(ConnectionString, new BlobClientOptions()
            {
                Transport = new HttpClientTransport(new HttpClientHandler()
                {
                    Proxy = new WebProxy()
                    {
                        Address = new Uri(ProxyUrl),
                        Credentials = new NetworkCredential(ProxyUserId, ProxyPassword)
                    },
                }),
                Retry = {
                    Delay = TimeSpan.FromSeconds(5),
                    MaxRetries = 5,
                    Mode = RetryMode.Exponential,
                }
            });
            var containerClient = serviceClient.GetBlobContainerClient("...");
            containerClient.CreateIfNotExists();
            containerClient.UploadBlob("...", new BinaryData("..."));
        }
    }
}
```
カオピーズが第5回 AI・業務自動化 展【秋】に出展します！

**2021年10月27日(水)～29日(金)、幕張メッセで開催される「第5回 AI・業務自動化 展【秋】」展示会に出展する運びとなりました。**

→「**<a href="https://ainow.ai/2021/10/19/259283/">画像認識AIモデルを開発するカオピーズが第5回 AI・業務自動化 展【秋】に出展</a>**」

弊社のブースではAI-OCR、画像認識・画像処理ソリューションの実演を行います。

画像認識AIモデルを開発するカオピーズは、AI研究開発などのさまざまなIT領域における豊富な経験を積み重ねたベトナムオフショア開発会社であり、ディープラーニングや強化学習、AI-OCRを活用し画像認識AIモデルを研究開発しています。

**※AI-OCR「Yomokka」**
弊社のAI-OCRは定型、非定型文書を問わず、活字や手書き文字を高精度に自動認識します。
当日はAI-OCRで読ませたい文書・資料をお持ちいただければ、その場でお試し頂けます。
▶ カオピーズの AI-OCR の詳細は**<a href="https://kaopiz.com/ja-news-kaopiz-ocr-engine-yomokka/">こちら</a>**。

**※書類スキャンアプリ**
スマホで紙の文書を撮影し、背景から用紙を自動的に認識してトリミング処理を実行します。読みやすい、明瞭なスキャンが迅速に出力されます。スキャンには時間や手間がかかる場合、是非弊社のスキャンアプリをご体験ください。
▶ カオピーズのスキャンアプリのデモサイトは**<a href="https://ocr.kaopiz.com/">こちら</a>**。

**※AI姿勢推定（人物姿勢・動作認識）**
モニターに表示する標準姿勢の画像に従い、ヨガを行います。身体の動きを読み取り、AI技術で正しい姿勢をしているかどうか判断します。正しい姿勢をしていない場合、AIにより修正するように指摘します。
AIトレーナーまたはAIで身体の動作を監視するソリューションをお探しでしたら、是非弊社のブースでご体験ください。

弊社のAI-OCR、画像認識・画像処理、といった**<a href="https://kaopiz.com/ja-ai-image-recognition/">AIソリューション</a>**をはじめ、ご要望に合わせて最適なソリューションをご提案します。
また、AIエンジニアやWebエンジニア不足や社内開発体制の構築に、**<a href="https://kaopiz.com/ja-labo-development/">ラボ型開発</a>**のご相談も承ります。ベトナム**<a href="https://kaopiz.com/ja-offshore-service/">オフショア開発</a>**の魅力、メリットデメリットについて、直接疑問にお答えします。
ぜひ弊社のブースへお立ち寄りください。皆様のご来場を心よりお待ちしております。
Pardotスペシャリスト合格への道

6月末に認定アドミニストレーター資格を取得してから、3ヶ月でPardotスペシャリスト資格を取得することができました:sunny:

#私のスペック
・今年4月まで「Salesforce」という言葉も知らなかった
・文系学部出身（社会人2年目）
・勉強は苦手、、、

#勉強方法
##1. Trailhead
Salesforceには、Trailheadという学習環境が用意されています。
Trailhead内で『Pardot』と検索して、出てきたトレイルは一通りやりました。
　↓ 公式から出ているトレイルMixを記載しておきます:raised_hands_tone2:
 「【Salesforce公式】認定 Pardot スペシャリスト 対策」

##2. Pardot体感ハンズオン

Trailheadで単語や何となくの知識を付けた後、Pardot体感ハンズオンを受講しました。
Pardot基礎では、Salesforce認定講師によるトレーニングにより、Pardotに関する基礎的な知識を学習することができます。

私は、Pardotに関するトレイルを一通り行った後に受講しましたが、本当に基礎的な部分を説明してもらえるので、受講⇒トレイルの順でも良かったかもしれません。

:rolling_eyes:　。〇（私が受講したときは3時間だったので、ある程度知識がある方だと「あー、それは知ってるなあ」が3時間続くことになってしまうかも…?）

あ、pardot体感ハンズオンは無料です:v:

##3. ヘルプ
Salesforceのヘルプを読み込むことが大事です:bangbang:
と、先にスペシャリストになった上司が言ってました。

実際、試験を受けてひしひしと感じました。大事です。
これは大事の一言です。


##4. 試験対策問題
トレイルが終わったら、試験対策問題に取り組みました。

アドミニに引き続き、お世話になったのは「Salesforceの1番星」さんです。
　　試験対策問題がめちゃくちゃ沢山のっています。
　　これだけ問題解いて、落ちたら諦めつくなあってギリ思えるぐらいの問題数です。
　　https://keneloper.com/exam-preparation-hypothetical-questions/#Salesforce_Pardot
　　:girl_tone1:　。〇（QiitaにSalesforceの一番星さんの問題に解説をつけてくださっている記事もあったので、間違えたところはそれで復習していました。）

####！！！ここで注意！！！
認定アドミニストレーターのときは、ネットに落ちている試験対策問題と同じ(ような)問題が、本番でも結構出てきた印象がありました。
でも、今回のPardotスペシャリスト試験には、同じ(ような)問題はぜっっっっっんぜん出てこなかったです。
合格基準も72％とアドミニより高いので、試験対策問題に全信頼を置くのはやめた方がいいと思われます:frowning2:

運でなんとかなる場合もありますけどネ:secret:

##アドミニ受験についてはコチラ
https://qiita.com/Supply-net/items/c435e6a6bd53dcf07e49
【備忘録】git pushでのerror "src refspec main does not match any"

rails学習中につき、よくやってしまうので備忘録として残しておきます。
私と同じような初学者の方の参考になれば幸いです。

```
% git push -u origin main
```

を実行したときにこのようなエラーが出たら

```
error: src refspec main does not match any
error: failed to push some refs to 'https://github.com/[githubアカウント名]/[githubリポジトリ名].git'
```

mainをmasterに変えて

```
% git push -u origin master
```

を実行すればよい！
Hinemosノウハウ集

## データのバックアップを取る
データはPostgreSQLに格納されているので、dumpファイルをエクスポートすればよい

```shell
# hinemos_manager stop
service hinemos_manager stop

# PostgreSQL start
service hinemos_pg start

# dump file export
/opt/hinemos/sbin/mng/hinemos_backup.sh -w hinemos

# PostgreSQL stop
service hinemos_pg stop

# hinemos_manager start
service hinemos_manager start
```

## データをリストアする
エクスポートしたdumpファイルをインポートする
これを使うと、クローンサーバーを構築する時が簡単になる

```shell
service hinemos_manager stop
service hinemos_pg start
/opt/hinemos/sbin/mng/hinemos_restore.sh hinemos_pgdump.XXXX-XX-XX_XXXXXX
service hinemos_pg stop
service hinemos_manager start
AWS Certified Advanced Networking - Specialty (ANS-C00) 取得しました

2021年10月27日にAWS Certified Advanced Networking - Specialty(ANS-C00)を受験して**合格**してきました。
合格のために私が実施した勉強方法などについてここに書き残しておきます。


# 試験概要の把握
最初に試験ガイドで試験の概要について確認しました。
[AWS Certified Advanced Networking - Specialty 試験ガイド](https://d1.awsstatic.com/ja_JP/training-and-certification/docs-advnetworking-spec/AWS-Certified-Advanced-Networking-Specialty_Exam-Guide.pdf)

試験ガイドに記載されている「出題の比率」を見ると第1分野、第2分野だけで全体の50%以上を占めており、この分野での知識を重要視されていることが分かります。

- **第 1 分野: ハイブリッド IT ネットワークアーキテクチャの大規な設計および実装　24%**
- **第 2 分野: AWS ネットワークの設計と実装　28%**
- 第 3 分野: AWS タスクのオートメーション　8%
- 第 4 分野: アプリケーションサービスとのネットワーク統合の構成　14%
- 第 5 分野: セキュリティとコンプライアンスの設計と実装　12%
- 第 6 分野: ネットワークの管理、最適化、トラブルシューティング　14%


# サンプル問題を解く
学習前の自身のスキルレベルを確認するためにサンプル問題を解きました。
[AWS Certified Advanced Networking - Specialty サンプル問題](https://d1.awsstatic.com/ja_JP/training-and-certification/docs-advnetworking-spec/AWS-Certified-Advanced-Networking-Specialty_Sample-Questions.pdf)

結果は10問中6問正解でしたのでまずまずの結果です。
但し正解した6問全てに自信を持って解答できた訳ではないので学習の必要性があることを実感しました。
また、試験は1000点中750点取得が合格条件のためこの時点では合格の可能性は低いと判断できます。


# AWS BlackBeltの動画を見る
BlackBeltで関連サービスの概要をおさらいしました。
動画はYoutubeで視聴可能です。
[AWS サービス別資料](https://aws.amazon.com/jp/aws-jp-introduction/aws-jp-webinar-service-cut/)

上記リンクの「Networking & Content Delivery」のカテゴリーの動画を視聴しましたが、私が試験を受けた時は以下のサービスについて問われる問題は出題されませんでした。

- Gateway Load Balancer 
- AWS Transit Gateway
- AWS Network Firewall
- AWS App Mesh

<br>
私は時間の都合上見ていませんが、余裕があれば以下のBlackBeltも視聴することをお勧めします。

- Amazon S3
- AWS CloudFormation
- AWS CloudTrail
- AWS Config 
- AWS OpsWorks
- Amazon WorkSpaces


# AWS公式サイトの「よくある質問」を読む
この「よくある質問」はAWSのサービスを理解する上でものすごく勉強になります。
これを読んだ後に改めてBlackBeltを見ると更に理解が深まります。


# Udemyの問題集
問題慣れするのにお勧めです。
回答を間違った個所を調べながら何度か周回すると効果的です。


# サービスを触る
実際にVPCやELBを作成してみたりRoute53やcloudfrontを設定してみたりしました。
これをやると各サービスの機能が具体的なイメージとして頭の中に残ります。


# その他やっておいたほうがよいと思う勉強
・公式トレーニングサイトのANS-C00対策動画を見る(英語)
英語苦手なので見ませんでした。。

・ネットワークの基礎知識の学習
本試験はネットワークの基礎知識を保有していることが前提の試験になっています。
私はオンプレでのネットワーク設計・構築の経験が活きましたが、もしネットワークの知識が乏しいという場合は最低でも以下の用語に対する理解をしておくことをお勧めします。

- CIDR
- ルーティング
- BGP
- VPN
- DNS


# 学習時のポイント
・古いアーキテクチャについての知識
ANS-C00は以下のような一昔前のアーキテクチャについて問われる設問があります。
[Transit VPC](https://aws.amazon.com/jp/blogs/news/aws-solution-transit-vpc/)
[オンプレ - AWS間の名前解決](https://aws.amazon.com/jp/blogs/security/how-to-set-up-dns-resolution-between-on-premises-networks-and-aws-by-using-unbound/)
これらは現在だとTransitGatewayやRoute53 ResolverといったAWSマネージドサービスで実現可能ですが試験合格のためと割り切って学習しておきましょう。

・DirectConnectの知識
DirectConnectを自前で用意して検証することは難しいため、ここは大多数の方が机上での学習止まりになるかと思います。
但しDirectConnect関連の問題は多く出題されるため、不安な方はBlackBeltだけではなく公式マニュアルや各種ブログサイトなどからできる限り情報を集めておくことをお勧めします。

・ネットワーク構成図を書く
サンプル問題やudemyの問題を解く時に文章を読むだけではなくネットワーク構成図を書いてみることをお勧めします。
慣れれば問題を読みながら頭の中で構成図を描けるようになってきます。


# 受験結果
参考までに受験の所要時間とスコアも記載しておきます。

- 試験時間：見直し含めて約90分
- スコア：876

以上です。
どなたかの参考になれば幸いです。
StripeでJPY以外の決済通貨を指定する際の注意点

##前置き
普段JPYしか使っていないと「…ん？」となる部分があったため書き残します。

##やりたかったこと
$50（USD）で決済させたい。

##起きた問題

###こうしたら
```
<form action="" method="POST">
  <script
    src="https://checkout.stripe.com/checkout.js" class="stripe-button"
    data-key="key"
    data-name="hoge"
    data-amount=50
    data-currency="USD">
  </script>
</form>
```
###こうなった
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201780/e1e29e5c-1735-9302-1c35-a35a28b92ea1.png)
**$0.50 になっとる。。。。。**

data-currencyでUSDを指定したところ、金額がamountで指定した数値の1/100になってしまいました。

##原因
amountで指定した数値は、currencyで指定した通貨の最小単位（USDの場合はセント）の金額として適用されるようです。
これまでJPYしか使ってこなかったため、この仕様に気が付きませんでした。

https://stripe.com/docs/currencies#zero-decimal
>API リクエストはすべて、金額が通貨の最小単位で指定されると想定しています。たとえば、10 USD を請求するには、amount の値を 1000 (1000 セント) で指定します。
>小数点以下のない通貨の場合は、100 を掛けずに整数として金額を指定します。たとえば、500 円を請求するには、amount の値を 500 で指定します。
>小数点以下のない通貨:
BIF, CLP, DJF, GNF, JPY, KMF, KRW, MGA, PYG, RWF, UGX, VND, VUV, XAF, XOF, XPF

##対処法
amountを通貨の最小単位に揃えましょう。

```
<form action="" method="POST">
  <script
    src="https://checkout.stripe.com/checkout.js" class="stripe-button"
    data-key="key"
    data-name="hoge"
    data-amount=5000
    data-currency="USD">
  </script>
</form>
```

```
$stripe->charges->create([
    'amount' => 5000,
    'currency' => 'USD',
    'source' => $token,
    'description' => 'description',
]);
```

###結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201780/1b290cd1-3727-afa0-b2fa-956230275ed5.png)
**決済金額が $50.00 になりました🎉🎉**
streamlitとplotlyによるnikkei225のplot

### streamlitとplotlyで日経平均225のチャートをプロットです。
株式チャートのプロットについて、plotlyを使った、日本語の文書があまり見つからなかったので、投稿したいと思います。
plotlyは、jupyterで表示出来ますが、ここではstreamlitを使用する為、pycharm ceで書きました。

【環境】Linux Mint20
python3.8
plotly==5.3.1
streamlit==1.0.0

**1.ライブラリのインポート<br>**
使ってないライブラリも読んでおりますが、悪しからず。

```
# Nikkei225のplot

# starandard libarary
import datetime as dt
import numpy as np
import os
import pandas as pd
import pandas_datareader as pdr

# for plot
import matplotlib.pyplot as plt
import plotly.express as px
import plotly.graph_objs as go
import plotly.figure_factory as ff
import seaborn as sns
import streamlit as st

# for ml, statistics
import statsmodels.api as sm
import statsmodels.formula.api as smf
import statsmodels.tsa

```
**2.データセットの読み込み<br>**
ここでは、yahooからデータを取得しました。<br>
OHLCと全てのデータが取得できます。
*@st.cache*がポイント、streamlitでの以降のplotの処理速度が大幅に変わります。
データを取得がyahooからの場合: information_source='yahoo'
yahooからNikkei225を取得する場合: ticker_symbol='^N225'
取得する銘柄によって、また同じNikkei225でも他から取得する場合は、変更になる。
ここでは、関数にしてみました。

```
# dataset
@st.cache
def load_dataset():
    start ='2019-01-01'
    end = dt.date.today()
    information_source='yahoo'
    ticker_symbol='^N225'
    df = pdr.DataReader(ticker_symbol, information_source, start, end)
    return df

```
**3.データフレーム表示**
取得したデータをstreamlitで表示する関数を作成してみました。

```
def show_df():
    data = load_dataset()
    df = st.write(data)
    df = st.write(df)
    return df

```
**4.streamlitでデータフレーム表示**
先程、定義したデータフレーム表示の関数を実行。

```
show_df()
```
**5.plot**
5-1.plotly.expressで、時系列データを表示する関数を作成。
ここでは、closeだけを抽出。

```
def plot_ts():
    df = load_dataset()
    # df = df
    plot_line = px.line(data_frame=df, x=df.index, y=df['Close'], title="Close")
    return plot_line
```
5-2.変化率のplot
pct_change関数で、変化率をplot
デフォルトなので、前日のcloseから変化が大きければ、変化の大きい折れ線グラフがplotされる。
こちらも、関数にまとめました。

```
def plot_PctChange():
    df = load_dataset()
    plot_line = px.line(data_frame=df, x=df.index, y=df['Close'].pct_change(), title="Rate of Change")
    return plot_line

```
**6.streamlitによる、データフレームとグラフのplot**
streamlitのwrite関数で、ブラウザに表示。
基本構文: st.write()
この書き方で、データフレームもグラフの描画等も可能。

6-1.closeのplot
plot_ts()として、st.write()の中に作成した関数を書いて、実行。

```
st.write('時系列データをline plot')
st.write(
    plot_ts()
)

```
6-2.変化率のplot
plot_PctChange()として、st.write()の中に作成した関数を書いて、実行。

```
st.write(
    plot_PctChange()
)
```
plotly.graph_objs等を使用して、candlestickや複数のグラフを重ねたり、その他の統計データを使用したり等、機会がありましたら、また時系列データとplotlyのについて、投稿したいと思います。
以上、streamlitとplotlyによるnikkei225のplotでした。
Power shellを使用して自動化したい

## 目標
PowerShellを使用して自分の業務の効率化をする
しかしどんなものをどう効率化するのかが決まっていないため、自分が調べて活用するための備忘録でもある

## PowerShellの概要
Windowsに標準で搭載されいているCUI
通常のコマンドプロンプトと異なるのが、記憶しておくことができる
なので、よくあるプログラミング言語のように記述して、定期実行することで、自動化することが可能になる

### コマンドレット

PowerShellではコマンドレットを使用する
めっちゃ簡単
命名ルールは「動詞-名詞」
詳細情報の確認にはGet-Helpコマンドレットを使う

https://atmarkit.itmedia.co.jp/ait/articles/0708/30/news137_3.html

あれ？めっちゃ優しくない？？？？
Dataverseのリレーション

前回のエントリの続きとなります。

お問い合わせアプリ（拡張版）利用の流れは以下のようになります。
 - ユーザーが問い合わせる
 - 問合せリストに入る
 - 担当者がAcceptする
 - 調査してログ（コメント）を記入する
 - ユーザーは内容を確認する
 - 問題なければクローズ または さらにコメントを追加する
 
ここでのポイントはユーザーと担当者が何回かやり取りをするということです。これを実現するためにはいくつかの方法がありますが、ここでは以下のように「お問い合わせ」（お問い合わせの各情報を格納するテーブル）と「お問い合わせ詳細」（ログを格納するテーブル）を分けることにしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/6abe216a-1824-8bf8-b78e-c60d5bb9a9c6.png)
このうちカテゴリID（何についてのお問い合わせ？）とステータス(新規？対応中？完了）については選択肢列として設定します。ユーザーと担当者は個人列にします(AzureADからデータを持ってくる）。
従って、必要なテーブルは上記の2つのみとなります。

さて、「お問い合わせ」は１つのお問い合わせごとにレコードが一つです。一方で、「お問い合わせ詳細」は、対応の過程で以下のように複数できるでしょう。
![Qiita211028_01.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/3179c5b9-6eef-8785-1dee-ffe003d82111.jpeg)

ぱっと見た限りでは両方のテーブルに「お問い合わせID」があれば両テーブルを関連付けることはできそうです。
もちろんそれで問題ありません。例えばSharePointのリストで同じようなアプリを作るのであればそうするべきでしょう。
例）あるお問い合わせを選択する→選択したお問い合わせのログをすべて抽出したい場合
Filterで「お問い合わせ詳細」テーブルの中からお問い合わせIDが一致するものを抽出する。通し番号or日付で並び替え

しかし、Dataverseには便利な機能があります。それがリレーションです。
リレーションを設定しておけば参照元テーブルから参照先テーブルにある値を簡単に参照することができます。
Teams から Power Apps を起動し、「テーブル」→「参照元テーブル名」→「リレーションシップ」を開き、リレーションシップの追加から「多対１」を選択します。

![Qiita211028_02.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/616574e1-5bf0-13f0-0a11-22689b5820b6.jpeg)

参照先のテーブルを選択します。

![Qiita211028_03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/2a37e0e0-461d-ff1b-e51c-d26fc7b3a66b.jpeg)

設定はこれで完了です。どのように参照できるのか確認してみましょう。
新規アプリを作成し、垂直ギャラリーを追加します。データソースを参照元（ここではお問い合わせ詳細）にします。
フィルタなどは設定していないので「すべてのお問い合わせ詳細（ログ）を表示する」というギャラリーになります。
このギャラリーのラベルを以下のように設定すると「お問い合わせ詳細」には入っていないタイトル列が表示できます。

ThisItem.お問い合わせ.タイトル

![Qiita211028_04.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/798209be-d6cf-0354-d63c-d699a803c740.jpeg)

自動的に「結合」処理をしてくれるというわけです。

ちなみに、いずれかのレコードが削除された場合どうなるのでしょう。
たとえば「お問い合わせ」テーブルのあるレコードを削除した場合、それに関連づいている「お問い合わせ詳細」はどうなるか？
・そもそも「お問い合わせ詳細」にログ（レコード）がある「お問い合わせ」は削除できない
・そのお問い合わせ自体が不要になったものと判断して、関連している「お問い合わせ詳細」のログ（レコード）をすべて消す
・お問い合わせのレコードは削除していいけど、何らかの形で参照したいのでお問い合わせ詳細のレコードは残す

上記のいずれも設定で可能です。（上記スクリーンショットの詳細オプションで設定）

リレーションを使いこなすためにはある程度データベース理論の知識が必要ですが、使ってみると便利ですのでぜひ試してみていただければと思います。
[Rails]暗黙的レンダリングでハマった

## 概要
開発環境とrspecで、APIレスポンスがなんか全然違う・・・開発環境だとステータスコード204なのに、rspecだと500どういうこと？
ということがあったので調査したことまとめ。

## 前提
参考: [ActionController::ImplicitRender](https://api.rubyonrails.org/classes/ActionController/ImplicitRender.html)

以下のメソッドを使った明示的なレスポンスを返さないコントローラーのアクションメソッドに対して「暗黙的なレンダリング」がなされる。

- render
- respond_to
- redirect
- head

## 暗黙的なレンダリング
### パターン①
https://railsguides.jp/api_app.html
でapiのアプリケーションを構築した場合(= ApplicationControllerをActionController::API から継承している場合)は、

204 No Content

が返るらしい

### パターン②
そうでない多くの場合は、implicit_render.rbで定義されているモジュールによって、現状以下のように制御されるらしい。
上から順に優先度高

1. テンプレートがある場合それをレンダリング
2. 一部一致する？テンプレートがある場合これをレンダリング + ActionController::UnknownFormat 例外発生
3. webブラウザからのアクセスと判断された(GETリクエスト & Content-typeがtext/html & リクエストヘッダHTTP_X_REQUESTED_WITHが"XMLHttpRequest")場合 ActionController::MissingExactTemplate 例外発生
4. 上記いずれにも引っかからなかった 204 No Content を返す

## 原因
以下3要因が重なったこと

① APIで明示的なレスポンスをかえしていない
② APIだけど、ApplicationControllerをActionController::APIから継承する構成になってない
③ content-typeをAPIのリクエストヘッダで指定していない

③の場合Webサーバによって推測されたcontent-typeとなり、これが開発環境とrspecで違っていたことで、パターン②の3.になったり4.になったりしていた。

## どう対応した？
そもそも「暗黙的なレンダリング」を通ること自体がのぞましくない。
implicit_render.rb自体が過去に色々とアップデートされて暗黙的レンダリングの挙動も変わってきているっぽい

なので、明示的なレスポンスをちゃんと返してやることで対応。
他の端末からPostgreSQLに接続するための設定


#概要

PostgreSQLはデフォルトでは他の端末から接続できないようになっているので、接続できるようにする方法を書く。

* 環境・バージョン
  + Windows 10 Pro
  + PostgreSQL 9.2


#手順

1. 許可する接続の設定（pg_hba.conf）
1. ファイアウォールの設定

## 1．許可する接続の設定（pg_hba.conf）

（1） PostgreSQLがインストールされているフォルダ（デフォルトだとC:\Program Files\PostgreSQL\9.2）のdataフォルダを開く。

（2）pg_hba.confをメモ帳などテキストエディタで開く。
※管理者権限が必要

（3）ファイルの下の方の「# IPv4 local connections:」と書かれているところを探し、
設定を追加する。

```conf:pg_hba.conf（抜粋）
# TYPE  DATABASE        USER            ADDRESS                 METHOD

# IPv4 local connections:
host    all             all             127.0.0.1/32            md5
host    all             all             192.168.0.0/16          md5　⇖追加例
# IPv6 local connections:
host    all             all             ::1/128                 md5
# Allow replication connections from localhost, by a user with the
# replication privilege.
#host    replication     postgres        127.0.0.1/32            md5
#host    replication     postgres        ::1/128                 md5
```

パスワード認証の場合、METHODは「md5」または「password」にする。
例えば
`host  　all  　all  　192.168.0.0/16  　md5`
とすると、IPアドレスが「192.168.0.0」～「192.168.255.255」のIPアドレスからパスワード認証で接続できるようになる。

詳細は公式へ。
https://www.postgresql.jp/document/9.2/html/auth-pg-hba-conf.html

（4）ファイルを保存する。

## 2．ファイアウォールの設定

（1）スタートボタンを右クリックし［検索］をクリックする。
「管理ツール」で検索して「Windows 管理ツール」を開く。

（2）管理ツール画面で[セキュリティが強化された Windows Defender ファイアウォール］をクリックする。

（3）左のコンソール ツリーで「受信の規則」をクリックし、右の操作ウィンドウで「新しい規則」をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568592/41088d64-29c4-227b-6d83-6615fa53dd5c.png)

（4）「ポート」を選択して次へ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568592/3ff3aa16-20eb-4899-e7a7-a53cfbe9502e.png)

（5）「TCP」を選択し、ポート番号を入力する。
PostgreSQLのデフォルトは5432だが、変えている場合はそれに合わせる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568592/5eaa8955-0ae9-11b3-fdbe-c3e4eac28f40.png)

（6）「接続を許可する」を選択して次へ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568592/bd26da62-42fc-24fe-1da9-0da858ce0a3f.png)

（7）社内なら「ドメイン」「プライベート」にチェックを入れておけばOK。次へ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568592/4c32f132-f74d-3e5f-bce9-9b5c014bf931.png)

（8）名前をつけて完了。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568592/a0c64903-5ed3-da3f-77b7-60e27562023f.png)


（9）受信の規則に追加されていればOKです。他の端末から接続してみましょう！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568592/5671508e-ef89-aa7c-8793-34bba970f14f.png)
[Python] クラスの実装について

##1. クラスの定義
クラスの定義は次のように記述する。

```python
class <クラス名>:
class Sample:
```

##2.インスタンスの生成
インスタンスを生成する場合は次のように記述する。

```python
<変数名> = <クラス名>(引数)
myClass = Sample()
```

##3. コンストラクタ
コンストラクタは、オブジェクトを生成する際に初期化関数として一度だけ呼ばれるメソッド。
Pythonにおけるコンストラクタは、「***\_\_init\_\_***」と表記する。

```python
def __init__(self):
    # コンストラクタ内の処理
```
ここで、***self***は、インスタンス自身を指す。Javaでいう「***this***」のようなもの。***self***を引数とすることで、クラス内の変数やメソッドにアクセスすることができるようになる。

#4. メソッドの定義
メソッドは、ある処理をまとめたクラス内の関数のこと。
メソッドを定義する場合は「***def***」キーワードを使用する。

```python
class Sample:
    def <メソッド名> (引数):
        # 処理内容
```

#5.継承
***継承***とは、新しい機能を作るとき、以前作った機能と共通する部分を引き継ぐことであり、オブジェクト指向プログラミングの基本的な概念。継承は次のように書くことができる。

```python
class <新しいクラスの名前> (<継承するクラスの名前>):    
```
またJavaScriptとは違い、複数のクラスを継承する「多重継承」を行うことができる。
M5StickCで洗濯終わったアラームを作る

うちの洗濯機↓はぼろくて洗濯完了を知らせるアラームが付いておらず、洗濯が終わったのに取り出すのを忘れることがよくある。そこで、M5StickCを使って、洗濯が終わったらスマフォに通知が来るようにしてみた。
<img width="360" alt="sentakuki" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/465152/dcbc9f4b-b20d-b1e4-ee4b-bc0d19d3fe4a.jpeg">

わけあって高校生の演習向けのプレゼン例に仕立ててあるので、大筋となる考え方についてはこちらを参照して欲しい。

https://docs.google.com/presentation/d/1YuHm2xtzMkeHpbUml0EzY9qz6KXpUA6QVQMvpXl43cI/edit?usp=sharing

コードはこちら。

https://gist.github.com/tomoto/842c869bbf7f316feccdc875d8d4c097

プレゼンで説明されていない点を以下に補足する。

- ボタン操作: 洗濯開始時にボタンを押す必要がある。ボタンを押すとスリープから復帰し、洗濯機の起動を待ってから監視を開始する。3分以内に洗濯機の起動を検知できなければ再びスリープに入る。
- スマフォ通知のカスタマイズ: スマフォへの通知処理は Net.cpp に書かれているが、ここは使用者によるカスタマイズが必要である。筆者の場合は自宅WiFi上に中継サーバ(家庭内IoTを一手に処理するRaspberry Pi機)が立ててあり、このコードはそれに向かってHTTP POSTを投げる構造になっている。そんなものは存在しない普通のご家庭のみなさんは、「[IFTTTで簡単IoT！M5StackとLINEを連携する方法](http://kyokucho1989.chillout.jp/2019/11/09/ifttt%e3%81%a7%e7%b0%a1%e5%8d%98iot%ef%bc%81m5stack%e3%81%a8line%e3%82%92%e9%80%a3%e6%90%ba%e3%81%99%e3%82%8b%e6%96%b9%e6%b3%95/)」あたりを参考に、直接インターネット上のIFTTTを叩いてLINEにメッセージを送るなどするのがよいだろう。
- しきい値のカスタマイズ: 各種しきい値がinoファイルの中に書いてあるので、自分の環境に合わせてカスタマイズが必要かもしれない。「1秒間の振動の大きさを表す数値」と「過去40秒間の動作中・停止中の優勢劣勢を表すバー」が画面に表示される↓ので、それを見てうまく検知できるか確認し、適切に調整してみて欲しい。<br>
<img width="480" alt="alarm_device" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/465152/a316a3d7-e308-632d-a2e6-41d149a03d37.jpeg">
Go言語 stringsパッケージ

#文字列チェック

#####■文字列に「,」が含まれているかをチェック

```go:
if strings.Contains("red,blue", ",") {
    fmt.Println("複数")
} else {
    fmt.Println("単数")
}

// 複数
```

#文字列変換

#####■「,」区切りの文字列を配列（スライス）に変換

```go:
colorArr := strings.Split("red,blue", ",")
for _, v := range colorArr {
    fmt.Print(v + "\n")
    // red
    // blue
}
```
WEBコーディング開始で気付くデザインとの違い

デザインが素晴らしいのが前提として素晴らしいデザイン通りにWEBコーディング時にて
難儀なところをいくつか出てきたので、
お客様とのすり合わせの際に参考にしてもらえると嬉しいです

#フォントファミリー
あたりまえのように日常に存在しているフォント。
しかし、デザイナー様が持っているフォントは当たり前のように皆様のパソコンに付属しているものではなかったりします。
例をいくつか

* ヒラギノ　- macのみ（windowsXD使いはフォントもっていないと見れない、無理やり持ってきても改行は〼となります）
* 游ゴシック - mac , windowsのみ（実際は近しいフォント）,モバイル(iOS , Androidにはない）
* Adobe製品のフォント デザイナー様ではなくサイト管理者様がadobeフォントを使用できるライセンスに登録してもらう必要があります

これらはフォントを選別して使いたいフォントを使用したいのならフォント自体どのようなものかを知っておく事が大事だと思うのです。

#カーニング(letter-spacing)

●デザイン上のレタースペーシング
レ◯タ◯ー◯ス◯ペ◯ー◯シ◯ン◯グ

●WEB上のレタースペーシング（lette-spacing:◯em;）
レ◯タ◯ー◯ス◯ペ◯ー◯シ◯ン◯グ◯

文字の最後にレタースペーシングの値分余計に増えています。つまり。

__テキストの中央配置のときにその分ずれます__

●デザイン上のレタースペーシング
【左余白】レ◯タ◯ー◯ス◯ペ◯ー◯シ◯ン◯グ【右余白】

●WEB上のレタースペーシング（lette-spacing:◯em;）
【左余白】レ◯タ◯ー◯ス◯ペ◯ー◯シ◯ン◯グ◯【右余白】

きっちり中央寄せしたい場合にちょっとずれるので__WEBではtext-indentを足してあげます__

●WEB上のレタースペーシング（lette-spacing:◯em; + text-indent:◯em;）
【左余白】◯レ◯タ◯ー◯ス◯ペ◯ー◯シ◯ン◯グ◯【右余白】

こうなります。

##起こる可能性のある不具合
きっちり中央寄せしたい場合text-indentとletter-pacingのスペースがデザインより設定した値の2つ分増えてしまうので
__letter-spacingに値がある＋中央寄せしたい場合は無理のないような余白があるデザイン__が必要です。

###右詰めは？
文字部分をspanなどでインラインにしてから右ネガティブマージンをいれてあげます。
margin-right:-◯;

#トラッキング(font-feature-settings)

字詰をよしなに設定する装飾です。
よしななので厳密にはわかるかもしれませんが、どのくらいのサイズを詰めているかは計測難しいです。
2021/10/28時点ではnoto sans JPがまたfont-feature-settings効くようになったみたいです。

##起こる可能性のある不具合
トラッキング＋カーニングで＋の値を指定している場合

__広げたいのか詰めたいのかどっちなのかわからないのと実数が計測しにくいのでやめてほしい。__


##まとめ
昔はこんなカーニングやトラッキングが頻繁に発生している場合は全部画像でよかったのですが、
昨今はフォント＋装飾で指定できるようになってきました。
（本当に画像よりフォントだけのほうがSEO評価高いの？グーグルさん！？とは未だに謎ではありますが）
また映画などの翻訳が昔よりかなり短い文章になっていると聞いたのですが、
昨今のデザインにデフォルト的に使用される文字を広げるカーニングはその時代背景を組んでいるのかもしれません。

疑問なのですがその文字を広げるカーニンは果たして日本だけで起こっている現象なのでしょうか。
英語圏の方はletter-spadingなんてタイトル部分以外使わんよ？と言われるかもしれません。
海外サイト作成の際はどの国の人に向けて文字を見てもらいたいかを考えると海外のWEBに詳しい人に教えてもらうしかないのかもですね。
（誰かしっていたら教えてください。）

読んでいただきありがとうございました！
Nuxt.jsでフォームをComponent化した話

初めてNuxt.jsを触って、ちょっとハマったところを備忘録的にメモしておきます。

# 環境

Nuxt.js 2.15.8
Vuetify 2.5.5

# やりたいこと
新規登録と編集など、内容がかぶっているフォームがあり、まるッとコンポーネントにしたかった。

# ESLintに引っかかったソースコード

```js:parent.vue
<edit-form :form="form" />
```
edit-formから抜粋

```js:form.vue
<v-text-field
    v-model="form.name"
    :counter="30"
    label="氏名"
/>
```
挙動は思った通りに動いていると思ったのですが、この`v-model`がダメらしいんですね。

```
 Unexpected mutation of "form" prop
```
というエラーが出ました。

フォームプロップの予期せぬ突然変異とは…？

フロントをほとんどやったことがなかったのでお作法を知らなかったのですが、
コンポーネントで勝手に変えて親に知らせないのはダメ、っていうことみたい？

# 修正後

そこで、↓のように修正しました。

```js:form.vue
<v-form @submit.prevent="$emit('send')">
// 中略
    <v-text-field
        :value="name"
        :counter="30"
        label="氏名"
        @input="$emit('update:name', $event)"
    />
// 中略
    <v-btn
        type="submit"
        color="primary"
        class="my-2"
        @click="$emit('submit')"
    >
        登録
    </v-btn>
</v-form>

<script>
export default {
    props: {
        name: { type: String, default: '' },
        // 中略
        // フォームの項目ごとに必要
    }
}
</script>
```

```js:parent.vue
<edit-form v-bind.sync="form" @submit="submit"/>
```

### 余談

`@input="$emit('update:name', $event.target.value)"`としたら↓のエラーになってしまった。
どうやら`$event`だけで良いっぽい。

```
TypeError: Cannot read property ‘value’ of undefined
```
Cisco Packet TracerでNAPTを設定しよう

#はじめに
　今回は前回のNATに続き、Cisco Packet TracerでNAPTを設定し、そのパケットの中身を見ていきます。

##Packet Tracerで必要なもの
・PC 3台
・Switch2960
・Router2911

##NAPTとは
簡単に言うと、NATの進化版である。NATではグローバルIPアドレスの数しか同時接続できなかったが、NAPTではポート番号を利用することで、1つのグローバルIPアドレスと複数のプライベートIPアドレスを紐付けて変換することができる。詳しくは以下のサイトを参照してほしい。

https://wa3.i-3-i.info/word11979.html

##目的
NAPTではプライベートIPアドレスをグローバルIPアドレスに変換するだけでなく、ポート番号を見てパケットの送り先を決めているため、実際にパケットの中身のIPアドレスが代わっていることとポート番号が付与されていることを確認することでNAPTの理解を深める。

##NAPTの設定
![2021-10-27 (8).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2169540/869cf718-e22b-2092-8392-f94764ea462d.png)



まず、上の図のようにPC、ルータ、ip addressを割り振る。PC、サーバーはConfigから設定し、デフォルトゲートウェイも入力する。デフォルトゲートウェイは、PC0、PC1は192.168.1.10、PC2は192.168.2.10である。ルーターは以下のコマンドを打ち込み設定する。

```
Router>enable
Router#configure terminal
Router(config)#interface gigabitEthernet 0/0
Router(config-if)#ip address 192.168.1.10 255.255.255.0
Router(config-if)#no shutdown
Router(config-if)#exit
Router(config)#interface gigabitEthernet 0/1
Router(config-if)#ip address 192.168.2.10 255.255.255.0
Router(config-if)#no shutdown
Router(config-if)#exit
```

次にNAPTを設定する。

```
Router(config)#ip nat pool TEST 150.1.1.1 150.1.1.1 netmask 255.255.255.0
Router(config)#access-list 1 permit 192.168.1.0 0.0.0.255
Router(config)#ip nat inside source list 1 pool TEST overload
Router(config)#int gigabitEthernet 0/0
Router(config-if)#ip nat inside 
Router(config-if)#exit
Router(config)#int gigabitEthernet 0/1
Router(config-if)#ip nat outside
Router(config-if)#exit
```

設定し終えたらPC同士でPingが通ることを確認する。
その後、実際にパケットを送りその中身を確認する。IPアドレスが代わっていることと、PC0からPC2、PC1からPC2へ通信を行った際にそれぞれポート番号が違うことを確かめる。


##パケットの中身を確認する
まずPC0からPC2へ通信を行う。以下のようにPC0のデスクトップからPC2のIPアドレスを打って通信を行う。
![2021-10-27 (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2169540/70f35aab-4f37-d812-bde9-332273b4de2d.png)

PC2に届いたパケットを見てみる。
![2021-10-27 (10).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2169540/df9a63b0-37d3-41f9-886f-a05bd91de324.png)

宛先IPアドレスがグローバルアドレスに代わっていることが分かる。さらにTCPには宛先のポート番号が1030と分かる。
次にPC1からPC2へ通信を行う。今回も同じようにPC2に届いたパケットを見てみる。
![2021-10-28 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2169540/d47b3d6a-c1e4-145c-5548-d002ce04ef62.png)

こちらもIPアドレスが代わっているが、ポート番号はPC0のときとは違い、1025番である。

##まとめ
実際に通信を行いそのパケットの中身を見ると、NAPTではグローバルアドレスが代わっているだけでなく、PC0とPC1をポート番号を見てそのパケットの送り先を判別していることが分かった。このことからNAPTはNATとは違い、ポート番号で判別できるので、複数台のコンピュータでも同時にインターネットをすることができることが分かる。

##参考文献

https://www.infraexpert.com/study/natz2.html

https://nwengblog.com/cisco-nat/
Cisco Packet Tracerで静的NATを設定しよう！

#はじめに
　今回、NATとNAPTを設定し、そのパケットの中身がどのようになっているかを見ました。
ここではNATの内容を書いていきます。NAPTに関しては次の記事を見てください。
同じようにNATとNAPTについてcisco packet tracerで勉強したい人に参考にしていただけると幸いです。

##Packet Tracerで必要なもの
・PC 1台
・Server
・Router2911

##NATとは
プライベートIPアドレスをグローバルIPアドレスに変換する仕組みである。
詳しくは以下のサイトが非常にわかりやすいので参考に見ていただきたい。

https://wa3.i-3-i.info/word11978.html

##目的
NATではプライベートIPアドレスをグローバルIPアドレスに変換する機能があるので、実際にパケットの中身を見てIPアドレスを確認することでNATの理解を深める。

##NATの設定
![2021-10-22 (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2169540/19fb36ec-05a0-fc7b-df2d-416a0a25ff59.png)
まず、上の図のようにPC、ルータ、サーバーを配置し、ip addressを割り振る。PC、サーバーはConfigから設定し、デフォルトゲートウェイも入力する。PCは192.168.1.1、サーバーは192.168.2.1である。ルーターは以下のコマンドを打ち込み設定する。

```
Router>enable
Router#configure terminal
Router(config)#interface gigabitEthernet 0/0
Router(config-if)#ip address 192.168.1.1 255.255.255.0
Router(config-if)#no shutdown
Router(config-if)#exit
Router(config)#interface gigabitEthernet 0/1
Router(config-if)#ip address 192.168.2.1 255.255.255.0
Router(config-if)#no shutdown
Router(config-if)#exit
```

次にNATを設定する。内部の送信元アドレス変換を行うためのCiscoコマンドの

```
　ip nat inside source static <変換前ipアドレス> <変更後ipアドレス>
```
を使って設定する。

```
Router(config)#ip nat inside source static 192.168.1.10 202.150.20.10
Router(config)#int gigabitEthernet 0/0
Router(config-if)#ip nat inside 
Router(config-if)#exit
Router(config)#int gigabitEthernet 0/1
Router(config-if)#ip nat outside
Router(config-if)#exit
```
設定が終わったらPC1からサーバーへパケットを送ってみて、その中身を確認する。
![2021-10-22 (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2169540/1ec4c5a3-fee9-3393-3922-a1b999b97dbf.png)
以下はルーターからサーバーへ送られたパケットの中身である。
![natパケット.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2169540/6cc97b97-51ef-d006-495c-760c819e8d0a.png)
真ん中に記載されているIPアドレスを見てほしい。送信元IPアドレスが192.168.1.10から202.150.20.10に代わっていることが分かる。

##NATのメリット・デメリット
上記よりIPアドレスが変換されていることは分かったが、どのようなメリットがあるかを説明する。
###メリット
・ネットワーク外部からの通信を防ぐことができ、セキュリティ面で優れている点
・多くのノードを接続できる点
###デメリット
・グローバルIPアドレスの数しか同時接続できない点
・IPアドレスが重複してしまった場合、ネットワーク通信が行うことができない点

##まとめ
　今回はCisco Packet Tracerを使ってNATを設定したが、実際にパケットの中身を見ることで、IPアドレスがルーターで変換されていることが分かった。普段我々が使っているインターネットでもこのような機能が働いていると思うと面白いと感じる。
　次回はNAPTも設定に関しての記事を書くのでそちらも見てもらえれば幸いです。

##参考文献

https://www.infraexpert.com/study/natz6.html

https://www.infraexpert.com/study/natz0.html

https://nwengblog.com/cisco-nat/

https://milestone-of-se.nesuke.com/nw-basic/nat/nat-summary/
”f文字列を使った文字列の書き方”と”関数の引数の指定方法”のtips

##はじめに
始めまして、株式会社ジール所属の@oreo_tです。
業務としてAWSやPythonを使いながらDWHの構築をしています。
その中で得たノウハウやtipsを、Qiitaを通して発信していきたいと思います。

今回は初回ということで、開発でよく使っているPythonについてのtipsを記事にしてみます。
内容は、コードの可読性を上げるf文字列を使った文字列の書き方と、関数の引数の指定方法についてです。


## f文字列を使った文字列の書き方
例えば、「item_name」変数と「item_cnt」変数を使って

```
ボールペンが10個あります。
```
という文字列を出力する場合、一番簡単なのは

```.py
item_name = 'ボールペン'
item_cnt = 10
print(item_name + "が" + str(item_cnt) + "個あります。")
```

という書き方ではないでしょうか。

しかしこれでは変数が挟まるたびにprint文の中に「+」をいれなくてはいけなくて少々煩雑です。

そこで、Python3.6から導入されている「f文字列」という書き方をするのがおすすめです。
書き方は以下の通りで、別途モジュール等のインポートも必要ありません。

①先頭にf(大文字小文字問わず)を入れ、文字列全体をクォーテーションで囲う
②変数名は{}で囲う

以下がコード例です。

```.py
item_name = 'ボールペン'
item_cnt = 10
print(f"{item_name}が{item_cnt}個あります。")
```

このように、print文が全体的にすっきりしました。


他にもメリットとして、文字列以外のデータ型が入った変数は型変換しなくてもよいという点があります。
(今回のitem_cntにはint型の10が入っていますが、型変換しなくても問題なく出力できます。)




## 関数の引数の指定方法
例えば、func関数に引数が2つあるとき、以下のように引数を指定すると思います。

```.py
def func(item_name, item_cnt):

    print(f"{item_name}が{item_cnt}個あります。"
    
    return

name = "ボールペン"
cnt = 10

func(name, cnt)
```

この書き方では、1つ目の「item_name」に対応するのが「name」、2つ目の「item_cnt」に対応するのが「cnt」として自然に処理されますが、以下のような書き方をすることで明示的に引数と値を対応させることができます。

```.py
def func(item_name, item_cnt):
    
    print(f"{item_name}が{item_cnt}個あります。")  

    return

name = "ボールペン"
cnt = 10

func(item_name = name, item_cnt = cnt)
```

このように書くことで変数名と値の対応がより分かりやすくなります。



## おわりに

今回紹介した書き方は業務の中で知った書き方で、知っていると複雑なコードでも見やすくすることができるので、ぜひご活用ください。
今後もこのようにノウハウやtipsを共有していきたいと思います、よろしくお願いします。
RuboCopの Rails/InverseOf に引っかかった

# Rails/InverseOfは何の警告か？
アソシエーションを定義する際に明示的に :inverse_of を指定すべき箇所で指定されていないことを警告している。

# :inverse_ofとは何者か？
[Railsガイド](https://railsguides.jp/association_basics.html#%E5%8F%8C%E6%96%B9%E5%90%91%E9%96%A2%E9%80%A3%E4%BB%98%E3%81%91)より。
ActiveRecordで、双方向の関連付けを明示的に宣言するもの。

```ruby
class User
  has_many :posts
end

class Post
  belongs_to :user
end
```

inverse_ofが効いていない場合、下例のようになる。

```ruby
user = User.first
post = user.posts.first
user.name == post.user.name #=> true
user.name = "hogehoge"
user.name == post.user.name #=> false
```
別々のオブジェクトとして扱われるため、postをたどってuserのnameを変更できない。

inverse_ofが効いている場合、双方向に関連付けが行われて同じオブジェクトになる。

# 今まで書いた記憶がない。。。
Rails4.1以降、Railsが自動でつけてくれるようになった。
それ以前は都度SQLを発行してインスタンスを生成していた。
そのため、以下のようなことが起こり得た。

・ 同じレコードを参照しているはずなのに、データを取得するためにSQLが発行される
・ 更新したレコードの内容が、アソシエーション経由だと反映されない

しかし、自動で付けてくれるならなぜ警告されたんだ。

# :inverse_ofを明示的に指定すべきパターンとは？
foreign_keyやscopeが指定されている場合など、inverse_ofを明示的に指定しないとこのオプションが効かないパターンがある。

### foreign_key

次のように、foreign_keyを指定して関連付けされている場合、inverse_ofが自動で適用されないため明示する必要がある。

```ruby:model
class User < ApplicationRecord
  has_many :posts, foreign_key: :id
end

class Post < ApplicationRecord
  belongs_to :user
end
```
```ruby
user = User.first
post = user.posts.first
# user.name と post.user.name は同じオブジェクトを見ていて欲しい

user.name = "変更" # user.nameを変更
user.name == post.user.name #=> false
```

### scope
次のように、scopeを含む場合は自動でinverse_ofが適用されないため、明示する必要がある。

```ruby:model
class User < ApplicationRecord
  has_many :posts, -> () { order(:created_at) }
end

class Post < ApplicationRecord
  belongs_to :user
end
```

```ruby
user = User.first
post = user.posts.first
# user.name と post.user.name は同じオブジェクトを見ていて欲しい

user.name = "変更" # user.nameを変更
user.name == post.user.name #=> false
```

# どう書くか？
has_many - belongs_toの場合は、
belongs_toで紐付けされているモデルを設定すれば良い。

```ruby:model
class User < ApplicationRecord
  has_many :posts, -> () { order(:created_at) }, inverse_of: :user
end

class Post < ApplicationRecord
  belongs_to :user
end
```
【備忘録　C#】HTTP経由を使用す場合

#背景
Web上からJsonデータを取得してあれこれしたいと思い、HttpClientを使った際の学んだことを記録。

##環境
・Visual studio 2019
・.NET Framwork 4.8


##内容
WebからJsonデータを取得すにはHTTP経由で取得する。
HTTPを使用する場合、誰が(client)を記載する必要がある。
特定の人が決まっていなくても、枠だけでも用意する必要がある。


###▼ユーザー認証がいらない場合
Webでアクセスした際に、ユーザーとパスワードを聞かれない場合この方式で大丈夫。

```C#
using System.Net.Http

HttpClient client = new HttpClient();//枠だけのclient
var request = new HttpRequestMessage(HttpMethod.Get, url);//注文書(リクエスト文)の作成
var result = client.SendAsync(request)//”誰が”(client)が”注文書”(リクエスト文)をもとにHTTPからとってくる。

```

###▼ユーザー認証が必要な場合
Webでアクセスした際に、ユーザーとパスワードを聞かれる場合はclientにIDとPasswordを持たせる必要がある。

```C#
using System.Net.Http
using System.Net

//ユーザー認証の処理
var clientInfo = new HttpClientHandler();
clientInfo.Credentials = new NetworkCredential(LoginID, Password);
HttpClient client = new HttpClient(clientInfo);

//下記一緒
var request = new HttpRequestMessage(HttpMethod.Get, url);//注文書(リクエスト文)の作成
var result = client.SendAsync(request)//”誰が”(client)が”注文書”(リクエスト文)をもとにHTTPからとってくる。
```

###▼認証をスキップする
証明書エラーなどで認証をスキップしたいときにこちらを追記すると良い。

```C#
using System.Net.Http
using System.Net

//証明書エラー認証スキップ
var httpClientHandler = new HttpClientHandler();
httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, sslPlicyErrors) => true;

//ユーザー認証の処理
var clientInfo = new HttpClientHandler();
clientInfo.Credentials = new NetworkCredential(LoginID, Password);
HttpClient client = new HttpClient(clientInfo);

//下記一緒
var request = new HttpRequestMessage(HttpMethod.Get, url);//注文書(リクエスト文)の作成
var result = client.SendAsync(request)//”誰が”(client)が”注文書”(リクエスト文)をもとにHTTPからとってくる。
```
［Laravel8］Vue.jsをインストールする手順・備忘録！

Laravel8にVue.jsをインストールする手順の備忘録です。
プロジェクトは既に作ってある前提で進めます。
（因みに、参考にさせてもらったのは、以下のサイトさんです！ありがたや～！(人''▽｀)☆ こちらでの情報を元に、所々追加・簡略化して記載しています。）
環境：XAMPP

https://biz.addisteria.com/laravel8_vue_install/

手順1：　まずは、ターミナルでlaravel/uiパッケージをインストールします。

```
composer require laravel/ui
```

手順2：　次に、Vue.jsをインストールします。
--authもつけると認証機能もつくけど、laravel/uiパッケージの古いバージョンの認証機能になりますよね。。。

```
php artisan ui vue
```

手順3：　ビルドします。

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

☆おまけ。☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
ここでビルドした時に、
『npm ERR! Failed at the @ dev script.』
『npm ERR! This is probably not a problem with npm. There is likely additional logging output above.』
というエラーが出ました。
他には、『Additional dependencies must be installed. This will only take a moment.』とか。。。
色々ググってみると、どうやらPackage.jsonの書き方がダメなようで。。。
↓↓こちらの記事を参考に、以下のコマンドを連続して実行したら、解消されました！Package.jsonのバージョンを最新にすれば良いそうです。

https://qiita.com/Shoryu_N/items/9ae2417489c9faaa271c

$ npm install --save-dev webpack@latest
↓
$ npm install webpack-cli -D
↓
$ npm install --save-dev webpack-dev-server@latest
↓
$ npm install vue-loader@latest

☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆

手順4： \resources\views\welcome.blade.php の中身を、以下のように書き換えます。

```\resources\views\welcome.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
    <div id="app">
        <example-component></example-component>
    </div>
    <script src="{{ mix('/js/app.js') }}"></script>
</body>
</html>
```

これで、ターミナルで『php artisan serve』とすると、以下画像のように表示されて、使えていることがわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235741/7856febb-214a-2313-3cfa-77a91f4b1543.png)

手順としては以上です。

ちょこっと解説すると、
まず、laravel/uiパッケージは、resources/js/componentsというディレクトリを新しく作ります。自分で新しくVueコンポーネントを作るときは、ここに追加していきます。
（サンプルとして、ExampleComponent.vueファイルがインストール時点で既に作られています。）
次に、新しくVueコンポーネントファイルを作ったら、resources/js/app.jsファイルに登録する必要があります。
resources/js/app.jsファイルの中身を見てみると、22行目に既にExampleComponent.vueが設定されているのがわかります。自分で新しく作った時は、ここに同じように追記していく形となります。

```resources/js/app.js
// 22行目
Vue.component('example-component', require('./components/ExampleComponent.vue').default);
```

以上です。