OmniAICreator/Qiita-1.07M huggingface dataset:
TypeScriptを基本からまとめてみた【2】【TypeScript入門】

## TypeScriptとは

- マイクロソフトが開発したオープンソース言語
- Javascript + 『型付き』= TypeScript　
- 静的型付き言語

※『Type』＝　型付の意味

## 型とは

```
//typescript

var list: String[] = [];
            ↑ 型
let suuzi : Number = 1;
　　　　　　　 ↑ 型
const name: String = "プログラミング";
　　　　　　　　↑ 型
```

## メリットは

- コンパイル時に型エラーチェックができる
- 型が付いているから可読性UP
- プログラムの処理速度が早い　　　

## TypeScriptを実行できる環境を構築する

1.フォルダを準備する。

2.フォルダの中に、新しいフォルダを作成する。

```
$ mkdir <プロジェクト名>
$ cd <プロジェクト名>
```

3.package.jsonを作成する。

```
$ npm init -y
```

4.typescriptのインストールする

```
$ npm install --save-dev typescript
```

5.tscのversionを確認する

```
$ npx tsc -v
```

6.index.tsを作成する

```
$ touch index.ts
```

```
node_modules

index.ts

package-lock.json

package.json
```

7.node_modulesが.gitignoreファイルによりgitの管理から除外されていること

① .gitignoreをファイル作成する

```
$ touch .gitignore
```
②. gitignoreにvimで無視するもの(node_modules/)を書き込む 
　　編集後ZZで保存できる
　　拡張子のない隠しファイルは $ vim(sublとかでもok) ファイル名 で編集できる

```
$ vim .gitignore
```
③ ファイル(node_modules)を残したまま管理対象(git)から外す (外すだけ)
(--cached オプションつけないと、ファイルごと削除になる)

```
$ git rm -r --cached node_modules
```
```
$ git status
$ git add .
$ git commit -m 'create .ignore and add node_modules to .ignore, and Remove node_modules from git'
$ git push origin master
```

```index.js
const output = function (text) {
  return text;
};
console.log(output('Hello World!'));
```

```index.ts
const output = (text: string): string => {
  return text;
};
console.log(output('Hello World!'));
```

8.コンパイルをする

```
$ npx tsc index.ts
```

9.tsconfig.jsonの作成と設定

```
$ tsc --init
```






## 参考サイト
[【TypeScript入門】本当の初心者からTypeScript×Webpackの開発環境構築までをハンズオン形式で学ぼう！](https://www.youtube.com/watch?v=ECc1EXnx7VQ)
C:\Users を別のドライブに移動する

# 説明
`C:\Users`が肥大化するので別のボリュームに移動したいなあ、と思った事がきっかけ。
何が起こるかわからないのと、サポート対象外となってしまうので実施するのであれば自己責任でお願いします。
Windows 10です。
# 準備するもの
- Windows のインストールされたパーティション
- 空のドライブ又はパーティション
- Windows インストールメディア (DVD-R, USBメモリ等。起動ディスクでも出来るかも)
# 手順
1. ボリューム`C:`のクローンを作成する([GParted](https://gparted.org/)等で可能)。
1. Windows を起動し、クローンのドライブレターを認識させる(`D:`等)。
1. シャットダウンし、Windows インストールメディアからセットアップを起動する。
    (UEFIインストールされている場合、UEFIで起動する)
1. 修復ツールからコマンド プロンプトを起動する。
1. 元のドライブの`C:\Users`を`C:\Users_`等にリネームする。
    ※`C:`が元の Windows の(クローンではない方の)ボリュームであるかどうかは DISKPART 等で確認した方が良い。
    ```
    C:\>REN Users Users_
    ```
1. `C:\Users`からクローンの`Users`へのジャンクションを作成する。
    ```
    C:\>MKLINK /J Users D:\Users
    ```
1. 再起動し、`C:`から元々のユーザーでサインインする事ができたら、必要に応じ`D:\Users`以外のディレクトリを削除する。
    SYSTEM管理のディレクトリは権限が必要になるので、エクスプローラからディレクトリのプロパティを開き"セキュリティ"タブから"詳細設定"をクリック
    所有者をログイン ユーザーに変更し、Usersのアクセス許可をフル コントロールに変更、
    "子オブジェクトのアクセス許可エントリすべてを～"にチェックを入れて"継承を有効化"をクリックしてUsersに権限を与えれば良い。

# 補足
- ボリュームのクローンの代わりにROBOCOPYで`C:\Users`をコピーしてみたが、上手く起動できる時とできない時があった。
    ```
    C:\>ROBOCOPY Users D:\Users /E /COPYALL /SJ /SL /R:0
    ```

# 注意
- 失敗すると元に戻すのが困難になる場合あり。
- アプリケーションによっては動作が不安定になる。
    恐らく、レジストリ等で`C:\Users\～`と`D:\Users\～`が別々に扱われる。
    Thunderbird では受信トレイや検索フォルダが重複するものが増えた。ツールバーとコントロールをリセットして回復した。
- Windows Updateや Windows のアップグレード等が正常に動作しなくなる可能性あり。
- マイクロソフトが対策を入れてくる可能性あり。
MediaWikiの折り畳み機能を使ったページをPDF化した際に見やすくする

時々使いたくなるのだがいつも方法を忘れるのでメモ。MediaWikiの[折り畳み機能](https://www.mediawiki.org/wiki/Manual:Collapsible_elements)を使ったページを印刷しようとしたら折り畳み部分が見えなくて困ったので、JSで全部開いてみました。chromeのコンソール等にコピペしやすい形にしています。

# コード例
```javascript
document.querySelectorAll(".mw-collapsible-content").forEach((e) => e.style.display = "block")
document.querySelectorAll(".mw-collapsible").forEach((e) => e.style.width = "100%")
document.querySelectorAll("pre").forEach((e) => e.style.whiteSpace = "pre-wrap")
```

# 補足
- IE11はNodeListにforEachが生えてなかったと思うので、いったん配列に乗せ換えるなどの対策が必要。これについてはいろんな方法があるのと、最新事情をあまり分かってないので適宜調べ直した方がよい。
- querySelectorAllの戻り値はNode Listというもので、ライブではないので、一度戻り値を保持した後にDOM要素が増えたりした場合、その増分を操作する際は再度querySelectorAllを呼ぶ必要がある。getElementsByXXX系はDOM要素の増減に応じて戻り値 (HTML Collection) の要素数が変わるので、そういう使い方をしたい場合はそちらを使うと良いらしい。
BlenderからUnityにモデルを移行する際、マテリアルがピンクになる現象

[事象]
BlenderからUnityにモデルを移行する際、マテリアルを割り当てようとするとピンク一色になってしまう。

[解決方法]
移行してきたモデルがプレハブの状態であることを確認する。
その後、マテリアルを割り当てる。
※アンパックプレハブした後にマテリアルを割り当てると、ピンク一色になる。
M1チップ　Mac Book でimport talib ができない時の解決策

2022/04/03

システムトレードでの需要が高いtalibをimport しようとしたところpipを使用しても入らず、かなり時間を要したので自分用メモ

```bash
conda install -c conda-forge ta-lib -y
```


### 参考

https://github.com/mrjbq7/ta-lib/issues/408
Ajax通信が今どの状態にあるかチェック

JSONファイルの読み込みが終わってから処理をしたい，などの場合が多々あるので備忘録
例えば下記の例

```js
var ajax = new XMLHttpRequest();  

    //処理

ajax.onreadystatechange = function() {
    // 処理
};
```

XMLHttpRequest.readyState プロパティは今の読み込み状況を0〜4で表してくれる

0ー UNSENT **インスタンスができた**
1ー OPENED **openメソッドを利用した**
2ー HEADERS_RECEIVED **ヘッダーが受信できた**
3ー LOADING **データを受信中**
4ー DONE **通信が終了**

例として，alert(ajax.readyState)を入れ状況を見てみると下記のようになる

```js
var ajax = new XMLHttpRequest();　　// XMLHttpRequestオブジェクトを作成
// ここの場合は0
ajax.open('GET', 'http://jsonファイル');
//ここの場合は1
ajax.responseType = 'json';
ajax.send(null);

ajax.onreadystatechange = function() {
    alert(ajax.readyState) // ここの場合はajax.send(null);後の2~4が順番に表示される
};
```

## Ajax通信が完了したのを待ってからレスポンスを返す場合

```js
var ajax = new XMLHttpRequest();
ajax.open('GET', 'http://jsonファイル');
ajax.responseType = 'json';
ajax.send(null);


ajax.onreadystatechange = function() {
    if(ajax.readyState === XMLHttpRequest.DONE && ajax.status === 200) {  
       //XMLHttpRequest.DONE = 通信状況4のこと
       // 処理 
    };
};
};
```

## JQueyを使えば簡単になる
```js
// jquery読み込んでから
$.getJSON('https://jsonファイル', function(data) {
    //処理
});
```
とすれば，JSONファイルの通信が終わってから処理することができる
Ruby 試験対策　例外処理編

# 基本形
第一引数、`例外クラス`、第２引数,`エラー文`
```
raise 例外クラス、ORそのインスタンス　, "エラー文"
```
※第一引数は、省略可能。その場合は、`RuntimeError`クラスの例外が発生。
ただ、このままだとエラーが発生した場所で止まってしまう。
## RuntimeErrorとは
特定の例外クラスには該当しないエラーが発生した場合や例外クラスを省略した場合などに起こる

## 変化形
```
err = 例外クラス.new("エラー文")
raise err
```
## 例外処理のbegin
```
begin
 通常はここが実行
rescue
　　エラーがあれば、実行
else
　　通常が実行されれば、実行
ensure
　　絶対の実行
end
```

参考図書
[Ruby技術者認定試験合格教本（Silver/Gold対応）Ruby公式資格教科書](https://gihyo.jp/book/2017/978-4-7741-9194-2)
アルゴリズムの勉強

線形探索法・・・大量のデータの中から特定のデータを探し出す。
　　　　　　　　１つ１つの要素を順に調べていく方法。

入力　データの数
　　　探したいデータ
出力　データがあればデータがある配列の番号、データがなければデータなし
　　　数列の最小値

    // 線形探索法
    void LinearSearch()
    {
	    int data_num;						// データの数
	    int data_target;					// 探したいデータ
	    int data_min = 20000000;			// 最小値を保存する
	    int find_index = -1;				// 見つけた配列の番号
	    std::vector<int> data;	// 配列

	    // データの数と探索する値を入力する
	    std::cin >> data_num >> data_target;

	    // データを格納する
	    data.resize(data_num);
	    for (int i = 0; i < data_num; i++)
	    {
		    data[i] = rand() % 100;
	    }

	    // 線形探索
	    bool exist = false;
	    for (int i = 0; i < data_num; i++)
	    {
		    // 一致するデータが見つかったら
		    if (data_target == data[i])
		    {
			    // データある番号を保存する
			    find_index = i;
			    exist = true;
		    }

		    // 探索している値が今の最小値より低ければ、最小値を更新
		    if (data[i] < data_min)
		    {
			    data_min = data[i];
		    }
	    }

	    // 出力
	    if (exist)
	    {
		    std::cout << "データが : " << find_index << "番目のある" << std::endl;
	    }
	    else
	    {
		    std::cout << "データなし" << std::endl;
	    }
	    std::cout << "最小値 : " << data_min << std::endl;
    }
MacのFinderで.gitや.gitignoreが見えない時

Finderで該当フォルダを開いたあと、以下ショートカットキーを押す。
```
“command + shift + .(dot)”
```

見えるようになりました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533960/03411777-c014-3033-b9a7-91076b196eb1.png)
MicrosoftStore から Ubuntu20.04 が インストールできない　コマンドでインストールする方法

# はじめに

経験したエラーや躓いたこと、その解決法についてアウトプットしたいと思い始めました。
未経験でエンジニア転職し日が浅く、至らない部分が多い記事だと思いますがご容赦ください。

# やりたいこと
Linuxディストリビューションをコマンドでインストールする。
（Ubuntu20.04）

# 先に結論
Ubuntu20.04をインストールする場合
```:powershell
curl.exe -L -o ubuntu-2004.appx https://aka.ms/wslubuntu2004 
```

このコマンドでダウンロードされる。
ダウンロードが完了したら、下記コマンド

```:powershell
Add-AppxPackage .\app-name.appx
```
app-nameの部分好きに変更する。

以下、背景や状況の詳細



# 実行環境
・Windows Pro 
・バージョン21H2
・OSビルド19044

# 背景
Docker上にLaravel sailで環境構築した際のこと。
自宅PCでは難なく環境構築が行えたが、
会社PCにてMicrosoftStoreからLinuxディストリビューションがインストールできず
キャッシュ削除や[Microsoftサポート](https://support.microsoft.com/ja-jp/account-billing/microsoft-store-%E3%81%AB%E3%82%A2%E3%83%97%E3%83%AA%E3%81%8C%E8%A6%8B%E3%81%A4%E3%81%8B%E3%82%89%E3%81%AA%E3%81%84-%E3%81%BE%E3%81%9F%E3%81%AF%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84-ca530de4-cd19-f728-dae7-7368fab8df4d)など試すも解決に至らない。
コマンドでインストールすることにしたが、
方法を調べるのに時間がかかった。

【Dockerとは、、】
使用しているPC上に複数の隔離された環境を構築する軽量なコンテナ型の仮想技術。
Dockerを使用するにはLinuxカーネルが必要となる。
WindowsでLinuxカーネルを動かす為にはWSL2（WIndows Subsystem for Linux）
をダウンロードする。
そこまでの手順は以下。ここでは割愛。
[WSL の手動インストール手順](https://docs.microsoft.com/ja-jp/windows/wsl/install-manual)

## 発生した問題
上記の通りWSL2を設定したのち、
手順6の - 「Linux ディストリビューションをインストールする」で、
Microsoft StoreからUbuntuのインストールを試みるも下記画面になりインストールできない。



<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2553351/f0627c45-7778-12c2-85b7-ef44c1e066bd.png">

手順6のリンク押下しても同じ。
（（なぜできないかは不明です。。"(-""-)"
# 結論
[WSL の手動インストール手順](https://docs.microsoft.com/ja-jp/windows/wsl/install-manual)の下部にトラブルシューティングがあった。
手順6以降ちゃんと最後まで読んでいなかった。。。


Ubuntu20.04をインストールする場合
```:powershell
curl.exe -L -o ubuntu-2004.appx https://aka.ms/wslubuntu2004 
```

このコマンドでダウンロードされる。
ダウンロードが完了したら、下記コマンド

```:powershell
Add-AppxPackage .\app-name.appx
```

（app-nameの部分
ubuntu20.04の場合ubuntu-2004とかにしました。.appxは変えない。）

これでインストール完了('ω')ノ
SwiftでMultipeer Connectivityを使ってUIImageを送信する

# 目次
- [はじめに](#はじめに)
- [環境](#環境)
- [sendメソッドでのUIImageの送信は時間がかかる](#sendメソッドでのUIImageの送信は時間がかかる)
- [UIImage送信をスムーズに行う為の解決策](#UIImage送信をスムーズに行う為の解決策)
- [参考コード](#参考コード)
- [さいごに](#さいごに)

# はじめに
SwiftでMultipeer Connectivityを使用してUIImageを送信する方法をまとめました。
Multipeer Connectivityの基本的な使い方はこちらの記事を参考にしました。
→[Multipeer ConnectivityでのP2P通信（Swift）](https://qiita.com/am10/items/e56c2bc6eaab75bc9c8c)

# 環境
- Xcode13.2.1
- Swift5

# sendメソッドでUIImageを送信すると時間がかかる
MCSessionクラスの[sendメソッド](https://developer.apple.com/documentation/multipeerconnectivity/mcsession/1406997-send)でUIImageの送信を行う場合は、文字列の送信と比較するとデータ量が大きい為、時間がかかります。

5枚のUIImageを一度に送信した場合には、送信が完了するまで30秒〜2分程度かかりました。
(文字列を送信した場合は1秒もかからず処理が完了します。)

sendメソッドはData型であれば文字列に限らず送信できますが、
**UIImageを複数送信したい場合には、適切な方法ではなさそうです。**

# UIImage送信をスムーズに行う為の解決策
ここからはUIImageをスムーズに送信する為の方法について、私が試したものを記載します。

①sendResouceメソッドを使用する
Multipeer Connectivityには[sendResource](https://developer.apple.com/documentation/multipeerconnectivity/mcsession/1407056-sendresource)というメソッドが用意されています。
こちらを使用すれば、多くの場合スムーズなUIImageの送信が可能になります。
特別な事情がない限りはこちらの方法がおすすめです。

※ただしこの方法の場合は、**引数にresourceのurlを指定する必要がある**ので、
FileManagerを使ってアプリ内部のディレクトリに画像を配置する等、**UIImageをURLに変換して管理する必要があります。** (FileManagerで管理する方法は[こちら](https://develop.hateblo.jp/entry/iosapp-uiimage-save)が参考になりました。)
\
\
②sendメソッドを複数回呼ぶ方法で実装する
UIImage複数を1つのDataとして送信するのではなく、***UIImage1つにつき1回ずつsendメソッドを呼ぶと、送信速度が速くなりました。***
(反対に、一度に送信するDataの量が大きすぎると、通信処理が途中で止まってしまうこともありました。)

私は画像をUIImageのまま管理したかったので、sendResouceメソッドは使用せずこちらの方法で実装しました。
この方法でも処理はまあまあ重くなってしまうので、インジケータを実装したり、処理をしつつユーザーを次のアクションに進ませる等の工夫が必要だと思います。
\
\
③OGP画像として送信する
OGP画像ならString型で画像を管理できデータが軽くなる為、送信しようとしているデータがOGP画像で代替できる機能を提供している場合は、この方法を検討しても良いかもしれません。

# 参考コード
sendメソッドを使用した場合の参考コードを載せておきます。

```
// UIImageの配列を用意する
let animalImageList = [UIImage(named: "cat"), UIImage(named: "dog"), UIImage(named: "monkey")]
            
// 配列をfor文で回す
for animalImage in animalImageList {
    // UIImage型からData型に変換する
    if let imageData try! NSKeyedArchiver.archivedData(withRootObject: animalImage, requiringSecureCoding: false) {
        do {
            // sendメソッドでData型にした画像を接続中の別端末に送信する。
            try self.session.send(imageData, toPeers: self.session.connectedPeers, with: .unreliable)
        } catch let error {
            // 失敗した場合はこちらに入る
            print("エラーだよ：\(error)")
        }
    }
}
```

# さいごに
Multipeer Connectivityは端末同士のP2P通信でデータを送信できる便利なフレームワークです。
UIImageの送信については他にもっと良い方法があるかもしれませんが、私の書いた方法が少しでもお役に立てば幸いです。
Raspberry pi へOpenCVのインストール

OpenCVをインストールしようとしてうまくいかなかったので、OSのクリーンインストールから再挑戦したので、そのメモとして残しておきます。

インストールしたのは、bullseye(32bit版 DeskTop1)です。Raspberry Pi Imager v1.7.1でイメージを書き込み、ラズパイにSDカードを挿して、起動。初期設定とアップデートをまずやって、キーボードとマウスをまず片付けたいので、VNCを有効にしました。

VNCを有効にしても、HDMIケーブルを挿して、モニターをつけておかないと、ノートPCに画面が来ないので`/boot/config.txt`を書き換えます。


    # uncomment if hdmi display is not detected and composite is being output
    # hdmi_force_hotplug=1

この部分をuncommentすることで、VNCで繋がります。ただし、解像度は低いです。現時点で、この解像度を上げる方法が分かりません。

    # uncomment if hdmi display is not detected and composite is being output
    hdmi_force_hotplug=1

それは置いておいて、早速OpenCVのインストールをしてみます。
そぞらさんのブログを参考にしました。

https://sozorablog.com/opencv_install/

しかし、エラーが出て、インストールが成功しません。numpyが文句を言っているようです。
そこで、文句で検索したら

https://qiita.com/electronics_diy721/items/d09d49fc6c554612b253

こちらの記事で、numpyをインストールし直したらエラーが出なくなりました。
JupyterLab をインストールしてみる


# JupyterLab を使う(作業メモ)
## Windows に python を入れる
Windows Store で python を検索すると python 3.10 というのが出てくるのでインストールする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306041/a76a6a43-f981-6551-b745-e9c7ecabf727.png)

あれ？Jupyter Notebook じゃなかったっけ？？？Notebook が機能アップして Lab になったの？どうもそうらしい。んじゃ JupyterLab で。

## JupyterLab をインストール
コマンドプロンプトで
```cmd:
C:\Users\bun> pip install jupyterlab
C:\Users\bun> pip install jupyterlab-language-pack-ja-JP
```
2行目は日本語環境の追加です。

## インストールした JupyterLab のパスを確認
そして JupyterLab がどこへインストールされたのか探します。(検索でも、Everythingでも構いませんが) 折角なので python を使いましょう。
スタートメニューで python を起動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306041/73e700fd-5665-79f4-44b9-751e5bf54605.png)
ぽちぽちと打って最後にエンターを叩くと
```python:jupyter-lab.exe のパスを探す
import os
targetDirPath = os.environ.get('LOCALAPPDATA')
for dirPath, dirList, fileList in os.walk(targetDirPath):
  for fileName in fileList:
    if fileName == 'jupyter-lab.exe':
      print(dirPath + "/" + fileName)

```
暫く待つと実行ファイルのパスが表示されます。
実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306041/8bcebcd2-98b4-0c3e-4a6a-44eec3d6c352.png)

## jupyter-lab の起動
コマンドプロンプトに先ほど表示されたパスを入力します。
```cmd:jupyter-lab.exe を起動
C:\Users\bun>%LOCALAPPDATA%\Packages\PythonSoftwareFoundation.Python.3.10_<ランダム>\LocalCache\local-packages\Python310\Scripts\jupyter-lab.exe
```
そうすると、自動的にブラウザが開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306041/ad0be9b0-75c0-d002-66a3-56507eeafbbf.png)

ブラウザが開かない場合は、jupyter-lab.exe を叩いたコマンドプロンプトの最後に URL (localhost や、127.0.0.1 と書かれているもの) が表示されていますので、それ (どちらでも、一方) をブラウザで開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306041/59b958c3-0a5e-0d8d-5a1b-0c0fd4bc44fc.png)

## メニューの日本語化
画像の通りですが、Settings から Language → Japanese (Japan) - 日本語 (日本) を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306041/41eba9e1-1ef8-056e-e127-d501a9b4e112.png)

言語を変更するにはリロードが必要だけど、リロードして良いか？と聞かれるので、まだ何もしてないし、Reload をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306041/54b25413-612c-4163-1c18-ddeafb5f231e.png)
暫く待つと、幾つかのメニューが日本語化された状態で画面が更新されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306041/cf0455b9-e21c-e22c-ef2f-aa4497adf8fd.png)

## 何か実行してみる
ランチャーの Notebook をクリックしてウィンドウを開く。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306041/16dc5e9c-8078-54bf-3f6b-33dc935d2d2f.png)
Untitled というウィンドウが開きます。
試しに jupyter-lab.exe を探したコマンドを入力してみます。(四角い入力欄 = cell へ入力)
コマンドを入力した後に上部の ᐅ を押すと実行されます。([Ctrl] + ⏎ でも構いません)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306041/93ccd72a-b6fe-af67-bb6e-43359d07d68f.png)

## 何故書いたの？
[Installing Jupyter](https://jupyter.org/install) では `jupyter-lab` だけで起動するように書いてありましたが、パスが通って無くて起動しなかったのでメモ書きでした。
Qiita記事のサンプル

# はじめに
この記事はQiitaで記事を書く際の個人用テンプレート兼Markdown記法の備忘録です。
<!-- このようにコメントを記載することができます -->

# 記載例
以下はMarkdownの記載例です。

段落に合わせて右側に自動的にリンクができるようです。段落は１段階ごとに落としていった方がリンクが自然になります。

## 文体
- 文字を**Bold**で書く。
- 文字を _Italic_ で書く。（アンダースコアの前後には空白が必要）
- 文字を~~打ち消す~~。

## リンク
- Google検索は[こちら](https://www.google.com/)からどうぞ。

## 注釈
- 文章に注釈をつけたい場合はこのようにします。[^1]
[^1]: ここに注釈を記載します。

## 引用
下記の文章は引用です。
> 引用文はこのように表示されます。

## 折り畳み
<details><summary>ここに折りたたまれている</summary>

折りたたまれた部分で _Markdown_ を使用するには空行を一つ入れる必要があります。
</details>

## コードブロック
コードブロックを記載する例。
コードブロック内に「#」から始まる行を入れると右側のリンクが崩れてしまう。[^2]
[^2]: コードブロックの前後に空白行を入れると回避できるようです。[参考情報はこちら](https://github.com/increments/qiita-discussions/discussions/202)

```shell:sample.sh
# echo 'Hello World!!'
```

## 状態遷移図
[Mermaid](https://mermaid-js.github.io/mermaid/#/)というツールのSyntaxで図を書くことができる。
```mermaid
stateDiagram-v2
　　s1: ご機嫌
 s2: 仕事
 s3: 不機嫌
 s4: 休憩
　　s1 --> s2
 s2 --> s3
 s3 --> s4
 s4 --> s1
```

## テーブル
テーブルのサンプル
| Column1 | Column2 | Column3 |
| --- | --- | --- |
| Data1-1 | Data1-2 | Data1-3 |
| Data2-1 | Data2-2 | Data2-3 |

# 最後に
ここにまとめを書きます。
courseraのMachine Learning講義を受けてみた1

# 前提
機械学習について学習しなくては行けない理由ができた。だから、いろんなサイトを検索した結果、まずはcourseraのMachine Learning講義を受けてみた。

タダだから皆さんもぜひ。

受けるだけではいけないから、感想兼知識整理としてこの記事を投稿する。

# 1週目
## What is Machine Learning?
### 機械学習の定義
ある課題Tについて、ある性能基準 P に基づき、もし T についての性能が基準 P で測定して、経験 E と共に改善している場合に、 経験 E から学習したと言うことが出来る。

### 機械学習の分類
教師あり学習と教師無し学習の主に2つだけ。

## 教師あり学習
データセットに正しい答えが与えられている学習。
### 回帰問題
一種の連続的な属性の値を予測すること。

例としては、敷地面積から、土地の価格を予測することなどがある。

### 分類問題
離散的な値を予測すること。

例としては、腫瘍の大きさから、癌か否かを予測することがある。

別に二値である必要はなく、癌の種類が3つあってそのどれに当てはまるかを予測する場合も分類問題に当たる。

## 教師無し学習
クラスタリングとほぼ同じかな。

ラベル（正解）の与えられていないデータセットをクラスタリングする（規則性を見つけてグループに分ける）ことで正解を予測する。

### 非クラスタリング
カクテルパーティーアルゴリズムが挙げられる。

2つのマイクを用意し、福数人の会話を録音すると、大きさは異なるが同じ波形のデータペアが見つけられる。

これにより、雑音を取り除き、一人一人の声を抽出できる。

これも教師無し学習。

## プログラミング言語　Octive
オープンソースソフトウェアであるのはもちろんだが、特に機械学習においてはかなり簡略化されたコードで書けるため、試作する上では非常に重宝する。

試作をOctiveで作り、それを他の言語に移植するのが吉。

##Model representation
### 代表的なシンボル（お作法）
### m
訓練サンプルの総数
### x
入力変数。特徴量とも呼ぶ
### y
出力変数。目標変数とも呼ぶ。
### i
訓練データの順番。
### h
仮説(hypothesis)。ただ、昔の呼び方が定着してしまったため、分かりにくい。

データセットをアルゴリズムにつっこうんだ時とき、導き出される関数のこと。

つまり、y=h(x)となる。ちなみに、この関数の定数はθを用いる。

### 線形回帰
結局何を求めているかというと、
h(x)=ax+bのとき、yーh(x)が誤差であるわけだが、

J(a, b)＝1/2m*Σ（y-h(x))^2が最小となるようなa,bを求めているのだ。

これを最小二乗法という。また、J(a, b)を目的関数という。

## 最急降下法
### アルゴリズム
```
repeat until convergence{
  Θ := Θ + α＊(J(a,b)の導関数）　　　（Θはaかb)
  //αは学習率を指し、大きいほどθの変化がでかい
}
```
:=は代入を表す。
こうするとどんどんa,bが変化していくのだが、例えば(a,b)=(1,3)でa := 1 +J`(1,3) =3となったとき、b:=3+J`(3,3)にしてはいけない点だ。

必ずb:=3+J`(1,3)とし、同時進行性を持たせること。

この式は傾きに着目している。

例えば、変数を減らしてJ(a)=(a-2)^2+3の二次関数だとする。ちなみにmin J(a)はa=2のとき。

最急降下法のスタートがa=5のとき、a=5の点でのJの傾きは正である。よって、

a := a + αJ`(a)の式において、αJ`(a)＞0であるため、代入されるaは5より小さい。

するとどうだろう。aはa=2に近づいたことになる。これが最急降下法の原理である。

学習率αが小さいと、計算に時間がかかるが、大きすぎると最小値を飛び越してしまう。注意が必要。

ただ、αを変化させる必要があるかと言えばNoである。なぜなら、最小のaに近づくにつれて傾きは小さくなるため、勝手にJ`の項が小さくなるからである。

よくできたアルゴリズムである。

これは、すべてのデータセットを毎回代入することから、バッチ勾配降下法という。

### 一瞬だけ用語整理
勾配降下法∋最急降下法＝バッチ勾配降下法

## 行列
縦3、横4の行列を3＊4行列と呼ぶ。

また、n*1行列をベクトルと呼ぶ。

### 行列同士のかけ算
m*n行列とn*1ベクトルのかけ算なら行うことができる。答えはm*1のベクトル

```
A = [[2, 3, 5],
     [1, 3, 6]]
B = [[1],
     [2],
     [3]]

A*B = [[2*1 + 3*2 + 5*3],
       [1*1 + 3*2 + 6*2]]
```
つまり、行列の順序を入れ替えると計算が行えない

これを用いるととんでもないことが起きる。


例えば、y = 10 + 8xであり、x = 5, 6, 2などを代入したいとする。

ループでやっても勿論良いのだが。
```
A = [[1, 5],
     [1, 6],
     [1, 2]]

B = [[10],
     [8]]
```
とするとどうだろうか。簡単に計算結果がベクトルとして得られるのだ。

### かけ算の注意点
A*B != B*A

(A*B)*C = A*(B*C)

### 単位行列
スカラー量同士のかけ算においての1のような行列のこと。

正方行列で、
```
I = [[1, 0, 0]
     [0, 1, 0]
     [0, 0, 1]]
```
などを指す。


単位行列をIとしたとき

A*I =　I*A　= A となる

ただし、Iの次元はそれぞれ異なるが、、、

### 行列の逆数
Aが正方行列（m*m行列）であるとき、
A*B = IとなるようなBをAの逆数と言う。

手計算ではかなりしんどい

また存在しない場合もある。

### 行列の転置
行列Aに対して、行と列を入れ替えたような行列BをAの転置と呼ぶ。
【Nuxt.jsとTypeScriptにStorybookを導入】Github ActionsでS3にデプロイする

## はじめに
この記事では以下のことを行います。
<ul>
<li>Nuxt.jsでTypeScriptやComposition-APIが使える環境を作る</li>
<li>Github ActionsでCI/CDを行う</li>
<li>AWSのIAMの作成を行う</li>
<li>AWSのS3の作成を行う</li>
<li>Github Actionsを使うための設定をGithub上で行う</li>
</ul>

## Github

https://github.com/ssk9597/Clone_Nuxtjs_TypeScript_Composition-API_Storybook_GithubActions

こちらのGithubをクローンすることで、以下の2つが作成できます。
<ul>
<li>Nuxt.jsでTypeScriptやComposition-APIが使える環境を作る</li>
<li>Github ActionsでCI/CDを行う</li>
</ul>

それでは、S3にデプロイできるようにAWSの設定をしていきましょう。

## AWSのIAMの作成を行う
### 1. AWSにルートユーザーでログインを行う
ルートユーザーを作成していない方はこちらの記事から作成を行ってください。

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_root-user.html

ログインしました。

![スクリーンショット 2022-03-30 17.11.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/838372/207d4316-bfca-3db7-fb7d-635dab51e9dd.png)

### 2. IAMにアクセスする
ここでユーザーを追加します。

![スクリーンショット 2022-03-30 17.15.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/838372/c88f900a-3901-82bc-9126-b02e33bf06e7.png)

ユーザーには、S3のフルアクセスを付与します。
![スクリーンショット 2022-03-30 17.16.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/838372/f06b91eb-50b2-3fc1-85a6-b11f8bbe217c.png)

ここで、`アクセスキーID`と`シークレットアクセスキー`が発行されるので忘れないようにしてください。
![スクリーンショット 2022-03-30 17.20.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/838372/beadd713-040a-7f76-d6e8-099d85480bde.png)

## AWSのS3の作成を行う
### 1. S3にアクセスする

![スクリーンショット 2022-03-30 17.25.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/838372/555d85fd-af6b-7272-b2ad-4ed4b4953d07.png)

### 2. バケットを作成する
設定を変更する箇所を赤枠で囲っています。

![スクリーンショット 2022-03-30 17.30.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/838372/d650486c-357c-cf1e-c5ee-8ab248f89201.png)

![スクリーンショット 2022-03-30 17.31.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/838372/062b3782-00d2-f9a9-9b12-c9ab2040154d.png)

### 3. バケットポリシーを作成する
バケットポリシーに関しては以下の記事をベースに作成します。

https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/WebsiteAccessPermissionsReqd.html#bucket-policy-static-site

今回は以下のようにしました。

![スクリーンショット 2022-03-30 17.38.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/838372/b1619992-3453-de17-4e3d-ec49c2797d43.png)

### 4. 静的ウェブサイトホスティングができるように設定を行う

バケット内のプロパティを選択します。
![スクリーンショット 2022-03-30 17.40.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/838372/2a0974f5-81fe-e4b7-d8a8-7731e3311a89.png)

設定は以下の通りに行います。
![スクリーンショット 2022-03-30 17.41.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/838372/2d75464f-6be7-2663-e480-55f8ba73a764.png)

これで完了です。

## Github Actionsを使うための設定をGithub上で行う
Github Acrionsのworkflow内のパラメータの指定で`${{ secrets.〜 }}`とある記述は、すべてセキュアな情報です。
IAMのアクセスキーなどのセキュアな情報は workflowファイル内に直接書かず、ここに登録して参照するようにします。
![スクリーンショット 2022-03-30 17.48.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/838372/fd2b4ac2-94f2-6827-9c18-7776d5e64307.png)
FireStoreの値を取得する

## FireStoreの学習をやってみた。
**参考にしたサイト**
日本語の記事（こちらを参考にした）
https://flutternyumon.com/firestore-get-realtime-data/
**公式ドキュメント**
StreamBuilderについて書かれた公式ドキュメント
https://api.flutter.dev/flutter/widgets/StreamBuilder-class.html

**開発環境**
- macOS Monterey
- flutter2.10.3

**やろうと思った理由**
Firebaseとの接続をするときの知識が、まだ足りていないので、StatefulWidgetで先ずやってみようと思った。
コピペだけだと勉強にならないので、コードを書き換えたりFirebaseのフィールドを追加してみた。

main.dart
```dart
//ソース
import 'package:firebase_core/firebase_core.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  //ステップ１
  final _firestore = FirebaseFirestore.instance;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('Chat')),
        body: SafeArea(
          //ステップ２
          child: StreamBuilder(
            stream: _firestore.collection('messages').snapshots(),
            builder:
                (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
              if (snapshot.hasError) {
                return const Center(
                  child: Text('取得できませんでした'),
                );
              }

              if (!snapshot.hasData) {
                return const Center(
                  child: Text("Loading"),
                );
              }

              return ListView(
                children: snapshot.data!.docs.map((DocumentSnapshot document) {
                  Map<String, dynamic> message =
                      document.data()! as Map<String, dynamic>;
                  return Card(
                    color: Colors.grey[100],
                    child: ListTile(
                      title: Text(
                        document['text'],
                        style: const TextStyle(
                            fontSize: 20,
                            fontWeight: FontWeight.bold,
                            color: Colors.black87),
                      ),
                      subtitle: Text(document['subtext']),
                    ),
                  );
                }).toList(),
              );
            },
          ),
        ),
      ),
    );
  }
}
```

![スクリーンショット 2022-04-03 15.19.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2303722/cccd5c5d-658f-8239-8aec-ae87217a7c48.png)

**Cloud Firestore データモデル**
文字の書き方が理解できた気がする🤔

```
messages:
  text: ""
  subtext: ""
```

公式のドキュメント
https://firebase.google.com/docs/firestore/data-model?hl=ja#documents

ドキュメント内の複雑なネストされたオブジェクトはマップと呼ばれるらしい?
ドキュメントは JSON によく似ており、実際基本的には JSON と同じです。
一般的にドキュメントは軽量の JSON レコードとして扱うことができます。
RDBと構造が違うから、慣れるまでは難しそう...
【C】初めてのC言語（3. ポインタ）

# はじめに

* これまでの学習に続いて、今回はポインタなどについて学んだ結果をまとめてみました。
  * [【C】初めてのC言語（1. Hello world）](https://qiita.com/nkojima/items/518c1a4ec06861d74b3c)
  * [【C】初めてのC言語（2. 四則演算とフォーマット指定子）](https://qiita.com/nkojima/items/36ea93b7296ce9e8a55b)


# 学習環境

* 今回は[paiza.io](https://paiza.io/ja/projects/new)のC言語のエディタを使いました。

# ポインタとは

## ポインタの必要性

* [こちらのサイト](https://www.cc.kyoto-su.ac.jp/~yamada/programming/pointer.html)にはポインタの必要なシーンが以下のように説明されています。
* 私のようなC言語の初学者にはこの説明だけだと理解が難しいですが、ここは軽く読み飛ばして先に進んでみます。

1. 関数に「参照渡し」という形で引数を渡す場合
1. ヒープ領域を使う場合
1. 関数自体をデータとして扱う場合

## 変数とアドレス

* メモリ上のデータは8ビットを1まとめにした1バイト単位で扱われます。
* メモリ上のデータにアクセスするには、バイト単位で付与されたアドレスを指定します。
  * ビット単位ではデータにアクセスできません。
* メモリ上のアドレスは通常16進数で表されます。
  * 例えば「0x7ffe3f1afd5c」などの形で表されます。
* 変数には様々なデータ型があり、それらは全てバイトの整数倍のメモリサイズで表されます。
  * int型：4バイト
  * float型：4バイト
  * double型：8バイト

## 変数とポインタ

* 変数名の前に「&」という記号を付けると、その変数に割り当てられたメモリ上の領域を「ポインタ」という形で得られます。
  * 「&」はアドレス演算子と呼ぶそうです。
* 「\*&a」のように、ポインタ値の前に「\*」を付けることで、そのポインタが指している変数を参照できます。
  * 実際の変数を直接参照するのではなく、ポインタを介して参照しているので「間接参照」と呼ぶそうです。
  * 「\*」は間接参照演算子と呼ぶそうです。
* ポインタ値を格納するポインタ変数は、`int* a_ptr`もしくは`int *a_ptr`というように宣言することが出来ます。
  * `int *a_ptr`を使うと紛らわしいので、ここでは`int* a_ptr`を使っています。

# サンプルコード

* 以下のコードを作ってみましたが、まだポインタの利点などを理解できていない状態です。
  * 今後学習を進めれば少しずつ理解できるのでしょうか？

```c:main.c
#include <stdio.h>
int main(void){
    int a=3;
    printf("aの値は%dです。\n", a);
    
    // 変数の前に「&」を付けるとアドレスを取得できる。
    printf("aのアドレス(&a)は%pです。\n", &a);
    
    // アドレスの前に「*」を付けると、そのアドレスにある値を取得できる。
    printf("&aの値は%dです。\n", *&a);

    // ポインタ型変数（int型）の利用
    int* a_ptr;
    /*
    int *a_ptr;  // こちらは紛らわしいので使わない
    */
    a_ptr = &a;                                   // アドレスをポインタ型変数に代入
    printf("a_ptrのアドレスは%pです。\n", a_ptr);   // ポインタ型変数のアドレスを表示
    printf("a_ptrの値は%dです。\n", *a_ptr);       // ポインタ型変数のアドレスが指す場所にある値を表示
    
    *a_ptr = 5;                                   // ポインタ型変数を「通常変数モード」にして値を代入
    printf("a_ptrのアドレスは%pです。\n", a_ptr);   // ポインタ型変数のアドレスを表示
    printf("a_ptrの値は%dです。\n", *a_ptr);       // ポインタ型変数のアドレスが指す場所にある値を表示

    return 0;
}
```

```text:実行結果
aの値は3です。
aのアドレス(&a)は0x7ffe3acc6dbcです。
&aの値は3です。
a_ptrのアドレスは0x7ffe3acc6dbcです。
a_ptrの値は3です。
a_ptrのアドレスは0x7ffe3acc6dbcです。
a_ptrの値は5です。
```

# 参考URL

* [ポインタ型変数とは](https://qiita.com/kazuooooo/items/3fd14ca5b8827c60a4fe)
* [ポインタ (pointer)](https://www.cc.kyoto-su.ac.jp/~yamada/programming/pointer.html)
* [第６章　C言語のポインタ ～ ＆ と ＊ を使ってみる ～](https://www.sgnet.co.jp/technology/c/6-1/)
* [【C言語入門】ポインタのわかりやすい使い方(配列、関数、構造体)](https://www.sejuku.net/blog/25094)
API Gatewayを試してみた

# 背景・目的
- [LambdaからDynamoDBを操作する](https://qiita.com/zumastee/items/93f9301e7c8cea8883c0)で作成したLambdaをWebリクエストをもとに実行したい。
- 今回は、API Gatewayを使って実行する。
- 本ページでは、まずAPI Gatewayのチュートリアルを対象とし、実際に接続する方法は次回以降に試す。
# 概要
## API Gatewayとは
- REST、HTTP、WebSocketなどのAPIを作成、公開、維持、モニタリング、セキュア化するためのサービス
- 最大で数十万個の同時 API コールの受け入れ処理に伴うすべてのタスクを取り扱う

## 特徴
- ステートフル (WebSocket) およびステートレス (HTTP と REST) API のサポート。
- 強力で認証メカニズム
    - IAMポリシー
    - Lambdaオーソライザー関数 
    - Cognitoユーザプール
- API発行するための開発者ポータル
- 変更を安全に進めるためのCanaryリリースのデプロイ
- APIの使用状況と、APIの変更に関するCloudTrailログ記録とモニタリング
- CloudWatchのログ記録
    - アクセスログ
    - 実行ログ
- CloudFormation対応
- AWS WAFとの統合
- X-Rayとの統合

# 実践
[ドキュメント](https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/getting-started.html)を参考に、実際に作成し動かしてみる。
## ステップ 1: Lambda 関数を作成する
- 既に作成したLambda関数を使用する。レスポンスの形式はLambada関数レスポンス2.0であれば、メッセージだけ返せばAPI Gatewayで解釈するらしい。（詳細は、[こちら](https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html#http-api-develop-integrations-lambda.response)を参照）
- カスタマイズする場合は、以下のように修正する必要がある。
```
{
    "cookies" : ["cookie1", "cookie2"],
    "isBase64Encoded": true|false,
    "statusCode": httpStatusCode,
    "headers": { "headername": "headervalue", ... },
    "body": "Hello from Lambda!"
}    
```
- 今回は、bodyに詰めるメッセージだけ変更する。
```
 return '{"message","finish!"}'
```

## ステップ 2: HTTP API を作成する
- REST APIではなくHTTP APIで試す。

1.API Gatewayコンソールで「HTTP API」の構築をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/ae070b55-99d2-4f0b-62db-40ab61a57a99.png)

2.APIの作成では、以下を入力し「次へ」をクリック。
- 統合をLambda
- AWSリージョンをap-northeast-1
- Lambda関数をexternal_request_func
- バージョンを2.0
- API名をexternal_request_api
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/37950c93-ab4f-2cee-8fc4-d32313063031.png)

3.ルートを設定では、以下を設定し「次へ」をクリック。
- メソッドをGET
- リソースパス、統合ターゲットは、先程、入力したAPI名とLambda関数を指定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/e72c9b2b-336e-6c72-aaef-1ac9c8771b6e.png)

4.ステージを定義では、デフォルトのまま「次へ」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/09d9ef0d-3c49-0ab3-6be1-535900cf78b5.png)

5.確認して作成画面で「作成」をクリック。

6. ブラウザでアクセスし、確認する。
- 以下が表示された。（見づらいがブラウザに表示された内容）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/ce661866-93fc-ae34-0a3f-7f8c716df0a9.png)

7.DDBも確認する。
実行した直後のデータが入っていることを確認できた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/4062a962-76ae-4aa9-40c7-a5ba47be91cc.png)

# 考察
- 今回は、HTTP APIを使用したが、次回はREST APIを試す。

# 参考
https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/welcome.html

https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/getting-started.html
【AWS認定試験】AWS クラウドプラクティショナーに合格しました

先日、[AWS Certified Cloud Practitioner(クラウドプラクティショナー）](https://aws.amazon.com/jp/certification/certified-cloud-practitioner/)に合格しましたので、
合格体験記として勉強法等を記録したいと思います。

# 細かい情報

- AWS使用経験: およそ1年
    - コアサービス(EC2,S3,ELB,Lambda等)は使用経験はあるが、それ以外はあまり使用経験なし😓
- 勉強期間: およそ1か月

# 使用した教材

教材には[Udemy](https://www.udemy.com/)にあるShingo Shibataさんのコースを利用しました。

https://www.udemy.com/course/ok-aws-e/

https://www.udemy.com/course/aws-4260/

試験を受けた際に利用した講座は上記2点ですが、
CLFの受験を思い立つ前に個人的に読んでいた以下の本も参考になりましたので一応記載します。

https://www.amazon.co.jp/dp/B084QQ7TCF

また、受験直前には公式から出てる模擬問題（あまり数は無いですが…）を利用しました。

https://d1.awsstatic.com/ja_JP/training-and-certification/docs-cloud-practitioner/AWS-Certified-Cloud-Practitioner_Sample-Questions.pdf

https://explore.skillbuilder.aws/learn/course/external/view/elearning/9159/aws-certification-official-practice-question-sets-japanese

スキルビルダーへの登録＆ログインは下記を参考にしてください。

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

# 勉強方法

## 1. [Udemyの講座動画](https://www.udemy.com/course/ok-aws-e/)を一通り閲覧する

https://www.udemy.com/course/ok-aws-e/

何はともあれ、まずは上記の講座を一通り見ました。

内容的には当然「そんなの知っとるわ！」みたいなのもあったのですが、
よくよく話を聞いていると知らない事も多く、非常に勉強になりました。
特に請求系のサービスだけでもあんなに種類があったのは驚きました。

こちらの動画は時短のため基本倍速で視聴していたのですが、
若干流し見な感じになってしまい、後々の問題集で苦労する事に…😢


## 2. [Udemyの問題集](https://www.udemy.com/course/aws-4260/)を一通り解いてみる

https://www.udemy.com/course/aws-4260/

講座動画を視聴後、講座動画についている模擬問題2問を解きました。
その後、上記の問題集を基本2つ、応用3つを通しで解いてみました。
（SAAの問題もついてきましたが、そちらは今回解きませんでした）

結果として、基本問題は70%程度取れたのですが、
応用問題は55%程度しか取ることができず、少し絶望しました…
問題を見て「なんだよこれ知らねぇよ！」ってなった物も
改めて講座動画を見直してみると、ちゃんと解説が書いてあったりしたので
流し見が完全に裏目に出てしまいました…

## 3. 勉強法を変えてもう1度問題集を解き直し

このままだとまずいので、勉強方法を以下のように変えて再度問題集を解き直しました。

1. 問題集を10問だけ解く
1. 回答を終了し、答え合わせ。
1. 間違った問題があれば、解説をしっかり読みこんで理解をする
1. 再度、同じ問題を10問解く
1. これを65問全て繰り返す

これでインプットを改めてやり直しつつ、問題の練習を行いました。

この方法を模擬問題全部で実施した後、再度問題集を解き直すと
安定して応用問題でも8割程度取れるようになり、かなり合格が見えてきました。


## 4. 試験直前に公式問題を解く

https://d1.awsstatic.com/ja_JP/training-and-certification/docs-cloud-practitioner/AWS-Certified-Cloud-Practitioner_Sample-Questions.pdf

https://explore.skillbuilder.aws/learn/course/external/view/elearning/9159/aws-certification-official-practice-question-sets-japanese

最後に試験直前になったら公式問題を解いて腕試ししてみました。
この時点でどちらも満点を取ることができ、自信になりました。

# 試験申し込み

申し込みはピアソンvueから行いました。

受験はオンライン受験にしたかったですが、
オンラインだと全部英語でやり取りしなきゃいけなかったり、
モニターを片付けて1画面しなければいけなかったり、PC周辺に紙類を置いちゃいけなかったりで
非常に面倒だったので、テストセンターでの受験にしました…

# 試験当日

当日必要な持ち物は身分証明書のみとなります。

https://www.pearsonvue.co.jp/Test-takers/Tutorial/Identification-2.aspx

```
以下のいずれかの組み合わせで計 2 点をご提示ください。
 (1) A グループから 2 点
 (2) A グループから 1 点 ＋ B / C / D グループから 1 点
 (3) B グループから 1 点 ＋ C グループから 1 点
```
自分は免許証と健康保険証の組み合わせで行きました。

テストセンターに入場後、色々手続きや試験の注意事項等の説明を受けた後、
持ち物をロッカーに入れた後に受験ができる形になります。
少し手続きに時間がかかるので、テストセンターには試験開始の15分前には到着するようにしましょう。

準備完了後、テストセンターに設置されているPCから問題を解きます。
テスト完了後、その場ですぐに画面に結果が表示されます。
この時点では細かい点数までは表示されず、採点結果は数時間経過すると
[CertMetrics](https://www.certmetrics.com/amazon/)のマイページからダウンロードできるようになります。

# 結果

結果は1000点中、797点で無事に合格でした！

少しギリギリの結果になりましたが、Udemyの問題集を網羅しておけば
十分合格が狙える難易度かなと思いました。

# あとがき

次はSAA、DVA、SOAのいずれかを受験しようと思いますが、
流し見で勉強するのはやめたいと思います…。
kdump とは

## 勉強前イメージ

dumpはわかるけど、kはなに？

## 調査

### kdump とは

linuxカーネルが異常終了したときにマシンのメモリの中身を保存する仕組みになります。
メモリにkdumpが駐在しており、クラッシュカーネルに処理を渡してdumpを行います。

クラッシュが発生すると標準で /var/crash 配下にディレクトリが作成され
詳細な状態を記録したものが保存される。
何も発生していないときは以下のように /var/crash は何も記載されていない。

```
[root@localhost ~]# ls -al /var/crash/
合計 0
drwxr-xr-x.  2 root root   6 11月 17  2020 .
drwxr-xr-x. 20 root root 278  4月  7  2021 ..
```

### kdumpの仕組み

kdumpは `kexec` という 現在起動しているカーネルの上で新しいカーネルをブートするものを使って
2番目のカーネルを起動し、クラッシュしたカーネルのメモリの内容をキャプチャして保存します。

## 勉強後イメージ

kはカーネルのkか。
正直カーネルクラッシュって何が起こるのかがあんまわかってないけど・・・
dmesgとかも見るんね？

## 参考

- [第7章 カーネルクラッシュダンプガイド](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/kernel_administration_guide/_kernel_crash_dump_guide)
- [kdump](https://e-words.jp/w/kdump.html)
Qiitaの記事で表を書く　右揃え・中央揃え・左揃え

## 用途
 Qiitaの記事で表を用いる際に使用する。
表の値を、右揃え・中央揃え・左揃えにしたい時に使用する。

## 使用方法
#### 記述方法
```
|  右揃えにするよ  | 中央揃えにするよ | 左揃えにするよ　 |
|--------------:|:------------:|:-------------|
|     右揃え     |    中央揃え    | 　  　左揃え　   　|
|     右揃え     |    中央揃え    | 　 　 左揃え　　   |
|     右揃え     |    中央揃え    | 　 　 左揃え　　   |
```

２行目の `:` の位置で変わる。

#### 結果
|  右揃えにするよ  | 中央揃えにするよ | 左揃えにするよ　 |
|--------------:|:------------:|:------------|
|     右揃え     |    中央揃え    |   左揃え    　|
|     右揃え     |    中央揃え    |   左揃え　    |
|     右揃え     |    中央揃え    |   左揃え　    |
Classic asp 文字化け対策

文字化けで困ったことがったためその忘備録
# 1. 開発者ツールで文字化けする場合
Webページは正常に表示できているんだけど、開発者ツールだと文字化けしている。。みたいなケース
Responseオブジェクトを使用します
```vb:sample.asp
<%
RESPONSE.CHARSET = "Shift-Jis"
%>
```

# 2.Ajaxで文字化けする場合
フォーム値に日本語が含まれている場合は、javaScript でエンコードし、classic aspでデコードを行い取得します。

```javascript:client.js
const form = $("#form1"); // 送信したいform
form.each(function(i,ele){
    ele.value = encodeURI(ele.value); // 全ての値をencode
});

// 送信処理...
```

```vb:server.asp
<%
Dim formVal

'デコードして取得
formVal = URLDecode(REQUEST.FORM("nameAttr"))

'デコード関数
Function URLDecode(val)
    Dim obj
    Dim strDecode

    'basp21を使用しデコード
    set obj = server.createobject("basp21")
    strDecode = obj.Base64(val,5)
    
    set obj = Nothing
    URLDecode = strDecode
End Function
%>
```

# 3.Webページが文字化けしている場合
始めたばかりだと遭遇するかもしれません。
aspの最初に @ CodePageを記述
```vb:client.asp
<%@ CodePage=65001 %> 'utf8の場合
<%@ CodePage=932 %>   'SJISの場合
```

# 参考ページ
http://asp.style-mods.net
http://www.b21soft.co.jp/basp21/basp21pref.html
INSERTするときに「MySQL server has gone away」エラーが出る

## 現象
アプリケーションでMySQLにINSERTする部分でコードも変えていないのにいきなり以下のようなエラーがでるようになった

```
/home/some-path/bundle/ruby/2.6.0/gems/mysql2-0.5.3/lib/mysql2/client.rb:131:in `_query': MySQL server has gone away (Mysql2::Error::ConnectionError)
	from /home/some-path/vendor/bundle/ruby/2.6.0/gems/mysql2-0.5.3/lib/mysql2/client.rb:131:in `block in query'
/// 省略 ///
```

## 原因
MySQLには、1つのクエリーでINSERTできるデータの最大値を制限するパラメター（`max_allowed_packet`）がある。
参考：https://dev.mysql.com/doc/refman/5.6/ja/packet-too-large.html

このエラーが出る場合には max_allowed_packet の値を超えたデータ量をINSERTしている可能性がある。

### max_allowed_packet の確認方法

以下はmysqlコマンドでの確認方法。

プログラムからMySQLにアクセスしている場合には、プログラムからのアクセス方法と同じライブラリーなどを使い以下の`show variables like 'max_allowed_packet';`を実行するのが良い。（ライブラリーによって`max_allowed_packet`に異なる値を使っているかもしれないため）

```
mysql> show variables like 'max_allowed_packet';
+--------------------+---------+
| Variable_name      | Value   |
+--------------------+---------+
| max_allowed_packet | 4194304 |
+--------------------+---------+
1 row in set (0.04 sec)
```


### 解決方法

#### 解決方法1. プログラムを変える
そもそも1行で大きなデータを入れているのが原因であれば、その部分を変更する方法が考えられる。

例えば、複数の行へのINSERTを1つのクエリーで`INSERT INTO some_table (col1, col2) VALUES (1, 1), (2, 2), ...ここに大量の行がある...(xxx, xxx);`みたいに大量のINSERTを行っているのであれば、INSERT文自体を複数INSERTに分けて1つのINSERTのデータ量を減らす手が考えられる。

この方法の利点は影響範囲がその部分に限られることである。欠点は、同じようなバグが他のコード箇所にあったとしてもそこは対応できないことになる。


#### 解決方法2. サーバー全体またはプログラムで利用しているライブラリーが使う`max_allowed_packet`の値を変更する

:::note warn
注：筆者はやったことはないので想像で書いています
:::


https://dev.mysql.com/doc/refman/5.6/ja/packet-too-large.html などに書かれているように`max_allowed_packet`の値を変更してしまう方法が考えられます。

この方法の利点は、サーバー全体やクライアント全体に適用される方法なので同じバグが他にもあってもこの設定変更だけで対応できる。欠点としては、設定変更が全体に及ぶので、いままで問題にならなかった部分にも問題がでるかもしれない。（上限値を緩めるだけなのでおそらく大丈夫だと思うが）
C++ ポインタと参照を５秒で復習


ポインタとか参照って言葉で覚えないで、そのまま理解する

```c++
#include <iostream>

int main() {
  int a{1};     // 新アドレスに値を入れる
  int b = a;    // 新アドレスにaの値を入れる
  int* c = &a;  // 新アドレスにaのアドレスを入れる
  int& d = a;   // アドレスも値もaと全く同じ

  std::cout << "&a : " << &a << "  a : " << a << std::endl;
  std::cout << "--------------------------------------" << std::endl;
  std::cout << "&b : " << &b << "  b : " << b << std::endl;
  std::cout << "--------------------------------------" << std::endl;
  std::cout << "&c != &a : " << &c << " != " << &a << std::endl;
  std::cout << "c == &a  : " << c << " == " << &a << std::endl;
  std::cout << "*c == a  : " << *c << " == " << a << std::endl;
  std::cout << "--------------------------------------" << std::endl;
  std::cout << "&d == &a : " << &d << " == " << &a << std::endl;
  std::cout << "d == a   : " << d << " == " << a << std::endl;

  return 0;
}
```

```:結果
&a : 0xdc3bfffab4  a : 1
--------------------------------------
&b : 0xdc3bfffab0  b : 1
--------------------------------------
&c != &a : 0xdc3bfffaa8 != 0xdc3bfffab4
c == &a  : 0xdc3bfffab4 == 0xdc3bfffab4
*c == a  : 1 == 1
--------------------------------------
&d == &a : 0xdc3bfffab4 == 0xdc3bfffab4
d == a   : 1 == 1
```
API Gatewayでカスタムドメインを使用してAPI呼び出しの時にMissing Authentication Tokenエラーになった場合

# はじめに
AWS　API Gatewayを使って作成したAPIエンドポイントを独自ドメインでアクセス出来るようになりたいと
色々と調べて試してみましたが、Missing Authentication Tokenエラーが返ってきてしまいました。

結果的には、カスタムドメイン名で設定するAPIマッピングの```パス (オプション)```を勘違いしていたのが原因でした。

以下のカスタムドメイン名を設定するAPIマッピングの```パス (オプション)```(スクリーンショットの赤枠部分)には、***APIのリソース名***を入れるものだと勘違いしていたのが原因でした。

![スクリーンショット 2022-04-03 14.20.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44053/94244e44-abb9-5166-88fd-a796a6dc1003.png)


```https://foofoofoo.execute-api.{region}.amazonaws.com/production/users```を```https://example.com/users```でアクセスしたい場合は、```パス (オプション)```欄は空白にするが正解でした。

```パス (オプション)```欄にAPIリソース名の```users```を設定していたのでエラーが出ていました。


```https://foofoofoo.execute-api.{region}.amazonaws.com/production/users```を```https://example.com/prod/users```でアクセスしたい場合は、```パス (オプション)```欄に```prod```を設定します。


[APIGatewayでカスタムドメイン利用時に繋がらない問題で同じ轍を踏んだのでメモしておく](https://qiita.com/YoukyMurakami/items/9f3d4b7aaac4a33c9649)が参考になりました。ありがとうございました〜！


## 参考にしたサイト一覧
[API Gateway リージョン別カスタムドメイン (Route 53は他アカウント)](https://kacfg.com/aws-apigateway-custom-domain-regional-different-account-domain/)

[API Gatewayとバックエンドの疎通確認で時間を無駄にしないための手順書](https://zenn.dev/hiroga/articles/api-gateway-connection-playbook)

[AWS API Gateway に独自ドメインを使ってアクセスできるようにする](https://zenn.dev/tatsurom/articles/api-gateway-domain-mapping)
広告運用レポート作成時間の削減を可能にした「Google Apps Script」活用方法

# はじめに
ヴェネクト株式会社のインターンメンバー 佐々木です。
普段はエンジニアとして、社内業務を効率化するためのツールを開発しています。
今回はその一つを紹介いたします。
弊社の業務の一つに「**広告運用レポートの作成**」があります。
クライアントに広告運用の結果を報告するためのレポート作成は、週単位・月単位・四半期単位など高頻度で行われるため、広告代理店のメンバーを繁忙にさせている業務の一つではないでしょうか。

特に、「**日次のレポートを確認し、数値変動の管理・集計**」というルーティンワークに時間を取られてしまうと、その他業務に費やせる時間が減少します。

弊社では、Google Apps Scriptによって作られた社内ツールによって、それらルーティンワークが自動化されています。

# ツール概要
**二つのレポートを比較し、各項目（列）ごとに設定された数値の許容範囲を超えているセルや数式が間違っているセルを黄色にハイライトすることができるツールです**
|10/17週の運用レポート|10/10週の運用レポート|
|---|---|
|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519598/abb8d371-ef02-8f0d-d7d2-17b0910b2cca.png)|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519598/62376e7d-068d-8801-ef32-d082066960cc.png)|

- 10/10の配信金額は、10/10週は`¥10,500`だったのに対し、10/17週では`¥20,500`に変化しています。配信金額の許容範囲を`前週の80%~120%`に設定しており、10/17週の`¥20,500円(前週の配信金額の約195%)`は許容範囲を超えているため黄色にハイライトされています。
- 10/06のCPC（Click単価）は、`CPC = 配信金額 / Click`であるため、`¥10,300 / 2,000 = ¥5`になるはずです。しかし、10/17週のレポートでは`¥9`になっており間違っています。そのため黄色にハイライトされています。

# ツール活用の手順
1. スプレッドシートに今週のレポートと先週のレポートをインポートする。（弊社の場合、運用レポートが.xlxs形式でパートナーから共有されます）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519598/fdb5e6e6-35b0-5c55-d081-81c143f03514.png)

2. Google Apps Scriptで作成したメニューからレポート比較（②差分検知）を実行する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519598/b48f6217-b4b4-fec7-1e80-ff04be5a3fda.png)

3. 先週分と今週分の2つのスプレッドシートの同一のシート名からGoogle Apps Scriptでデータを配列で取得する。
4. 取得した二つのレポートの配列内のデータを比較（※比較内容は設定した許容範囲毎に変わる）し、各列ごとに設定された数値の許容範囲を超えているセル・数式が間違っているセルは黄色にハイライトされます。
5. 黄色にハイライトされたセルがあるシート名がポップアップで通知されます。 

# まとめ
Google Apps Scriptを活用すると様々なルーティンワークを自動化することができます。Google Appsを業務で使用している方はぜひトライしてみてください。
本記事含め、弊社の他の記事もぜひご覧ください！
ROBOTIS サーボモータ DynamixelをROS2で操作する


## はじめに
ROS2でROBOTIS Dynamixelを動かすための、セットアップおよび実際に動作させるまでについて記述します。

## 実行環境

### コンピュータ
||| 
|:---|:-----|
|デバイス|Raspberry Pi 4|
|RAM|8GB|
|OS|Ubuntu 20.04LTS|
|ROS2|Foxy Fitzroy|

### アクチュエータ(Dynamixel)
||| 
|:---|:-----|
|メーカー|ROBOTIS|
|シリーズ|XM430-W350|
|詳細|https://emanual.robotis.com/docs/en/dxl/x/xm430-w350/|


## 環境構築

### DynamixelSDKのインストール

DynamixelSDK(Dynamixcelを扱うためのパッケージ)を特定のワークスペースにインストールしてビルドしてください。

```
$ mkdir -p ~/hogehoge_ws/src
$ cd ~/hogehoge_ws/src
$ git clone -b $ROS_DISTRO-devel https://github.com/ROBOTIS-GIT/DynamixelSDK
$ cd ~/robotis_ws && colcon build --symlink-install
```

## サンプルプログラム
dynamixel_sdk_examples/srcにあるread_write_node.cppのデフォルトセッティングのうちボーレートとシリアル通信のデバイス名を変更してください。
![スクリーンショット 2022-04-03 131010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2610001/fed91b75-cac9-247e-da05-74252b023696.png)
デバイス名は以下のコマンドで確認できます。
```
$ ls /dev/ttyUSB
```
またDynamixelのボーレートやID等の情報は[DYNAMIXEL Wizard](https://emanual.robotis.com/docs/en/software/dynamixel/dynamixel_wizard2/)から確認することができます。


## 動作確認

DynamixelSDKをインストールしたワークスペースからdynamixel_sdk_examplesのサンプルプログラムread_write_nodeを実行してください。
```
$ ros2 run dynamixel_sdk_examples read_write_node
```
idと位置をパブリッシュしてDynamixelを動かします。
```
$ ros2 topic pub -1 /set_position dynamixel_sdk_custom_interfaces/SetPosition "{id: 32, position: 1000}
```
上手くいくと動画のように動かせると思います。(動画ではポジションを0→1000に動かしています）

<iframe width="400" height="315" src="https://www.youtube.com/embed/T6NQRHhOXdI" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>


## 参考文献

https://emanual.robotis.com/docs/en/software/dynamixel/dynamixel_sdk/overview/
【初心者向け】ネットワーク基本


初投稿です。
主に自分の備忘用で投稿します。
誤った情報があればご指摘ください。


# はじめに

こちらの記事では以下3点について記述しています
1.そもそもネットワークとは
2.インターネットとは
3.インターネットソリューションプロバイダ(ISP)
4.コラボ光とは
インターネットの事しか書いてませんので一般向けです。


## 1.そもそもネットワークとは
広義の意味としてネットワーク(NW)は以下を指します。


`１ テレビ・ラジオで、キー局を中心にして多数の放送局が協定を結び、同一番組を放送すること。また、その組織。放送網。`
`２ 複数のコンピューターを結び、データなどを共有し、情報処理の効率化を図るシステム。
    具体的にはインターネットやLAN(ラン)などを指す。`
`３ 個々の人のつながり。特に、情報の交換を行うグループ。「地域ネットワーク」`

>引用元：https://www.weblio.jp/content/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF

この中では２を扱っていきます。

## 2.インターネットとは
インターネットとは世界中の機器が接続されているネットワークを指します。

パソコンや様々な機器をLANケーブルを始めとした有線で繋がっており、
スマホなどの無線電波も到達先は各キャリアの基地局から有線を使用して
どこかの機器(Webサーバー、アプリケーションサーバーetc...)へ接続していきます。

そういったNWは日本のみならず世界中にあります。
世界中と相互接続するたみに日本のある場所にある、
インターネットエクスチェンジ(IX)から海底ケーブルを通じて世界と通信をしています。
このあらゆる機器が接続されて情報交換をしているネットワークを「インターネット」といいます。

## 3.インターネットソリューションプロバイダ(ISP)
ISPとはインターネットへ行くための入口を提供している企業です。
例えばNTT東西が提供しているフレッツ光を敷設するだけでは、
インターネットを使うことはできません。
NTTコミュニケーションズのOCN、BIGLOBE、nifty等が提供している
「ISP」と呼ばれるサービスを契約することでインターネットを使うことができます。

## 4.コラボ光とは
よく一般向けにドコモ光、auひかり、ソフトバンク光、、、など
○○光といったサービスをよく見かけます。
このサービスを契約すれば回線とISPを一緒に利用することができるので、
別々の会社と契約することなくインターネットを利用することができます。
※これをコラボ光と呼びますが、後述します。

そもそもなぜこういう提供形態になっているかというと、
NTT法という法律があります。
今のNTTの前身として電電公社というものがありました。
民営化するにあたり、電電公社の既存設備を受け継いでいるので独占的にならないよう、
ある程度の制限を掛けています。
その中の一部としてISP事業はNTT東西と持株会社では提供することができません。

またNTT東西が持っている回線設備をISP事業者へ貸し出す事業を行っています。
そして借り受けたISP事業者が自社のISPサービスと組み合わせてユーザーへ提供しています。
これをコラボ光といいます。
ISP事業者としてはサービス以外にキャッシュバックやプレゼントなどを組み合わせることで、
お得に提供するようにしています。

今回はここで以上とします。
ご覧いただきありがとうございました。
次回以降でVPNとか色々書いていこうかと考えてます。
M5stick用ジョイスティックでBLEマウスを作成してiPadを操作

M5stickCと、ジョイスティックユニットを接続して、bluetoothマウスを作成し、iPadを操作してみました。


https://twitter.com/shirox22/status/1430500632683683847?s=20&t=iEWdRGfQswctG1etD_KOYA


## M5stickCとジョイスティックユニットをgrove互換ケーブルで接続

![IMG-6007.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1039768/ad203ab0-d674-2e72-c168-f9b1b611cd63.jpeg)

## M5stickCにプログラムをインストール
```
#include <M5StickCPlus.h>
#include "Wire.h"
#include <BleMouse.h>

#define JOY_ADDR 0x52
BleMouse bleMouse;
double vbat = 0.0;
int8_t bat_charge_p = 0;

void show_battery_info() {
  // バッテリー電圧表示
  // GetVbatData()の戻り値はバッテリー電圧のステップ数で、
  // AXP192のデータシートによると1ステップは1.1mV
  vbat = M5.Axp.GetVbatData() * 1.1 / 1000;
  // バッテリー残量表示
  // 簡易的に、線形で4.2Vで100%、3.0Vで0%とする
  bat_charge_p = int8_t((vbat - 3.0) / 1.2 * 100);
  if (bat_charge_p > 100) {
    bat_charge_p = 100;
  } else if (bat_charge_p < 0) {
    bat_charge_p = 0;
  }
  M5.Lcd.setCursor(45, 2, 1);
  M5.Lcd.printf("Charge: %3d%%", bat_charge_p);
}

void setup() {
  M5.begin();
  //M5.Lcd.clear();
  //disable the speak noise
  //dacWrite(25, 0);
  bleMouse.begin();
  Wire.begin(32, 33, 100000);
  M5.Lcd.setRotation(1);
}
uint8_t x_data;
uint8_t y_data;
uint8_t button_data;
char data[100];
int cnt = 1;

void loop() {
  M5.update();
// ボタンBでパワーオフ
  if ( M5.BtnB.wasPressed() ) {
    M5.Axp.PowerOff();
  }

//ボタンAで画面表示のオンオフ
  if (M5.BtnA.wasPressed())
  {
    cnt++;
    if (cnt % 2 == 0) {
      M5.Axp.ScreenBreath(0);
    } else {
      M5.Axp.ScreenBreath( 10 );
    }
  }
  show_battery_info();

  Wire.requestFrom(JOY_ADDR, 3);
  if (Wire.available()) {
    x_data = Wire.read();
    y_data = Wire.read();
    button_data = Wire.read();
    sprintf(data, "x:%d y:%d button:%d\n", x_data, y_data, button_data);
    Serial.print(data);
    M5.Lcd.setCursor(1, 30, 2);
    M5.Lcd.printf("x:%04d y:%04d button:%d\n", x_data, y_data, button_data);
    if (x_data < 110) {
      bleMouse.move(4, 0);
      delay(10);
    }
    if (x_data > 135) {
      bleMouse.move(-4, 0);
      delay(10);
    }
    if (y_data > 135) {
      bleMouse.move(0, 4);
      delay(10);
    }
    if (y_data < 110) {
      bleMouse.move(0, -4);
      delay(10);
    }
    if (button_data == 1) {
      bleMouse.click(MOUSE_LEFT);
      delay(1000);
    }

    delay(10);
  }
}
```
ジョイスティックマウスとiPadは、bluetooth接続できるので便利です。

もちろん、このマウスは、PCでも使えます。

何らかの障害があって普通のマウスが使えない場合に、このようなジョイスティックマウスを使えば、操作できるかどうか試してみることができると思います。

市販のジョイスティックマウスより安価で試せると思います。
 
ジョイスティックを押し込む操作が難しい場合には、iPad側のアクセシビリティの設定で、滞留コントロールをオンにすれば、クリック操作は自動で行ってくれますので、試してみてください。
Reactの基本知識

React-native での基本知識
ComponentsにはJSX, Props, State

JSX
render関数が返すJSXによって画面描写
JSXでComponentの見た目を定義
```react:example
   render(){
       return(
        <View>
          <Text>Hello World</Text>
        </View>
   );
 }
```

PropsとStateの違い

Propsは性質や、変わることのないものを表す（不変）
Componentの”性質”を定義
親から子に情報を渡す

```react:example
props.gender: female
```



Stateは状態や、変わりえるものを表す（可変）
Componentの”状態”を表現
可変な値
stateを変更することで画面が更新される
```react:example
state.hungry: false
```