OmniAICreator/Qiita-1.07M huggingface dataset:
Cloud Foundry（IBM Cloud）でNode.jsのバージョン指定【.nvmrc】


Node.jsアプリケーションをそのままデプロイしようとすると以下の警告が出ます。

```
**WARNING** Node version not specified in package.json or .nvmrc. See: http://docs.cloudfoundry.org/buildpacks/node/node-tips.html
          Attempting to install: 10.24.0
```

`package.json`か`.nvmrc`に記述しろと書いてありますね。

> [Support .nvmrc file as an alternative to engine.version setting in package.json](https://github.com/cloudfoundry/nodejs-buildpack/issues/148)

前に書いた記事では`package.json`のenginesに記載するやり方でしたが、今回は`.nvmrc`に記述します。

> [Cloud Foundry（IBM Cloud）でNode.jsの最新バージョンを利用する](https://qiita.com/n0bisuke/items/cf435ab9a24836513d14)


## .nvmrcを作成してデプロイ

今更ですがnvmを内部で使ってたんですね。

macなどの場合はプロジェクトのルートで以下を実行します。

```bash
$ node -v >> .nvmrc
```

これで`.nvmrc`が作成されてローカルのバージョンが`.nvmrc`に記載されます。

## ただ最新は動かない場合が多い

先程のコマンドを実施した`.nvmrc`の中身は`v16.0.0`でした。

```.nvmrc
v16.0.0
```

この状態でデプロイしたら以下のエラーが発生

```
  **ERROR** Unable to install node: no match found for 16.0.0 in [10.23.3 10.24.0 12.20.2 12.21.0 14.15.5 14.16.0 15.11.0 15.12.0]
   2021-05-04T02:26:19.14+0900 [STG/0] ERR Failed to compile droplet: Failed to run all supply scripts: exit status 14
```

まぁつまりv15.12.0までしか対応してないよとのことです。

```.nvmrc
v15.12.0
```

と変更してデプロイしなおすとエラー回避できます。

**時期によって対応状況は違うので、まずは最新版でデプロイして出たエラーメッセージにどのバージョンで対応済みかを知る**のが良いかもしれません。

## 最新を使いたい時はbuildpacks指定の方法も

[Cloud Foundry（IBM Cloud）でNode.jsの最新バージョンを利用する](https://qiita.com/n0bisuke/items/cf435ab9a24836513d14)の記事にあるbuildpacksでURL指定などをすると最新が使えるかもしれません。

## 所感

package.jsonのenginesに指定していると他の環境で利用しようとした時や利用パッケージによって変な挙動が発生することがあるので、pacakge.jsonのenginesに指定よりは楽な印象です。

個人的に今後も触ることがあれば`.nvmrc`に記載の方を選ぶ気がします。
elについて



Vueインスタンス内のelというオプションについて確認しておきましょう。
elというオプションが指定した要素がVue.jsが作用を及ぼす範囲になります。
elは「element」の略です。


'#app' のように、DOM要素を指し示すセレクタが指定されます。
このプロパティの値は、Vueアプリーケーションの範囲、Vueの管轄領域を表します。
<div id="app"> タグ内部がVueアプリケーションとして認識されるということです。

>https://jsstudy.hatenablog.com/entry/What-is-el-in-Vuejs

elやdataは、Vue.jsのAPIと呼ばれるもので、Vue.jsを扱う上での規格のようなものです。
用意されているAPIを使って、さまざまな処理を記述します。

![20210504-114813.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/541bd747-6b89-d989-fb65-cee4a38d4b07.png)

new Vue({})の直下にあるものはAPIと思ってだいたい間違いないです。

初期化
-

初期化
Vueインスタンスの生成の際に el オプションが与えられた場合、Vueインスタンスは直ちにコンパイルの段階に入ります。コンパイルの段階の間に、VueはDOMをひと通り見て、遭遇したディレクティブを収集します。一旦紐付けられると、それらのDOMノードはVueインスタンスによって管理されていることになります。
最小限の環境構築したVSCodeでC#のexeを作る

# 何がしたいの？

* VSCodeでC#のexeを作りたい。
* ひとまず **最小限の環境構築** で **最小限のサンプルプログラム** が作れればヨシッ！

# VSCodeインストール

VSCodeはインストール済で話を進めます。
まだの場合は [こっち](https://qiita.com/waokitsune/items/a0e25114fbb1b6190379) 。

#VSCodeにC#のプラグインをインストール

プラグインのメニューを開いて `csharp` で検索してインストール。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/f03c7c77-95dc-5301-c39c-c03c50877c46.png)


# .NET Coreをインストール

↓公式サイトさんへ。

https://dotnet.microsoft.com/download

下記のようにインストーラーをダウンロードしてインストール。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/e69e4b3d-efa4-d53b-e5a3-4d450cc89154.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/8e08b3dc-1e2f-1b63-9a01-a2ec6de8cd11.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/767b3b04-5a74-1c3f-bc0f-082c9467bf5a.png)

# プロジェクト作成

適当にフォルダーを作った後に、VSCodeでそのフォルダーを開く！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/fe888b14-46b5-22c1-bbcc-cf0c70467c4a.png)

`Ctrl + @ ` でターミナルを開いて下記コマンド。

```powershell:コマンド
dotnet new console
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/1ca984a2-a47e-97ae-2efd-70fcce09368c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/b0f51e96-1e4d-8b40-e972-df619c2dde6a.png)
下記のように初期化してくれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/7b24e357-ad8f-f608-b6a4-adea4631e2f3.png)
はろーわーるどをコンソール出力するプログラムも用意してくれてます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/0f5fefc1-9c92-62bd-963b-1d9c92330a56.png)


# とりあえず実行

VSCodeのターミナルで下記コマンド。

```powershell:コマンド
dotnet run
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/bc8c9711-77d8-6932-99d7-b2f3647bd9df.png)
ハローワールド出てます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/0a12d4ce-4b5c-eff6-a3b2-3f2f956d98df.png)
プログラムの中身をちょっとだけ変えて…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/955108d2-7dfe-b234-884d-cc9b40e5376b.png)
`dotnet run` を実行。
変更が反映されてます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/65318989-86ad-047b-9b6d-9e396c3cd25c.png)

# exeをエクスプローラー経由で実行

exeは下記にあります。
コンソール出力だけだと一瞬でプログラムが終了して、本当に作ったプログラムが動いているかの確認ができないです。
なので、コンソールを入力待ちの状態にする `Console.ReadKey();` を追加して、 `dotnet run` で一回コンパイルしておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/953e6d82-00c0-b769-2d79-8f6ff12df7ff.png)
VSCode経由ではなく、エクスプローラー経由で出来上がったexeを実行してみまーす。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/fb93ccdc-9ffb-5c72-c169-89c07fefc661.png)
ちゃんと『ほげええええええええ』が出て入力待ち状態になりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/4a36e72d-52c8-0643-4d18-77a341937754.png)

# 蛇足

『exe を作るなら Visual Studio』が普通だけど、選択肢は多いに越したことはないかなって思います。


# 参考サイトさん

https://www.typea.info/blog/index.php/2017/06/19/visual_studio_code_c_exe/
https://ict119.com/console_stop/

# バージョン

Windows 10 Pro バージョン 20H2 OSビルド 19042.928
Visual Studido Code 1.55.2
【Swift】NWPathMonitorを使ったネットワーク監視方法について

## 本日内容
ライブラリを使わずにApple純正の方法(NWPathMonitor)で、Networkのハンドリングをできることが気がつきました。
今回はその時の手順を記載しております。

### NWPathMonitor
An observer that you use to monitor and react to network changes.
ネットワークの変更を監視して対応するために使用するオブザーバー。

### Availability
iOS 12.0+
macOS 10.14+
Mac Catalyst 13.0+
tvOS 12.0+
watchOS 5.0+
Xcode 10.0+

### 開発環境
Xcode 14.4
Swift
iOS14以上


## 手順
1.Network.swiftを作り、下記を追加します。

``` .swift
import Network

class Network {
    static let shared = Network() //シングルトン
    private let monitor = NWPathMonitor()
    func setUp() {
        monitor.pathUpdateHandler = { _ in
        }
        let queue = DispatchQueue(label: "Monitor")
        // ネットワーク監視開始
        monitor.start(queue: queue)
    }
    func isOnline() -> Bool {
        return monitor.currentPath.status == .satisfied
    }
}
```

2.AppDelegateに下記を参考に、Network.shared.setUp()を追加します

``` .swift
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        Network.shared.setUp() // 初期化対応
        return true
    }
```

3.ネットワークを実際に確認する場合

``` .swift
    if Network.shared.isOnline {
       //ネットワークあり
    } else {
       //ネットワークなし
    }
```

今回は以上になります!
これでネットワークErrorハンドリングして、ユーザー体験の向上にお役に立てればと存じます！
素敵な開発生活を！

最後まで読んでいただき、ありがとうございましたmm

## 参考資料
NWPathMonitorを使ったインターネット接続の確認方法
https://www.richcoding.co.jp/2020/03/26/nwpathmonitor/

NWPathMonitorのハマりどころ
https://qiita.com/noppefoxwolf/items/55fafdea55de754d2b3d

Apple公式
https://developer.apple.com/documentation/network/nwpathmonitor
【Vue.js】インスタンス内のプロパティーにアクセスする

先ほどの関数をつかってい同じインスタンス内にあるメッセージプロパティーを呼ぶには「this.」をつける必要がある。

```vuejs
<body>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
<div id="app">
<p>{{sayYes()}}</p>
<!-- <button v-on:click="reverseMessage">メッセージ反転</button> -->
</div>
<script>
  new Vue({
    el: '#app',
      data: { message: "おはよう"},
      methods: {
         sayYes: function() {
            return this.message;
      }
  }
})
</script>
</body>
```

![20210504-114320.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/ddca498f-1098-d6b8-4c77-c5018092d89e.png)
Cloud Foundry（IBM Cloud）にDiscord BOTをデプロイしようとした際にハマったメモ


手元で作成したDiscord BOTのNode.jsアプリケーションをCloud Foundry（IBM Cloud）にデプロイする際にハマりました。

デプロイ時間長すぎて検証に時間かかるのが大変......

## おさらい: ログの調べ方

デプロイや起動に失敗した際は

```bash
$ ibmcloud cf logs アプリ名 --recent
```

でエラーログを見れます。

## ERR Failed to make TCP connection to port 8080:

デプロイ時後の起動時にエラーが発生してました。

```
  2021-05-04T02:37:11.28+0900 [HEALTH/0] ERR Failed to make TCP connection to port 8080: connection refused (out of memory)
   2021-05-04T02:37:11.28+0900 [CELL/0] ERR Failed after 1m0.927s: readiness health check never passed.
```

待ち受けるサーバーが無いよと怒られてる模様です。

Discord.jsを利用してますが、このライブラリはHTTP サーバーを立てる方式ではない模様です。

> Discord.js does not expose any kind of port nor a http server.
> 参考: https://github.com/discordjs/discord.js/issues/3577

以下のようなDiscrod.jsのサンプルのままだとうまく起動してくれませんでした。

```js
const Discord = require('discord.js');
const client = new Discord.Client();

client.on('ready', () => {
  console.log(`Logged in as ${client.user.tag}!`);
});

client.on('message', async msg => {
  if (msg.content === 'ping') {
    msg.reply('Pong!');
  }
});

client.login(process.env.DISCORD_TOKEN);
```

ちなみにこのときのmanifest.yamlはこんな感じです。

```manifest.yaml
applications:
 - name: アプリ名
   random-route: true
   memory: 64M
   command: npm start
```

### 解決策1: expressを追加してサーバーを起動

待ち受けるサーバーが無くて怒られてるのでexpressを追加します。

```js
const Discord = require('discord.js');
const client = new Discord.Client();

client.on('ready', () => {
  console.log(`Logged in as ${client.user.tag}!`);
});

client.on('message', async msg => {
  if (msg.content === 'ping') {
    msg.reply('Pong!');
  }
});

client.login(process.env.DISCORD_TOKEN);

/*expressを追加*/
const express = require('express')
const app = express()
 
app.get('/', function (req, res) {
  res.send('Hello World')
})
 
app.listen(process.env.PORT || 3000);
```

これでOKです。

### 解決策2: manifest.yaml（の変更でできる気がする）

ProcessのTypeがWebでは無く別の指定にしたり、`no-route: true`なども試してサーバーを追加しなくても起動するようにしたかったけどエラー解消されなかったです汗　

> 参考: https://docs.cloudfoundry.org/devguide/deploy-apps/manifest-attributes.html

一旦諦め。

## ERR Killed

こちらもアプリ起動後に発生したエラーです。

```
[2021-05-04T10:52:45.49+0900 [APP/PROC/WEB/0] ERR Killed
```

> 例えば、 OOM Killed とあれば「メモリー不足」を意味し、コンテナーがリソース制限によってクラッシュしている
> 参考: https://www.ibm.com/docs/ja/bluemix_stage/containers/cs_troubleshoot_clusters.html?view=kc

みたいな話をググったら見つけたので64Mに指定してメモリを128Mにしてみました。

```manifest.yaml
applications:
 - name: アプリ名
   random-route: true
   memory: 128M
   command: npm start
```

たまたま感ありますがこれで解決出来ました。

express入れた分でメモリ多く使ってしまったのかもしれません。

## ひとりごと。 デプロイの時間が長すぎる問題

Cloud Foundryのmanifest.yamlだけでどうにかなる気がしてますが、検証しようにもデプロイの時間が長すぎる問題があります。

**デプロイボタン押したらモンハンで一狩り行ってました。それくらい遅い。**

ちゃちゃっと試したいのに時間長すぎるので拘りなければHerokuがいい気がするなぁ。
raspberry pi 初期設定

raspberry pi初期設定。
たくさん初期設定ページは存在するが、こういう記事はたくさん同じような記事があることが重要なのだろうと信じ、書いておく。

# 手順


- SDカードにOSを書き込む
    - このページをよく見ていましたが、Raspberry Pi Imager で入れるだけです

https://raspida.com/setup-raspbian4rpi4b-2020

- SDカードを差し込んでブート
- 出てくる画面にしたがってポチポチ
    - timezoneは、「Japan」、「Japanese」、「Tokyo」（チェックは入れない）
    - パスワードを設定
    - wifiを設定
    - アップデートを実行
- リブート
- sudo apt update/sudo apt upgradeを念のため実施
    - 何かがあがってたらリブート
- sshの設定
    - sudo mkdir /boot/ssh
    - sudo shutdown -r now
- userの追加
    - sudo useradd  --group sudo -m <アカウント名>
    - sudo passwd <アカウント名>
- sshで入る (teratermで)
- IP addressの固定
    - ifconfig で現在のIPを確認
    - netstat -nr でゲートウェイを確認
    - sudo vi /etc/dhcpcd.conf で以下を追記

```
interface wlan0
static ip_address=<ifconfigで確認したIP>/24
static routers=<netstatで確認したゲートウェイ>
```

- ホスト名の設定(/etc/hosts)
    - sudo vi /etc/hosts

```
<snip>

127.0.1.1       <ホスト名>
```

- ホスト名の設定(/etc/hostname)
    - sudo vi /etc/hostname

```
<ホスト名>
```

- リブート
    - sudo shutdown -r now
- pi アカウントの削除(teratermで新しいユーザでloginして実施)
    - userdel -r pi
switchbotアプリから時間を指定して加湿器やエアコンのオンオフ

switchbotだけでやれることを色々やってみました。
本当は気温とかと連動するといいんだと思いますが、加湿器とエアコンが時間になったら自動でついたり消えたりするだけでも、結構いい感じです。

夜寝るときに寝室に入って寒いなあと思ってエアコンをつけるのと、夜寝るときに寝室に入ったらちょうどいい気温になっているのは、やっぱり全然違います。

# 加湿器の追加

switchbot加湿器を買いました。switchbotアプリから登録するだけです。本家のチュートリアルを置いておきます。
この加湿器、結構容量が大きいので、夜中だけつけるなら1週間ぐらいは水を追加しなくても大丈夫です。

https://support.switch-bot.com/hc/ja/articles/360039939573-SwitchBot-%E5%8A%A0%E6%B9%BF%E5%99%A8%E3%82%92%E3%82%BB%E3%83%83%E3%83%88%E3%82%A2%E3%83%83%E3%83%97%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95

# エアコンの追加

switchbot hub miniが必要です。買わんといかんです。
あとはリモコンをswitchbot hub miniに向けてつけたり消したりして、機種を認識させると、switchbot hub miniがリモコンの代わりに赤外線を飛ばしてエアコンを操作してくれるようになります（機種の認識は少し手間取りました。似た機種を見つけて試してみるしかないかも）

https://support.switch-bot.com/hc/ja/articles/360038240833-%E5%AE%B6%E9%9B%BB%E3%83%AA%E3%83%A2%E3%82%B3%E3%83%B3%E3%82%92%E7%99%BB%E9%8C%B2%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95-SwitchBot%E3%83%8F%E3%83%96%E3%83%9F%E3%83%8B%E7%B7%A8-


-------
2021年3月から始めたスマートホーム化はこちらに一覧化しています（2021年5月時点）

https://qiita.com/tosshie/private/738a85184d6cdaf20b3e
switchbotアプリからswitchbot hub経由で時間を指定してカーテンを開閉

switchbotだけでカーテンを朝自動で開けることができることを知り、嬉しくなって買いました。

# カーテンレールにswitchbotカーテンを取り付けてアプリをポチポチするだけです

本家のチュートリアルを置いておきます

https://support.switch-bot.com/hc/ja/articles/360052119093-SwitchBot%E3%82%AB%E3%83%BC%E3%83%86%E3%83%B3-U%E5%9E%8B-%E3%82%92%E3%82%BB%E3%83%83%E3%83%88%E3%82%A2%E3%83%83%E3%83%97%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95


# ちなみに私はswitchbotカーテンを少し削っています
KEYUKAのカーテン(カーテンレール)なのですが、U型で少し幅が狭くて、そのままswitchbotカーテンを取り付けても動かなかったので、switchbotカーテンを数mmほどカッターで削って使っています（今のところ問題なく使えています）

# ソーラーパネルは一緒に購入するのをおすすめします
最初はUSB-Cの長いケーブルを買ってきてswitchbotカーテンに取り付けていたのですが、いつの間にか外れていることがあって、いつの間にか動かなくなってしまっていました。充電も1週間は持つのですが、充電をする手間がめんどくさい（しかも忘れる）ので、ソーラーパネルも一緒に買って取り付けてしまうのがいいと思います。


-------
2021年3月から始めたスマートホーム化はこちらに一覧化しています（2021年5月時点）

https://qiita.com/tosshie/private/738a85184d6cdaf20b3e
家の1階～ロフトに1個ずつ置いてあるswitchbotの温湿度計のデータをswitchbot hubに集め、switch botアプリで確認する

自粛生活で家でできる楽しそうなことということで、スマートホーム（最近はおうちハックという言うらしいですが）をやり始めました。
最初に、簡単にできそうなswitchbotの温湿度計を買ってみました。

- switchbotのアプリを入れてポチポチするだけです
とても簡単です。本家のチュートリアルを置いておきます。

https://support.switch-bot.com/hc/ja/articles/360038241053-SwitchBot%E6%B8%A9%E6%B9%BF%E5%BA%A6%E8%A8%88%E3%81%AE%E3%82%BB%E3%83%83%E3%83%88%E3%82%A2%E3%83%83%E3%83%97%E6%96%B9%E6%B3%95%E5%8F%8A%E3%81%B3Hub%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA%E3%81%A8%E3%81%AE%E3%83%9A%E3%82%A2%E3%83%AA%E3%83%B3%E3%82%B0

- 安さでいくと、やはりswitchbotのようです。

https://qiita.com/c60evaporator/items/675452d5de9587eed25c


- switchbotのアプリからデータを抜き出すこともできますが、私はraspberry piを使ってgoogle spreadsheetにデータを書き込んでいます。
(switchbotのアプリからexportすると、timestampがバラバラで複数の温湿度計データをひとつのグラフにできなかったので)

https://qiita.com/tosshie/private/0b6a93a8e351cd801321

-------
2021年3月から始めたスマートホーム化はこちらに一覧化しています（2021年5月時点）

https://qiita.com/tosshie/private/738a85184d6cdaf20b3e
自粛生活期間に家のスマートホーム化をやってみる

自粛生活でやることがなくて、昔からやってみたかったスマートホーム化をやってみています。
2021年3月頃にはじめて2か月ほどで色々できたので、まとめてみます。

# できたこと

![dekitakoto_20210430.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/849198/d196cbb2-e089-140e-d8d9-a891518aa1f7.png)


[1]

https://qiita.com/tosshie/private/90c83be2b9bea44b3f7a

[2]

https://qiita.com/tosshie/private/06f0eb342614f6018804

[3]

https://qiita.com/tosshie/private/cecda208c67d22782e48

[4]

https://qiita.com/tosshie/private/eee733de2540d1bf49a2

[5]

https://qiita.com/tosshie/private/0b6a93a8e351cd801321

[6]

https://qiita.com/tosshie/private/fe79368c6ef75df3736c

[7]

https://qiita.com/tosshie/private/08a2c740e19c4154daf7

[8] & [9]

https://qiita.com/tosshie/private/43e141121cd5a83513ec

[10]

https://qiita.com/tosshie/items/97e4389e7db999ebd55e

[11]

https://qiita.com/tosshie/items/ff028698842da78c1b6d


# かかった費用
買ったときの値段と後から調べた値段が混ざっていますが、大体6万円ぐらいです。

| No. | item | 単価 | 個数 | 費用 |
|:-:|:-:|:-:|:-:|:-:|
| 1  |  switchbotの温湿度計 | 1,680円  | 4個  |  6,720円 |
| 2  | switchbot hub mini  | 3,380円  | 1個  |  3,380円 |
| 3  | switchbotカーテン(ソーラーパネル付き)  | 11,210円  | 1個 |  11,210円  |
| 4  | switchbot加湿器  | 5,500円  |  1個 | 5,500円  |
| 5  | google nest hub  | 6,500円  | 1個  |  6,500円 |
| 6  | raspberry pi(2台分ケース代、SDカード代とかも含む)  | 10,021円  | 2個  | 20,042円  |
| 7  | MHZ19C(二酸化炭素濃度計)  |  3,331円 | 2個  | 6,662円   |
| 合計  |   |   |   | 60,014円  |
ルンゲクッタ法(四次)を実装(JavaScript)


#ルンゲクッタ法とは

ルンゲクッタ法は、常微分方程式において、解析的に解を求められない状況で初期値を元に適切な答えを求めるための数値解析手法.

$$\frac{dy}{dx} = f(y,x)$$

上記常微分方程式と適切な初期値が与えられる時にその解を数値計算で求めます.
今回は4次のルンゲクッタのJavaScript実装を行います.

参考文献に記載させていただいた神戸大学の陰山様の資料やYouTubeがイメージを掴むのによいかと思います.
次数に関しては、これも参考文献のシキノート様のが非常に参考になるかと思います.

#ルンゲクッタ実装

想定する関数は下記とします.

$$y = \frac{1}{10} cos(x) + 3.9$$

常微分方程式は以下とします.

$$\frac{dy}{dx} = f(x) = -\frac{1}{10} sin(x)$$

y不使用のため、diffEquationでは、xしか引数に取っていません.
初期値は$(x,y)=(0, 4)$.

rungeFに推定した関数の結果が入ります.

```javascript
const COEFF = 0.1;
const DATA_NUM = 100;
const HALF_DATA_NUM = Math.floor(DATA_NUM/2);
const RUNGE_STEP = 0.1;
let init_x = 0;
let init_y = 4;
let X = [];
let datas = [];

for(let i = 0; i < DATA_NUM; i++){
    X.push((i - HALF_DATA_NUM) * COEFF);
}

function ansEquation(x){
    return 1/10 * Math.cos(x) + 3.9;
}

function diffEquation(x){
    return -1/10 * Math.sin(x);
}

let ansY = X.map((x)=> ansEquation(x));
let ansF = X.map(function(x,index){return {x:x, y:ansY[index]}});
let maxX = Math.max(...X);
let curX = init_x;
let prevY = init_y;
let rungeF = [{x:curX, y:init_y}];

while(maxX > curX){
    let k1 = diffEquation(curX);
    let k2 = diffEquation(curX + RUNGE_STEP / 2 * k1);
    let k3 = diffEquation(curX + RUNGE_STEP / 2 * k2);
    let k4 = diffEquation(curX + RUNGE_STEP     * k3);
    let y = prevY + RUNGE_STEP * (
        k1 * 1/6 + k2 * 2/6 + k3 * 2/6 + k4 * 1/6
    );

    curX += RUNGE_STEP;

    rungeF.push({x:curX, y:y});

    prevY = y;
}

```


#参考文献


http://www.research.kobe-u.ac.jp/csi-viz/members/kageyama/docs/161122_RK4.pdf

https://slpr.sakura.ne.jp/qp/runge-kutta-ex/

https://www.youtube.com/watch?v=PQa1SGz3Oz4
javascript 関数オブジェクトの内部関数へのアクセス（私的整理）

JSの関数オブジェクトは色々と生成方法があって、生成方法にって中身が異なったりするよう。すごく迷うところに感じる。

以下はちょっと自分的な迷いどころで、内部関数に関して自分用に整理してみた。

| 関数の生成|内部関数inn()へのアクセス |呼び出し|備考|
|--------------------------------|--|--|--|
|sam=function( ){inn=function( ){ }};|不可|-|クロージャー|
|function sam( ){inn=function( ){ }}|不可|-|クロージャー|
|sam=function( ){inn=function( ){ };return inn;};|可|sam( )( );|直接inn( )は呼べないが、returnで戻せばOK|
|function sam( ){inn=function( ){ };return inn;}|可|sam( )( );|上に同じ|
|function sam( ){this.inn=function( ){ }}|可|new sam( ).inn( );|
|sam={inn:function( ){ }};|可|sam.fun( )|innは関数ではなくパラメータ<br>（クロージャーにならない）|

sam=function( ){inn.function( ){ }}には、constructorはなく、インスタンス化できないので、new sam( ).inn( );のようにはできない。
MAMPで構築した

htdocs自体が
MAMPの初期設定では、公開ディレクトリ（ドキュメントルート）は /Applications/MAMP/htdocs/ になっていて、
公開ディレクトリをブラウザで確認する場合のURLは　http://localhost:8888/ ということになります。

http://localhost:8888/index.phpと打つと、phpのページが表示されました！！！！嬉しい〜
ちなみに、これでもindex.phpと同じページが出ました。
→http://localhost:8888/ 


http://localhost:8888/todolist/index.php
と、htdocsのあとはパスを記載してあげるとしっかり出ました。

:santa: spanタグとは
spanタグとは汎用的なhtmlタグで、囲んだ要素を強調するなどのデザイン微調整によく利用されるタグです。

具体的には個別にテキストのフォント調整、文字色・背景色の変更を施すのによく利用します。
特徴としては、インライン要素のため、そのまま利用すると幅や位置の調整に多少制限があります。

:santa:見やすくしようと思って改行したら、まさかのplaceholderが削除されたw
<input type="text" name="title" placeholder="ここに予定を入れよう！">
WSLでクリップボードにコピー(WSL 2でXサーバへの接続）

WSL2でXサーバーを動かす際に、localhostの問題に加えて、Windwows defnder Filrewallの設定が必要でした。以下、作業メモです。

clip.exeを使えばよいことが判明。なんだかなとも思うけど、まぁ良いか。

```
ls | clip.exe
```



# そもそもの目的
PDFをDeepLで翻訳したいときに、PDFのデータが行ごとで分割されていて、そのままでは翻訳がかけられないので、文として成り立つように行を連結する簡単なプログラムを作った。Windows上の特定のテキストファイルに保存し、WSLでコマンドを実行することでWSL上に連結した文書が表示されるので、これをコピーしてDeepLにかければ、良い感じの翻訳ができる。
しかし、だんだんWSLでのコピーが面倒になってきた。プログラムの中で、クリップボードにコピーできないかと調べてみると、xselというプログラムを使ってコピーができるようだ。

# xselのインストール
以下のページなどを参考に xselとXサーバーをインストールする。
今になって気付いたが、XのコマンドだからXサーバーをインストールする必要があるのね。

https://qiita.com/7iva/items/9ecd7f2f178cd7c1d0b3

http://lldev.jp/linux_c_cpp/linux_cmd/xsel.html

# Error: Can't open display

実行してみると、"Error: Can't open display"などのエラーになってしまう。調べてみると、WSL2になった際に、WSLのネットワークが Hyper-Vを使ってWindows10とは別のネットワークになったことが原因らしい。

https://qiita.com/Engr_Coal33/items/6aabb6932b53bd43b843

https://odaryo.hatenablog.com/entry/2020/01/08/114846

https://qiita.com/hana_shin/items/4ccf9d53aecd290d2cbb


そうか、このIPアドレスを使えばよいのか。

```
$ cat /etc/resolv.conf | grep nameserver | awk '{print $2}'
172.29.96.1
```

早速、IPアドレスを指定して接続してみるが、タイムアウトしてしまう。これは、ネットワークがつながっていないのではないかと、直接 telnetで叩いてみるとやはりタイムアウト。

```
telnet 172.29.96.1 6000
```

どういうネットワークになっているんだろうと調べたところ、こちらのページに詳しく述べられていました。

https://www.atmarkit.co.jp/ait/articles/1909/09/news020.html#_ga=2.56645994.1579801921.1620008784-1112020589.1610170785
# Windows defender firewallの設定


上記情報参考に、Windows側でネットワークを見てみると、WSLが使用する vEnthernet(WSL)は"プライベートネットワーク"になっていない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/529969/3cf8b06c-5eb4-c40a-1118-926808a0f790.png)

それではと、Windows Defnder Firewallの"受信の規則"を見ると、VcXsvのTCPとUDPにブロックルールが書かれている。（残骸として残っているXmingが動かなかったのも、同じ理由だった模様）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/529969/ea8dd356-eda0-1f91-04e5-13ecd78ebd40.png)

ブロックしている二つのルールを"接続をブロックする"から"接続を許可する"に変更して適用。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/529969/c9ac219d-172b-5d51-6c08-d5e5678a5e90.png)

```
$ telnet 172.29.96.1 6000
Trying 172.29.96.1...
Connected to 172.29.96.1.
Escape character is '^]'.
^]
telnet> quit
Connection closed.
```

これにより無事に、Xサーバーと通信ができるようになりました。

```
$ echo "Hello world!" | xsel -bi
```

Hello world!


# 調べる中で参考になったサイトなど

https://www.atmarkit.co.jp/ait/articles/1812/06/news040.html

https://rin-ka.net/windows-x-server/

https://qiita.com/hana_shin/items/4ccf9d53aecd290d2cbb
NTPを調べてみた

## 勉強前イメージ

## 調査

### NTP とは？

Network Time Protocol の略で、
ネットワークに接続されている機器の時刻同期に使用されるプロトコル。
NTPはネットワークを介してサーバと時刻の同期を行います。
NTPは送信元も送信先もUDPの123ポートを使用します。

### NTPは階層構造になっている

NTPはstratum(ストラタム)と呼ばれる階層構造になっており、
最上位から順に `stratum1` `stratum2` と、 `stratum16` まで存在します。

最上位の stratum1 は原子時計やGPSの正確な時刻源から正しい情報を得ています。
一般には公開せず、限られた下位サーバからのみ参照できるようにしているそうです。

イメージ図としては以下で、
原子時計やGPSは statum0 とも呼ばれます。
stratum2 は statum1から情報を得ている NTPクライアントでもあり
statum3に時刻情報を通知する NTPサーバでもあり、 どちらの機能も保持しています。

![1# NTPを調べてみた - diagrams.net - Google Chrome 2021-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/8ae68f99-dc82-e448-1685-fa860b51c05c.png)

### NTPのモード

NTPのよく使用される同期モードは2つあります。

- server/client モード
	- NTPサーバとNTPクライアントのモード
	- NTPクライアントがNTPサーバに対して動機を行うモード
	- よく使われる
- active/passive モード
	- 同じ階層同士のNTPサーバで使用されるモード
	- グループ化された同階層の中から基準のNTPサーバを動的に決定

active/passiveモードが分かりづらいので以下に図を置いています。

![2# NTPを調べてみた - diagrams.net - Google Chrome 2021-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/17125e01-7018-4887-8038-1b7c35560b2e.png)

## 勉強後イメージ

階層構造になってるって知らなかったけど、よくよく考えてみたらそうだよね。。。。
この階層構造がstratumって言われるのも知らなかった
あとUDPなんだー

## 参考

- [NTPとは](https://www.nic.ad.jp/ja/basics/terms/ntp.html)
- [TCP/IP - NTP](https://www.infraexpert.com/study/tcpip25.html)
- [NTPとは？ NTPの仕組み含めておおまかに解説](https://eng-entrance.com/what-is-ntp)
.Netの証明書関連のAPIは、Ubuntuではどこを参照している？

#はじめに

Windowでは、証明書はLocalMachineやCurrentUserストアに保存されています。（certlm.mscやcertmgr.mscで確認できます。）
.NetのAPIからもLocalMachineやCurrentUserを指定して証明書にアクセスすることができます。
ubuntu20.04.2LTSでは、どのような仕組みになっているのか調べてみました。

以下の記事に詳しく書かれています。

https://docs.microsoft.com/ja-jp/dotnet/standard/security/cross-platform-cryptography


#CurrentUser
ユーザのストアは、以下の場所に保存されます。ストアは、初回アクセス時に作成されます。

 ~/.dotnet/corefx/x509stores/

.Netが内部的に管理しているフォルダなのでAPI経由で使用します。（パスも変更されるかもしれません。）
My、Root、IntermediateでWindows上とほぼ同様の操作が可能です。

#LocalMachine
Ubuntu では基本的な CA 証明書が ca-certificates パッケージで提供されていて、ローカルマシンストアは、このパッケージと連携しています。

通常、ca-certificatesパッケージは、以下のフォルダにインストールされています。
/usr/share/ca-certificates/
ca-certificatesパッケージで有効にする証明書のリストです。
/etc/ca-certificates.conf

```conf:ca-certificates.conf
...
mozilla/ACCVRAIZ1.crt
mozilla/AC_RAIZ_FNMT-RCM.crt
...
```

自己署名証明書はRoot、それ以外はIntermediateとして認識されます。
APIからは、読み取り専用で書き込むことはできません。

証明書を登録する方法

1. /usr/share/ca-certificates/にPEM形式の証明書をコピーします。
1. ca-certificates.confにコピーした証明書を追記します。
1. sudo update-ca-certificatesを実行します。

削除方法

1. ca-certificates.confから削除したい証明書の行を削除します。
1. sudo update-ca-certificates -fを実行します。

Myは存在しません。

#まとめ
ユーザストアは、.Net独自の形式で保存されているため、Windowsとの互換性が高いようです。ローカルマシンストアは、OSの証明書を参照する形になっているので参照のみとなっています。ローカルマシンストア、Myがないため、.net Web API等で使用できるWebサーバのKestrelでも、ストアは使用せずに、環境変数にサーバ証明書のpfxファイルのパスを指定するようになっています。
Nextjsよくわかんないこと

# 概要

チュートリアルでよくわかんないことを書きなぐっていく

https://nextjs.org/learn/basics/create-nextjs-app

※やってる間にどんどん追加していく

## Linkの中にaタグを仕込む必要がある？

#### ここでの話
https://nextjs.org/learn/basics/navigate-between-pages/link-component

こう書くと
![Screen Shot 2021-05-04 at 10.49.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117615/d680fb05-be59-1be2-496a-a394b305152f.png)

こうなる
![Screen Shot 2021-05-04 at 10.49.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117615/c9fa3501-4c7d-9c01-53b1-3910d93260aa.png)

でもこう書くと
![Screen Shot 2021-05-04 at 10.51.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117615/b69d859a-ad76-b689-3fb3-9f05126b5002.png)

こうなる
![Screen Shot 2021-05-04 at 10.51.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117615/d4c00ae5-fc66-429e-a3e4-26cb370f054d.png)

classが付与されないことが違いっぽい。

なんで？？

## pages/_document.js

`_app.js` で書くのと挙動変わるんやろか

https://nextjs.org/docs/advanced-features/custom-document

https://tyotto-good.com/blog/next-document-app

## styled-jsx

vercel公式のん使ったほうがええのか、、？サーバーサイドレンダリングとなんか関わってくるんやろうか

https://github.com/vercel/styled-jsx

https://nextjs.org/learn/basics/assets-metadata-css/css-styling
配列操作に便利な高階関数

配列操作で使える高階関数について、今回は投稿します。
高階関数とは、引数や戻り値に関数を扱う関数の事です。

##forEach

まずは普通のループ文から。

```javascript:for.js
const list = ["モンスター", "レッドブル", "水"];
for (let i = 0; i < list.length; i++) {
  console.log(list[i]); 
}
// -> モンスター、レッドブル、水
```

代表的なループの書き方だと思います。
これを**forEach**という高階関数で書いてみましょう。

```javascript:forEach.js
const list = ["モンスター", "レッドブル", "水"];
list.forEach(function (elm) {
  console.log(elm);
});
 // -> モンスター、レッドブル、水
```
なんかスッキリしましたね。
**forEach**がやってる事は、引数の関数に配列の要素を一つずつ渡す。
ただそれだけですね！


##map
まずは普通にループ文使います。

```javascript:for.js
const list = [1, 2, 3];
const newList = [];
for (let i = 0; i < list.length; i++) {
  newList.push(list[i] * 2);
}
// newList -> 2,4,6
```
listの要素を一つずつ２倍にして新しいリストを作成しているプログラムです。
これを**map**という高階関数を使用して書いてみます。

```javascript:map.js
const list = [1, 2, 3];
const newList = list.map(function (elm) {
  return elm * 2;
});
// newList -> 2,4,6
```
かなり読みやすいですよね。
**map**は要素を一つずつ引数の関数に渡し、関数内で加工された値を戻り値として返しているだけです。

##filter
通常のfor文

```javascript:for.js
const list = [1, 2, 3];
const newList = [];
for (let i = 0; i < list.length; i++) {
  if (list[i] > 1) {
    newList.push(list[i]);
  }
}
// newList -> 2,3
```
特定の条件に合う要素のみを新しい配列へ格納しているプログラムです。
これは**filter**という高階関数でもっと読みやすく記述できます。

```javascript:filter.js
const list = [1, 2, 3];
const newList = list.filter(function (elm) {
  return elm > 1;
});
// newList -> 2,3
```

ネストもなくなりとてもスッキリします。
**filter**は、戻り値がboolean型の関数を引数に取り、trueだった場合にその要素を戻り値として返します。

他にも**sort**や**reduce**などがあります。

ちなみに、これらの高階関数は繋げて書くことも出来ます。
例えば、配列から条件に合うものを加工して出力したい場合

```javascript:test.js
const list = [1, 2, 3];
list.filter(function (elm) { 
  return elm > 1; // 絞って
}).map(function (elm) { 
  return elm * 2; // 加工して
}).forEach(function (elm) { 
  console.log(elm); // 出力します
});
// newList -> 4,6
```

なんかイマイチなので、
ちょっとこれをアロー関数という奴で書いてみます。処理内容は上記と変わりません。

```javascript:test.js
const list = [1, 2, 3];
list.filter(elm => elm > 1).map(elm => elm * 2).forEach(elm => console.log(elm));
// newList -> 4,6
```

まるで工場の流れ作業のような書き方が出来ます。
アロー関数についてはまた別途投稿しようと思います。


##最後に
処理によってはかなり可読性が上がる書き方だと思いますが、関数を呼ぶ回数を考えると速度に関しては通常のfor文が早そうです。
とは言っても楽に書けるand読みやすいので積極的に使って良いのではないでしょうか。
Google: アカウントにアクセスできるアプリ

# 概要

Google Apps Scriptで作ったアプリを実行するとき、多くの場合はスクリプトを実行する時に承認が必要です。
たくさんアプリを作っていると、どのアプリを承認したのかわからなくなるので一覧で確認したいです。
いつもその一覧がどこにあるのかわからなくなるのでメモです。

# 承認・許可したアプリの一覧ページまでの行き方

1. Googleのページにアクセスすると右上に表示されるアイコンをクリックします
1. 「Google アカウントを管理」をクリックします
1. Googleアカウントの管理画面が表示されます。
1. 左のメニューの「セキュリティ」をクリックします。
1. セキュリティ関連のメニューが表示されるのでスクロールしていきます。「アカウントにアクセスできるサードパーティ アプリ」というメニューがあるのでクリックします
1. ここにGoogle Apps Scriptの実行を承認・許可したアプリの一覧が表示されます

付与されている権限の内容の詳細確認や、権限の削除などはこのページで行えます。

# ショートカット

該当のGoogleアカウントでログインして
https://myaccount.google.com/permissions
にアクセスしてもよいです

# 補足
## Google Apps Scriptのプロジェクト一覧が確認できるページ

https://script.google.com/home
【vue.js】{{　　}}二重中括弧

```html
<body>
  <script src="vue.js"></script>
   <div id="abc">
    <p>{{message}}</p>
   </div>
  <script>

  new Vue({
   el: '#abc',
    data: {
     message: 'HelloWorld!'
          },
         })
   </script>
</body>
```

{{}}二重中括弧はnew Vueでコードされたdataの中の同じキー[message]を探してその値[HelloWorld]を代入し表示してくれる。

![20210504-104708.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/b80b2718-8668-e9b0-2051-04da0c4c7e69.png)

(発展）
{{}}の中身はRuby on Railsの式展開#{}のように変数や構文が使えます。

・データの中身を５に変えて

```vuejs  
data: { number: 5}
```
```vuejs
<p>{{number}}</p>
```

![20210504-111122.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/e7ff3c98-793d-c40f-07ab-06892efb3e80.png)

・その数を使って計算させてみる

```
<p>{{number + 3}}</p>
```

![20210504-111439.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/2dd44ace-8bea-daf5-8bd2-a909c0e4727c.png)

・関数を使ってメソッドを作って表示
同じ処理を定義し何度も使い回しができる形にしたもの。

関数とは

```javascript
<script>
  function 関数名(){
  処理
  }
</script>
```

無名関数とは関数名なしのもの。

```javascript
<script>
  function(){
  処理
  }
</script>
```
今回は

```javascript
<body>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
<div id="app">
<p>{{sayYes()}}</p>
</div>
<script>
  new Vue({
    el: '#app',
      // data: { number: 5}
   methods: {
    sayYes: function() {
      return 'Yes';
    }
  }
})
</script>
</body>
```

![20210504-113216.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/48ce5358-70b2-5c7d-b9aa-d929f15aef94.png)
Vue.jsはじめます

(1)

https://jp.vuejs.org/v2/guide/installation.html

へアクセスします。

(2)
![20210504-102320.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/e7b56ad4-afaf-adb4-5589-cc3cde4b24c9.png)

CDNをコピペしてください。ダウンロードへダウンロードします。

（３）

```vuejs
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue TEST</title>
<!-- Vue.js を読み込む -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
</head>
<body>

<div id="app-1">{{ message }}</div>  <!-- {{ message }} が Vueデータに置換される -->

<script>
var app1 = new Vue({
  el: '#app-1',                        /* #app-1 要素に対して Vue を適用する */
  data: { message: 'Hello world!' }    /* message という名前のデータを定義する */
})
</script>

</body>
</html>
```

ブラウザで確認する方法
![20210505-152835.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/35fe2dc6-e9fb-185f-c89f-561f8e69cf7f.png)
を右クリック

![20210505-153019.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/f1c843d2-97b1-6800-c903-830bff3396c6.png)
Finderで表示しますを選択

![20210505-153221.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/7238478b-53e9-2e98-2996-f0a0ce63897b.png)

ファイルをクリックします。


>Vue.js入門 - とほほのWWW入門
>https://www.tohoho-web.com/ex/vuejs.html#how_to_use
NuxtでThough the "loose" option was set to "false"...を解消した話

# 何が起きたか？

Nuxt.jsで`yarn dev`するとターミナルに下記のWARNが大量に現れたので解決したメモです。
深追いはしていません。とりあえず消すための対処療法だという事をご承知下さい。

```
WARN  Though the "loose" option was set to "false" in your @babel/preset-env config, it will not be used for @babel/plugin-proposal-private-methods since the "loose" mode option was set to "true" for @babel/plugin-proposal-class-properties.
The "loose" option must be the same for @babel/plugin-proposal-class-properties, @babel/plugin-proposal-private-methods and @babel/plugin-proposal-private-property-in-object (when they are enabled): you can silence this warning by explicitly adding
        ["@babel/plugin-proposal-private-methods", { "loose": true }]
to the "plugins" section of your Babel config.
```

# 解決する方法

nuxt.config.jsのbuildプロパティを下記と置き換えればとりあえず消えてくれます。[公式](https://ja.nuxtjs.org/docs/2.x/configuration-glossary/configuration-build/#presets)を参考に、babelの設定を変更しました。


```js
  build: {
    babel: {
      presets({ isServer }, [ preset, options ]) {
        options.loose = true;
      }
    }
  }
```


# looseって何なん？

[@babel/pluginのloose/specモードについてまとめ](https://qiita.com/jkr_2255/items/b7024c4984b69787d9c9)

babelの変換ルールを緩くする。例えば「ES6の実装をES5で表現するには、厳密にはこうなんだけど、少し緩くして、大体こんな感じ」で変換するモードという理解（不安）。


# 終わりに

Google先生に質問するも、あまり情報が出てこなかったので、**こんなとこでつまずいているのは自分だけなのか？**と劣等感に苛まれつつも、もし、同じ人がいたら解決の役に立つかもしれないというモチベーションで、トラブルシュートの記録を残します。

もっと良い方法をご存知の方いましたら是非教えて下さい。
Ubuntu 21.04でキーボードがus配列に変わってしまう問題

（執筆 2021/05/04)
　Ubuntu 21.04 の日本語Remixがまだ出ていないので、オリジナル版をインストールするのですが、インストール時に日本語キーボードを選択しても、ibusの設定を終えると、いつの間にか英語キーボードになってしまう問題を解決します。

# Ubuntu 21.04 オリジナル版のインストール
　Long Term Supportに関心がなく、常に最新版をインストールしたい新しもの好きは、当然オリジナル版からインストールします。
　ディレクトリ名が日本語になるのが嫌いなこだわり派は、最初はEnglishのままInstall Ubuntuです。（日本語ディレクトリ名は後から英語に変更できるんですが）
![Screenshot from 2021-05-04 09-43-27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/9aa599a5-0d18-390a-c573-8651c418ad5f.png)
　キーボードレイアウトは、Japaneseにします。
![Screenshot from 2021-05-04 09-44-35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/c2a442fe-9c2e-64d9-c8ef-7b4922b9f346.png)
　Updates and other softwareでは、third-party softwareも含めます。
![Screenshot from 2021-05-04 09-45-20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/7315b373-d0ce-1086-bda5-6f5dd3cf8cb0.png)
　その後、あれこれ入れてインストールを終えます。

# Setting
　Settingを起動し、Region & Languageで、Languageをクリックして英語を選択します。
![Screenshot from 2021-05-04 09-57-48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/3ef98549-67d6-a642-f95a-290f2000885b.png)
　続いて、Manage Installed languagesをクリックすると、Fontのインストールなどなどが始まります。ここで、日本語が一番上になっていれば、そのまま再起動させます。なっていない場合は、再起動後、日本語を一番上にドラッグ＆ドロップで移動させます。
![Screenshot from 2021-05-04 10-01-42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/89efbd28-8233-1498-94cd-5d170ab62fcc.png)
　再起動後に、フォルダー名を日本語にするか尋ねてくるので、「次回から表示しない」にチェックをいれて「古い名前のままにする」をクリック！
![Screenshot from 2021-05-04 10-04-14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/aca8b220-b850-c51d-1f46-d8fe75c17aed.png)
　もう一度「設定」を開いて、「地域と言語」の入力ソースに表示される「日本語」の右のゴミ箱をクリックして消します。（Mozcと付いていない方）
![Screenshot from 2021-05-04 10-06-23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/2934c9eb-7116-0aa1-1333-15ce14888424.png)
　残った日本語（Mozc）の右側にある歯車マークをクリックして、キー設定の選択の編集をします。私は、変換キーをIMEオン、無変換キーをIMEオフにしたいので、その設定をします。
![Screenshot from 2021-05-04 10-11-22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/2f21562e-c4e2-aa25-35b4-7e1ca775af79.png)

# 再起動後、キーボードがUS配列になってしまう。
　先の設定後はまだJISキーボードなのですが、再起動するとUSキー配列になってしまいます。JISキーボードのない頃のMacintosh使いの私は、USキー配列もだいたい頭に入っているのですが、（）や［］の位置が一個ズレで、キートップの刻印とズレた位置を打つ「見えているものに惑わされるな！」という何かの真髄を問われているような気になってきます。色々探ってみると、**/usr/share/ibus/component/mozc.xml** にキーボードの配列の設定があるとの記述が見つかり開いてみる。（こだわりの私は当然 vim を使う）
![Screenshot from 2021-05-04 10-19-54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/360d001a-590b-4773-3ede-efbaf389da18.png)
　layoutのタグがないぞとよく読むと、enginesとlayoutの設定は **user configuration directoryの ibus_config.textproto** にあるとのこと。**~/.config/mozc/ibus_config.textproto** を開き、layoutのdefaultを jp に変更。（20.10からアップグレードすると、**~/.mozc/ibus_config.textproto** になります。）
![Screenshot from 2021-05-04 10-23-34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/b9e7d1dd-2554-5cce-75d9-846149460856.png)
　変更後
![Screenshot from 2021-05-04 10-26-50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/db3ec366-fd24-9ead-fb47-f74f8415f593.png)

　これで、キーボード問題は解決しました。
データ分析の力で効率よく痩せたい：初日

初の投稿。駆け出しのデータ分析者です。

# 経緯
某ウイルスの関係で在宅勤務となり完全な運動不足なので、GWをきっかけにランニング始めました。ASICSの[Runkeeper](https://runkeeper.com/cms/ja/)を使ってランニングの記録を取っており、「これ解析したら効率よく痩せられんじゃね？」という安直な考えのもと、とりあえずやってみた。

# 企んでいること
- ジョギングのペースや距離、天候といった情報をデータとして蓄積
- 蓄積したデータを使って、体脂肪の減少を目的とした分析を行う
- 分析結果から導かれたランニングの改善点は、本当に効果があったのか検証する

# 初日：データとご対面
データ分析のピカピカキラキラしてる部分は全体作業の中のほんの1割未満な訳で、残りは殆ど調べものか実装か頭を抱える時間になる印象です。今回の取り組みでも、[Runkeeper](https://runkeeper.com/cms/ja/)のアプリに記録されたペースや高低差、ケイデンスをエクスポートすればいいかと思ってたが、そう簡単にいかないのが世の常。
この記事では、[Runkeeper](https://runkeeper.com/cms/ja/)からデータを取り出して加工してみたときの記録を残します。

## まずはデータ落とす
とにかくどんなデータが手に入るのか知らねばならん、というか、そもそもデータを取得できるのか。恐る恐るマイページ見てみた。ありがたいことに画面右下にExport機能があった。
![export.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352603/a24fe645-41bc-0a1f-870c-9c5d958be818.png)
...GPX？Google Earthでエクスポート？
初めての取組というものは、最初は分からないことだらけです。~~秒でやる気を無くしました~~調べてみました。
### GPX

https://ja.wikipedia.org/wiki/GPX

なるほどGPXというのは、**GPS eXchange Format**の略なのか。
> GPXファイルに必要な最小限のプロパティは、単一のポイントの緯度経度情報である。それ以外の情報はすべて任意である。

これは痺れますね。ドキドキしながらExportします。
中身はこんな感じ。
![gpx.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352603/432e329a-444d-ed89-0a8f-79ca2fb13d9f.png)
上の部分はヘッダーですが、下にある`trkseg`タグに座標データ群が入っているようです。個々のデータは`trkpt`タグにあります。見たところ緯度経度の他に、高度情報（`ele`タグ）とタイムスタンプ（`time`タグ）がある。
つまり、2つの座標から距離を計算し、タイムスタンプの差分から速度を算出せねばならないということか。距離やペースの情報が欲しいのに。と思いつつも、こねくり回されたデータを渡されるより観測値を渡すからあとは好きにしちゃって、というのは理解できる。
### Google Earth (kml)
続いてGoogle Earth形式。

https://developers.google.com/kml/documentation/kml_tut

リンク先によると、GPXと同じくXML形式で記述されていて、名前の通りGoogle EarthやGoogleマップで表示するためのデータ形式らしい。中身はこんな感じ。
![kml.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352603/0f847cf5-8161-0299-0bd5-8df495c85ad8.png)
座標データ群は、`coordinates`タグで一括で記載されているが、GPXと異なるのは、タイムスタンプが無い。これじゃ速度の計算ができない。

以上のことから、[今回やりたいこと](https://qiita.com/Mugichaa/items/08c82f2a84cfa64ae711#%E4%BC%81%E3%82%93%E3%81%A7%E3%81%84%E3%82%8B%E3%81%93%E3%81%A8)を実現するにはGPX形式のデータを使えばよいと分かった。
続いて、緯度経度やタイムスタンプからランニングのペースを算出してみる。
## 意外と大変!? 座標→距離計算
近いうちにアップします。
（備忘録）AWS認定試験テキストAWS認定クラウドプラクティショナーのデモ(コンピューティング)

# 1. はじめに
2021年5月3日に[ヤマムギ](https://yamamugi.connpass.com/)様主催にて開催された[vol.17 AWS認定試験テキストAWS認定クラウドプラクティショナーのデモ(コンピューティング)](https://yamamugi.connpass.com/event/211613/)でのAWS学習内容について、自分への備忘録としてまとめてみました。ご参考になれば幸いです。

# 2. 学んだ内容
- コンピューティングサービス
- ALBを作る
- 複数AZを含んだ構成にする
- セキュリティグループを割当する
　SGは主にINBOUNDを設定する
- ルーティングでリクエスト先を指定
- 起動イメージを指定してやる
- 詳細モニタリングを有効化(有料)

# 3. 学習サイト
- [YouTube：AWS ALB + Auto Scalingのデモ](https://youtu.be/h4CYPNY8toU)
- [UserData.txt](https://github.com/yamamanx/yamamugi/blob/main/v14/UserData.txt)

# 4. 参考サイト

# 5. ハンズオンで得た豆知識
- 負荷をかけます
    `$ yes > /dev/null`

- AMIから起動イメージを起動するようにすれば簡単にマシンが動作する。

- アプリの更新頻度が激しい場合はEC2起動時にGitPullで引いてくるという手法もある

- EC2の料金
　使った時間：リージョン、OS、インスタンスタイプ
- スポットインスタンス
　EC2インスタンスはAZ依存に起動AZ単位で起動可能
　インスタンスの数が決まっている。余っているインス
　タンスを安い価格で利用できる。
　＊最近は変動は小さいらしい。

- スポットインスタンスはいきなり終了されるケースがある。大量並列で短時間使用には適しているみたい。


# 6. おわりに
AWS学習の参考になれば幸いです。
ハンズオン開催してくださいました[ヤマムギ](https://yamamugi.connpass.com/)様、感謝いたします。

2021/05/03 NISHIZONO Takahiro
The document is inaccessible. Please try again later.

GASで作成した内容をコピー複製し、再度実行しようとしたとき
グーグルドキュメントを開く場所で以下のエラーが

#エラー
##The document is inaccessible. Please try again later.

#結論
##グーグルドキュメントのつもりでしたが、コピーしたときにワード形式になってました。
ワード形式からグーグルドキュメントに変更したらエラーは消えました。

エラーが出た該当ソース

```:GAS

const MAILTEXT="vb××〇〇S0cL-_〇〇"　　//グーグルドキュメントのID
    
var doc = DocumentApp.openById(MAILTEXT);  //グーグルドキュメント ここでエラー発生

```


くだらない間違いだった
でもなぜか
The document is inaccessible. Please try again later.
で検索しても英文サイトしかでてこなかった。2021/5
日本人はこんな間違いしないのかしら、と思って、こちらにメモしました。
VC++でのstd::regexにおける"\D"の実装がおかしい

C++で正規表現を使っていた時にバグにハマったので書き残し

# バグ発見に至った経緯

某🐎ゲー向けのソフトを開発中に、OCRで読み取った文字列の正規化を行うために正規表現(std::regex)を使ったのだが、なぜか本来ならマッチするはずの文字列がマッチせず、書いたコードが動かなかった

```C++
#include <iostream>
#include <regex>
#include <string>

int main() {

    const std::wstring turn = L"ジュニア紹7月得半";    // turn にはOCRで読み取った正確性に欠く文字列が入っている
    std::wregex rx(LR"((ジュニア|クラシック|シニア)\D+(\d+)月(前|\W)半)");
    std::wsmatch result;
    if (std::regex_match(turn, result, rx)) {
        // "前"は認識しやすいが、"後"は認識が難しいので
        std::wstring half = result[3].str() == L"前" ? L"前半" : L"後半";
        std::wstring guessTurn = result[1].str() + L"級" + result[2].str() + L"月" + half;
        std::cout << "match!" << std::endl;
    } else {
        std::cout << "no match" << std::endl;
    }
}
````

だいたいこういったコードを書いていたわけだ
OCRで読み取った文字列は完璧ではないので、正確に読み取れる部分だけを抜き出して再構築してあげる必要があった
このコードをvisual studio 2019で実行してみると"no match"と表示されてしまう

https://regex101.com/
などの正規表現のテストできるサイトでチェックしてみても、自分が書いた正規表現で問題なくマッチしてくれるので、これはおかしいぞとなった

で、いろいろ試行錯誤してみるとどうやら"\D"が怪しいことが分かった
正規表現の"\D"は"[^0-9]"と同じであり、数字以外にマッチするマッチングパターンだ
"紹"は数字ではないので、本来ならマッチするのが正しいが

```C++
#include <iostream>
#include <regex>
#include <string>

int main()
{
    bool a = std::regex_search(L"あ", std::wregex(LR"(\D)"));// false
    bool b = std::regex_search(L"A", std::wregex(LR"(\D)"));// true
    bool c = std::regex_search(L"あ", std::wregex(LR"([^0-9])"));// true
    bool d = std::regex_search(L"A", std::wregex(LR"([^0-9])"));// true

    std::cout << std::boolalpha
        << "あ == \\D: " << a << "\n"
        << "A  == \\D: " << b << "\n"
        << "あ == [^0-9] : " << c << "\n"
        << "A  == [^0-9] : " << d << "\n" 
        << std::endl;

    return 0;

}
```

試しにこういうコードを書いてみると、 "a"がtrueにならない…
つまり、VC++の実装では"\D"は"[^0-9]"と同じではない

ちなみに他のコンパイラ(clang,gcc)では "a"はtrueとなるので、VC++だけがおかしい
https://wandbox.org/permlink/wmDPndG53xwsWZ73

# バグ回避

VC++のstd::regexにおける"\D"の実装がバグってるのは分かったので、"[^0-9]"と書き直してバグを回避した

```C++
std::wregex rx(LR"((ジュニア|クラシック|シニア)[^0-9]+(\d+)月(前|\W)半)");
```

# バグ報告

https://developercommunity.visualstudio.com/t/Wrong-implementation-of-D-in-std::reg/1412768

問題の再現が出来たので一応バグの報告しておいた
直るといいね！
LeetCode 1000000本ノック【1. Two Sum】

# 目次

|No.|項目|
|:----:|:-------------|
| 1 | [概要](#概要) |
| 2 | [問題](#問題) |
| 3 | [解法](#解法) |
| 4 | [ハッシュマップを使った解法（本当はこっちが正答）](#ハッシュマップを使った解法（本当はこっちが正答）) |

# 概要
<!-- 発端や概要を記載 -->
●発端
　・競プロ初心者、コーディング面接でズタボロにされ、
　・最低限のアルゴリズム学習とコーディング力強化を習慣化するため記事化
●環境
　・LeetCodeブラウザ上で実装（vscodeに拡張機能にするかもシレナイ）
　・言語はpython3
●その他ルール
　・google検索は自由に（直接的なLeetCodeの問題解説ページはNG）
　　（60分実装して実装出来なければ解説ページ参照）
　・[コーディング面接対策のために解きたいLeetCode 60問](https://1kohei1.com/leetcode/)から問題選出
　・「1000000」は任意の2進数とする


<!-- 各チャプター -->
<a id="#Chapter1"></a>
# 問題
- [1. Two Sum](https://leetcode.com/problems/two-sum/)


>Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target.

>You may assume that each input would have exactly one solution, and you may not use the same element twice.

>You can return the answer in any order.

⇨配列numsと整数targetが渡されるよ。
　numsの中の要素２つを足すとtargetになる組み合わせが１パターンだけあるよ。
　足す要素は同じ要素を２回使っちゃだめだよ。
　足してもtargetになる組み合わせは必ずあるよ。
　正しい組み合わせの要素インデックスを返してネ。
　　という具合のことが書かれています。知らんけど。

`ex
Input: nums = [2,7,11,15], target = 9
Output: [0,1]
補足：nums[0]とnums[1]に入っている要素2と7を足すと9になる`

※正答のないテストはInvalid Testcaseで弾かれるので考慮不要
　（ex. Input: nums = [2,7,11,15], target = 30)
※正答が複数あるテストもInvalid Testcaseで弾かれるので考慮不要
　Input: nums = [2,7,4,5], target = 9

<a id="#Chapter2"></a>
# 解法
実施時間：35分

要素が重ならないように2重ループして総当たりで判定していけばOK

コーディング前の仮コーディングはこんな感じ

```2つの要素を加算してtargetになる組み合わせを確認
        #要素LOOP A　最初~最後
            #要素LOOP B　2つ目~最後
            #AとB照合
                #Trueならreturn
        #LOOP終了したらFalse
```
実際のsubmitコードはこちら


```python
class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        secoundNums = list(nums)
        for i,firstNum in enumerate(nums):
            secoundNums.pop(0)
            for j,secoundNum in enumerate(secoundNums):
                if firstNum + secoundNum == target:
                    return [i,j+i+1]
        return False
        
```

注意点は
　pythonの代入は参照型なので、2つ目のループ宣言時にはlist()で参照回避すること
　pop(0)は破壊的なので、jの要素数が実際よりi周回分マイナスになるため要調整
　~~↑可読性ゴミ~~



<a id="#reference"></a>
# ハッシュマップを使った解法（本当はこっちが正答）

正直BigOとかふんわりしか分かってない自分でもわかる。これは力技や（確信）

どうやら私のコードは時間計算量がO(n2)なのが難点のよう。

[LeetCode / Two Sum」](https://qiita.com/mhiro216/items/482a504d175ded39147e)

↑こちらで辞書（ハッシュテーブル）を使用した解法がされていました。
とりあえず「二重for文ぶん回し解法」と「全部辞書にしまっちゃう解法」で比較してみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502026/696cc611-123b-1359-deb6-723deeca992f.png)

***↑二重for文ぶん回し解法***

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502026/8c6d2af3-2203-a568-688b-1b54161833c9.png)

***↑全部辞書にしまっちゃう解法***


ですよね〜。空間計算量がO(n)に増しても、
時間計算量がO(n)になればこうなりますよね（分かってない）

備忘：BigOも一度ちゃんと学習
php初学者がLaravelの環境構築した

#phpとは
サーバーサイド側のプログラミング言語。
JavaScriptはフロント側の言語。
DBの内容を入力したり更新したりするのに裏側で動いている言語ってことだな...
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699389/8adbeef4-45bb-153d-17e1-fea1966d9e3d.png)

#Laravelとは
MVCのWebアプリケーション開発用のオープンソースフレームワーク。
php使ってWebアプリ構築する際に使えるフレームワークの一種ですね...
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699389/4e267a0d-cfa8-8c8f-c7a3-2c620312ddaa.png)

#Laravel構築の方法
phpのパッケージインストールソフト"Composer"が必要（例の指揮者的なアイコンのアレですね...わかります...）
composerのインストール方法は[こちら](https://getcomposer.org/download/)から
（WinとMacでインストール方法が違います。そこら辺もdocumentを見てください...）
Macならターミナルで、

```
composer create-project laravel/laravel project名 --prefer-dist "version指定"
```
「project名」と「version指定」の部分はお好きな名前、versionを指定してください。
project名が全体のディレクトリ名になります。
versionを指定しない場合、最新版が勝手にインストールされます。

#動作確認
動作テストをするLaravelのディレクトリ上で、

```
php artisan serve
```
を入力→簡易サーバーが立ち上がります。
artisan神か
webブラウザでlocalhost:8000を使えば、、、

![スクリーンショット 2021-05-04 8.19.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699389/3b116fcc-26c8-2a99-d9d7-5402345ce1a9.png)

こんな感じに表示されました。（version6.xの場合）

#使用感
Laravelを少し触り開発をした感想としては、phpで細かくバリデーションする必要もないし、bootstrap4などのフロント側も様々なフレームワーク？があり使いやすいかと思う。

php初学者なので、ここから色々触っていきたいと思います！！
→もっと面白みのある記事書きたいですね...
JavaScriptで入力チェックする方法（修正版）

スペースが入ると入力チェックを通過してしまうのと、入力漏れメッセージを配列に変えたほうが良いとのアドバイスを頂きましたので修正いたします。また修正前の記事でタグに誤りがあったのを発見したのでその部分も修正済みです。修正前の記事も勉強のため残します。

```HTML
<!DOCTYPE html>
<html lang="ja">
<style>
    body {
        padding:50px;
        background-color: greenyellow;
    }
    
    body #title {
        color:red;
        font-size : 50px;
    }
    body #name {
        width:200px;
    }

    body #mail {
        width:400px;
    }

    body #button1 {
        background-color: blue;
        
}

</style>
<head>
  <meta charset="utf-8">
  <title>sample</title>
</head>

<body>
  <h1 id = "title">送信フォーム</h1>
  <form action = "index4.html" method="POST">
  Name:<input type="text" id="name"><br>
  Mail:<input type="email" id="email"><br>
  Detail:<textarea id="detail" value="detail" cols="50" rows="3" maxlength="150"></textarea><br>
  year：<select id = "year">
      <option value="2021" id="2021">2021年</option>
      <option value="2022" id="2022">2022年</option>
      <option value="2023" id="2023">2022年</option>
  </select>
  month:<select id = "month">
    <option value="1" id="1">1月</option>
    <option value="2" id="2">2月</option>
    <option value="3" id="3">3月</option>
    <option value="4" id="4">4月</option>
    <option value="5" id="5">5月</option>
    <option value="6" id="6">6月</option>
    <option value="7" id="7">7月</option>
    <option value="8" id="8">8月</option>
    <option value="9" id="9">9月</option>
    <option value="10" id="10">10月</option>
    <option value="11" id="11">11月</option>
    <option value="12" id="12">12月</option>
  </select>
  <input type="button" id="button1" value="送信" onclick="func1()">
  </form>
  <div id="div1"></div>
  
  
  

<script language="javascript" type="text/javascript">
  //変数の定義
  const name = document.getElementById('name');
  const mail = document.getElementById('email');
  const detail = document.getElementById('detail');
  const button1 = document.getElementById('button1');
  
  //入力チェック処理
  const func1 = () => {
    const unfilledItems = [];
    if(name.value.replace(/\s+/, '').length === 0) {
      unfilledItems.push('名前');
    }
    if(mail.value.replace(/\s+/, '').length === 0) {
      unfilledItems.push('メールアドレス');
    }
    if(detail.value.replace(/\s+/g, '').length === 0) {
      unfilledItems.push('詳細');
    }

    if(unfilledItems.length > 0) {
      alert(`${unfilledItems.join('、')}が入力されていません。`);
    } else {
      if (window.confirm('送信してもよろしいですか？')) {
        div1.innerText = `Name:${name.value}、Mail:${mail.value}、Detail:${detail.value}、year:${year.value}、month:${month.value}`;
      }
    }
  } 
  </script>
</body>
</html>
```