OmniAICreator/Qiita-1.07M huggingface dataset:
プルーフリスト(proof list)

応用情報技術者平成29年春期 午前59

販売管理システムにおいて，起票された受注伝票の入力が，漏れなく，かつ，重複することなく実施されていることを確かめる監査手続として，適切なものはどれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/7a4004b1-3371-33e1-1020-a45b29542aa8.png)


１、プルーフリストとは、
入力データを加工せずにそのままプリントアウトしたもの。会計ソフトにこの機能が組み込まれている場合が多い。監査ではこのプルーフリストと受注伝票を照合することにより、何か問題が発生していないか、漏れが発生していないか確認する。

ビジネスなどでは、キーボードやマウス等から入力されたデータを、入力者の目視チェックだけに頼らず、結果を用紙に印刷して、別人がチェックして正確を記することをシステムの１ステップに組み入れています。この入力結果シートの内容データか書類のことを言います。入力したデータそのものだけでなく、それより表引きしたデータなどを
印字してチェックしやすくしたります。例えば社員コードを入力した時、社員名もマスターから引いてきて印刷しておくと、チェックがやりやすく誤りが見つけやすいことがあります。ＰｒｏｏｆＲｅａｄｉｎｇ校正、ＰｒｏｏｆＳｈｅｅｔ校正刷り、Ｐｒｏｏｆには検算、吟味、試験などの意味が有ります。


プルーフリストと受注伝票を照合することで、入力データの完全性および一意性が確認できます。監査においてはこの照合が確実に実施されているかを確認するために照合印をチェックすることがポイントになります。


２、IT業務処理統制
企業会計審議会が2007年2月に発表した内部統制の「実施基準」では、IT業務処理統制として次の4項目を挙げています。
・入力情報の完全性、正確性、正当性等を確保する統制
・例外処理（エラー）の修正と再処理
・マスタデータの維持管理
・システムの利用に関する認証、操作範囲の限定などアクセスの管理

監査において「起票された受注伝票が漏れなく，重複することなく入力されていることを確かめる」には入力データの完全性および一意性に係るコントロール項目をチェックすることになります。

３、
・受注データから値引取引データなどの例外取引データを抽出し，承認の記録を確かめる。
⇒「例外処理（エラー）の修正と再処理」に係るコントロール機能です。

・受注伝票の入力時に論理チェック及びフォーマットチェックが行われているか，テストデータ法で確かめる。
⇒入力データの正当性に係るコントロール項目です。
プ

・並行シミュレーション法を用いて，受注伝票を処理するプログラムの論理の正当性を確かめる。
⇒受注伝票処理の正確性に係るコントロール項目です。


参照：
https://www.ap-siken.com/kakomon/29_haru/q59.html

プルーフリストとは(proof list)
http://tooljp.com/jyosho/glossary/proof-list.html
https://oshiete.goo.ne.jp/qa/272693.html
【GAS】AppSheetからスプレッドシートを操作するとonEditが動かない問題の対処法

##概要
スプレッドシートを元に、簡単にアプリを作れるGoogleAppSheet。微妙なところで躓いてしまったのが表題。

スプレッドシートのセル編集をトリガーにスクリプトを動作させるonEdit(e)を使っていたのだけれど、AppSheetで作成したアプリからのセル編集だとスクリプトが動作しない？？？

仕様なのかと諦めモードになっていたら、海外のＱ＆Ａサイトに「onEditじゃなくてonChangeなら出来たって人がいるよ」との記述があったので試してみた。

##そういう事じゃなかった
軽率な素人として、まずは `function onEdit(e) {` を `function onChange(e) {` に変更・・・挙動に一切の変化なし。そういう事ではない模様。

##こういう事だった
どうやら関数名をonChangeにするだけじゃなくて、onChange関数をトリガー設定する必要があったみたい。

具体的には、時計アイコンでトリガーの設定を開いてトリガーを追加。トリガーの設定は次の通り。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/708687/e3396255-1225-e833-9fac-23499beb1a5a.png)
実行する関数で「onChange」を選択、イベントの種類は「変更時」。
見事、AppSheetからのセル編集をトリガーにスクリプトが動作しましたとさ。

これってトリガーで関数を指定してるんだから、もしかして関数名はonChangeでなくて良かったのかも？

###おしまい
textlintrcを使わないで設定する

動的に設定を流したいよねって話

```bash
$ npm init --yes
$ npm install --save-dev textlint
// TODOをチェックするルール
$ npm install --save-dev textlint-rule-no-todo
// 連続する漢字をチェックするルール
$ npm install --save-dev textlint-rule-max-kanji-continuous-len
```


`textlintrc: false`しておくことで.textlintrcを拾わないようにする

```js:cl.js
"use strict";
const TextLintEngine = require('textlint').TextLintEngine;

const text = "TODO: this is TODO 一二三四五六";
const options = {
  rules: [
    "no-todo",
    "max-kanji-continuous-len",
  ],
  rulesConfig: {
    "no-todo": true,
    "max-kanji-continuous-len": true,
  },
  textlintrc: false,
};
const engine = new TextLintEngine(options);
engine.executeOnText(text).then(results => {
  if (engine.isErrorResults(results)) {
    var output = engine.formatResults(results);
    console.log(output);
  } else {
    console.log("All Passed!");
  }
});
```

```bash
$ node cl.js

<text>
  1:1   error  Found TODO: 'TODO: this is TODO 一二三四五六'  no-todo
  1:20  error  漢字が6つ以上連続しています: 一二三四五六      max-kanji-continuous-len

? 2 problems (2 errors, 0 warnings)
```


## 参照情報

[textlint/index\.js at master · textlint/textlint](https://github.com/textlint/textlint/blob/master/examples/use-as-module/index.js)

[textlint/config\.ts at 0503af68f4a34beaab2e45c34463ad4e0e24a958 · textlint/textlint](https://github.com/textlint/textlint/blob/0503af68f4a34beaab2e45c34463ad4e0e24a958/packages/textlint/src/config/config.ts)
問題管理プロセス


応用情報技術者平成29年春期 午前57

ITサービスマネジメントにおける問題管理プロセスの活動はどれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/59ff161f-177c-19db-e98f-8baa62faa9da.png)

１、問題管理プロセスは、
インシデントの根本原因を特定し、インシデント及び問題の影響を最小化又は回避することを目的とするプロセスです。主な活動は以下の通りです。

・インシデントの根本原因と潜在的な予防処置を特定する
・問題解決のための変更要求を提起する
・サービスへの影響を低減又は除去するための処置を特定する
・既知の誤りを記録する

２、
・サービス要求の優先度付け
⇒インシデント及びサービス要求管理の活動です。

・変更要求の記録
⇒変更管理の活動です。

・リリースの試験
⇒リリース及び展開管理の活動です。


参照：
https://www.ap-siken.com/kakomon/29_haru/q57.html
AWS HoneyCodeの現状

いつも忘れないように、コンセプトから。

###コンセプト
・お金かけてまでやりたくないのでほぼ無料でAWSを勉強する
　→ちょっとしたサービスを起動すると結構高額になりやすい。
・高いレベルのセキュリティ確保を目指す
　→アカウントを不正に使われるととんでもない額を請求されるので防ぐ



###HoneyCodeの現状
AWS Summitがオンラインで公開されてますが、HoneyCodeは特に特集されてませんね。。。まあベータ版なので仕方ないところかもしれませんが、個人的には非常に残念です。

最新状況を知りたいなと思ってコミュニティを読んでましたが、ちょうどいい感じのページがありました。
https://honeycodecommunity.aws/t/external-integrations-share-your-feedback/5839

これは実際に寄せられた意見が書かれています。さまざまなニーズがあるんだなと思います。もちろん現状だとできなくて、検討します、ありがとうみたいな回答にはなっているんですが、逆にこれができるとなると、ITに対してのある意味革命にもなりそうな気がしています。実装されるかわかりませんが、いいなと思うリクエストをピックアップしてみます。

・外部データベースへのアクセス
https://honeycodecommunity.aws/t/feasibility-to-connect-data-to-external-database/1599

・Googleドライブ使えないの？
https://honeycodecommunity.aws/t/google-drive-connect/5352

・JIRAやGoogleシートへのアップデート
https://honeycodecommunity.aws/t/integrating-with-jira-and-google-sheets/2367/5
確かにJIRAと連携できるといいかも！？

・REST APIからデータ読めない？
https://honeycodecommunity.aws/t/read-data-from-rest-api/1237

・APIを作らずに外部APIアクセスできないか？
https://honeycodecommunity.aws/t/external-api-access-without-requirement-to-create-app/4875

・Amplifyとの統合
https://honeycodecommunity.aws/t/integration-with-aws-amplify-deployment-at-client-end/3706

・Quicksightとの統合
https://honeycodecommunity.aws/t/aws-quicksight-integration/1270
これは欲しいかも！？

あとはLambdaとの連携とかデータベースアクセスに関する質問が多いですね。現状ベータ版なので、その辺は今後拡充されていくでしょうし、少なくともAWSの全データベースやストレージサービスとは連携できて当たり前って感じがしますね。

個人的に期待しているのは、現状テンプレートとしてそのまま使えるアプリケーション（ToDoリストとか）がありますが、これがどんどん増えて、簡単にカスタマイズできることです。もっと複雑なアプリを第三者が投稿してみんなが使えるようになるといいなと。マーケットプレイスみたいな感じになるといいなと思います。そうなってくると、システムを作ると使うの境界がかなり崩れてきて、システムを使いこなす＝自分でカスタムする、みたいな感じになっていくと思います。
[Python] コマンド一つでpipにインストールしたライブラリを全削除

## はじめに
たまにpipのライブラリを全削除したくなるのですが，

```bash
pip freeze > u.txt
pip uninstall -r u.txt -y
```
とするのが面倒なので一行pipのライブラリを削除する方法を考えました．

## コマンド

```bash
pip uninstall -r <(pip freeze) -y
```

## 説明
[プロセス置換という考え方](https://shellscript.sunone.me/input_output.html#%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9%E7%BD%AE%E6%8F%9B-)(1)を参考にしました．
この考え方によって，一時ファイルである```u.txt```の部分を``` <(pip freeze)```と書き換えることにより一行に短縮することができました．

## さいごに
毎回使用する簡単なコマンドを一行にできると作業効率も上がりますし，コマンドの使い方について豆知識もつくので楽しいです．

## 参考文献
(1)[UNIX & Linux コマンド・シェルスクリプト リファレンス](https://shellscript.sunone.me/input_output.html#%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9%E7%BD%AE%E6%8F%9B-)
ページ内の全てのチェックボックスにチェックを付けるブックマークレット

たまに使っているブックマークレットです。

```js
javascript:(function (){var inputs = document.getElementsByTagName('input');for (var j=0; j < inputs.length; j ++) {var e = inputs[j];if (e.type == 'checkbox')e.checked = true;}})();
```
Jenkinsで「Pipeline script from SCM」で「Jenkinsfile」と「Git Parameter Plug-In」を上手く動かすための備忘録

## 問題

1. ソースコードと同じレポジトリにJenkinsfileを配置し、Pipeline script from SCMでビルド時に動的にJenkinsfileを読み込んでビルドするようにする
2. Git Parameter Plug-Inをインストールしてパラメータ付きビルドでブランチを指定してビルドを動かす
3. **ビルド時に指定したブランチのJenkinsfileを上手く読み込むことができない**

## 環境

- Jenkins 2.249.1
- Git Parameter Plug-In 0.9.13

## 再現手順

Git Parameter Plug-Inをインストールし、Jenkinsfileに下記の設定を行う

```
  parameters {
    gitParameter branchFilter: 'origin/(.*)', defaultValue: 'master', name: 'BRANCH', type: 'PT_BRANCH'
  }
```

設定のパイプラインで、定義を「Pipeline script from SCM」とし、ビルドするブランチを「${BRANCH}」とすると、ビルド時に下記のエラーが表示される

```
hudson.plugins.git.GitException: Command "git fetch --tags --progress --prune -- origin +refs/heads/${BRANCH}:refs/remotes/origin/${BRANCH}" returned status code 128:
stdout: 
stderr: fatal: Couldn't find remote ref refs/heads/${BRANCH}
```

## 解決方法

設定のパイプラインで、「Lightweight checkout」のチェックを外す

*※ワークアラウンドで上記の対応を行ってから同様の解決方法が検索できたけど、対応前は辿り着けなかったので残しときます。。。*
【Cannot find module ... or its corresponding type declarations.】 tsconfig.json がプロジェクトのルート直下にない場合

# 事の発端

![スクリーンショット 2020-09-19 22.44.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38580/afc2f7a0-17f5-e8c2-b507-86983345ef64.png)

inject の戻り値の型が正しく返らず unknown になってる。

![スクリーンショット 2020-09-20 15.18.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38580/86d22159-bca4-48ee-fee5-679343131661.png)

そういえば import する時にエラーを吐いてる。

```
Cannot find module ... or its corresponding type declarations
```

こいつが原因か？

しかし、なぜ Cannot find module になるか分からない...

# 原因


自分の場合だと Rails プロジェクトの上に frontend ディレクトリを作り、tsconfig.json を置いていたのでこのような状況に陥った。そして、プロジェクトのルート直下で VSCode を開いていたため、tsconfig.json の内容がうまく機能していなかった。

フォルダ構成は以下のような感じ。

```
.
├── Gemfile
├── Gemfile.lock
└── frontend
  └── tsconfig.json
  └── components
...
```

# 解決

frontend ディレクトリ配下で VSCode を開いても解決するのだが、ルート直下に `tsconfig.json` を置いても解決する。`extend` でファイルパスを指定することで、継承する `tsconfig.json` を指定できる。

```tsconfig.json
{
  "extends": "./frontend/tsconfig.json"
}
```

# 参考リンク

https://github.com/vuejs/vetur/issues/815#issuecomment-450545705
【React Native × Expo】「Expo pasted from Expo」、「Expo pasted from CoreSimulator」という通知メッセージを削除したい

### エラー内容と原因
エミュレータをiOS14にバージョンアップしたら、
`Expo pasted from Expo`、`Expo pasted from CoreSimulator`という通知メッセージが表示されるようになりました。

調べてみると、どうやらiOS14から`Clipboard`の仕様に変更があったことが原因のようです。

iOS14の新機能としてアプリでコピペした際、
プライバシー機能として「どのアプリからコピーされ、どのアプリに貼り付けたのか」をバナーで通知する機能がが追加されています。

このバグはExpoのbugレポートには上がっており、今後のアップデートで解消されるかもしれません。

### 対策


今回は応急処置として、通知メッセージを削除する方法について共有します。

##### ①`Clipboard`を`import`しているファイルを開きます。

##### ②`import`文の下に以下の記述を追加
```javascript
import {Clipboard} from 'react-native';
// 以下を追加
if (__DEV__) {
Clipboard.setString('');
}
```
##### ③`Automatically Sync Pasteboard`のチェックを外す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659719/46fe0a34-dfe3-c27a-efb6-a6844a4add81.png)

##### ④アプリを再ビルドする

これで、通知メッセージは表示されなくなったと思います。

お疲れ様でした〜☕️☕️☕️


### 余談
エラー原因を調べる過程で面白いニュースを発見しました。

TikTokが`Clipboard`から無断でテキストを読み取っていることが判明されたそうです。（SmartNewsも？）
真相はわかりませんが、TikTok側は指摘を受けて、機能を廃止したとのこと。

[Engadgetのニュース記事](https://mobilelaby.com/blog-entry-tiktok-reading-user-clipboards.html)
[Swift] NSLogを安易に使ってしまうとセキュリティ的にマズい

# 前提環境

- Xcode 11.3.1
- Swift 5.1.3

# ログ出力とセキュリティ

`print`と比べて`NSLog`は日時を出力してくれるので便利そうに見えますが、、、
![スクリーンショット 2020-09-15 9.06.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122917/68306ce1-e210-73c4-407d-f1bca0d3c40c.png)

端末をPC接続して、Apple Configurator 2などのツールを使うとコンソールに出力されてしまいます。
セキュリティ的に危うい状況です。
![スクリーンショット 2020-09-15 9.08.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122917/211055ae-1d0c-d786-86a0-195c08730ca5.png)

一方、`print`はコンソールに出力されません。

`print`を自前で拡張するか、SwiftLog（Apple製のOSSライブラリ）などを利用すると良いかと思います。
https://github.com/apple/swift-log
Markdown形式でURLをコピーするブックマークレット

いつも使っているスクリプトを貼ります。実際にブックマークレットを追加する方法については、お使いのブラウザのマニュアルを読んでみてください。

```js:Markdown用
javascript:(function(){y=window.open('','','resizable,width=500,height=200');y.document.write('<body onload="t.focus();"><form><textarea id="t" onfocus="this.select()" style="width:100%;height:100%">'+"["+document.title+"]("+document.URL+')</textarea></form></body>');y.document.close();})();
```

このブックマークレットではウインドウが出てしまうので、直接コピーするスクリプトをご存知のかたはコメント欄で教えて頂けると助かります。

```js:メール等にコピペする用
javascript:(function(){y=window.open('','','resizable,width=500,height=200');y.document.write('<body onload="t.focus();"><form><textarea id="t" onfocus="this.select()" style="width:100%;height:100%">'+""+document.title+""+"\n"+document.URL+'</textarea></form></body>');y.document.close();})();
```
[開発環境]　ディスプレポートが抜けねー俺、やっちまったなあ

HDMIとちがいDPにはラッチという機構がついておりこれを押しながらじゃないと抜けないのです、１０万のグラボが壊れるところでした！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282788/c29c0a73-23c1-fe85-1222-bd640c84e763.png)
https://tabenoaso.com/14519.html
【VPC】ネットワークACLの作成・設定

## 1. ネットワークACLを作成する
作成したVPC（`test-vpc`）に関連付くネットワークACLは、インバウンド・アウトバウンドともに全てのトラフィックを許可しており、ネットワークACLによるアクセス制御がされていない状態
![スクリーンショット 2020-08-15 10.42.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/335f29e9-53b7-268e-58ac-ffabee2356ed.png)

## 2. 名前タグの入力、VPCの選択をする
![スクリーンショット 2020-08-15 10.45.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/cb13d876-95db-d8c0-ebce-73186bddb14a.png)

### 作成完了
全てのトラフィックを拒否する設定のネットワークACLが作成される
![スクリーンショット 2020-08-15 10.52.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/497e8415-6e2f-7f3a-4234-3486ea95192d.png)

## 3. Apache内にhtmlファイルを作成する
```
[ec2-user@ip-[パブリックインスタンスのプライベートIP] ~]$ sudo su -
[root@ip-[パブリックインスタンスのプライベートIP] ~]# cd /var/www/html
[root@ip-[パブリックインスタンスのプライベートIP] html]# nano index.html
```

## 4. Apacheを起動する
```
[root@ip-[パブリックインスタンスのプライベートIP] html]# service httpd start
```

## 5. パブリックIPにアクセスする
作成したネットワークACL（`test-vpc-acl`）にサブネットが関連付けられていないため、アクセスが可能
![スクリーンショット 2020-08-15 11.17.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/3e45475f-1b1b-4a97-4cb3-c397d05f8dc5.png)

## 6. インバウンドルールを追加する
![スクリーンショット 2020-08-15 14.14.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/aaaf0466-0940-6f2d-5268-fa9b8756bae9.png)

ルールは番号の順に適用される
![スクリーンショット 2020-08-15 14.17.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/5120167f-0252-2f52-bac4-6ad25f0ae37f.png)

## 7. アウトバウンドルールを追加する
![スクリーンショット 2020-08-15 14.20.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/a48b18d7-151c-6c24-13c9-a5ba452b8082.png)

クライアント側のポート番号は固定ではなく、**エフェメラルポート**が自動で割り当てられているため、カスタムTCPルールでエフェメラルポートのポートレンジを設定する必要がある
![スクリーンショット 2020-08-15 14.25.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/95ab89c9-6c83-4aa1-fe4a-1f66bdfa8daa.png)

## 8. サブネットを関連付ける
![スクリーンショット 2020-08-15 14.27.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/280d954a-f93b-e16b-60e1-edc936db7466.png)
![スクリーンショット 2020-08-15 14.29.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/7decfbe6-90e1-fbe5-11eb-d12d2adde011.png)

### 再度パブリックIPにアクセスする
ネットワークACLによるアクセス制御がうまくいっていることが確認出来る
![スクリーンショット 2020-08-15 11.17.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/3e45475f-1b1b-4a97-4cb3-c397d05f8dc5.png)
ノーコード(No code) Adaloを使おうとしたが断念した話し

情弱で他のノーコード(No code) で今から説明することが実現できる場合は教えてください。

## Rails APIのユーザーデータを使いたい

/login とかにPostして Herokuの上に乗ってるDBデータを使って、モバイルアプリを使いたくて、それができればノーコード(No code) 完璧やんって思った。

## でも無理だった

https://forum.adalo.com/t/is-it-possible-to-login-using-external-data-with-adalo/3983


> Hey there, third party authentication isn’t available yet… But do help to upvote it on Adalo’s roadmap. It’d help them prioritise that (VERY MUCH needed) feature.
DjangoのTemplateDoesNotExistの対処法

#TemplateDoesNotExist
Djangoで、以下のコードを実行したときに上記のエラーが出た。

```python:views.py

from django.template.response import TemplateResponse


def product_list(request):
    return TemplateResponse(request, 'catalogue/product_list.html')
```
どうすればいいのか。見るべき場所はsetting.pyの中の2箇所。

##１．Templateのパス
以下のようになっているか確認する。

```python:setting.py
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
```
こうなっていればオッケー。デフォルトでこうなっているはずなので、変更していなければ大丈夫なはず。

##２．INSTALLED_APPS
筆者のエラーの原因はここだった。

```python:setting.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'ec.catalogue',
]
```

INSTALLED_APPSには、そのプロジェクト内の全てのアプリケーションを登録する必要がある。
つまり、views.pyやurls.pyが入っている場所も追加しなければならない。
よって、アプリケーションが入っている場所（筆者の場合はec.catalogue）を追加することで、Templateを使えるようになった。
ハッカソン中にM5StackでMQTTに挑戦しようとしてダメだったメモ

#ハッカソンでMQTT挑戦しようとしてテンパってたね
先日ヒーローズリーグのM5Stackハッカソンに参加してきました。
今までM5Stackを触ったことが無かったものの、2度目のハッカソンなので気合十分で挑戦。
しかし、最初のアイデア実現には「MQTT」というものを使わないといけないらしいﾅｧﾆｿﾚﾍｪｪ

色々トライしてみたものの結局うまくいかず、アイデア自体の方向転換を余儀なくされました。
その時に調べたものを備忘録的にメモしておきます。

#備忘録
##M5Stackまわり
・M5Stack：おしゃれなマイコン。自分が持ってるのはBasic。このドキュメントからセットアップ。Driver InstallationとM5Burnerの項目だけやる。終わったら下記UIFlowへ
https://docs.m5stack.com/#/en/quick_start/m5core/m5stack_core_get_started_MicroPython

・UIFlow：M5Stackに入れる処理の実装GUIツール。ブロックを組み合わせて処理を作る。M5StackをUSB接続し、作ったら右上の再生ボタンで実行。ブロックの保存は右上のハンバーガボタンから。
　https://m5stack.github.io/UIFlow_doc/ja/

##MQTTまわり
・そもそもやりたかったこと：
　端末を操作してサーバーへリクエストするのは、httpリクエストを出せばいいだけだからできる。
　例えばブラウザ上の操作で情報をinputして、それを端末に送ることはできるのかなぁと思い、手段としてMQTTとArduino IDEがあるらしい。
　ArduinoはC言語を使うらしく、ハッカソンの時は一旦MQTTで作戦を考えました。
　このあたり何かご指摘ありましたらコメントお願いしたいです。

・MQTTとは：Pub/Subの仕組みを使ってM5Stackへ情報を送れるらしい。仕組みも理解しないと。
　https://dotstud.io/docs/mqtt/

・テスト用MQTTブローカ：本番環境には使えないけど疎通確認などには便利！
　https://mqtt.uko.jp/

・他のMQTTブローカ＆セットアップ：Shiftr.ioというサービスを使っている
　https://qiita.com/kmaepu/items/644b0bf2c3f438e71aa6

・MQTTとUIFlowを組み合わせたい：
　https://qiita.com/kmaepu/items/74a04c79607c43f4cbff

・M5StickからMQTTを使ってサーバーへ通信するパターン：
　https://qiita.com/kmaepu/items/74a04c79607c43f4cbff

・pythonでMQTTのpublishをするとき：
　https://qiita.com/hsgucci/items/6461d8555ea1245ef6c2

#さいごに
1年後の自分がこれを見返したときに、「こんな記事なんて見なくても頭に入っているぜ」となっていると嬉しいです。
というかなっててね？？？？？？？？？？？？？？？？？？？？
【VPC】プライベートインスタンスへのアクセス

## やること
- NATゲートウェイを作成し、パブリックインスタンスからプライベートインスタンスにインターネット接続する
- MySQLをインストールし、DBサーバーを構築する

## 1. シークレットキーを作成する
プライベートインスタンス作成時に使用したキー（pemファイルの中身）をパブリックインスタンス側に配置する

```
[root@ip-[パブリックインスタンスのプライベートIP] ~]# nano myprivatekey.pem　//キーを貼り付ける
```

## 2. キーにアクセス権限を付与する
```
[root@ip-[パブリックインスタンスのプライベートIP] ~]# chmod 400 myprivatekey.pem　//読み取り権限を付与
```

## 3. プライベートインスタンスにアクセスする
パブリックインスタンス側に配置したプライベートインスタンスのキーを使用

```
[root@ip-[パブリックインスタンスのプライベートIP] ~]# ssh ec2-user@[プライベートインスタンスのプライベートIP] -i myprivatekey.pem
[ec2-user@ip-[プライベートインスタンスのプライベートIP] ~]$　//アクセス完了
```

## 4. インターネットへの接続を試みる
```
[ec2-user@ip-[プライベートインスタンスのプライベートIP] ~]$ sudo su -
[root@ip-[プライベートインスタンスのプライベートIP] ~]# yum update -y
```
yumファイルのアップデートは応答無しでタイムアウトとなる
→ プライベートインスタンスからインターネットへのトラフィックが処理されない状態

## 5. NATゲートウェイを作成する
![スクリーンショット 2020-08-15 0.48.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/8f296f59-9a0a-b2f1-f15c-7eb83c06a141.png)

パブリックサブネットを選択し、Elastic IPアドレスを自動割り当てする
![スクリーンショット 2020-08-15 0.51.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/4453f16a-e87b-b4d9-9a80-52b3267f2a4f.png)

### 作成完了
![スクリーンショット 2020-08-15 0.58.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/5a0414f5-437e-cf58-8174-649618ae64c1.png)

## 6. ルートテーブルを編集する
プライベートサブネットのルートテーブルにNATゲートウェイを追加する
![スクリーンショット 2020-08-15 1.07.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/f59c3205-74e1-2088-2b71-76d36dac2363.png)

## 7. ルートテーブルにNATゲートウェイを追加する
![スクリーンショット 2020-08-15 1.10.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/4c2f33b1-fb8f-1706-1c21-51497aa035b2.png)

## 8. 再度インターネットへの接続を試みる
プライベートインスタンスとインターネットの疎通の成功が確認出来る

```
[root@ip-[プライベートインスタンスのプライベートIP] ~]# yum update -y
:
:
Updated:
  amazon-linux-extras.noarch 0:1.6.12-1.amzn2    amazon-linux-extras-yum-plugin.noarch 0:1.6.12-1.amzn2    ca-certificates.noarch 0:2019.2.32-76.amzn2.0.3   
  python.x86_64 0:2.7.18-1.amzn2.0.1             python-devel.x86_64 0:2.7.18-1.amzn2.0.1                  python-libs.x86_64 0:2.7.18-1.amzn2.0.1           
  python2-rsa.noarch 0:3.4.1-1.amzn2.0.1         tzdata.noarch 0:2020a-1.amzn2                            

Complete!
```

## 9. DBサーバーを構築する
mysqlをインストールし、DBサーバーとしての設定が完了

```
[root@ip-[プライベートインスタンスのプライベートIP] ~]# yum install -y mysql
：
：
Installed:
  mariadb.x86_64 1:5.5.64-1.amzn2                                                                                                                             

Complete!
```
Mavenプロジェクトの作り方

##Mavenプロジェクトの作り方
```$mvn archetype:generate```
上記のコマンドをターミナル・コマンドプロンプトで実行すると、Mavenプロジェクトが作られ始めます。（＊Mavenをインストールしておく必要がある。私の場合はhomebrewでインストールしました。）
そして以下の事を聞かれるので、以下のように答えていきます。

```Choose a number or apply filter```
上記のメッセージが出てくる。これはグループIDの指定。
フィルターを設定する必要がないのであればEnter。

```Choose org.apache.maven.archetypes:maven-archetype-quickstart version:```
リストの中から使いたいバージョンを選択。
特にないならEnter。

```Define value for property ‘groupId’::```
これはプロジェクトのグループID。
基本的に作成するプログラムを配置するパッケージを指定。
パッケージ名を何か適当に入力
（例：　jp.tuyano.spring.sample1）

```Define value for property ‘artifactId’::```
アーティファクトIDを入力。
プロジェクトの名前を入力。
（例：MySampleApp1）

```Define value for property ‘version’: 1.0-SNAPSHOT::```
バージョン名。1.0-SNAPSHOTがデフォルトで指定されている。
特に変える必要がないのであればEnter。

```Define value for property ‘package’:```
さっきグループIDで入力したものがデフォルトで設定されているので、Enter。

次に内容の確認。Y／Nで聞かれるから間違っていなかったら、Y

---
##MavenによるBuild

```$ cd プロジェクト名（MySampleApp1）
$mvn install```
プログラムをパッケージ化し、ローカルリポジトリにインストールする命令。
必要なライブラリをダウンロードして、プロジェクトを指定のパッケージファイルにまとめてくれる。

プログラムをコンパイルするならmvn compile,
パッケージを作成するならmvn package
などのコマンドがある。
ここら辺は適宜調べてみるといいと思います。

---
##Mavenによる実行
```$cd target```
```$java -classpath ./MySampleApp1-1.0-SNAPSHOT.jar jp.tuyano.spring.sample1.App```
"/"を使っているが"/"の部分をOSによって変える必要がある。
https://stackoverflow.com/questions/4528438/classpath-does-not-work-under-linux
[MySQL]挿入後のテーブルの一番お尻の行のidの値を取得する


# はじめに やりたいこと

タイトル通り「挿入後のテーブルの一番お尻の行のidの値を取得」したい。

次のようなテーブルがあるとする。

- テーブル名：user_list

|id  |ユーザー名  |
|---|---|
|**1**  |**はじめ君**  |
|2  |次子ちゃん  |
|3  |三版君  |
|4  |四手ちゃん  |
|5  |五点さん  |

※idは[オートインクリメント](https://www.dbonline.jp/mysql/table/index7.html)の属性があるため挿入のたびに自動で+1されるとする。

上記テーブルを下記のようにした際に一番お尻のidの値(今回だと6)を取得する方法を紹介する

```
-- (コメント)：id=1のユーザーを一番おしりに挿入。
INSERT INTO user_list (ユーザー名)
SELECT ユーザー名 FROM user_list WHERE id = 1;
```

※ちなみに上のようにINSERTとSELECTを組み合わせる場合は`VALUES`はいらないのです！([INSERT...SELECT構文](https://dev.mysql.com/doc/refman/5.6/ja/insert-select.html))

- テーブル名：user_list

|id  |ユーザー名  |
|---|---|
|**1**  |**はじめ君**  |
|2  |次子ちゃん  |
|3  |三版君  |
|4  |四手ちゃん  |
|5  |五点さん  |
|**6**  |**はじめ君**  |


### [やり方1] idの大きい順に並べ替えて一番最初の行のidを取得

まず並べ替えの方法を復習しましょう。
あるカラム(列)を基準にソート(並べ替え)するには`ORDER BY`句を用います。また逆順のソートをするには`DESC`キーワードを追加します。また、`LIMIT` 句を使用すると、`SELECT` ステートメントによって返される行数を制約させることが出来ます。

```
ORDER BY 基準のカラム(列) DESC LIMIT 制限数;
```

※参考：[SELECT 構文/MySQL公式](https://dev.mysql.com/doc/refman/5.6/ja/select.html)

以上から(1)「idを`ORDER BY`句と`DESC`で大きい順に並べて」(2)「`LIMIT`句で1に限定」すれば、idの一番大きい値が取得出来ることがわかるでしょう。

実際にやってみましょう。

```
SELECT id FROM user_list ORDER BY id DESC LIMIT 1;
->6
```


### [やり方2] 情報関数を用いて挿入されたidの値を取得

MySQLでは標準で便利な関数が数多く用意されています。今回はそういった関数の中の[情報関数](https://dev.mysql.com/doc/refman/5.6/ja/information-functions.html#function_last-insert-id)の一つである`LAST_INSERT_ID()`を用いて『前回の INSERT での AUTOINCREMENT カラムの値』を取得しましょう。

```
SELECT LAST_INSERT_ID();
```

こちらのほうが圧倒的に簡単ですね。

ただし公式ドキュメントにもある通り`LAST_INSERT_ID`関数は『AUTOINCREMENT カラムの値』を取得してくれるだけであって『最後にインサートしたレコードのID』では無いことに注意しましょう。
※参考：[MySQLのlast_insert_id()は「最後にインサートしたレコードのID」じゃなかった/個人ブログ](https://blue1st.hateblo.jp/entry/2015/08/11/000821)

本日は以上です。
VScodeでXdebugでデバックするときの、実行方法

こんにちは！　kouです。
今日は、vscodeでxdebugを使うために注意すべきことについて説明します！
この記事は、[Visual Studio CodeでPHPをデバッグする方法](https://qiita.com/deux222/items/af75319ece05653c4bb5)に、補足を加えたものです
##実施環境
* windows10
* visual studio code(以下vs code)が、インストール済み
* xamppがC:直下にインストール済み
* [Visual Studio CodeでPHPをデバッグする方法](https://qiita.com/deux222/items/af75319ece05653c4bb5)を読んで手順４までが完了している

#lunch.jsonファイル
実行したいファイルがあるフォルダーを開き、実行したいファイルを選択＞左メニューバーからデバッグボタンをクリック
![create-launch.json.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642180/b5d20e83-6008-f81a-4a2b-1dc882a46e17.png)
"launch.jsonファイルを作成します"をクリックし、PHPを選択![launch.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642180/4c5acc98-f3ae-3806-5323-9b4bfc2dec88.png)

launch.jsonに、["runtimeExecutable": "C:\\xampp\\php\\php.exe"]という行を追加し、下記のように修正。"runtimeExecutable"パスには、php.exeのpathを入力

*修正後

```php5:lunch.json
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Listen for XDebug",
            "type": "php",
            "request": "launch",
            "port": 9000
        },
        {
            "name": "Launch currently open script",
            "type": "php",
            "request": "launch",
            "program": "${file}",
            "cwd": "${fileDirname}",
            "port": 9000,
            "runtimeExecutable": "C:\\xampp\\php\\php.exe"
        }
    ]
}
```

#デバックの方法１－Webサーバーを使わないでデバック
「Launch currently open script」が選択されていることを確認し、デバック開始ボタンを押す
![launch-current.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642180/d24e58e8-1132-a205-f4ba-238c874bc5f8.png)

#デバックの方法２－Webサーバーからデバック
xmappで、Actions>Start からapacheを起動し、adminをクリック![xmapp-ctrl.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642180/c877506f-53d8-7180-01ba-6d7e74224cba.png)
すると、このような画面が開く
![localhost.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642180/8ede9ef0-431e-1ee6-d9be-c0c92878d971.png)
そこで、vscode上で、左サイドバー＞listen for XDebugをクリック
その状態でapache上から実行したいファイルを開くと、デバッグができる
【備忘録】grib2形式のデータをcsvファイルに変換するスクリプトを作成しました

# 目的
- grib2形（バイナリ）のデータをCSVファイル出力するスクリプトを作成しました。
- データは、気象庁HPの[GPVサンプルデータの一覧](http://www.data.jma.go.jp/developer/gpv_sample.html)から高解像度降水ナウキャストをダウンロードして使用しました。

※備忘録です

# 前提条件
- Windows10
- Windows PowerShell
- [wgrib2](https://www.ftp.cpc.ncep.noaa.gov/wd51we/wgrib2/Windows_64/)がダウンロード済みであること
- こちらの[ブログの記事](https://ods.n-kishou.co.jp/tech/blog/detail/?pid=2869)を参考にさせていただきました。

# 実行
- wgrib2.exeは、上記でダウンロードしたexeのフルパスを指定してください。
- inputfileは、csvファイルに変換するbinファイルのフルパスを指定ください。
- outputfileは、出力するcsvファイルのフルパスを指定してください。
- ③では、「anl（初期時刻）」で絞り込みを行い、csvファイル出力しています。

```grib2toCSV_anl.ps1
# ①grib2形式のデータの中身を確認する
wgrib2.exe inputfile.bin

# ②grib2形式のデータをcsvファイル出力する
wgrib2.exe inputfile.bin -csv outputfile.csv

# ③grib2形式のデータをanl(初期時刻）で絞り込んでcsvファイル出力する
wgrib2.exe -match "anl" inputfile.bin -csv outputfile.csv

# ④grib2形式のデータの格子配列を確認する
wgrib2.exe -grid *.bin
```

#変換結果
- 変換結果は、上記の③で実行した結果になります。
- 1列目、2列目の日時はUTCになります（日本時間では2016年8月22日11:00）。
- 7列目に降水量の数値が入っています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205045/ccbdb00a-4927-32b6-4a24-72c7589f6f40.png)
Sapper × Go(echo) × Dockerの開発環境構築

# はじめに
フロント:Svelte.js(Sapper),API:Go(echo)でアプリを作ってみたかったので
Dockerを使って構築した。

# どこまでやるか
Sapper,echoをローカルホストで接続できるところまで

# 初期のディレクトリ構造
今回の環境構築にあたり、[「Vue.js + Go言語 + Docker」で作る！画像アップロード機能実装ハンズオン
](https://qiita.com/po3rin/items/c70105f684e6816621d2)を参考にさせていただきました。

シンプルでわかりやすい。

```bash

.
├── docker-compose.yml
└── server
```
# Sapperの開発環境構築

```bash

npx degit "sveltejs/sapper-template#rollup" client

cd client
npm install
touch Dockerfile_develop
```

Dockerfileですが、自分の場合production用のDockerfileも用意したいため、名前を`Dockerfile_develop`にしてます。
特に分ける必要がなかったり、マルチステージビルドでおさまりそうであれば一個にしてしていただいて構いません。

Dockerfile

```Dockerfile
FROM mhart/alpine-node:12

WORKDIR /app
COPY package.json package-lock.json ./

RUN npm ci

ENV HOST=0.0.0.0
EXPOSE 3000
```
docker-compose.yml

```yml
version: '3.8'

services:
  client:
    env_file: .env
    build: 
      context: ./client
      dockerfile: Dockerfile_${DOCKER_ENV} # この行はいらなければ削除
    ports:
      - 3000:3000
    tty: true
    volumes:
      - ./client:/app
    command: npm run dev
```

※環境変数がある場合

```
touch .env
vim .env
```

```
DOCKER_ENV=develop
```

この段階でSapperが起動するかみてみましょう

```bash
docker-compose up --build
```

# Go(echo)の開発環境構築

```bash
cd server
touch Dockerfile
touch main.go
```
Dockerfile

```Dockerfile
FROM golang:1.15.2-alpine


WORKDIR /go/src/api
ADD .  /go/src/api
ENV GO111MODULE=off

RUN apk update && apk add curl git
```
main.go

```go
package main

import (
  "net/http"
  "github.com/labstack/echo"
)

func main() {
  e := echo.New()
  e.GET("/", func(c echo.Context) error {
    return c.String(http.StatusOK, "Hello, World")
  })
  e.Logger.Fatal(e.Start(":8080"))
}
```

docker-compose.yml

```yml

version: '3.8'
...
  server:
    build: ./server
    ports:
      - 8080:8080
    tty: true
    volumes:
      - ./server:/api
```

echoのローカルサーバーを立ち上げます。

```bash
docker-compose up --build
docker-compose exec server /bin/ash
go get github.com/labstack/echo
go run main.go
```
これで`localhost:8080`にアクセスできれば完了です。

# おわりに

次は`Gorm`, `MySQL`を入れるところまでやりたい

# 参考資料
[「Vue.js + Go言語 + Docker」で作る！画像アップロード機能実装ハンズオン](https://qiita.com/po3rin/items/c70105f684e6816621d2)
[svelteの開発環境の作り方](https://qiita.com/mkin/items/22272dc052e9cdf80a8b)
[Hello World Recipe](https://echo.labstack.com/cookbook/hello-world)
勉強メモ2_OpenPyXLの読み込み、書き込みサンプル

★1 この記事で簡単に作れる

　https://techacademy.jp/magazine/23344

　後、この記事も確認
　https://tonari-it.com/python-openpyxl-beginner/

★2 Excel作成用のサンプルコードを作成してeclipseで実行

```python:SampleCreateExcel.py
'''
Created on 2020/09/20

@author: rinchome
'''
import openpyxl
import os

# ワークブックを新規作成する
book = openpyxl.Workbook()

# シートを取得し名前を変更する
sheet = book.active
sheet.title = 'First sheet'

# 範囲を指定してセルを取得する
cells = sheet['A1':'B3']
i = 0
for row in cells:
    for cell in row:
        cell.value = i # セルに値を設定する
        if i == 1:
            cell.value = 'aiueo'

        i += 1

# ワークブックに名前をつけて保存する
book.save('demo.xlsx')

#保存された場所確認
print(os.getcwd())

# demo.xlsx保存確認
ls = os.listdir(os.getcwd())
print(ls);
```
★3 Excel読み込み用のサンプルソースを作成してeclipseで実行

```python:SampleReadExcel.py
'''
Created on 2020/09/20

@author: rinchome
'''
import openpyxl

wb=openpyxl.load_workbook('demo.xlsx')

sheet = wb.get_sheet_by_name('First sheet')

a1Val = sheet['B1'].value

print(a1Val)
```
【JavaScript】自分なりのワンライナー（配列操作）

元記事はこちらになります。

ワンライナーで行こう！（JavaScriptで配列操作いろいろ）
https://qiita.com/snst-lab/items/cf1fe64cfad70838ee93

こちらで気になったものを自分なりに。
1年以上前の記事に今更かもしれませんが…

重複の削除は`filter`使うより`Array.form(new Set(arr))`が良いという記事はあちこちで見るので割愛。

#startからendまでの連続した数値配列を生成する

2行目だけ見て書いたら、1行目がほぼ同じだったので削除

#配列の中身を結合した文字列を作る
```javascript
const string = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].join('');

console.log( string );		//'0123456789'
```
元記事では正規表現でreplaceしてたのがきになりました。

#隣り合うN個の要素をまとめた配列の配列を作る（N=3）
```javascript
const array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

const wrapInArray = (arr, n) => 
	Array(Math.floor(arr.length/n)).fill().map( (_, i) => arr.slice(i*n, i*n+n) );

console.log ( wrapInArray(array, 3) );		//[[0, 1, 2], [3, 4, 5], [6, 7, 8]]
console.log ( wrapInArray(array, 2) );		//[[0, 1], [2, 3], [4, 5], [6, 7], [8, 9]]
```
N個未満になる配列も残したい時は、`Math.floor()`ではなく`Math.ceil()`に変更

```javascript
const wrapInArray = (arr, n) => 
	Array(Math.ceil(arr.length/n)).fill().map( (_, i) => arr.slice(i*n, i*n+n) );
```


#まとめ
`Array(n).fill().map((_, i)) => {...});`を使いたいだけの記事でした。
Lambdaから引数を指定して AWS Batch起動方法

## 概要

[前回](https://qiita.com/dmikita/items/af33d64f4d6aef556439)作成したAWS BatchをLambdaから実行するようにします。


## 準備

AWS Batchは[前回](https://qiita.com/dmikita/items/af33d64f4d6aef556439)のものをそのまま使います。AWS BatchのジョブさえできていればいいのでCodeCommitなどはこのためだけに準備しなくても大丈夫です。


### Lambdaの準備

* Lambdaを作成します。今回はpythonで実装していますがほかの言語でも可能です。
    * JOB_NAME はジョブ定義の名称
    * JOB_DEFINITION はジョブ定義のジョブ定義ARN
    * JOB_QUEUE はジョブキューのキューARN
        * `XXXXXXXXXX` の部分はAWSのアカウントIDを設定します。
    * `command` の部分に引数をリスト形式で
    * `environment` には環境変数を辞書形式 name,valeの辞書をリスト形式で設定します

```python
import json
import boto3

def lambda_handler(event, context):
    
    client = boto3.client('batch')

    JOB_NAME = 'pandas-envtest'
    JOB_QUEUE = "arn:aws:batch:ap-northeast-1:XXXXXXXXXX:job-queue/first-run-job-queue"
    JOB_DEFINITION = "arn:aws:batch:ap-northeast-1:XXXXXXXXXX:job-definition/pandas-envtest:1"

    response = client.submit_job(
        jobName = JOB_NAME,
        jobQueue = JOB_QUEUE,
        jobDefinition = JOB_DEFINITION,
    containerOverrides={
        'command': [
            'test','abc','ckd'
        ],
        'environment': [
            {
                'name': 'DYNAMODB_REGION',
                'value': 'test'
            }
        ]
    }
    )
    print(response)
    
    return {
        'statusCode': 200,
        'body': json.dumps('run')
    }

```

* 実行結果は以下のようになります。
* 引数で指定した内容と環境変数が出力されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657697/ae278434-e0da-8844-89fb-04e40ac6751b.png)


* パラメータを外から送信してlambdaを通してバッチを起動するような形にできます。
DDコマンドでSDカードまるごとバックアップ

#はじめに
ラズパイイメージをSDカードからまるまるバックアップしてバージョン管理がしたい。
環境はUbuntu 20.0.4

#ddコマンドについて
ddコマンドは、dataset definitionコマンドで、ディスクドライブのデータを読み出し・書き込みを行うコマンド。ファイルでのコピーとは異なり、バイナリとしてコピーできるので、MBRやGPTなどのパーティション情報や、ファイルシステムのメタデータまでバックアップができる。そのため、SDカードやHDDの完全なバックアップをとることができるので、万が一今のディスクが破壊されたとしても、バックアップイメージを新しいディスクドライブに書き込めば全く同じ状態に戻すことができる。
なお、ddコマンドはdisk destroyerとも呼ばれている。これは、書き込み先のディスクを誤ってOSの入っているシステムドライブに指定してしまうとデータが壊れて起動しなくなってしまう(筆者は2,3回破壊している・・・)という恐ろしいコマンドであることに由来している。
コマンドを実行する前に、書き込み先を念入りに確認すること。。

#手順
まず、fdiskコマンドを使用してSDカードがどのデバイスファイルとして認識されているか確認する。

```shell
#SDカードを外した状態で実行
$sudo fdisk -l > before.txt

#SDカードを挿入した状態で実行
$sudo fdisk -l > after.txt

#diffコマンド挿入前後で追加されたデバイスファイルの差分を確認する
$diff -urpN before.txt after.txt
--- before.txt	2020-09-20 15:01:01.056882300 +0900
+++ after.txt	2020-09-20 15:00:35.895621277 +0900
@@ -59,6 +59,19 @@ Device       Start       End   Sectors
 /dev/sda2  1050624 490233855 489183232 233.3G Linux filesystem
 
 
+Disk /dev/sdb: 29.74 GiB, 31914983424 bytes, 62333952 sectors
+Disk model: SD Card Reader  
+Units: sectors of 1 * 512 = 512 bytes
+Sector size (logical/physical): 512 bytes / 512 bytes
+I/O size (minimum/optimal): 512 bytes / 512 bytes
+Disklabel type: dos
+Disk identifier: 0x4a030cf2
+
+Device     Boot  Start      End  Sectors  Size Id Type
+/dev/sdb1         8192   532479   524288  256M  c W95 FAT32 (LBA)
+/dev/sdb2       532480 62333951 61801472 29.5G 83 Linux
+
+
 Disk /dev/loop8: 160.16 MiB, 167931904 bytes, 327992 sectors
 Units: sectors of 1 * 512 = 512 bytes
 Sector size (logical/physical): 512 bytes / 512 bytes
```

/dev/sdbがバックアップ対象SDカードのデバイスファイルであることが分かる。sdb1, sdb2とかっていうのは、ディスク内のパーティション番号。

ddコマンドでバックアップする。32GBもバックアップしたくないな。。
とりあえず、テスト用bs(buffer size)3回分(3*4M = 12MB)だけバックアップする。

```shell
$sudo dd bs=4M if=/dev/sdb of=./backup.img conv=fsync count=3
$ls -l 
total 12288
-rw-r--r-- 1 root root 12582912  9月 20 15:07 backup.img
```
できた！

count=3を削除すれば、まるごとバックアップできるはず。
AtCoder ABC 179 Python (A~E)

# 総括
A, Bのみ解けました。
最近パフォーマンスが下がり続けています。


#問題
https://atcoder.jp/contests/abc179

# A. Plural Form
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668985/949e626b-3470-4bbf-b6a2-1127ce61c16d.png)

##### 回答

```python

S = input()

if S[-1] == 's':
    answer = S + 'es'
else:
    answer = S + 's'

print(answer)


```
問題文通り書きます。


# B. Go to Jail
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668985/77efc646-2616-4fd3-6f3d-3e2d60d6c76c.png)

##### 回答
```python

N = int(input())
D = [tuple(map(int, input().split())) for _ in range(N)]

answer = 'No'

count = 0
for i in range(N):
    if D[i][0] != D[i][1]:
        count = 0
    else:
        count += 1
    
    if count == 3:
        answer = 'Yes'
        break

print(answer)

```

ぞろ目を判定し、```count```が```3```に達したら```Yes```を返します。


# C. A x B + C
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668985/f7183899-ba0a-710b-f7b1-785b9779996d.png)

##### 回答

```python

N = int(input())

answer = 0
for a in range(1, N):
    answer += (N-1) // a

print(answer)

```

制約を考えるとforループは1回しか回せそうにないです。
```A * B + C = N``` を変形して```A * B = N - C``` とすると```A * B ```の組み合わせの数を数える問題とよみかえられます。


# D. Leaping Tak
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668985/fac1846f-3f99-ea6c-e752-b0995eb071a6.png)

##### 回答
```python

MOD = 998244353
N, K = map(int, input().split()) #Nはマス目の数、Kは区間の数(Kは10以下)
kukan = [tuple(map(int, input().split())) for _ in range(K)]

dp = [0] * (N+1)
dp[1] = 1

sumdp = [0] * (N+1)
sumdp[1] = 1

for i in range(2, N+1):
    for l, r in kukan:
        li = max(i - l, 0)
        ri = max(i - r - 1, 0)

        dp[i] += sumdp[li] - sumdp[ri]
        dp[i] %= MOD

    sumdp[i] = sumdp[i-1] + dp[i]

print(dp[N])

```

普通に```dp```をとると間に合わないので、```dp```と累積和```sumdp```を使用します。


# E. Sequence Sum
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668985/53c17945-e431-f592-593f-85d9e4be41e7.png)

##### 回答
```python

N, X, M = map(int, input().split())
count_memo = [-1] * 10**6 # 回数のメモ
num_memo = [0] # Aのメモ。1インデックスるにする. 

a = X
count = 1
count_memo[a] = count
num_memo.append(a)
for i in range(1, N):
    a = a**2 % M
    if count_memo[a] == -1:
        count += 1
        count_memo[a] = count
        num_memo.append(a)
    else:
        break

if count == N: # サイクルに入る前に終わった場合は全部合計
    answer = sum(num_memo)
else:
    # 周期に入るまでの回数と合計
    count_before_cycle = count_memo[a] - 1
    sum_before_cycle = sum(num_memo[:count_before_cycle+1])
    # 1周期の数と合計
    count_cycle = count - count_before_cycle
    sum_cycle = sum(num_memo[count_before_cycle+1:])
    # 残りのサイクルの数と合計
    cycle_count = (N - count) // count_cycle
    sum_after_cycle = sum_cycle * cycle_count
    # あまりの数と合計
    remain_count =  (N - count) % count_cycle
    sum_remain = sum(num_memo[count_before_cycle+1:count_before_cycle+1 + remain_count])

    answer = sum_before_cycle + sum_cycle + sum_after_cycle + sum_remain

print(answer)

```

```A``` はどこかでサイクルに入ります。
したがって、
1. サイクルに入る前
2. サイクル
3. サイクルの繰り返し
4. サイクルの途中で終わる余分な回数
の4通りに分けて足し合わせます。
【VPC】サブネット間の接続設定

## やること
- [【VPC】サブネットへのサーバーの設置](https://qiita.com/777cb_/items/aff770b6f0572910e857) で起動したサーバーを使用
- WebサーバーからDBサーバーへの接続を可能にする

## 1. WebサーバーにApacheをインストールする
Webサーバー用のEC2インスタンス（`test-publicserver`）にインストール

```
$ ssh -i ~/.ssh/[秘密鍵名].pem ec3-user@[パブリックIP]
[ec2-user@ip-[プライベートIP] ~]$ sudu su -
[root@ip-[プライベートIP] ~]# yum update -y
[root@ip-[プライベートIP] ~]# yum install -y httpd
```

## 2. セキュリティグループを作成する
DBサーバー用のEC2インスタンス（`test-privateserver`）のセキュリティグループを変更するために新規作成
![スクリーンショット 2020-08-14 20.44.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/5cc76de7-9261-9810-b7c5-bc9f0aea299d.png)

## 3. インバウンドルールを追加する
WebサーバーのIPアドレスからのアクセスのみを許可したいので、WebサーバーのCIDRブロック（`10.0.5.0/24`）を指定する
![スクリーンショット 2020-08-14 20.46.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/b9dcfa84-8e92-6432-c5de-8d498430e149.png)

## 4. セキュリティグループを変更する
DBサーバー用のインスタンス（`test-privateserver`）のセキュリティグループを変更
→ DBサーバーがWebサーバーとの疎通を許可する状態となる
![スクリーンショット 2020-08-14 21.11.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/b268e21d-d4bb-54d4-dc93-8f3c59418abf.png)
![スクリーンショット 2020-08-14 21.12.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379501/8ab7032f-981e-e943-fc33-463730804ef8.png)

## 5. サブネット間の接続を確認する
Webサーバー用インスタンスにssh接続し、DBサーバー用インスタンスのプライベートIPアドレスにpingで疎通する

```
[ec2-user@ip-[パブリックIP] ~]$ sudo su -
[root@ip-[WebサーバーのプライベートIP] ~]# ping [DBサーバーのプライベートIP]
```

### 接続の確認完了
```
PING 10.0.10.173 (10.0.10.173) 56(84) bytes of data.
64 bytes from 10.0.10.173: icmp_seq=1 ttl=255 time=2.65 ms
64 bytes from 10.0.10.173: icmp_seq=2 ttl=255 time=2.75 ms
64 bytes from 10.0.10.173: icmp_seq=3 ttl=255 time=2.61 ms
:
:
```

## 【 備忘 】
### <a href="https://qiita.com/kwtck_/private/9b7d5d49371889558a5f#1-%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%83%B3%E3%82%B9%E3%81%ABssh%E6%8E%A5%E7%B6%9A%E3%81%97apache%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B">手順1</a> でssh接続が出来ない！

**事象**：コマンドを実行しても応答が無く、タイムアウトしてしまう

**原因**：ルートテーブルがインターネットゲートウェイと関連付けられていなかった

**解決法**：<a href="https://xn--o9j8h1c9hb5756dt0ua226amc1a.com/?p=3583">AWS EC2にSSH接続できない・繋がらないときの確認項目</a> の「VPC のサブネット・インターネットゲートウェイを確認する」を参考に解決
Update your C# in Unity ~ nameof ~


Unityにおいて古いC#しか使えない時代もありました。しかし、それは過去のことです。本稿執筆時の最新LTSであるUnity 2019.4ではC# 7.3がサポートされています。また、本稿執筆時の最新Beta版であるUnity 2020.2ではC# 8.0がサポート予定です。

長らくUnityで古いC#しか使えなかったことで、「C#にこんな機能あるのか？知らなかった！」となることがある方も多いのではないでしょうか？この「Update your C# in Unity」シリーズでは、「C#の比較的新しい機能をUnityでこんな風に使えるよ！」という紹介を行います。


---

言語機能名: nameof
追加バージョン: C# 6.0
説明: 変数名、型名、メソッド・フィールド・プロパティなどのメンバ名を文字列リテラルとして取得する機能

利用例としては

* SendMessageの第一引数など、メソッド名を求められる箇所で、文字列リテラルべた書きではなくて、nameofを使う
* SerializedObjectのFindPropertyの第一引数など、フィールド名を求められる箇所で、文字列リテラルべた書きではなくて、nameofを使う

※ 個人的にはSendMessageの利用は避けるべきだと思っています。しかし、どうしようもない理由があって避けられない場合や、漸進的に改善をしていく必要がある場合、まずnameofで小さく改善するのがオススメです。

```csharp 
using UnityEngine;

public class EnemyLauncher : MonoBehaviour
{
    public void LaunchEnemy()
    {
        Debug.Log("Launched");
    }
}
```

```csharp 
using UnityEngine;

public class GameController : MonoBehaviour
{
    public void Start()
    {
        SendMessage(nameof(EnemyLauncher.LaunchEnemy));
    }
}
```

---

SendMessageやFindPropertyのように、メンバ（メソッドやフィールド）の名前を文字列リテラルとして引数にとる場合、コード中に文字列リテラルを直接埋め込むのではなく、`nameof`を使いましょう。

`nameof`を使うメリットは、「型名やメンバ名が変わった時に、対応する文字列リテラルの変更を変え忘れることが防止できる」ということです。

仮に、次のように文字列リテラルを直接引数として渡していて、使ってSendMessageを使っていたとします。

```csharp 
using UnityEngine;

public class GameController : MonoBehaviour
{
    public void Start()
    {
        // このように直接文字列リテラルを埋め込むのは避けるべき
        // EnemyLauncher型のLaunchEnemyメソッドの名前が変更された場合、実行時エラーになってしまう
        SendMessage("LaunchEnemy");
    }
}
```

この時、EnemyLauncher型のLaunchEnemyメソッドの名前が変えたとしましょう。同時に、GameControllerに直接埋め込まれている`"LaunchEnemy"`という文字列リテラルも変更しないといけません。しかし、これをうっかり変えそびれてしまうことがありえます。その場合、実行時エラーになってしまいます。このような実行時エラーは非常に厄介です。

---

一方で、次のように今回紹介する`nameof`を使っていた場合はどうでしょう？
EnemyLauncher型のLaunchEnemyメソッドの名前が変えた場合、GameController内の`nameof`内でコンパイルエラーになり、問題があることにすぐに気が付けます。
「メソッド名を変えたことが原因」の厄介な実行時エラーになる可能性を排除できます。
また、もしVisual SturioやRiderのリネーム機能でEnemyLauncher型のLaunchEnemyメソッドの名前が変えた場合、nameofの内部も自動的にリネームされ、非常に円滑にコードを編集することができます。

```csharp 
using UnityEngine;

public class GameController : MonoBehaviour
{
    public void Start()
    {
        // EnemyLauncher型のLaunchEnemyメソッドの名前が変更された場合、コンパイルエラーになり、厄介な実行時エラーの原因を事前に気付ける
        // また、IDEのリネーム機能を使った場合、↓の内容もリネーム対象となる
        SendMessage(nameof(EnemyLauncher.LaunchEnemy));
    }
}
```

このように`nameof`を使うメリットは、「型名やメンバ名が変わった時に、対応する文字列リテラルの変更を変え忘れることが防止できる」ということです。


---

この投稿では`nameof`のUnityでの利用例とそのメリットを説明しました。
なお、`nameof`のC#におけるより一般的な使い方は、INotifyPropertyChangedの実装や、ArgumentExceptionの引数に使うという利用方法です。
Unityにおいても、エラー文・警告文などでも使う場面があると思います。
変数名、型名、メソッド・フィールド・プロパティなどのメンバ名を文字列リテラルとして必要な場面では、積極的に`nameof`を使っていきましょう。


※ この投稿では、SendMessageを例に`nameof`を紹介しましたが、個人的にはSendMessageの利用は避けるべきだと思っています。しかし、どうしようもない理由があって避けられない場合や、漸進的に改善をしていく必要がある場合、まず`nameof`で小さく改善するのがオススメ。

---

関連・参考

* [C# 公式リファレンス](https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/operators/nameof)
* [++C++ nameof 演算子](https://ufcpp.net/study/csharp/st_string.html?sec=nameof-operator#nameof-operator)
プロジェクトにマイナスの影響を与えるリスクに対する戦略ー「回避」「転嫁」「軽減」「受容」

応用情報技術者平成29年春期 午前54

PMBOKガイド第5版における，マイナスのリスクに対する戦略として用いられる"リスク転嫁"の説明はどれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/59cd6832-66db-1b22-12ae-a8c0e76171cf.png)

１、プロジェクトのリスク
PMBOKガイド第5版において、リスクマネジメントとは「プロジェクトのリスクを識別し、分析し、リスクに対応するための系統的なプロセスで、プロジェクトの目標に対して
・プラスに働く事象には、それが起こる確率とその発生結果が最大となるように、
・マイナスに働く事象については、逆に最小となるようにすること」とされています。

２、マイナスの影響を与えるリスク対応
プロジェクトにマイナスの影響を与えるリスクに対して、「回避」「転嫁」「軽減」「受容」の4つの戦略があります。
・回避(かいひ)
　リスクそのものを取り除いたり、プロジェクトに影響がないようにスコープや目標を縮小・変更する方策。
・転嫁(てんか)
　リスクによるマイナスの影響を第三者へ移転する方策。リスクのある業務・作業のアウトソーシングや、損害保険の契約によってリスクの影響を自社から他社に移転する。
・軽減(けいげん)
　リスクの影響範囲を狭くしたり、発生確率を低減するような方策。
・受容(じゅよう)
　リスクが現実化した時の影響が許容可能範囲内である時やリスクの除去が困難である場合に、特段対策をせずにそのままにしておくこと。対策費用が予想される損失金額を上回っているときなどに採られる方策。


３、プラスのリスクもしくは好機に対する戦略
活用、共有、強化、受容の４つがある。

・活用
　好機が確実に来るようにすること
　有能な要因採用で、期間短縮・コスト削減するなど
・共有
　好機を実行する権限を、第三者に割り当てる
　パートナーシップ、ジョイントベンチャーの形成など
・強化
　発生確率・影響を増加させる
　アクティビティを早く終了させるために、資源を追加投入するなど
・受容
　積極的は利用しない

ーーーーーーーーーーーーーーーーーーーーーーー
補足

プロジェクトにおけるリスクには，マイナスのリスクとプラスのリスクがある。スケジュールに関するリスク対応策のうち，プラスのリスクへの対応策に該当するものはどれか。


ア、インフルエンザで要員が勤務できなくならないように，インフルエンザが流行する前にメンバ全員に予防接種を受けさせる。
イ、スケジュールを前倒しすると全体のコストを下げられるとき，プログラム作成を並行して作業することによって全体の期間を短縮する。
ウ、突発的な要員の離脱によるスケジュールの遅れに備えて，事前に交代要員を確保する。
エ、納期遅延の違約金の支払に備えて，損害保険に加入する。


イは、「全体のコストを下げられる」ことはプラスの影響です。事例はプラスの影響に対して、その好機の発生確率を高める活動なので、リスク強化策に分類されます。


ーーーーーーーーーーーーーーーーーーーーーーー
補足

PMBOKによれば，脅威となるマイナスのリスクと，好機となるプラスのリスクの，どちらのリスクに対しても採用される戦略はどれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/375dbb02-4433-0fae-9d22-59a0015f0563.png)

マイナスのリスクとプラスのリスクで採用される戦略は、両方ともあるのは、受容ですね。

参照：
https://www.itpassportsiken.com/kakomon/30_haru/q47.html#:~:text=%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%83%AA%E3%82%B9%E3%82%AF%E3%81%A8%E3%81%AF,%EF%BC%88%E8%84%85%E5%A8%81%EF%BC%89%E3%80%8D%E3%81%8C%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82


プラスのリスクもしくは好機に対する戦略
http://bluesnap.net/pmbok/index.php?%A5%D7%A5%E9%A5%B9%A4%CE%A5%EA%A5%B9%A5%AF%A4%E2%A4%B7%A4%AF%A4%CF%B9%A5%B5%A1%A4%CB%C2%D0%A4%B9%A4%EB%C0%EF%CE%AC

https://www.ap-siken.com/kakomon/29_haru/q54.html


https://www.ap-siken.com/kakomon/28_aki/q54.html
Javaに初めて触れてみた②

# Javaに触れてみました。
自己満の備忘録ですのでご容赦ください。

## プログラムの基本構造
プログラムの動きは3つだけ。
①順次進行
②条件分岐
③繰り返し

## 順次進行
```Greeting.java
class Greeting {
  public static void main(String args[]) {
    System.out.println("Good morning");
    System.out.println("Good afternoon");
    System.out.println("Good evening");
  }
}
```

```:ターミナル
$ javac Greeting.java
$ java Greeting

Good morning
Good afternoon
Good evening
```

javac Greeting.javaでGreeting.classというフォルダが作成されるようです。

## 配列
```Array.java
class Array {
  public static void main(String[] args) {
    String[] arr = {"sato", "suzuki", "takahashi"};    

    System.out.println(arr[0]);
    System.out.println(arr[1]);
    System.out.println(arr[2]);
  }
}
```

```:ターミナル
sato
suzuki
takahashi
```

## 繰り返し
```For.java
class For {
  public static void main(String[] args) {

    for (int i = 0; i <= 2; i++) {
      for (int j = 0; j <= 2; j++) {
        System.out.println(i + "-" + j);
      }
    }
  }
}
```

```:ターミナル
0-0
0-1
0-2
1-0
1-1
1-2
2-0
2-1
2-2
```

ネストさせているので、このような処理になります。

## 実践
あるサラリーマンの5ヶ月間の平均給料を求め、すごいかどうかを判定処理する機能を作ってみます。

```Lesson.java
class Office_worker {
  String name;

  public int calculateAVG(int[] data) {
    int sum = 0;
    for (int i = 0; i < data.length; i++) {
      sum += data[i];
    }
    int avg = sum / data.length;
    return avg;
  }

  public String judge(double avg) {
    String result;
    if (avg >= 250000) {
      result = "すごい！";
    } else {
      result = "まだまだ！";
    }
    return result;
  }
}

public class Lesson {
  public static void main(String[] args) {
    Office_worker a001 = new Office_worker();
    a001.name = "sato";
    int[] data = {270000, 265000, 250000, 290000, 230000};

    int avg = a001.calculateAVG(data);
    String result = a001.judge(avg);

    System.out.println(avg);
    System.out.println(a001.name + "の平均給料は" + result);
  }
}
```

```:ターミナル
261000
satoの平均給料はすごい！
```
ARCoachingOverlayViewでユーザーにデバイスをうごかしてもらって、ARKitに世界情報をあたえる

ARKitがWorldTrackingを確立するには、デバイスを動かして、ARKitに視点を与える必要があります。

ARCoachingOverlayViewでユーザーにガイダンスを出して、デバイスをうごかしてもらいます。

![Sep-20-2020 14-12-53.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/ddd7061e-b73e-baf7-7e95-7a41ca1e097d.gif)
###１、ARCoachingOverlayViewを初期化します。

```swift
let coachingOverlay = ARCoachingOverlayView()
```

ARCoachingOverlayViewの設定

```swift
coachingOverlay.goal = .anyPlane //情報を取る目標設定
// 可能な値
    case anyPlane
    case horizontalPlane
    case tracking
    case verticalPlane

coachingOverlay.activatesAutomatically = true //Tracking状態が不十分になると、再度コーチングするか

// セッションとデリゲートを設定
coachingOverlay.session = sceneView.session
coachingOverlay.delegate = self

// Viewとして扱う
coachingOverlay.frame = sceneView.bounds
sceneView.addSubview(coachingOverlay)
```

###２、ARCoachingOverlayViewDelegateを設定
コーチングの状態によって呼ばれるDelegate functionは以下

```swift
func coachingOverlayViewWillActivate(_ coachingOverlayView: ARCoachingOverlayView) {
    // コーチングが表示される前に呼ばれる。ここでコーチング中操作できないButtonなどを非表示にする。
}
    
func coachingOverlayViewDidDeactivate(_ coachingOverlayView: ARCoachingOverlayView) {
    // コーチングが終了したあとに呼ばれる。ここでコーチング中操作できないButtonなどを再表示する。

}
```

これでARSessionをrunすると動くはずです。
必要な情報が得られたら、コーチングは消えます。
このステップをやったほうが、正確なワールドトラッキングが得られます。

****
Core MLを使ったアプリを作っています。
機械学習関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[MLBoysチャンネル]
(https://www.youtube.com/channel/UCbHff-wfjTnB3rtXIP6y0xg)
[Medium](https://medium.com/@rockyshikoku)

[相棒](https://twitter.com/oka_yuuji)
[note](https://note.com/oka_yuuji)