OmniAICreator/Qiita-1.07M huggingface dataset:
Neptune MLのQuickStartを動かすために必要な事前準備

Neptune MLをちょっと試してみたいなと思ってドキュメントを見ているとQuickStartのページにCloudFormationが置かれています。
https://docs.aws.amazon.com/ja_jp/neptune/latest/userguide/machine-learning-quick-start.html

ここを一通り触ってみたら概要掴めるかなと試してみたのですが、色々なところで躓いたのでその時の作業メモです。
ML系を試すにはQuickStartでもそれなりにリソースを要求されるのですが、自分の勉強用に新しく立ち上げたAWSアカウントだとサービスクォータがかなり小さく設定されている場合があり、上限緩和申請を出さないと先に進めない場面が何度かありました。
```
CFnスタックを作成してインスタンスを起動する
 → 少し試す
 → 上限エラー
 → 上限緩和申請を出して適用されるまで一旦スタックを削除
 → 再トライ
```
というフローを何度か繰り返したので結構心が折れそうでしたね。。


NeptuneのDBインスタンスもSageMakerのNotebookも上限緩和申請が通るまでずっと立ち上げておくと細かく課金されるので毎回立ち上げ直すのも面倒ですし、一通り必要なスペックについては試す前にまとめて申請を出してしまうのがおすすめです。

ちなみに試したサンプルコートは上記CFnスタックで作成されるノートブックに含まれている
```
/Neptune/04-Machine-Learning/Sample-Applications/01-People-Analytics
```
です。

# 必要クォータ一覧

| サービス | 項目 | 必要数 |
|:-:|:-:|:-:|
| AWS Lambda | Concurrent executions | 100以上 |
| Amazon EC2 | Running On-Demand Standard (A, C, D, H, I, M, R, T, Z) instances | 72 |
| Amazon SageMaker | ml.r5.large for processing job usage | 1 |
|  | ml.r5.xlarge for endpoint usage | 2 |

## Lambda

### Concurrent executions

Concurrent Executionsはデフォルト値`1000`となっていますが、あまりアクティブではないアカウントだと`50`と制限されている場合があります。
途中で立ち上がるNeptune-Exportが `ReservedConcurrentExecutions : 50`と設定されたLambdaを2つ3つ起動しようとして、スタック起動エラーになりました。

※ 最新のCFnテンプレートだと全部で6件くらいの予約になっていたため改善したのかもしれません。
とはいえここはデフォルト1000まで上げておいてもよいと思います。
ハンズオン資料のCFnテンプレートが手癖のように`ReservedConcurrentExecutions : 50`と書かれていて失敗するケースは過去にも経験がありました。

## Amazon EC2

### Running On-Demand Standard (A, C, D, H, I, M, R, T, Z) instances

Neptune-ExportのExportジョブ(AWS Batch)がコンピューティング環境として`c5.18xlarge`のオンデマンドインスタンスを要求します。

ここでクォータが足りていないと、ノートブック上から実行した`neptune_ml export start`で起動したAWS Batchのジョブが`RUNNING`のまま先へ進まない(特にエラーにもならない)ということでハマりやすいポイントです。

## Amazon SageMaker

### ml.r5.large for processing job usage

[neptune_mlマジックのドキュメント](https://docs.aws.amazon.com/neptune/latest/userguide/notebooks-magics.html#notebooks-line-magics-neptune_ml)を読む限り、`neptune_ml dataprocessing start`コマンドではトレーニングジョブのインスタンスサイズを指定することはできなそうです。

[NeptuneのAPI仕様](https://docs.aws.amazon.com/neptune/latest/userguide/machine-learning-api-dataprocessing.html)によればインスタンスタイプ(processingInstanceType)のデフォルト値は`ml.r5`の中で処理しようとしているデータサイズの最小値、とのことなので、必要になるインスタンスはテストデータのサイズに依存しそうです。
今回試そうとしたサンプルでは
```
ml.r5.large for processing job usage' is 0 Instances, with current utilization of 0 Instances and a request delta of 1 Instances
```
とのこと。

しかしdataprocessingのデフォルトタイプが`ml.r5`なのにそれらが全てクォータ0っていうのはどういう想定なんでしょうね。。
![スクリーンショット 2022-06-12 19.18.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204890/a29471a6-38af-407b-7983-3755b988df7e.png)

### ml.r5.xlarge for endpoint usage

サンプルではnodeの推論エンドポイントとlinkの推論エンドポイントの2つを作成するため`2`件あるのが望ましいです。
節約するならlinkの推論を行う前にnodeのエンドポイントをクリーンアップしてしまえば1つでやりくりも可能。

# パラメータ名修正

クォータとは関係ないですが、サンプルのnotebookでは`neptune_ml endpoint create`コマンドの引数が
```
endpoint_params=f"""
--job-id {training_job_name} 
--model-job-id {training_job_name}"""
```
となっていましたが、どうやらAPIのI/Fが変更になったようで不正な引数エラーになってしまっていました。
下記のように書き換えることで無事動きました。
```
endpoint_params=f"""
--id {training_job_name} 
--model-training-job-id {training_job_name}"""
```
git&github初心者必見これだけでできる。mac版

# はじめに
本記事はProgaku Advent Calendar 2022 15日目担当のハヤシと申します。

__この記事にたどり着いた人はこう思っていると思います!__

「Gitは使えた方が良いと聞くが、そもそもなにがわからないかわからないし、難しい単語多すぎて調べてもわからない・・・」
この記事はそんな人達に簡単にですが流れをお教えします！

この記事は、主に一人で開発する際のやり方です。
ちなみに、**今回gitインストールやgithub登録については完了しているものとします。**

# 使用環境
・mac
・vscode

# そもそもgitやgithubはなんなのか？

**Gitとは**
簡単に言えばファイルやフォルダ、コードの変更を自分のPCに保存しておくものです。(これをバージョン管理といいます。)

**GitHubとは**
簡単に言えば上で紹介したgitにて自分のPCに保存したものをインターネット上に保存しておくものです。

　
　
やることとしては、
__1.変更ファイルを自分のPC上に保存__
__2.自分のPC上に保存したものをオンライン上に保存__

要するに、自分で作成したプログラムをなにかあった際の為に備えて自分のPCやオンライン上に保存しておこうってことですね。
それでは順番にやっていきましょう。


まずご自身のPCでmacターミナルまたはエディタ(vscodeなど)でターミナルを開きそのgit管理したいファイルのあるフォルダにターミナル上でパス指定して移動してください。

例.
```
MacBook@MyMacBook-pro ~ % 指定したいファイル名のあるフォルダまで
```
## 保存したいファイルをgitファイルであると指定する
ターミナル上でさきほど移動したフォルダを保存管理したいフォルダとする。
そこで下記を実行
```
$ git init
```
Initialized empty Git repository in　自分の保存した階層ファイルが表示されればOKです。



## 変更点をステージングする(仮保存すると思って貰えば大丈夫です。)
まずステージングする前に変更したファイル(保存したいファイル)の確認をします。
```
$ git status
```
* On branch mainまたはOn branch master
(現在いる<font color="red">**親ブランチ名**</font>です。)

* <font color="red">**赤字でファイル名**</font>が表示されていると思います。
(表示されない場合、フォルダ内にファイルを新しく作りもう一度git statusからやってみてください。)

その状態はステージング(仮保存)する前なので次に
```
$ git add .
```
これで仮保存完了しているはずです。
できているか確認してみましょう。
```
$ git status
```
先程<font color="red">**赤色**</font>だったものが<font color="green">**緑色**</font>になっていると思います。
これで仮保存は完了です。
(ちなみに、最後の　.　は変更のすべてを仮保存する意味合いがあります。ファイルを指定して保存する方法は . の代わりにファイルパス指定してあげればできます。)

## commitする(自分のPC上に本保存する)
```
$ git commit -m 'ここにどんなファイルかなど入力'
```
これでコメント付きで本保存できたはずです。
一度確認してみましょう。
```
$ git log
```
commit 777jfie・　・　・　・　・　・　と書かれていると思います。
一番上が最新の情報になります。
これで自分のPC上での保存が完了しました!

## githubからpush(保存)する為にURLを持ってきます。
まず、githubのマイページに行きRepositoriesを押してください。
![スクリーンショット 2022-06-16 0.41.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2701052/a78b0867-4fd4-0e96-e8e8-faeb76acab58.png)
Newのところをクリックします。
次にRepository nameに好きな名前を付けてください。
![スクリーンショット 2022-06-16 0.44.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2701052/fe8d9045-3e0e-b11d-4319-3709c970af6f.png)

最後に下の方にある <font color="green">**Create repository**</font> をボタンを押してください。
そうすると下記が表示されます。

#### Quick setup — if you’ve done this kind of thing before内の
```
https://github.com/dwhdi・　・　・　・　・　・と表示されているURL部分をコピーしてください。
```
このURLを保存先に指定して行きます。

## githubに保存(オンライン上に保存します。)
* 保存するgithubアカウントを指定します。
```
$ git remote add origin 先程の保存したgithubのURL 
```
* 保存先の指定が終わったのでpush(保存)して行きます。
```
$ git push origin 親ブランチ名(git statusの際に出ていたブランチ名です)
```

numerating objects: 3, done.
Counting objects: 100% (3/3), done.
Delta compression using up to 8 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 406 bytes | 406.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
こんな感じの表示がでればこれで保存の完了です。

これでご自身のgithubにログインしてそのフォルダがあるか確認してもらいあれば完了です。
初めてであればこれで以上になります！

## 最後に
初心者の内はこれを何回か練習してコマンドなどを覚えて行くといいと思います。

[こちら作業編](https://qiita.com/usamaro/items/6871cda76a43f2484617)の記事を書きましたので、ぜひやってみて下さい。

お付き合いくださりありがとうございました！
お疲れさまでした。
【VBA小ネタ】Dictionaryのアイテムに配列を突っ込むと読み取り専用になる

そのまんまです
---

VBAのDictionaryのアイテムに配列を突っ込むと読み取り専用になってしまうという話。

```VB:Module1
Sub Hoge()
    Dim dic As New Dictionary
    Dim i As Integer
    For i = 0 To 3
        Dim arr(1) As Variant
        arr(0) = "文字列" & i
        arr(1) = i
        Call dic.Add("キー" & i, arr)
    Next
    i = 3 ' 最後のアイテムを書き換えてみる
    Debug.Print "---書き換え前----------"
    Debug.Print dic("キー" & i)(0) & ": " & dic("キー" & i)(1)
    Debug.Print "---書き換え後----------"
    dic("キー" & i)(0) = dic("キー" & i)(0) & "_追記"
    dic("キー" & i)(1) = dic("キー" & i)(1) + 1
    For i = 0 To 3
        Debug.Print dic("キー" & i)(0) & ": " & dic("キー" & i)(1)
    Next
End Sub
```

```console:結果1
---書き換え前----------
文字列3: 3
---書き換え後----------
文字列0: 0
文字列1: 1
文字列2: 2
文字列3: 3
```

インデックス3のアイテムは、**文字列3_追記: 4**となることを期待したが結果は上記のとおりだった。何も変わっていない。配列の各要素を取得できるが設定はできない。
そして解せないのが、代入の際にエラーにならないことだ。

しかし、これはアイテムを丸ごと置き換えることで解決する。

```VB:Module2
Sub Huge()
    Dim dic As New Dictionary
    Dim i As Integer
    For i = 0 To 3
        Dim arr(1) As Variant
        arr(0) = "文字列" & i
        arr(1) = i
        Call dic.Add("キー" & i, arr)
    Next
    i = 3 ' 最後のアイテムを書き換えてみる
    Debug.Print "---書き換え前----------"
    Debug.Print dic("キー" & i)(0) & ": " & dic("キー" & i)(1)
    Debug.Print "---書き換え後----------"
    arr(0) = dic("キー" & i)(0) & "_追記"
    arr(1) = dic("キー" & i)(1) + 1
    dic("キー" & i) = arr ' ＜－値を設定した配列を丸ごと代入する
    For i = 0 To 3
        Debug.Print dic("キー" & i)(0) & ": " & dic("キー" & i)(1)
    Next
End Sub
```

```console:結果2
---書き換え前----------
文字列3: 3
---書き換え後----------
文字列0: 0
文字列1: 1
文字列2: 2
文字列3_追記: 4
```

ちなみに
---

当然ながら、VB.NETやC#では、この現象は起らない。

```vb:App1.vb
    Sub Main()
        Dim dic As New Dictionary(Of String, Object())
        Dim i As Integer
        For i = 0 To 3
            Dim arr(1) As Object
            arr(0) = "文字列" & i
            arr(1) = i
            dic.Add("キー" & i, arr)
        Next
        i = 3 ' 最後のアイテムを書き換えてみる
        Console.WriteLine("---書き換え前----------")
        Console.WriteLine($"{dic("キー" & i)(0)}: {dic("キー" & i)(1)}")
        Console.WriteLine("---書き換え後----------")
        dic("キー" & i)(0) = dic("キー" & i)(0) & "_追記"
        dic("キー" & i)(1) = dic("キー" & i)(1) + 1
        For i = 0 To 3
            Console.WriteLine($"{dic("キー" & i)(0)}: {dic("キー" & i)(1)}")
        Next
    End Sub
```

```c#:App1.cs
var dic = new Dictionary<string, object[]>();
int i;
for (i = 0; i < 4; i++)
{
    var arr = new object[2];
    arr[0] = "請求書" + i;
    arr[1] = i;
    dic.Add("キー" + i, arr);
}
i = 3; // 最後のアイテムを書き換えてみる
Console.WriteLine("---書き換え前----------");
Console.WriteLine($"{dic["キー" + i][0]}: {dic["キー" + i][1]}");
Console.WriteLine("---書き換え後----------");
dic["キー" + i][0] = dic["キー" + i][0] + "_追記";
dic["キー" + i][1] = (int)dic["キー" + i][1] + 1;
for (i = 0; i < 4; i++)
{
    Console.WriteLine($"{dic["キー" + i][0]}: {dic["キー" + i][1]}");
}
```

VB.NETはObject型配列宣言でNewがいらない。また、配列要素1の加算の際に整数へのキャストが不要。良いんだか悪いんだか、、、よく知った上で使いましょう。
Unreal Engine5の専用サーバーモードでTPSのテンプレートを動かす

# はじめに
とりあえず素人ながらUnrealEngine5を触ってみたいとなりサーバーを立てて見ました。今回のゴールは、TPSのテンプレートをAWSに立ててオンライン通信をするところまでです。

まず以下のリンクをとても参考にしたので興味のある方は一緒に読んでいただけると良いと思います。
- [AWSのブログ](https://aws.amazon.com/jp/blogs/news/compiling-unreal-engine-4-dedicated-servers-for-aws-graviton-ec2-instances/)
- [UnrealEngineのチュートリアル](https://docs.unrealengine.com/5.0/ja/setting-up-dedicated-servers-in-unreal-engine/)


# 環境
- Windows11 21H2
- UnrealEngine 5.0.2
- Visual Stadio 2019 (UE5が推奨しているバージョンのため2019)

# Epic LauncherからインストールしたUEだと専用サーバーはたてられない罠
実はEpicLauncherからインストールしたUnreal Enigineからだと専用サーバーをビルドできません。Epicのgithubからソースをダウンロードしてきてビルドする形になります。

まずは以下からEpicのgithub Organizationに参加しましょう。
[Epicのサイト](https://www.unrealengine.com/en-US/ue-on-github)

それができたら以下のリポジトリが閲覧可能になるはずなので、クローンしてReadmeの手順通りにファイルを実行していけばビルド版のUEが使えます。
[UEのソース](https://github.com/EpicGames/UnrealEngine)

AWSなどに乗っけることも踏まえてLinuxでのクロスビルドをする想定があれば、[この辺](https://docs.unrealengine.com/5.0/en-US/linux-development-requirements-for-unreal-engine/) からclangの推奨バージョンも入れておきましょう。自分は、UE 5.0.2を利用していたのでclang-13.0.1-basedを入れました。

# TPSのテンプレートから準備していく
UEを開いてGames-ThirdPersonから今回のプロジェクトを作成します。C++版を選択する必要があるので注意です。

![tpstemplate.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1646943/767f0333-b505-c797-5ea8-4c7942911319.png)


# サーバービルドターゲットをセットする
まずは、Games/Source配下に[ProjectName]Server.Target.csというファイルを[ProjectName].Target.csからコピー作成します。Visual Studio上でコピーしようとすると、[この辺](https://social.msdn.microsoft.com/Forums/vstudio/en-US/162b06e4-d1b8-4701-a3c8-d0ec01238f1e/cannot-copy-visual-c-items-within-the-same-project?forum=vcgeneral)のエラーでどうでもいいつまりをするので、ファイルエクスプローラー上でコピー・リネームして、Add-ExistingItemっから追加するとスムーズでした。
![visualstudio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1646943/6205f77e-4970-987e-9813-920e013ee2d5.png)

UnrealEngineのチュートリアルどおりに進めていきDevelopment Serverでbuildをすると[ProjectName]Server.exeというファイルができるます。
このファイルを使ってローカルで稼働確認ができるので[ProjectName]Server.exeを使ってローカルでサーバーが起動できるか確認してみましょう。（詳細は公式参照）

![developmentSever.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1646943/326445a7-4de6-2f3e-f644-2cb2c7624314.png)


# プロジェクトをパッケージ化
ここまできたらplatform Content/Device Management でOSを選択します。自分は、[AWSのブログ](https://aws.amazon.com/jp/blogs/news/compiling-unreal-engine-4-dedicated-servers-for-aws-graviton-ec2-instances/)を参考にm6g.mediumのインスタンスを使ったので、LinuxArm64を選択しました。BuildTargetをServerにしてPackage Projectを選択すればパッケージ化できます。パッケージ化を行う場所がUE5だと変わってしまっているようで、公式チュートリアルをみると若干迷います。

![package.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1646943/1594b41d-b856-1f86-50d6-3ca3c4437508.png)

# AWSに乗せてサーバーに接続してみる
パッケージ化したものを[AWSのブログ](https://aws.amazon.com/jp/blogs/news/compiling-unreal-engine-4-dedicated-servers-for-aws-graviton-ec2-instances/)の通りに、zipで固めてサーバー上に送って実行用のshellを叩けばサーバーは立ち上がります。

あとはローカルマシンでゲームを立ち上げ、＠を押下した後、「Open {サーバーのIPアドレス}」と打てば、TPSのチュートリアルの画面が映り、見事ゴールです！

駆け足でしたが自分が詰まったところのメモを中心に、以上で「Unreal Engine5の専用サーバーモードでTPSのテンプレートを動かす」が完了です。
スクロール可能なDialogを作成するDiallog+ConstraintLayout+ScrollView

"Android dialog constraintlayout"などで調べると山のように出てくるので、ダイアログをいじろうとしたときにみんなぶつかるんだろうなあという感じです。
自分も先人たちと同じ轍を踏んだので、いつかの誰かの助けになれればと思います。

# 前提
| ライブラリ | version |
|:-:|:-:|
|material|1.6.1|
|constraintlayout|2.1.4|

# 要点
ScrollViewに`app:layout_constraintHeight="wrap_content_constrained"`を指定するとよい。

# コード
```dialog_scrollable.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingHorizontal="24dp"
        android:paddingTop="16dp">

        <ScrollView
            android:id="@+id/content"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            app:layout_constraintBottom_toTopOf="@+id/checkBox"
            app:layout_constraintHeight="wrap_content_constrained"
            app:layout_constraintTop_toTopOf="parent">

　　　　　　　　　　　　　　　　<!-- スクロールさせたくなる長いコンテンツ -->

        </ScrollView>

        <com.google.android.material.checkbox.MaterialCheckBox
            android:id="@+id/checkBox"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="start"
            android:text="Checked"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

```

呼び出し側
```MainActivity.kt
MaterialAlertDialogBuilder(context)
    .setTitle("Title")
    .setView(R.layout.dialog_scrollable)
    .setPositiveButton("OK", null)
    .show()
```

![Screenshot_20220616_002753.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11920/8d7adc1a-702d-bf35-a827-8d328bd52474.png)

# 余談
最初はScrollViewに`app:layout_constraintHeight_default="wrap"`を指定していて、正しく動作していたがログに以下のようなエラーが出力されていた。
```
E/ConstraintLayout: layout_constraintHeight_default="wrap" is deprecated.
    Use layout_height="WRAP_CONTENT" and layout_constrainedHeight="true" instead.
```
このエラーに従って
```dialog.xml
<ScrollView
    android:layout_height="wrap_content"
    app:layout_constraintHeight="true"
    ...
```
と指定すると残念ながらレイアウトが崩れた。どういうことかと悩みに悩み、`app:layout_constraintHeight`の定義をcmd+クリックで確認したら
```
    <attr format="dimension|enum|string" name="layout_constraintHeight">
        <enum name="match_parent" value="-1"/>
        <enum name="wrap_content" value="-2"/>
        <enum name="match_constraint" value="-3"/>
        <enum name="wrap_content_constrained" value="-4"/>
    </attr>
```
となっていてboolean渡す意味がないということに気づいてしまった。
🤖 AWS認定 機械学習専門知識の兄です。真実(学習方法)をお話しします。

# はじめに
この記事では、[AWS認定機械学習–専門知識 (AWS Certified Machine Learning - Specialty)](https://aws.amazon.com/jp/certification/certified-machine-learning-specialty/)の受験にあたり、自分自身が学習・活用したコンテンツをだらだらと書いていきます。
他の認定を含めた受験の経緯などは[別記事](https://qiita.com/k_su21652/items/6e9ec7bee0f8efaf9165)をご覧ください。

# AWS認定機械学習–専門知識 とは
こちらは公式サイトよりそのまま拝借します。

> この資格は、組織がクラウドイニシアチブを実装するための重要なスキルを持つ人材を特定して育成するのに役立ちます。
> AWS Certified Machine Learning - Specialty を取得すると、AWS で機械学習 (ML) モデルの構築、トレーニング、チューニングおよびデプロイに関する専門知識を認定します。

https://aws.amazon.com/jp/certification/certified-machine-learning-specialty/

# 役立ったと感じる前提知識
ここでは認定試験を意識してやっていたわけではないものの、
合格に大いに役立ったと感じる内容を記載します。

以前からAI/ML分野に興味はあったものの何から手をつければいいか迷っていましたが、
業務もほぼ在宅で、となった20年4月から、基本的な統計学〜機械学習に関する学習を1年ほど行っていました。

認定試験に必要な機械学習の基礎的な用語や概念の理解は、
ほぼこの期間に習得した知識でまかなえました。

## やったこと
### G検定取得
何から手をつければ分からなかったとき、「機械学習 初心者 おすすめ」みたいな感じで検索し、
出てきたG検定合格をまずは目指すことにしました。

https://www.jdla.org/certificate/general/

参考にした書籍の一例としては、
- 人工知能は人間を超えるか
- 徹底攻略 ディープラーニングG検定ジェネラリスト問題集 etc...

### 技術書を通じた学習

G検定ではアルゴリズムの詳細な内容や、コーディングの知識は問われません。
そのため、実装スキルも身につけようということで技術書を購入して読んだりしていました。

機械学習については当時まったく知識がなかったため、写経に徹することも多々ありました。
しかし、徐々にでも吸収できていそうな実感があったのと、緊急事態宣言であまりに自宅から動けなかったことも作用し、
下記の書籍＋αで計10冊ほどは最後まで進められました。

- PythonとKerasによるディープラーニング
- オライリー本
    - Pythonではじめる機械学習
    - scikit-learn、Keras、TensorFlowによる実践機械学習
    - ゼロから作るDeep Learningシリーズ
- 100本ノックシリーズ
    - Python実践データ分析100本ノック
    - Python実践機械学習システム100本ノック 


# 認定試験に向けてやったこと
ここからは認定試験の申し込みから受験当日までの勉強方法を記載します。YO!!!

## 利用したコンテンツ
概ね、下記の並び順で進めました。

**1. 他の方の受験記・合格記**
先人の残した宝を活用しない手はありません。

QiitaやZennなど、検索すればたくさんの方の記事が見つかりますが、
私が特に参考にさせていただいたのが、NRIネットコム 小西さんの記事です。
2020年からAPN Top Engineerに選出されたほか、AWS認定に関する書籍も多く出版されているなど、十分すぎるほどに信頼できるなと感じたからです。

https://tech.nri-net.com/entry/aws_certified_machine_learning_specialty

**2. 試験ガイド→サンプル問題/模擬試験を解く**
前述のAWS公式サイトから、各認定ごとに試験ガイドとサンプル問題が準備されているので、
まずこれらに目を通します。
試験で問われる知識やこのあと学習すべきAWSサービス、設問のカテゴリや出題形式を大まかに把握できます。

サンプル問題とは別に、AWS Skill Builderでは無料で模擬試験を受験することができます。
こちらについても解いては解説を読み、また解き直して、というのを何度も行いました。

https://dev.classmethod.jp/articles/new-aws-official-practice-questions/

**3. Skill Builderのコンテンツを視聴する**

同じくSkill Builderには、さまざまなカテゴリの学習コンテンツが無料で公開されています。
ここでは、小西さんのブログ記事で紹介されているものからいくつかをピックアップして視聴しました。

- Exam Readiness: AWS Certified Machine Learning - Specialty (Japanese) (日本語実写版)
- The Elements of Data Science (Japanese) (日本語字幕版)
- Types of Machine Learning Solutions

機械学習についての予備知識が、この段階での学習時間短縮にかなり役立った印象です。

**4. Web問題集を繰り返し解く**
私はWeb学習サイトのひとつ（通称：コ○ワ）の有料会員になり、ひたすらWeb問題集を解きました。

間違った問題についてはサイト内の解説だけでなく、公式ドキュメント、ホワイトペーパー、Black Beltの動画から適切そうなものを確認し、試験で求められる知識の網羅的な取得に努めました。

# 最後に
おうち時間中の勉強がなかったら途中で絶対挫折していたと思う
rosparam + デフォルト値

# 概要

パラメータを取得する際、指定したキー値がなかった場合のデフォルト値を設定する方法

# 環境

| 項目 | 値 |
|:-:|:-:|
| Ubuntu | 20.04 |
| ROS | Noetic |

# ソースコード(C++)

メソッド`ros::NodeHandle::param()`を使う。

```
// private node handleの初期化
ros::NodeHandle private_node_handle("~");

// デフォルト値"param!"でパラメーターを取得
auto param = private_node_handle.param("path/to/param", std::string("param!"));
```

以下のように参照渡しでも設定可能

```
// パラメーター保存用の変数の宣言
std::string param;

// paramにパラメーターの値を設定
if (private_node_handle.param("path/to/param", param, std::string("param!")))
{
  ROS_INFO(
    "parameter %s set by user to path/to/param",
    private_node_handle.resolveName("path/to/param_none").c_str(),
    param.c_str()
  );
}
else
{
  ROS_INFO(
    "parameter %s set default",
    private_node_handle.resolveName("path/to/param_none").c_str()
  );
}
```

コードからもわかるよう(?)に、この使い方において`ros::NodeHandle::param()`は、パラメーターサーバーからパラメーターを取得できた場合は、`true`を、取得できなかった(=デフォルト値を設定した)場合は`false`を返す。

# ソースコード(Python)

Pythonではもっと簡単にできて、`rospy.get_param()`の第2引数にデフォルト値を指定すれば良い([公式wiki](http://wiki.ros.org/rospy/Overview/Parameter%20Server)にもコード例がある)

```
param = rospy.get_param('~path/to/param', 'param!')
```

# 余談

[公式wiki](http://wiki.ros.org/roscpp/Overview/Parameter%20Server)の`getParam`の説明にデフォルト値を返すバージョンもあるよとか書いてあったが、wiki自体には書いてなかったので以下のように実装していた。

```
ros::NodeHandle private_node_handle("~");
// 宣言時にデフォルト値で初期化
std::string param = "param!";

// パラメーターを取得できた場合のみ上書く
if (private_node_handle.hasParam("path/to/param"))
{ 
  private_node_handle_.getParam("path/to/param", param);
}
```

# 参考サイト

- 公式リファレンス (C++) : http://docs.ros.org/en/api/roscpp/html/classros_1_1NodeHandle.html#a8d0a7ae423a715eced81fa984c3437ac
- 公式wiki (C++) : http://wiki.ros.org/roscpp/Overview/Parameter%20Server
- 公式wiki (Python) : http://wiki.ros.org/rospy/Overview/Parameter%20Server
PythonでPDFの上に文字とか乗っけるアプリを作った！-４.今後について-

# 現状について
正直、個人的に使うことを目的に開発したので、正直、自己満足している状態です。
もし、リクエストが多かったら、頑張るかも。
誰かやってくれる人がいたら、教えてください！！！


# もしやる気が出ればやることリスト
**・exe化**
　Pythonがインストールされてない環境からでも実行できるようにする。
　pyinstaller を使用して、exe化してみましたが、POPPLER_PATHが通らなかったり、fontパスが指定できなかったりしていて、諦めているところです。

**・細かい修正**
　ユーザへの通知や、エラーチェック、エラー処理が少ないです。
　フォント補正に予期せぬ値を入力したり、Pythonが認識できない色を指定したら、エラーが発生すると思われます。

**・定数の設定ファイル化**
　pdfeditor.ini ファイルを作成して、フォントのパス、POPPLER_PATH、切り捨てピクセル数、canvasのサイズを
　ファイルから指定できるようにすることで、どの環境からも柔軟に使用できるようにしたい。

**・機能追加**
　canvasの拡大・縮小機能
　これって出来るのかな？　年末調整とか細かい箇所にマウス入れるの結構しんどいので、拡大縮小が10％ずつ(MAX±50%)とかでもいいので、
　出来ればいいなぁと。

**・もうちょっと環境作成について詳しく書きたい**
　環境がまっさらな状態にするのがキツイので、書いてませんが、
　出来ればPython勉強中の方へも環境設定から実行まで出来るように、手順化したいとこです。

**・UIからの座標微調整**
　今はcsvからx,yを修正するしかないのですが、座標の微調整が画面上から出来るようにしたいです。




# お仕事募集中
個別でお仕事の依頼がありましたら、お手数ですがご連絡ください。
なんでもやりますよー！

お問い合わせ窓口：
https://www.zero-one-system.co.jp/q-corp



# ソースコード、ダウンロードはGitから

【重要】
画面ディスプレイの解像度をフルHD（1920x1080）を想定して作成しております。

ここからダウンロードできますが、環境設定が必要となります。
https://github.com/kinjoarata/PDFEditor2/tree/main/PDFEditor2



# 関連記事（全４個）

PythonでPDFの上に文字とか乗っけるアプリを作った！-１.はじめに、成果物紹介-
https://qiita.com/ArataKinjo/items/1e83810623ee15259b0a

PythonでPDFの上に文字とか乗っけるアプリを作った！-２.機能説明-
https://qiita.com/ArataKinjo/items/f934812de7b471b352a8

PythonでPDFの上に文字とか乗っけるアプリを作った！-３.ソースコード解説-
https://qiita.com/ArataKinjo/items/c92b4637c44f2bf574e3

PythonでPDFの上に文字とか乗っけるアプリを作った！-４.今後について-
（この記事です）
6週目　Annotationとは？ @Controller、@RequestMapping、@ModelAttribute

Annotationとは？
Annotationはクラスとメソッドに追加して様々な機能を付与する役割を果たします。

@Controller
Springに該当ClassがControllerの役割を果たすと明示するために使用するAnnotationです。
@RequestMapping
@RequestMapping(value=””)のような形で作成し、要請が入ったURIの要請とAnnotationvalue値が一致すると、そのクラスやメソッドが実行されます。 Controllerオブジェクト内のメソッドとクラスに適用可能

Class単位に使用すると、下位メソッドにすべて適用されます。
メソッドに適用されると、該当メソッドで指定した方法でURIを処理します。

@Controller//このClassはControllerの役割をします。
@RequestMapping("/user")　//このClassは/userに入るリクエストをすべて処理します

@ModelAttribute
クライアントが転送するHTTPparameter、Body内容をSetter関数により1:1でオブジェクトにデータを接続(バインディング)します。
PythonでPDFの上に文字とか乗っけるアプリを作った！-１.はじめに、成果物紹介-

# はじめに
PDFを印刷して、ボールペンで入力して、再度スキャンするというルーティンを何度も繰り返してました・・・。
私は金釘流（字が下手だということらしい。）という流派に属しており、字を書くのもストレス。
それをスキャンして送って、相手を困らせるのもストレス。

これをなんとかしたい！！
と、もう10年くらい考えておりました。なので、作りました。

試行錯誤した期間が長いため、記事が長くなります。
私自身でも整理したいため、分割して投稿します。

-目次-
1.はじめにと、成果物紹介
2.機能説明
3.ソースコード解説
4.今後について

（後で変えるかもしれません。）


# 出来たもの
最終的には、権利関係が全くわからないので、フリーにしますが、
そのまま商用に製品化ーとかはやめてください。（なんとなく納得いかないので）


ソースコード、ダウンロートはGitから：
https://github.com/kinjoarata/PDFEditor2/tree/main/PDFEditor2


# 使い方
### 1.PDFファイル
私の運営しているプログラミングスクールの入会申込用紙を仮定してExcelでPDFの申込み用紙を作りました。
1ページ目（申込欄）：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249830/007eb928-02ed-f599-7343-c8b782ff8645.png)

2ページ目（規約的な）：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249830/aa187c3b-80a2-1329-9778-15789f26ba30.png)


### 2.PDFEditor2(PythonのCanvas)で開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249830/eb0d8fa8-dc0c-505c-07b0-ebf2ef8c9c96.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249830/9b90757f-89f5-6c29-fd95-6a7a3b433d01.png)


### 3.PDFEditor2(PythonのCanvas)で文字等を入力する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249830/4c5f1300-fd43-29f8-f796-1e220ee40e10.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249830/9d5ece7f-aeb7-d28d-c480-24f5aa173d15.png)


### 4.PDFを出力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249830/e96648b3-21cf-6f30-5e49-2866fc7271f1.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249830/3e445648-2f28-46fc-0b79-e598ad99caea.png)



# 途中で気付いたこと
これだけだったら、Adobeのローカルアプリ上で出来るんですね・・・。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249830/8bce3f6b-9384-ad75-e53f-87aefbaab5df.png)

最後の方に調べて、「入力を署名」で無料でPDFの上に文字を乗っけられるし、○つけられるし、レ点付けられるし・・・。ずっと有償版買わないといけないって思ってた。
PDFEditorを作り終わりそうなときに気付いてしまって、まぁ困った。

しかーし！　そこで折れたらプログラマーとしてのプライドが許さない！
もっと使い勝手がいいのを作ってやろうじゃないか！

ということで、色々機能を付けることにしましたので、次回から機能の説明をします！
・入力内容のCSV保存
・入力内容のCSV読み込み
・一括CSV→複数PDF出力

# 想定している使われ方
一般的というよりは、業務的に使えそうなアプリになりました。
定期的に手入力しなきゃならないデータがあります。
それらを事務方の方で予め入力してくれないかな？？？
ということで、CSVデータから一括でPDFを作れるようにしました。

**「年末調整とか」**
1.PDFテンプレートを用意
2.PDFEditor2 で1件目のレイアウト、csvデータを作成+保存
3.csvデータを編集して、全社員分のcsvデータ作成
4.一括処理でPDFを作成
5.印刷して配って、従業員は確認して、印鑑押して提出。

**「毎月やらないといけないやつ」**
1.PDFテンプレートを用意
2.PDFEditor2 でレイアウト、データを作成
3.csvデータの日付だけ変えて、PDFを作成
4.印刷して、印鑑押して、提出。

**「帳票システムとして使用」**
1.PDFテンプレートを用意
2.システムからcsvファイル作成
3.csvファイルの存在確認後、関連したPDFを生成
4.所定のフォルダに置く
5.システムからダウンロードできるようになる。

とりあえず思いつくのはこれくらいですが、悪くはないかなと。
自己満足出来るくらいのクオリティはでてます。


# ソースコード、ダウンロードはGitから

【重要】
画面ディスプレイの解像度をフルHD（1920x1080）を想定して作成しております。

ここからダウンロードできますが、環境設定が必要となります。
https://github.com/kinjoarata/PDFEditor2/tree/main/PDFEditor2


# 関連記事（全４個）

PythonでPDFの上に文字とか乗っけるアプリを作った！-１.はじめに、成果物紹介-
（この記事です）

PythonでPDFの上に文字とか乗っけるアプリを作った！-２.機能説明-
https://qiita.com/ArataKinjo/items/f934812de7b471b352a8

PythonでPDFの上に文字とか乗っけるアプリを作った！-３.ソースコード解説-
https://qiita.com/ArataKinjo/items/c92b4637c44f2bf574e3

PythonでPDFの上に文字とか乗っけるアプリを作った！-４.今後について-
https://qiita.com/ArataKinjo/items/c71492569bd9bb76d092
ffmpegコマンド忘備録

# 初めに
[ffmpeg](https://ffmpeg.org/)とは
>オーディオとビデオを記録、変換、ストリーミングするための完全なクロスプラットフォームソリューション。
# どんなことが出来るの？
・動画の拡張子の変更
・動画のカット,音声抽出等
・動画の圧縮
・TLS形式の配信動画の保存
・チャプター設定
・副音声設定
とにかく動画に関することがこれ一つで行える万能ツール


### 基本コマンド
```
 $ffmpeg  Option1 -i <src.file> Option2 <dest.file>
```
Option2には出力先のファイルに対して行いたい操作を指定する。
エンコード時のコーデックの指定はここで行う。
```:動画の情報を確認する
 $ ffmpeg -i 入力ファイル名
```

#### 動画エンコード
```:動画の拡張子を変更する
 $ ffmpeg -i src.mp4 dest.flv
```

```:nvidiaエンコーダーを使用して動画ファイルのエンコードを行う
#h264
 $ ffmpeg -i src.avi -c:v h264_nvenc dest.mp4
#h265
 $ ffmpeg -i src.avi -c:v hevc_nvenc dest.mp4
```
【GAS】ドキュメントファイルをGASでコピーしてChatWorkで通知するアレコレ

# 概要

「毎週ドキュメントファイルをコピーして通知する作業を自動化したい」という要望があったので、パッと作ってみた


# ご利用される環境にあわせて変更ください

```javascript
const mainWorker = () => {
  const mtgDate = getMtgDate()
  const previousMtgDate = getMtgDate(true)

  const SHEET_NAME = " ファイル名"
  const previousMtgName = previousMtgDate + SHEET_NAME
  const mtgName = mtgDate + SHEET_NAME
  const TEMPLATE_NAME = "2022年度テンプレート"

  const DIRECTORY_ID = "複製したいファイルのあるディレクトリID"
  const TEMPLATE_DIRECTORY_ID = "テンプレートファイルのあるディレクトリID"
  const directory = DriveApp.getFolderById(DIRECTORY_ID)
  const templateDirectory = DriveApp.getFolderById(TEMPLATE_DIRECTORY_ID)

  const previousFile = directory.getFilesByName(previousMtgName)
  const templateFile = templateDirectory.getFilesByName(TEMPLATE_NAME)
  const result = previousFile.hasNext() ? copyFile(previousFile, directory, mtgName) : copyFile(templateFile, directory, mtgName)

  if (result) {
    const url = directory.getFilesByName(mtgName).next().getUrl()
    const message = "[toall]\n作成しましたよ！\n" + url;
    sendChatWork(message);
  }
}

/**
 * https://github.com/cw-shibuya/chatwork-client-gas
 */
const sendChatWork = (message) => {
  const client = ChatWorkClient.factory({ token: "API Token" });
  client.sendMessage({ room_id: 通知したいルームID, body: message });
}


const copyFile = (copyFile, directory, mtgName) => {
  if (!copyFile.hasNext()) {
    sendChatWork("テンプレートファイルが見つかりません。")
    return;
  }

  const file = copyFile.next();

  // 重複しない場合だけ作成
  if (!directory.getFilesByName(mtgName).hasNext()) {
    file.makeCopy(mtgName, directory)
    return true;
  }
  else {
    sendChatWork("重複するファイルが存在します")
    return;
  }
}

const getMtgDate = (isPrevious) => {
  let date = new Date()
  isPrevious ? date.setDate(date.getDate() - 7) : date.setDate(date.getDate() + 1)
  return Utilities.formatDate(date, 'JST', 'YYYY/MM/dd');
}
```
中心点をずらさずに拡縮する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2704221/8a0c96d7-5570-2342-c552-f30a33f14e2b.png)
例えばこの瞳を縮小させたいとき

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2704221/019e83e7-80c9-96b7-9647-d49b1cfcdbbc.png)
一旦小さくしてから中心点を合わせようとすると正確に元の中心点に合わせるのは難しい・・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2704221/9a50c73e-afd7-5edf-6ee9-3b39a7dc9111.png)
そういう時はAltキーを押しながら拡縮すれば中心点はそのままに拡縮を行える

ちなみにShiftキーも合わせて使うと比率を維持したまま拡縮できる。
（Shiftキーは「線を引く」、「移動する」際にも方向を90度単位で固定できる。）
🔰【自分用】Webサービスはどのような思想で設計されているか

# はじめに
webは誕生から爆発的に普及し、巨大サービスへと成長した。
Webサービスがここまで成功した要因は、設計思想とその構造にあるらしい。
今回はタイトル通り。Webサービスがどのような思想で設計されているのか。代表的な設計指針を復習する。

# アーキテクチャとは？
webサービスや設計を形作る「構造」のこと。
webを例にするとブラウザ、HTTP、HTMLなどで構成されているので、これらがWebのアーキテクチャとなる。
### アーキテクチャスタイル
アーキテクチャを決める際の「設計指針」。指針やルールに沿って実装される。
自分が学習した「クライアント/サーバー」「MVCモデル」「オブジェクト指向」などもアーキテクチャスタイッルに含まれる。
無駄なアーキテクチャがなく整理されていて、ユーザーが使いやすいように設計されている。

アーキテクチャは**構造**アーキテクチャスタイルは**設計指針**という違い。
例：どのような家にするのか方針を定めるのがアーキテクチャスタイル。その方針に基づいた、トイレ、キッチン、リビングなど家の構造１つ１つがアーキテクチャ。

### REST
RESTはWebアーキテクチャスタイルのこと。洗練されていて、よく起用されている。
「クライアント/サーバー」が一番有名なアーキテクチャスタイル。これにいくつかの構成を加えることでRESTというアーキテクチャスタイルが成立する。

### リソース
RESTに関連する言葉で「web上で名前を持ったあらゆる情報のこと」
例
保存したブックマーク
渋谷の写真データ
渋谷の天気予報情報
など。いずれもリソースである。web上には無数のリソースがあり、どこにあるか指すものをURLという。
RESTはURLにHTTPメソッドを加えた情報でリクエストする。

## RESTの中身
RESTは複数のアーキテクチャスタイルが集まってできており、6つのアーキテクチャスタイルで成り立っている。
### ステートレスサーバー
クライアントの状態を保持しないサーバーのこと。
リクエストごとにすべての情報を送信する。メリットはサーバー側の実装が簡単になること。
### キャッシュ
一度得たリソースをクライアント側で保存しそれを使い回す仕組みのこと。
メリットはクライアントとサーバー間の通信を減らすことで処理時間の短縮と効率化に繋がる。
デメリットは、古いキャッシュを利用することで情報の信頼度が下がることがある。
### 統一インターフェース
全てのサーバーで使用するメソッドを固定する。例えばHTTPメソッドでは、URLで指し示したリソースをGETやPOSTなどに限定することで、全体がシンプルになる。
### 階層化システム
システムを階層に分ける。クライアントとサーバーの間に階層を分割するものを設け、負担を分散する。
統一インターフェースにより受けられる恩恵。
### コードオンデマンド
プログラムをクライアント側で実行すること。代表的なものでjavascriptがこれに当たる。
メリットはクライアントが後から新しい機能を追加していけること。
デメリットは、クライアント側での実行が増えるので、サーバーとやり取りされるリソースの内容が明確ではなくなる。

### SOAP
通信する上でのルールでリクエストおよびレスポンスともにコンピューターが読み取りやすいように作成されたデータでやり取りを行う。
特徴
- 複雑な入力や出力があるサービス向け
- 厳密なチェックなどが必要なサービス向け

#### RESTとSOAPの違い
違いは簡単RESTは`シンプルで簡単`SOAPは`高機能で複雑`

# 終わりに
今日この記事をまとめた理由はアーキテクチャという言葉を見たときにあれ？なんだっけ？となってしまったからです。一度その時理解したことでも、繰り返しが大事ですね。
iphone12から自作掲示板に投稿しようとしたら500servererrorが出た件

iphone12から自作掲示板（https://jichannel-renewal.herokuapp.com/
へ画像を投稿しようとしたら下のようなエラーが、、、
![error.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2707455/0e5f3ebc-5912-146b-fe39-26d638771d48.jpeg)
そこで調べてみると、どうやら画像を読み込むのに時間がかかっている。しかもネット上を調べてみると同様な理由でエラーになっている事例が散見される。つまり、画像サイズが大きすぎるためのエラーだった。iphone12は、写真の拡張子が.heicであるため画像が大きくアップロードが難しいらしい。なので、.jpegでアップロードして欲しい。
ipone画像を.jpegに変換する方法は以下URLを参照してください。
https://info-con.co.jp/tips/iphone-04-convert_heic_to_jpg/
teratermを使って公開鍵認証でSSH接続するときに"認証に失敗しました"と出たときの対処法

## はじめに

Linuxの知識，ネットワークの知識等全くありません．

## 環境
* 接続元
    * OS: windows10
    * teraterm: Version4.106
* 接続先
    * OS: Ubuntu22.04
    * OpenSSH_8.9p1 Ubuntu-3, OpenSSL 3.0.2 15 Mar 2022

## つまづいたところ

teratermを使って公開鍵認証でUbuntuの入ったPC(接続先)に接続しようとしても"__認証に失敗しました．再試行してください__"と出てしまい接続できませんでした．
![スクリーンショット 2022-06-15 230113_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/794319/e5f28440-4e91-ec58-b63f-368ee64079fd.jpeg)

### 当時の状況
* 接続元からPowerShell等を使って公開鍵認証でSSH接続することはできた
* teratermでもパスワード認証では接続できた
* teraterm使用かつ公開鍵認証時のみ接続できない

teratermでログを取りながら使いたかったので，その他の方法はできれば使いたくありませんでした．

### 解決した方法

#### __公開鍵暗号の生成にECDSAを使用する__

接続できなかったときの公開鍵は以下のコマンドで作っていました

~~~
$ ssh-keygen -t rsa -b 2048 <その他オプション>
~~~

これをECDSAに変えて

~~~
$ ssh-keygen -t ecdsa -b 521 <その他オプション>
~~~

として生成した鍵を使ったところ，無事teratermから接続することができました．

これ以外にも解決方法はあると思いますが，一つの参考になれば幸いです．

## 参考

https://qiita.com/YuuT_38/items/6b27cba9dc943f53ab30

https://blog.cles.jp/item/12876
Nuxt.jsに@nuxt/imageを使って画像を設定する方法

Nuxt.jsに[@nuxt/image](https://github.com/nuxt/image)を使って画像を設定する方法になります。

## @nuxt/imageをインストールする
まずは@nuxt/imageをインストールしていきます。

```
npm install -D @nuxt/image
# OR
yarn add --dev @nuxt/image
```

## nuxt.config.jsで設定をする
続いて`nuxt.config.js`に設定を追加します。
```nuxt.config.js
export default {
  modules: [
    '@nuxt/image',
  ]
}
```
`target: 'static'`の時は`buildModules`に設定します。

```nuxt.config.js
export default {
  target: 'static',
  buildModules: [
    '@nuxt/image',
  ]
}
```

## @nuxt/imageを使って画像を表示する

```vue
<template>
  <nuxt-img src="/photo.jpg" />
</template>
```
`nuxt-img`または`nuxt-picture`を使って画像を表示することができます。

```vue
<template>
  <nuxt-img
    src="/photo.jpg"
    width="400"
    height="200"
    loading="lazy"
    format="webp"
    quality="80"
    alt="image"
  />
</template>
```

オプションの指定も複数可能です。詳しいオプションは下記の公式サイトに記載されています。

https://image.nuxtjs.org/components/nuxt-img

### background（背景）で@nuxt/imageを使う場合の例

```vue
<template>
  <div :style="backgroundStyles"></div>
</template>

<script lang="ts">
import Vue from 'vue'
export default Vue.extend({
  computed: {
    backgroundStyles() {
      const imgUrl = this.$img(
        '/photo.jpg',
        { width: 400, height: 200, quality: 80 }
      )
      return {
        background: `url('${imgUrl}') repeat left top`
      }
    }
  }
})
</script>
```

## ローカルの画像はstaticフォルダに配置する必要がある

公式サイトにも記載がありますが、`nuxt-img`にローカルから画像を設定する場合は、staticフォルダに配置する必要があります。assetsフォルダでは機能しません。
https://image.nuxtjs.org/getting-started/providers

## 外部にある画像を表示する場合は設定が必要
外部にある画像を@nuxt/imageを使って表示するには、`nuxt.config.js`に設定を追加します。

```nuxt.config.js
export default {
  modules: [
    '@nuxt/image',
  ]
  /*
   ** ↓↓↓追加
   */
  image: {
    domains: ['nuxtjs.org']
  }
}
```
### Contentfulの画像を設定する例
ヘッドレスCMSのContentfulの画像を設定する場合の一例です。
```nuxt.config.js
export default {
  image: {
    provider: 'contentful',
    contentful: {
      baseURL: 'https://images.ctfassets.net'
    }
  }
}
```

## 参考
https://image.nuxtjs.org/
【Power Shell】フォルダサイズ取得スクリプトの作成


コマンドプロンプトのdirコマンドでフォルダサイズを確認するような運用作業があり
毎回手打ちするのが嫌なので、スクリプトを作成しようと思いました。

dirコマンドを実行する際に、以下のパラメーターの指定を行っておりました。

/s 再帰的に処理する
/a 指定した属性のみ表示を行う。-はNotで、指定した属性以外の表示となる。


個人的にBatを作成するのが嫌で、PowerShellで作成する事としました。
Get-ChildItemコマンドを使用してフォルダサイズの取得を行おうと思います。

以下のパラメータを使用します。
※下記ＵＲＬを参考に致しました。
https://docs.microsoft.com/ja-jp/powershell/module/Microsoft.PowerShell.Management/Get-ChildItem?view=powershell-7

-Recurce 再帰的に処理する
-Force 非表示の項目を取得(隠しファイル等)

Get-ChildItemコマンドを取得した情報の"Length"列にファイルサイズが出力されます。以下、実行イメージとなります。

```PowerShell:Sample
Mode                 LastWriteTime         Length Name                                                                              
----                 -------------         ------ ----                                                                              
-a----        2022/06/15     21:04              0 test1.txt                                                                         
-a----        2022/06/15     21:04              0 test2.txt                                                                         
-a-h--        2022/06/15     21:05              4 test3.txt                                                                         
-a----        2022/06/15     21:05              8 test4.txt     
     
```

"Length"カラムの合計値の取得を行います。
Get-ChildItemコマンドで取得した情報を、Measure-Objectコマンドに渡して合計値の取得を行います。下記のコマンドで合計値が取得出来ます。

Get-ChildItem -Recurse -Force | Measure-Object -Sum Length

"Sum"行に出力された値が、フォルダサイズとなります。
"Count"行は、ファイル数となります。
以下、実行イメージとなります。

```PowerShell:Sample_2
Count    : 4
Average  : 
Sum      : 12
Maximum  : 
Minimum  : 
Property : Length
```

※Measure-Objectコマンドの説明は詳しくないので、出来ないです。
下記URLが参考となりました。
凄くざっくり言うと、受け取った値の合計値や平均値等を計算してくれるコマンドだと思っています。今回は、Measure-Object -Sum Length で実行を行っていますが、-Sumから-Minに変更すると最小値の計算を行えます。便利です。
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/measure-object?view=powershell-7.2


フォルダサイズの取得まで行えました。
あとは、対象フォルダに移動する・ログに残す事を行うような機能があれば良いなと思ったので、最終的に下記のようなスクリプトを作成致しました、
以下、実行イメージとなります。

```PowerShell:Sample.ps1
#フォルダサイズ取得対象
$Target_Dir = "C:\Users\Test_User\Desktop\test"
#時間の取得
$Get_Time = Get-Date -Format "yyyyMMdd_HHmmss"
#ログファイルの作成
$Log_File =  "C:\Users\Test_User\Desktop\Log\" + $Get_Time + ".log"

cd $Target_Dir

Get-ChildItem -Recurse -Force | Measure-Object -Sum Length > $Log_File
```

簡単なスクリプトとなりますが、参考になれば幸いです。
【Git】.gitignoreって難しい Part1 - .gitignoreの作成未経験者が、ある程度の理解できるまで -

# .gitignoreって？
.gitignore とは、Git による追跡から、特定のディレクトリ・ファイルを除外するための設定を書き込むファイルです。

例えば、<b>node_modules</b> は膨大な量ですし、package.json を持っているので、 npm install または yarn install によって node_module にすべてのパッケージをインストール可能です。
そのため一般的にGitで追跡する必要がなくなります。
# どうやって設定するの？
まず、 .gitと同じ階層に移動します。
<br>
■ .gitignore ファイルを生成
```
$ touch .gitignore
```
<br>

■ .gitignore ファイルに設定を記述する
```.gitignore
# Nuxt dev/build outputs
.output
.nuxt
# Node dependencies
node_modules
# System files
*.log
```
こちらはプロジェクトごとに設定されてください。
VSCode、vimエディタでも編集可能です。

ちなみにNuxt.jsでは、公式に用意されているファイルがありますので、今回はこちらを使用させていただいております。
https://v3.nuxtjs.org/guide/directory-structure/gitignore/
<br>

■ 確認
```
$ git ls-files --other --ignored --exclude-standard
```
こちらのコマンドを叩くと、.gitignore されたディレクトリやファイルが出力されるはずです。
<br>

■ 問題
最初に作り忘れていた時に、後から作成する方法は別になってきます。
この記事は後ほど作成しますー

## 感想
ひゃーーーーーーーー、Gitって色々難しいなーーーー
プログラムが書けるからエンジニア、ではなくこういう所もどんどん成長していきたいね。
最近考え方ががらりと変わってます。w
Amazon EC2を使ってNginxを起動する

# はじめに
EC2インスタンスをWebサーバ化するべく、Nginxをインストールして起動するまでのやり方をまとめました。

# やること
- Nginxをインストール
- デフォルトページをブラウザで確認
- Hello,World!を表示

🔽 Webサーバー選定についてはこちらの記事を参考にしました。
> 参考：ApacheとNginxを比較！それぞれのメリット・デメリットを解説
https://www.geekly.co.jp/column/cat-technology/1903_096/

# 環境
- EC2インスタンス
  - Amazon Linux 2 AMI, SSD Volume Type
  - t2.micro
  - 64 ビット (x86)

EC2インスタンスの作成方法に関しては、[こちら](https://qiita.com/zanigani/items/3c72359c0642521b7021)に記事を書きました。

# 1. EC2インスタンスに接続
```
$ ssh -i キーペア名.pem ec2-user@パブリックIP
```

# 2. yumをアップデート
Amazon Linux2の場合、yumを使ってNginxをインストールします。
ただ、EC2インスタンスを作成した後だとインストールに失敗するようなので、まずはyumをアップデートします。

```
$ sudo yum update
```
Complete!と出たらOKです。

# 3. インストールできるパッケージの確認
amazon-linux-extrasでインストールできるパッケージを確認します。
```
$ which amazon-linux-extras
$ amazon-linux-extras
```
↓
```
 ~ 略 ~
 38  nginx1                   available    [ =stable ]
 ~ 略 ~
```
nginx1を確認できました。

# 4. Nginxをインストール
```
$ sudo amazon-linux-extras install nginx1
```
バージョンを確認してみます。
```
$ nginx -v
nginx version: nginx/1.20.0
```

# 5. Nginxを起動
```
$ sudo systemctl start nginx
```
Nginxが起動しているか確認します。
```
$ systemctl status nginx
```
`active (running) `と出たら成功です🎉

# 6. デフォルトページをブラウザで確認
```
http://パブリックIP
```
きちんと表示されました！ﾔｯﾀﾈ！
![Screen Shot 2022-06-15 at 20.45.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1809963/36492028-ebd1-31db-5c86-2f0506900254.png)


# 7. テストファイルで表示確認
せっかくなので、自分で作成したHTMLファイルを表示させてみましょう。
まずはデフォルトindex.htmlが配置されているパスを確認します。
```
$ cat /etc/nginx/nginx.conf
```
↓
```
 ~ 略 ~
#        root         /usr/share/nginx/html;
 ~ 略 ~
```
root項目にて、`/usr/share/nginx/html` に配置されていることが分かりました。
確認したディレクトリに移動します。
```
$ cd /usr/share/nginx/html
```
index.htmlを開きます。
```
$ sudo vi index.html
```
デフォルトhtmlを書き換えたいので、`:%d`コマンドで全削除して、以下のように変更します。
```
<!DOCTYPE html>
<html lang=“ja”>
 <head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Nginx test</title>
 </head>
 <body>
  <h1>Hello, World!</h1>
 </body>
</html>
```
書き換えたら`:wq`コマンドで上書き保存します。

先程のページにアクセスします。
```
http://パブリックIP
```
無事にページが反映されていたら成功です🙌🏻
![Screen Shot 2022-06-15 at 22.47.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1809963/abf86e23-60d7-3849-eaa4-a7dbd846ff56.png)

# おわりに
HTTPサーバー(Nginx)をEC2インスタンスに構築し、簡単なHTMLを表示させることができました！この記事で使用したAWSリソースは、適宜停止・削除してください。

最後までお読みいただきありがとうございました🌸
Azure Machine Learning にたどり着けるか

Azure Machine Learning を使って機械学習に関するナレッジをシェアしよう

https://qiita.com/official-events/602a6d1bb63c59538170

Azure Machine Learning を使用して責任のある MLOps をスケーリングする Daniel Moth

https://mybuild.microsoft.com/ja-JP/sessions/cb3775d8-b5eb-4d02-8975-c376d30fdd17

同時通訳はていねいでありがたい人は大勢いるのだろう。
できれば英語だけで聴きたい。探している。

The Big Book of Machine Learning Use Cases

https://databricks.com/p/ebook/big-book-of-machine-learning-use-cases?utm_medium=paid+search&utm_source=google&utm_campaign=17451594716&utm_adgroup=138257852620&utm_content=ebook&utm_offer=big-book-of-machine-learning-use-cases&utm_ad=602764586545&utm_term=machine%20learning&gclid=Cj0KCQjwhqaVBhCxARIsAHK1tiMMep6ndmcQmMux0_j2MYrWn7rghsQLj6c5HIgfoDVqQRIlNyDS8ggaAqY2EALw_wcB


Azure Machine Learning を使用して責任のある MLOps をスケーリングする

https://docs.microsoft.com/ja-jp/events/resources/build-2022/scaling-responsible-mlops?wt.mc_id=build22_srp_breakout_azuremktg

Azure Machine Learning

https://azure.microsoft.com/ja-jp/services/machine-learning/#features

Microsoft Azure Blog

https://azure.microsoft.com/en-us/blog/

MLOps Blog Series Part 1: The art of testing machine learning systems using MLOps

https://azure.microsoft.com/en-us/blog/mlops-blog-series-part-1-the-art-of-testing-machine-learning-systems-using-mlops/

このまま延々と資料を読んでいたら、来月までに何か動かすことは不可能かもしれない。

どうしよう。
python学習 - 3日目

こんにちは★

# おしながき
今日は以下をやっていきまする。

- 変数
- 定数
- 予約語

# 変数
何かの値に名前を付けることができます！
Windowsと違って、Pythonは大文字小文字の区別つくので気を付けます。
プログラムの処理が終了するまで変数の値は保持されるので、よろしくお願いいたします。
プログラム終了後も保持したい場合は、DBとかに保存する必要ありけり。

## 変数のコード例
```実行例
command = "cat"
neko = "Cat"

print(command)
print(neko)
```


```結果
cat
Cat
```

## 命名規則
命名規則は以下の3つに分けられる。
1. スネーク
1. ラクダ
1. ケパブ

### スネークケース
へびみたいなもの。
複数の言葉をアンダーバーでつなぐ。
- hello_world
- HELLO_WORLD

### キャメルケース
ラクダみたいなもの。大文字のところがラクダのこぶ。
- helloPython
- HelloPython

### ケパブケース
櫛が刺さったケパブみたい。おいしそう。
日本人なら焼き鳥ケースで。
- hello-python
- Hello-Python

### Pythonはどれが一般的？
全部小文字のスネークケースが一般的のよう。
お好みでチーム内で統一できていれば良いと思う。
書き方をキャメルにしたからといってエラーは出ない。


## 変数はなるべく使おう
```変数使わない場合
print("cat maillog")
print("cat /var/log/messages")
```
よりも
```変数使う場合
neko = "cat"
print(neko + "maillog")
print(neko + "/var/log/messages")
```
コマンドのcatをlessとかに変えたい場合は、変数nekoを変えるだけでおわおわり。

# 定数
Pythonでは、定数はすべて大文字で書く。
変数との差別化ですね。
```例
FROM_ADDRESS = "sample@example.com"
RCIPT_ADDRESS = "user1@test.net" 
print(FROM_ADDRESS)
print(RCIPT_ADDRESS)
```

# 予約語
関数名や変数名に使用できない単語を予約語という。
Python3では、30個ほどあって、これを変数名や関数名にしてはいけないのです。
Azure MLの計算リソースの寿命は短い

普段Azure Machine Learning(Azure ML)を用いて機械学習関連の開発業務を行っています。

いつものようにブラウザからStudioにアクセスして、Computing Instanceを起動させようとしたところ起動に失敗してしまいました。

# 起動しなくなった原因
Computing Instanceを作成してから大分日が経っていたことが原因だと考えられます。
といっても1年以上放置していたわけではなく、今回は作成してから9か月経った時点でダメになりました。

このような仮想マシンは作成した時点では最新ですが、以後は自動的に不具合修正やセキュリティ更新プログラムの適用がされることはないようです。
これが積み重なり、不具合が発生して起動しなくなる事態に発展するわけですね。

# 対処方法
起動しなくなったVMはもうどうしようもなく、削除して再作成するほかありません。
当然、再作成後のVMには以前インストールしたPythonのパッケージが残っているわけもないため、
環境の再構築が必要になります。面倒ですね。
(Experimentをきちんと立てて実行するだけならVM自体の環境が汚れていくことは無いのですが、
適当にNotebookからPythonを実行する際に足りないパッケージをインストールしていくことでこうなってしまうのです)

## 環境構築の簡略化
環境の再構築の面倒さが増す原因になるのが、何を「pip install」「conda install」したか分からないということ。
というのも私は複数のプロジェクトで同じconda環境を使いまわしており、何か新しいパッケージが必要になるたびに
継ぎ足し継ぎ足しでインストールしていました。
そのため、適切にパッケージ管理が出来ておらず、VMが起動出来なくなった段階でこれまで積み上げてきた
秘伝のパッケージ達がパァになったわけですね。(猛烈に後悔しております)

これを防ぐためには、何をインストールしたのかきちんと管理してやる必要があります。

### 方法1 conda環境の管理
まず思いついたのが新規プロジェクト立ち上げ時には新たなconda環境を作成するということです。
「conda create」する際にはymlファイルにinstallするcondaパッケージやpipパッケージを記載することが出来ます。
このymlファイルを軸にパッケージの管理をしてやれば、きちんとファイルが残っているので焦る必要は無くなります。

ただし、後々新規パッケージが必要になってもymlファイルに追記してconda環境を作り直すしか無さそうなのが面倒です。
(ここをもっと簡単にする方法をご存知の方　教えてください！)

### 方法2 Notebookからの実行をやめる
先ほども書きましたが、そもそもNotebookから実行しなければ適当にパッケージをインストールして訳が分からなくなることは無くなるでしょう。
つまり、training実行時にきちんとExperimentを呼び出して実行すれば、そのソースコード等にインストールするpipやcondaパッケージ、あるいはDocker Containerの内容が残されるはずです。

とりあえず試してみるハードルが高くなってしまう、Experimentの立ち上げから実行まで時間が掛かる等のデメリットはありますが、文書としてきちんと管理出来ることのメリットは大きいはずです。

# 最後に
今回、きちんとパッケージ管理をしておくことの重要性を思い知られました。
クラウド開発に対する知識不足が招いてしまった事態ですが、これを教訓として運用方法を考えていかないといけないですね。

皆さんもご注意ください…。
Excel 帳票 最新はどれ ~ Winmarge の差分レポート一括作成 ~


複数人で帳票を編集しているとき，最新はどれって思うことありませんか？

変更時のルールが曖昧な時など，人によってファイル名に rev1 をつけて保存したり，日付を付けて保存したりと最新のファイルの名前が変化していきます。。

で・・・・，どれが最新なのかひとつづつファイルを開いて確認するのは面倒だったので，Winmarge の差分レポート作成を一括で作成するスクリプトを書いてみました。

```Bat:とあるフォルダのファイル（残念な状態）
○○台帳.xlsx
○○台帳_220610.xlsx
○○台帳_220610_rev1.xlsx
○○台帳_rer2.xlsx
○○台帳_ver2_220615.xlsx
```

## どうやって比較しようか

ファイルのタイムスタンプが近いファイルどおしは，タイムスタンプが遠いもよりは，変更箇所は少ないという考えのもと

タイムスタンプの近いもの通しで比較し差分レポートを作ります。

## Script

```Bat:GetDiffreport.bat

powershell -NoProfile -ExecutionPolicy Unrestricted -File Get-DiffReport.ps1 -filePrefix "○○台帳_" -debugMode -All

```

```powershell:Get-DiffReport.ps1
# WinmargeでエクセルDiffReportを作成する
# 初版 22.06.15 SBY

param (
    [Parameter(Position=0)]
    [string]
    $filePrefix = "AAAA帳票BBBBB_",
    [Parameter()]
    [Switch]
    $all = $false,
    [Parameter()]
    [Switch]
    $debugMode = $false
)
# ============ 初期設定 ===================
$WINMARGE = "C:\Program Files\WinMerge\WinMergeU.exe"
$WINMARGEOP = " -noninteractive -minimize "

# =========================================
$t_file = $filePrefix + "*.xlsx"

# ファイルリスト取得し降順（最新のファイルがidx=0になる）で並び変え
$files = get-childitem -Filter $t_file | Sort-Object -Property 'LastWriteTime' -Descending

if ($debugMode) {
    write-host $files.count
}

if ( $files.count -ge 2){
    # ファイルが２つ以上の時に処理する

    # $all が true：全ファイルを対象に差分レポートを作成する
    # $all が false：最新のファイルとひとつ前のファイルのみ比較する
    if ($all){
        $fidxs = 0..($files.count - 2)
    } else{
        $fidxs = 0
    }

    foreach ($fidx in $fidxs){
        $file0 = $files[$fidx]     # 最も最近のファイル
        $file1 = $files[$fidx+1]   # そのひとつ前のタイムスタンプ

        $outFileName = $filePrefix + $file0.LastWriteTime.ToString("yyyyMMdd") + "_" + $file1.LastWriteTime.ToString("yyyyMMdd") + ".html"

        if ($debugMode) {
            write-host "Inputfile1:" $file0.Name
            write-host "Inputfile2:" $file1.Name
            write-host "Outputfile:" $outFileName
        }

        # ======= winmargeの実行 ==================
        # Winmargeの引数を作成
        $args =  $file0.Name + " " + $file1.Name + " -or " + $outFileName + " " + $WINMARGEOP

        if (-not (test-path $outFileName)) {
            write-host "Winmargeで比較処理を実行します。"
            # Winmarge を実行 ，-Waitで終了まで待機
            Start-Process -FilePath $WINMARGE -Wait -ArgumentList $args
        } else {
            write-host "出力ファイルが既にあるためWinmarge比較をパスします。"
        }
    }
}
```
テックキャンプ現役受講生のアプリ開発1日目

みなさんこんにちは！今日は要件定義とDB設計をやっていました（＋読書）。学んだことのアウトプットします。本日は２つです。

# 起業家の思考法（平尾著）を読んで学んだこと
起業アイデアの出し方について書かれた本です。アプリ開発のアイデア出しに応用できるかなと思って読んでいました。主に応用できるアイデアは２つ。

１、目的を見つけ、現状を分析して、それらの差分が解決すべき課題である。
上記の文脈に合わせて、一つアイデアを出してみます。
例えば、フードロスは０の方がいいよね（目的）。⇨日本ではフードロスが年間○千万トンある（現状）。⇨賞味期限ギリギリの食材を廉価で流通させる市場を作ればいい（課題＆解決アイデア）。というような感じです。今回は何らかの問題の解決を、アプリでしようと思います。

２、自分らしさ、優秀な手法、逆説（意外性）の３つを掛け合わせたものが、素晴らしい解である。
上の３要素が合わさらないと、素晴らしい解決策にはならないということです。
・自分らしさとはそのまま個性のこと。
・優秀な手法とは、世に認められている素晴らしいやり方やこと。
・逆説はそのまま
自分らしさだけを全面に押し出しても、それは独りよがりで、優れたやり方は皆がやることなのでレッドオーシャンである。３つを重ね合わせたところアイデアが良いアイデアになると本著は言っています。

だいぶ意訳が入っているので、鵜呑みにはしないでください。

# RDBのツリー構造の作り方
youtubeやtwitterのように、コメントに対して、コメントを返すといった仕組みをどうやって作ればいいのか調べていました。コメントに対して、コメントをするということは、別の見方をするとあるコメントが親で、その下に子のコメントがつくということです。そういった親子関係のある構造のことをツリー構造と言います。RDBではツリー構造を構築するのは不向きなそうですが、４つほどツリー構造を作るための解法があるそうです。以下のサイトがよくまとめられていたので、気になる方は是非！

https://www.wantedly.com/companies/tutorial/post_articles/299434

その他参考になったサイト

https://www.slideshare.net/kamekoopa/ss-27728799

今日は眠いので、ここまでにしますが、明日は採用するDBの構造を吟味（ついでにRDB以外のDB構築方法についても少し興味が湧いたので調べます）とrailsにDB設計図の詳細を記述する予定です。
M5Stackの導入時の注意メモ

(これまでのあらすじ)
己の大願を成就せんと、紀伊の国は吉野の山中で千日の荒行を自らに課していた俺は、ある日一人の子供と出会った。
不動明王の御使いで矜羯羅童子を名乗るその子供に、M5Stackというすごいマイコンモジュールを教えてもらった俺はさっそく家に帰ると、AmazonでM5Stack Core2を注文したのだが、それは天が課した試練のひとつに過ぎなかった…

M5Stackはデフォルトでタッチ式TFT液晶ディスプレイ、Wi-Fiモジュール、6軸ジャイロセンサーなどを搭載している
まさにオールインワンといった趣のマイコンモジュールである。
さらに、拡張モジュールを重ねる(stack)ことで様々な機能を追加できるのが売りだ。

(問題 ハードウェア編)
さて、購入したM5Stack Core2にGPSモジュールをつけようと思ったところで問題が発生する。
重ねるのはいいが裏蓋が閉まらないのである。
裏蓋についている出っ張りがあっちこっちで干渉してしまい、全く閉まらない。
なんならバッテリーすらも干渉する。
仕方がないのでニッパーで出っ張りを切り飛ばし、バッテリーを本体基盤の上に置いてようやく閉まった。
ちなみに、GPSモジュールには2本のアンテナ線がついているが、片方は外部アンテナ用だ。
端子がプラプラしてると短絡して危ないので、マスキングテープを巻いておいた。
![IMG_20220611_234548 (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1831303/c58cf78f-feda-1c2a-784d-a780104c1f3d.jpeg)

![IMG_20220611_234122 (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1831303/188eed49-b857-8a00-9a00-7538c918e0df.jpeg)
さらに問題が発生する
裏蓋がネジ止め(六角穴)であるため、追加したGPSモジュールで全長が伸びてしまい、
ネジの長さが足りなくなってしまった。
![IMG_20220611_234548.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1831303/6679aa6c-44c8-d0de-e413-2962f3c36021.jpeg)

これも仕方がないのでホームセンターでM3のネジを買ってきてつけた。
ひとまず、これでハードウェア編は一段落である。

![IMG_20220611_235447 (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1831303/832ab04b-dd00-b606-dbaf-252e4d4d3945.jpeg)


(問題 ソフトウェア編)
さてハードがどうにかなったので、ネットの記事を見ながらファームウェアの更新、IDEの導入、ハードウェアとの接続を済ませる。
M5StackにはUIFlowIDEというなかなかなモダンな開発環境がついている。
いわゆるヴィジュアルプログラミングの開発環境である。
Pythonのコードを吐き出すのでそちらを直接編集することも可能だ。
![fu1157874.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1831303/35eadde2-d0ab-b846-9e0b-b12e939f2852.jpeg)

しかし、UIFlowのライブラリではGPSから取得できる情報がかなり限られている。
GPSから送られてくる電文の内容をフルサポートしていないのだ。
カッチョいいUIを備えたアプリケーションを作ろうと思った俺は少しがっかりした。
そこでGPSから送られてくる電文をPythonで解析して変換して表示を行おうと思ったのだが、
正直めんどくさい。

そこで登場するのがarduinoである。
M5Stackはarduinoでの開発も可能なのだ。
arduinoのTinyGPS++ライブラリであればGPSの電文をフルサポートしている。
さっそく俺はネットの記事を見ながらarduinoにM5Stackのライブラリをインストールしたのだった。


サンプルプログラムをコンパイルする。
これはかなり時間がかかる(5分くらい？)。
コンパイルすると自動的にリセットがかかるはずなのだが…かからない。
画面が黒くなったままである。
電源も入らない。
ムカついたのでGPIOのリセット端子に針金を差し込んで短絡させてみたがダメだった。
壊したのかとあせりまくった。

色々設定も確認したのだがうまくいかない。
しかし、3日後原因が判明する。
多くのネットの記事ではM5Stackのライブラリを入れろと書いてある。
が、購入したのはM5Stack Core2である。
M5Stack Core2のライブラリを入れなければならないのだ。
![FU7mhSRUsAAGFHG.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1831303/949fec38-b29d-462a-3cb8-347a3570d7e4.png)

M5Stack Core2のライブラリをインストールし、サンプルプログラムをローディングし、ようやく動いた。
![FU7lSokVIAEtvmM.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1831303/d22d6bd8-b657-0370-396e-6c67897f99ab.jpeg)

これは感動モノである。
これでようやく俺が作ろうと思っていたGPSマルチメーターのスタートラインに立てたわけだ
。
![IMG_20220611_235535.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1831303/423fd13a-ac2f-d815-5027-74c220231313.jpeg)

(つづく)