OmniAICreator/Qiita-1.07M huggingface dataset:
ゼロから！　入門 Python3！　この２つの書籍を同じ人が出されているって。

#知らなかった

以下のような記事を書いたことがある。

[良書「ゼロから作るDeep Learning -- Pythonで学ぶディープラーニングの理論と実装」を読む](https://qiita.com/enoughspacefor/items/d545b23bd64d285647de)

[良書『入門 Python3』、説明に失敗しているところN選（N=3）。](https://qiita.com/enoughspacefor/items/1d53f38be261f3b0c8ec)

つまり、対象としている書籍は、

* **ゼロから作るDeep Learning -- Pythonで学ぶディープラーニングの理論と実装**
* **入門 Python3**

**これ、両方！**

|斎藤康毅　:tada:|
|:---:|


という方が、（後者は、訳本なので監訳であるが、）出されているよう。
巨人ですね。。。


#それをふまえ

以下のような記事も書いたが。。。

[良書「ゼロから作るDeep Learning 」のGitHub](https://qiita.com/enoughspacefor/items/31c0d81a0660eeec28eb)

[「ゼロから作るDeep Learning 」でModuleNotFoundError: No module named 'dataset.mnist'が出る理由。](https://qiita.com/enoughspacefor/items/af6aca4f885859c968fa)

⇒**この辺のPythonコードは、かなり、しっかりしたものと考えていいようです！！**

#ちょっと、ひっかかっていた部分

「ゼロから作るDeep Learning -- Pythonで学ぶディープラーニングの理論と実装」
の１章(ページ数:20)が、
Python入門
となっており、
20ページで、Pythonをざくっと説明されているのだが、
そんな量の説明では、無理でしょーーー、他の書籍とかに任せればーーー
と気になっていましたが、、、Pythonの**　ド、プロ　**なんですね。

#この記事の目的

これらの書籍、良書です。

| **良書　×？　良書**:tada:　なので、かなり信頼できるのでは？!|
|:---:|


という情報の共有。

以下、余談。
**「本」は、いまだ、重要です。＜－－買いましょう。**
ただ、お金がかかるし、紙の本は場所もとるし、重いし、
もとをとるために、
**良書だった場合には、**
筆者がネットで公開している良い情報をタダで得て、元を取りましょう！！
(というような活動を実践しようとした、２つの書籍を同じ人が出されていることに気づいた（驚いた）ので記事にした次第です。）
Oculus Integrationで反対の手のコントローラーを得る [Unity]

# 概要
`OVRInput.Controller.RTouch`を引数に`OVRInput.Controller.LTouch`を返す関数が欲しい。

# 実装
`OVRInput.Controller`はEnumで定義されていて、しかもありがたいことに、左手の数値を2倍すると右手の数値に対応している。
左右の概念が有るものはその逆を、無いものはそのまま返すようにしている。

```C#:C#
protected OVRInput.Controller getOppositeHand(OVRInput.Controller controller)
  {
    if (controller == OVRInput.Controller.LHand || controller == OVRInput.Controller.LTouch || controller == OVRInput.Controller.LTrackedRemote)
    {
      // OVRPlugin.Controller がEnum。キャストしまくる。
      var ovrpcon = (OVRPlugin.Controller)controller;
      ovrpcon = (OVRPlugin.Controller)((int)ovrpcon * 2);
      return (OVRInput.Controller)ovrpcon;
    }
    else if (controller == OVRInput.Controller.RHand || controller == OVRInput.Controller.RTouch || controller == OVRInput.Controller.RTrackedRemote)
    {
      var ovrpcon = (OVRPlugin.Controller)controller;
      ovrpcon = (OVRPlugin.Controller)((int)ovrpcon / 2);
      return (OVRInput.Controller)ovrpcon;
    }
    else
    {
      return controller;
    }
  }

```
【009_美術館定理】コマ大数学科

# 【009_美術館定理】コマ大数学科

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1017176/58b2aeee-1496-b322-d7b6-ee9e45709d62.png)

```latex
\begin{tikzpicture}
  \fill [color=green!50!black] (0,0) rectangle (6,6);
  \filldraw [fill=white,line join=rounded] (0,4) --(1.3,5)--(0.8,5)--(2.3,6)--(1.8,4.6)--(6,4.6)--(3.8,2.7)--(5.6,0)--cycle;
  \filldraw [fill=green!50!black,line join=rounded] (2,3) --(2.6,4.4)--(4,3.8)--(3.4,2.3)--cycle;

\end{tikzpicture}

```
Streamlitで作ったデータ閲覧用のWebアプリをherokuで公開する

# 概要

- [前回](https://qiita.com/yoichi_t/items/41ec07286a963b5e2eee)、Streamlitを使ってWebアプリを作れるようになった
- せっかくだから公開しよう
- ということで、できたもの → [Chocolate Ball Viewer](https://chocolate-view.herokuapp.com/)


# 前提

- herokuにアカウントを作っておく(無料でOK)
- githubのアカウントがある


# アプリ作成

[こちら](https://qiita.com/yoichi_t/items/41ec07286a963b5e2eee)などを参考にアプリを作成します。本記事ではStreamlitの記法などについては触れません。

```
$ streamlit run [python-file]
```

で、期待通りにアプリが作成されていることを確認しときます。


# herokuにデプロイ

ここからが本記事の本編です。
手順の概要としては次の通りです。

1. herokuデプロイに必要なファイルの用意
2. herokuにアプリの作成
3. デプロイ
4. 自動デプロイの確認をしてみよう

## 必要なファイルの用意

herokuにpythonアプリを公開するには次の2つのファイルが必要です。

- Procfile
    - 実行コマンドを書く
- requirements.txt
    - 必要なライブラリなどを書いておく

これだけでも十分ですが、streamlitの設定ファイルを作るためのスクリプトを作っておきます。port番号などを指定するものです。（Procfileで起動オプションとして指定してもOK）

- setup.sh

これらをまとめて、Streamlitアプリをherokuで公開するためのテンプレートを作ってくれている方がいます。
https://github.com/patryk-oleniuk/streamlit-heroku-template

今回はこんな感じで作りました。ほぼほぼ[streamlit-heroku-template](https://github.com/patryk-oleniuk/streamlit-heroku-template)からコピーしてきました。

Procfile

```
web: sh setup.sh && streamlit run src/choco_view.py
```

requirements.txt(バージョン固定したほうが安心っすね)

```
pylint
pandas
scipy
matplotlib
seaborn
streamlit
```

setup.sh

```
mkdir -p ~/.streamlit/
echo "[server]
headless = true
port = $PORT
enableCORS = false
" > ~/.streamlit/config.toml
```

これらをまとめてgithubにpushしておきます。プライベートリポジトリでもOKです。

## herokuにアプリの作成

herokuのアプリ作成はCLIを使ってコマンドで実行もできますが(herokuチュートリアルはCLIですね)、githubリポジトリと連携させるのであればWeb管理画面からも簡単です。今回はWebから作成します。

右上の「Create New App」からサービス名を設定して「Create app」します。

![スクリーンショット 2021-01-15 11.27.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66005/dd45cfcb-971b-c6a9-4f3b-87a85ad882a1.png)

これだけ

## デプロイ

createすると、デプロイ方法の選択になります。今回は「GitHub」タブを選択して連携するリポジトリを指定します。

![スクリーンショット 2021-01-20 0.01.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66005/2222f57b-f387-d0d3-0272-9094a6b88a96.png)

連携できると、デプロイ画面に遷移します。

ここで、「Enable Automatic Deploys」を押して自動デプロイを有効にすると、連携したGitHubリポジトリの指定したブランチに更新があれば自動でデプロイされます。

準備ができたらManualDeployメニューから「Deploy Branch」を押してデプロイ開始です。


## 自動デプロイの確認

データを更新などしてgithubにpushしてみよう。

herokuの管理画面を眺めているとデプロイされているのが見えます（楽しい）。


# できた

僕は趣味でチョコボールデータの計測をやっているので、その計測データを可視化するアプリを公開しました（詳しくは[チョコボール統計](https://chocolate-ball.hatenablog.com/)をみてね）。
https://chocolate-view.herokuapp.com/

Flavorを選択できる

![ezgif.com-gif-maker.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66005/2f16a226-eb23-9dac-24aa-2c488c3dcc85.gif)

銀のエンゼルが当たるまでに必要な購入数のシミュレーション

![ezgif.com-gif-maker (3).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66005/813b9144-aa99-ccec-e5ba-58488f235b55.gif)

おわり


# 参考

- [Show your ML Project to the Internet in Minutes](https://towardsdatascience.com/show-your-ml-project-to-the-internet-in-minutes-2a7bc3167bd0)
- [streamlit-heroku-template](https://github.com/patryk-oleniuk/streamlit-heroku-template)
- [チョコボール計測データのデータビューワーを作った](https://chocolate-ball.hatenablog.com/entry/2021/01/15/214339)
C3jsでリアルタイムグラフ

## 結果

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="js,result" data-user="nagitch" data-slug-hash="rNMrXNw" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="C3js TimeSeries Realtime Graph">
  <span>See the Pen <a href="https://codepen.io/nagitch/pen/rNMrXNw">
  C3js TimeSeries Realtime Graph</a> by Nagitch (<a href="https://codepen.io/nagitch">@nagitch</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://production-assets.codepen.io/assets/embed/ei.js"></script>


## 解説

### 過去1分間の時間軸を表示する

軸の設定をtype: timeseries(時系列), max/minに現在秒, 一分前の秒にしておくと自動的に過去1分間の時間軸を表示してくれます。
一秒刻みでデータを登録して無理やりプロットする、みたいなトリックは使わなくて大丈夫です。
また `2021-01-20 19:47:35` のような表示にする＆1分前の計算のためにdayjsを使っていますが、同じ形になれば何を使っても問題ありません。

```js

const timeNow = () => dayjs().format('YYYY-MM-DD HH:mm:ss');
const timeTail = () => dayjs().subtract(1, 'm').format('YYYY-MM-DD HH:mm:ss');

const chartAxis = {
  x: {
    type: 'timeseries',
    min: timeTail(),
    max: timeNow(),
```

また等間隔に満遍なく軸表示するために `fit: true`, 表示を倒して見やすくするため `rotate:-50` を指定します。

```js
    tick: {
      fit: true,
      rotate: -50,
      format: '%Y-%m-%d %H:%M:%S',
    }
```

### 時間軸(表示範囲)の更新

時間軸の更新には `axis.min()`, `axis.max()` 関数を使います。直接値を書き換えるだけだと反映されません。 `load()` を叩いても更新されません。

```js
setInterval(() => {
  chart.axis.min({x: timeTail()});
  chart.axis.max({x: timeNow()});
  ...
}, 1000)
```

サンプルでは毎秒新しいデータをプロットしていますが、歯抜けになっても大丈夫です。
好きなタイミングでどの秒にデータを入れても正しくプロットされます。

```js

  chartData.columns[0].push(timeNow());
  chartData.columns[1].push(Math.random());
  chart.load({columns: chartData.columns});
```
PUB400上のRPGコンパイル出来ない事を解決したい

AS400歴は3ヶ月程度なのですが
もう少し知ろうと思いNet上で見つけた
https://as400-howto.xyz/begin/hello-world/
をPUB400.com上で動作させてみようとしております。

ですが
最後のコンパイルで

```
    > CRTRPGPGM PGM(MOITARO1/SMPL01) SRCFILE(MOITARO1/QRPGSRC)       
      Unable to open file QRPGSRC in library MOITARO1 member SMPL01.    
      Compile failed. Program not created.
```
となってしまいます。

```
    > STRSEU SRCFILE(MOITARO1/QRPGSRC) SRCMBR(SMPL01M) TYPE(RPG)      
      Member SMPL01M added to file MOITARO1/QRPGSRC.                    
      Member SMPL01M in file MOITARO1/QRPGSRC changed with 3 records.
```
とRPGでSMPL01Mと指定しているのですがなぜ
＞Unable to open file
となってしまうのか調査するため記事にします。
【SQLServer】最大値のデータだけを更新したい【キーで絞り込めない場合】

#1 経緯
こんなテーブルがあった。

| ID  | 値段  |
|:----|:-----|
| 001 | 1000 |
| 001 | 3000 |
| 001 | 2000 |
| 001 | 1500 |
 
ここに最大フラグなるものを追加し、値段が最大のデータを知りたいと思った。
でもキーでは絞り込めない。いい感じにこうなってほしい。

| ID  | 値段  | 最大フラグ |
|:----|:-----|:----:|
| 001 | 1000 |  |
| 001 | 3000 | 1 |
| 001 | 2000 |  |
| 001 | 1500 |  |

#2 解決法
こう書いたら解決した。

```sql

UPDATE table
SET 最大フラグ = '1'
WHERE 値段 = ( SELECT TOP 1 値段
               FROM table
               ORDER BY 値段 DESC
             )
```

#3 どう？
解決した？
こう見たらぱっと思いつきそうだけど詰まった上に調べても全然出てこなかったから、
同じように詰まった人の助けになったらいいなと思う。
（UE4）フルスクリーン/ウィンドウモードの切り替え

パッケージ化したゲームを実行するとデフォルトでフルスクリーン表示になるが、これを変更する方法がある。
##◇ウィンドウモードに変更する方法
###iniファイルの書き換え
これはパッケージ後の実行ファイルを変更できるやり方になる。

・ローカルディスク/プロジェクト名/Saved/Config/Windows/GameUserSettings.ini
![スクリーンショット 2021-01-20 19.50.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939279/c1139d71-dc75-e5ce-8fae-d8112ea81c62.png)
この中にあるFullscreenModeの値を以下に書き換えることで設定できる。
0…ネイティブフルスクリーン
1…Windowフルスクリーン
2…Windowモード
（書き出した.exeがどのiniファイルを参照にしているか注意）
###ブループリントから
上記のコンソール設定を、ブループリントから設定する方法。

####・GameUserSetting
![スクリーンショット 2021-01-20 19.54.38のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939279/08cf4b81-bd99-5350-52c5-8cc1d6da7b1e.png)
このノードからiniファイルにアクセスして内部情報を編集することができる。

####・SetScreenResolution
![スクリーンショット 2021-01-20 19.54.38のコピー2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939279/d50b565d-2d73-ff1a-952d-e1a403142d04.png)
GameUserSettingノードのReturnValueからTargetに繋いで、Resolutionを任意に設定してウィンドウのサイズを決めることができる。

####・ApplySettings
![スクリーンショット 2021-01-20 19.54.38のコピー3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939279/065c614c-bb68-fa5f-67ce-1578803ba6eb.png)
最後にこれを繋いで、設定を適用する。
*これを繋ぎ忘れると適用されない。

このノードを活用すれば、キーボード等に割り当てることでゲームの画面表示を簡単に切り替えたりできる。
ウィンドウ表示だけでなく、このGameUserSettingから使えるノードは[他にも](https://docs.unrealengine.com/en-US/API/Runtime/Engine/GameFramework/UGameUserSettings/index.html)あり、全ての設定は適用した段階でコンフィグファイルに自動保存される。

##<メモ>
○フルスクリーンには2つのモードがある。
・ネイティブフルスクリーン…ディスプレイのサイズに合わせて引き伸ばす
・Windowフルスクリーン…Windowをフルスクリーンサイズに表示する
ネイティブフルスクリーンモードを利用する場合、パッケージ後に"Alt+Enter"キーで切り替えができる。

○SetFullScreenModeというノードもあり、上記のモード+Windowが設定できる。
Google Apps ScriptでGitHub Appsの認証をする

# はじめに

Google Apps Script(GAS)でGitHub Appsの認証をする方法について説明します。

だいぶ前にやったことなんですが、役に立つ人がいるかもしれないのでメモとして残しておきます。

# 準備

GitHub Appsの設定画面でpemファイルをダウンロードして、 `openssl pkey -in pemファイル` の出力をGASのユーザープロパティとかスクリプトプロパティとかに設定しておく[^1]。

[^1]: 他の人から見えない置き方をしていればなんでもいいです。


# コード

少し長いのですが、GitHub Appsの認証を行う関数です。

```js
function getAccessToken() {
  const props = PropertiesService.getUserProperties();
  const token = props.getProperty('token');

  // プロパティが存在しなかったら new Date(null) になって1970/1/1 9:00になる
  const expiration = new Date(props.getProperty('expiration'));

  if (token !== null && new Date().valueOf() < expiration.valueOf()) {
    return token;
  }

  const privateKey = props.getProperty('privateKey');

  const header = { alg: 'RS256', typ: 'JWT' };
  const payload = {
    iat: Math.floor(Date.now() / 1000),
    exp: Math.floor(Date.now() / 1000) + 5 * 60,
    iss: 0 /* App IDを入れる */,
  };

  const toSign = Utilities.base64EncodeWebSafe(JSON.stringify(header)) + '.' + Utilities.base64EncodeWebSafe(JSON.stringify(payload)).replace(/=+$/, '');
  const signatureBytes = Utilities.computeRsaSha256Signature(toSign, privateKey);
  const signature = Utilities.base64EncodeWebSafe(signatureBytes).replace(/=+$/, '');

  const jwt = `${toSign}.${signature}`;

  const installationsResponse = UrlFetchApp.fetch('https://api.github.com/app/installations', {
    method: 'get',
    headers: {
      accept: 'application/vnd.github.machine-man-preview+json',
      authorization: `Bearer ${jwt}`,
    },
  });
  const installations = JSON.parse(installationsResponse.getContentText());
  const installationId = installations.find(v => v.account.login === 'XXX' /* 適当な条件で判定する */).id;

  const accessTokenResponse = UrlFetchApp.fetch(
    `https://api.github.com/app/installations/${installationId}/access_tokens`, {
    method: 'post',
    headers: {
      accept: 'application/vnd.github.machine-man-preview+json',
      authorization: `Bearer ${jwt}`,
    },
  });
  const accessTokenJson = JSON.parse(accessTokenResponse.getContentText());
  const accessToken = accessTokenJson.token;

  props.setProperties({
    expiration: accessTokenJson.expires_at,
    token: accessToken,
  });

  return accessToken;
}
```

この関数は

- アクセストークンを1度も取得したことがなかったらアクセストークンを取得して返す
- アクセストークンが取得済みで、期限が切れていなかったらそのトークンを返す
- アクセストークンが取得済みで、期限が切れていたら、アクセストークンを取得し直して返す

というのをしているので、アクセストークンが欲しい場面で毎回この関数を呼ぶようにするといい感じになります。こんな感じです。

```js
UrlFetchApp.fetch('https://api.github.com/graphql', {
  method: 'post',
  contentType: 'application/json',
  headers: {
    Authorization: `Bearer ${getAccessToken()}`,
  },
  payload: ...
});
```

どういう流れでアクセストークンを取得しているのかは、調べると出てくると思うので省略します。
visual studio for macで複数行を同時に編集するには

#visual studioで複数行一括編集する方法

同じ様な内容をまとめて一括して編集することをマルチキャレットというのですが、それをするには下記のコマンドで解決

###control(⌃) + option(⌥) + 右クリック(指二本クリック)

![スクリーンショット 2021-01-20 20.04.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/566867/8f77b3fa-c6bb-1a69-1c87-dace4192129a.png)
初心者のためのJUnitテスト環境構築からのテスト実施(更新系まで)方法

JUnitを使った単体テストの環境構築の備忘録です。JUunit5の環境構築に困っている方の参考になればと思います.

1. pom.xmlに必要なDependencyを追加. ここでは、以下の３つを追加
 - 「JUnit」のバージョン5
 - Hamcrest(Assertionと呼ばれる値のチェックに使うメソッドのフレームワーク)
 - H2データベース(In-Memoryのデータベースを使うことで、ローカル環境にデータベースがなくてもテストできるようにする)

```xml
		<dependency>
			<groupId>org.junit.jupiter</groupId>
			<artifactId>junit-jupiter</artifactId>
			<version>5.7.0</version>
		</dependency>
		<dependency>
			<groupId>org.hamcrest</groupId>
			<artifactId>hamcrest-all</artifactId>
			<version>1.3</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>com.h2database</groupId>
			<artifactId>h2</artifactId>
			<version>1.4.197</version>
			<scope>test</scope>
		</dependency>
```
２. application.ymlを編集する.

```yaml

spring:
  datasource:
    driverClassName: org.h2.Driver
    # "CLOSE_DELAY=-1"でテストを実行してから終了するまでの間、DBがある状態を作る設定
    url: jdbc:h2:mem:[あなたのDB名];DB_CLOSE_DELAY=-1 
    username: sa
    password:
  h2:
    console:
      enabled: true

  jpa:
    formatsql: true
    show_sql: true
    properties:
      hibernate:
        dialect: org.hibernate.dialect.H2Dialect
      hbm2ddl:
        auto: none
    hibernate:
      ddl-auto: create
```

3.テストファイルを作成。 画像のように、「src/test/java/com/example/myApp」以下にフォルダ&Javaファイルを作成

![スクリーンショット 2021-01-20 8.22.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637360/8c64858e-1eb9-f865-5570-fb329bd284a6.png)
　
4. テスト用のデータを挿入するSQLファイルを作成。ファイルの作成場所は「テスト.java」と同じフォルダ　
 ![スクリーンショット 2021-01-20 8.45.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637360/8a10c5e6-a586-b779-1aa0-256d80b36a25.png)
　　※5.で記述する@Sqlはデフォルトで同じフォルダ内にある、ファイル名が「テスト.java」の「.java」を「.sql」にしたファイルを探す

　
５. 「テスト.java」の中身を記述


```java
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Transactional
@Sql
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD) //  メソッドごとにDBをリフレッシュする
@AutoConfigureTestDatabase(replace = Replace.ANY)
public class HogeTest { // テストしたいクラス名の後ろに"Test"をつける

  @Autowired
  private Repository repos; // テストしたいクラスをインポート

  @Autowired
  private JdbcTemplate jdbcTemplate; // 戻り値がvoidのメソッドが正しく機能したかをSELECTして確認するために使う

　 @Test // 戻り値メソッドの場合
  public void testFindProduct() { 
    int id = 1;
    Product actual = repos.findProduct(id); // idでレコードを１つ取得するメソッドがあるとした場合
　　// import static org.junit.jupiter.api.Assertions.assertTrue;
    assertTrue(actual != null); // 
  }
  
  @Test
  public void testUpdateUser() {
    int id = 1;
    String name = "updatedName";
    repos.updateUser(id, name) //　戻り値なしでidを条件に名前を変更するメソッドの場合
    String sql = "SELECT name FROM users WHERE id = ?";
    RowMapper<User> rowMapper = new BeanPropertyRowMapper<User>(User.class);
    List<User> actual = jdbcTemplate.query(sql, rowMapper, id);
    assertEquals("updatedName", actual); // 変更した名前とメソッド実行後に取得した名前を比較して一致していることチェック
    
  }

}

```

6.テストを実行する。問題がなければ画像のようにデバッグコンソールにログが表示され、「✔️」がつく

![スクリーンショット 2021-01-20 19.56.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637360/166ffdab-8b31-90f4-e359-d9e3ee68578b.png)
32bitと64bitの変数を時間として扱った場合に溢れるまでの時間一覧

##概要

主にC++で int と long long を時刻として割り当てて使った時に、いつ溢れるんだっけと忘れるので、桁あふれ（オーバーフロー）する時間を表にまとめた。
(Excelでやろうとしたらセルの精度不足で、64bitの大きい数値は打ち切り誤差出てしまったので、一部はWindowsの "calc" による手計算。なのでその辺りは誤差乗っているかも。)

なお、型のサイズ一覧は以下等を参照のこと

**データ型の範囲 - Microsoft Docs**
https://docs.microsoft.com/ja-jp/cpp/cpp/data-type-ranges?view=msvc-160

---

######変数サイズ

|ビット数|32 bit|64 bit|
|---|--:|--:|
|バイト数|4 byte|8 byte|
|最低値(signed)|-2,147,483,648|-9,223,372,036,854,775,808|
|最大値(signed)|2,147,483,647|9,223,372,036,854,775,807|
|最低値(unsigned)|0|0|
|最大値(unsigned)|4,294,967,295|18,446,744,073,709,551,615|

---

######32bit (signed) の枯渇時期  ※ 0から増加させた場合

|使用単位|時間|日数|年数|
|--:|--:|--:|--:|
|1秒|596,523 時間|24,855 日|68 年|
|100ms|59,652 時間|2,486 日|7 年|
|10ms|5,965 時間|249 日|1 年|
|1ms|597 時間|25 日|0 年|
|100us|60 時間|2 日|0 年|
|10us|6 時間|0 日|0 年|
|1us|1 時間|0 日|0 年|

---

#####32bit (unsigned) の枯渇時期
	
|使用単位|時間|日数|年数|
|--:|--:|--:|--:|
|1秒|1,193,046 時間|49,710 日|136 年|
|100ms|119,305 時間|4,971 日|14 年|
|10ms|11,930 時間|497 日|1 年|
|1ms|1,193 時間|50 日|0 年|
|100us|119 時間|5 日|0 年|
|10us|12 時間|0 日|0 年|
|1us|1 時間|0 日|0 年|

---

#####64bit (signed) の枯渇時期  ※ 0から増加させた場合

|使用単位|時間|日数|年数|
|--:|--:|--:|--:|
|1秒|2,562,047,788,015,216 時間|106,751,991,167,301 日|292,471,208,678 年|
|100ms|256,204,778,801,522 時間|10,675,199,116,730 日|29,247,120,868 年|
|10ms|25,620,477,880,152 時間|1,067,519,911,673 日|2,924,712,087 年|
|1ms|2,562,047,788,015 時間|106,751,991,167 日|292,471,209 年|
|100us|256,204,778,802 時間|10,675,199,117 日|29,247,121 年|
|10us|25,620,477,880 時間|1,067,519,912 日|2,924,712 年|
|1us|2,562,047,788 時間|106,751,991 日|292,471 年|
|100ns|256,204,779 時間|10,675,199 日|29,247 年|
|10ns|25,620,478 時間|1,067,520 日|2,925 年|
|1ns|2,562,048 時間|106,752 日|292 年|

---

#####64bit (unsigned) の枯渇時期			

|使用単位|時間|日数|年数|
|--:|--:|--:|--:|
|1秒|5,124,095,576,030,431 時間|213,503,982,334,601 日|584,942,417,355 年|
|100ms|512,409,557,603,043 時間|21,350,398,233,460 日|58,494,241,736 年|
|10ms|51,240,955,760,304 時間|2,135,039,823,346 日|5,849,424,174 年|
|1ms|5,124,095,576,030 時間|213,503,982,335 日|584,942,417 年|
|100us|512,409,557,603 時間|21,350,398,233 日|58,494,242 年|
|10us|51,240,955,760 時間|2,135,039,823 日|5,849,424 年|
|1us|5,124,095,576 時間|213,503,982 日|584,942 年|
|100ns|512,409,558 時間|21,350,398 日|58,494 年|
|10ns|51,240,956 時間|2,135,040 日|5,849 年|
|1ns|5,124,096 時間|213,504 日|585 年|

---

##まとめ
よほど理由がない限り、思考停止で64bitを使おう。

あと、ありがちなのは・・・

- 2000年問題 (西暦を下2桁で管理する環境)
- 2038年問題 (UNIX時間を signed 32bit で扱う環境)
- GPS/GNSSの19.6年問題 (GPS/GNSS 週数ロールオーバー)

最後に余談、signed で使っておくと、`x++;`し続けてマイナスに到達したとしても、変数の繰り上がりによるバッファ破壊を起こすことはない（が、言語使用等によって変わるだろうし、おすすめはしない）。
（signedの値は、2進数的に見ると`最大値+1`=`最低値`なので自動的にマイナスに突入し、その後は通常通り"+1"されていく。）
manimの作法 その23

#概要

manimの作法、調べてみた。
VectorScene使ってみた。

#サンプルコード

```
from manimlib.imports import *

class test(VectorScene):
	def construct(self):
		two_dot = TexMobject("2\\cdot")
		equals = TexMobject("=")
		self.add_axes()
		v = self.add_vector([3, 1])
		v_coords, vx_line, vy_line = self.vector_to_coords(v, clean_up = False)
		self.play(ApplyMethod(v_coords.to_edge, UP))
		two_dot.next_to(v_coords, LEFT)
		equals.next_to(v_coords, RIGHT)
		two_v = self.add_vector([6, 2], animate = False)
		self.remove(two_v)
		self.play(Transform(v.copy(), two_v), Write(two_dot, run_time = 1))
		two_v_coords, two_v_x_line, two_v_y_line = self.vector_to_coords(two_v, clean_up = False)
		self.play(ApplyMethod(two_v_coords.next_to, equals, RIGHT),Write(equals, run_time = 1))
		self.wait(2)
		x, y = v_coords.get_mob_matrix().flatten()
		two_v_elems = two_v_coords.get_mob_matrix().flatten()
		x_sym, y_sym = list(map(TexMobject, ["x", "y"]))
		two_x_sym, two_y_sym = list(map(TexMobject, ["2x", "2y"]))
		#VMobject(x_sym, two_x_sym).set_color(X_COLOR)
		#VMobject(y_sym, two_y_sym).set_color(Y_COLOR)
		syms = [x_sym, y_sym, two_x_sym, two_y_sym]
		#VMobject(*syms).scale(VECTOR_LABEL_SCALE_FACTOR)
		for sym, num in zip(syms, [x, y] + list(two_v_elems)):
			sym.move_to(num)
		#self.play(Transform(x, x_sym), Transform(y, y_sym), FadeOut(VMobject(*two_v_elems)))
		self.wait()
		#self.play(Transform(VMobject(two_dot.copy(), x.copy()), two_x_sym), Transform(VMobject(two_dot.copy(), y.copy() ), two_y_sym))
		#self.wait(2)





```

#生成した動画

https://www.youtube.com/watch?v=Kq7Ptpt6YZQ

以上。
【Swift】繰り返し文まとめ

#はじめに
この記事には、Swiftで多用する繰り返し文についてまとめました。
⚠️当方初学のため認識違いがある可能性大です
誤りを見つけた際はコメントにて指摘していただけると幸いです🙇‍♀️🙇‍♂️


#参考文献
この記事は以下の情報を参考にして執筆しました。

- [Swift実践入門](https://www.amazon.co.jp/%EF%BC%BB%E5%A2%97%E8%A3%9C%E6%94%B9%E8%A8%82%E7%AC%AC3%E7%89%88%EF%BC%BDSwift%E5%AE%9F%E8%B7%B5%E5%85%A5%E9%96%80-%E7%9B%B4%E6%84%9F%E7%9A%84%E3%81%AA%E6%96%87%E6%B3%95%E3%81%A8%E5%AE%89%E5%85%A8%E6%80%A7%E3%82%92%E5%85%BC%E3%81%AD%E5%82%99%E3%81%88%E3%81%9F%E8%A8%80%E8%AA%9E-WEB-PRESS-plus-ebook/dp/B086VVQ3DJ/ref=sr_1_1?adgrpid=56053864951&dchild=1&gclid=CjwKCAiAo5qABhBdEiwAOtGmbtEdp97n9eQCgn4VQpffZut8DhCnND9sXQBMoTecHwls0LKIy4l-cxoCCZwQAvD_BwE&hvadid=338518511220&hvdev=c&hvlocphy=1009155&hvnetw=g&hvqmt=e&hvrand=13959960213026669174&hvtargid=kwd-306987067810&hydadcr=27263_11561109&jp-ad-ap=0&keywords=swift%E5%AE%9F%E8%B7%B5%E5%85%A5%E9%96%80&qid=1611048736&sr=8-1&tag=googhydr-22)


#目次
1. for-in文 - シーケンスの要素の列挙
2. while文 - 継続条件による繰り返し
3. repeat-while文 - 初回実行を保証する繰り返し
4. 実行文の中断


#1. for-in文 - シーケンスの要素の列挙
Sequenceプロトコルに準拠した型（ArrayやDittionary等）の要素にアクセスするための制御構文。
各要素を実行文に順次渡しながらその要素の数だけ繰り返す。
実行文内では、要素名として指定した名前の定数を通じて要素にアクセスできる。

```for 要素名 in シーケンス {
要素ごとに繰り返し実行される文
}
```

Array<Element>型の要素をfor-in文で列挙する場合、要素の型はElement型となる。
Dictionary<Key, Value>型の要素をfor-in文で列挙する場合、要素の型は（Key, Value）型のタプルとなる。


#2. while文 - 継続条件による繰り返し
条件式が成り立つ限り繰り返しを続ける制御構文。
while文は条件式と繰り返し実行される文から構成されている。
while文の条件式は、if文やfor-in文と同様にBool型を返す必要がある。
条件式は実行文の実行前に毎回評価され、結果がtrueであれば繰り返しを継続し、falseであれば繰り返しを停止し、while文全体の処理を終了する。

```while 条件式 {
条件式が成立する間、繰り返し実行される文
}
```



#3. repeat-while文 - 初回実行を保証する繰り返し
通常while文は実行前に評価を行うので、場合によっては一度も処理が行われない場合がある。だが、repeat-while文を使えば条件式は実行文の後に評価されるので条件の成否に関わらず、必ず一回は処理が行われる。

```repeat {
一回は必ず処理され、それ以降は条件式が成立する限り繰り返し実行される文
} while 条件式
```



#4. 実行文の中断

###break文 - 繰り返しの終了
実行文を中断し、繰り返し文全体を終了する。
これ以上繰り返しを行う必要がない場合などに使用する。

###continue文 - 繰り返しの継続
実行文を中断した後、後続の繰り返しを継続する。
特定の場面だけ処理をスキップしたい場合など使用する。
continue文は、continueキーワードのみかラベルとの組み合わせで使用する。

###ラベル - break文やcontinue文の制御対象の指定
break文やcontinue文はラベルを用いて制御対象を指定できる。
ネストした繰り返しから一度退出する場合などに使用する。
ラベルによって繰り返し文を参照可能にするには、繰り返し文の前にラベル名:を追加する。

```ラベル名: 繰り返し文
```

breakやcontinueキーワードに続けてラベル名を追加することで対象の繰り返し文を明示する。

```break ラベル名
```

```continue ラベル名
```
[Tableau] データはフィルターせずに、ビューだけフィルターする 

# こんなときに

時系列のVizを作ってるが、この期間ピンポイントで見たい。けど、過去のデータを参照しているので、フィルターすると値が無くなっちゃう、おかしくなる。

#用意するもの

* データソース : サンプル - スーパーストア(Tableau に入っているサンプルです。)

#環境

* Tableau Desktop : 2020.3.0

#準備

* ここまで作ってみましょう。
 
年ごとの売上合計の前年との差分 遷移
お試し用なので適当に

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177920/f3b8f1b1-7eeb-7baf-cc29-c95f87204eb6.png)

#これだと

特定の年（たとえば 2019 のみ) を見たくて、フィルター（オーダー日）いじると、ビューに何も表示されない。
なぜなら、前年 2018 のデータがフィルターから除外されてしまうので。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177920/baf0bdda-e84e-73f4-ebf5-2667983eeaa5.png)

#ほんとは、こうしたい

2019 にすると、それ以外の年はビューには表示されず、かつ 前年(2018)のデータも反映された形で表示される
 （あまり意味は無いですが、あくまでサンプルとして）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177920/d0601b35-d158-a7a8-b56b-3737afb57ee1.png)

#やり方

* Step1

1. 計算フィールドを作成
2. 年単位なので、DATEPART関数で ‘year’ で抽出
3. MINでその年の最小の値を取得（年単位なので、この場合該当年が入る）: 2018 年の最小値は、2018
4. LOOKUP関数を使って、オフセットを 0 にし”現在位置”を取得する : 2018なら、-1 なら１行前(2017)、+1 なら1行後(2019)
5. これをフィルターにすることで選択したものが 「現在位置」として指定できる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177920/3dc7ef27-4de9-3667-acd7-18dd613bd87c.png)

参考資料
※ [日付関数 DATEPAET](https://help.tableau.com/current/pro/desktop/ja-jp/functions_functions_date.htm)
※ [表計算関数 LOOKUP](https://help.tableau.com/current/pro/desktop/ja-jp/functions_functions_tablecalculation.htm#lookupexpression-offset)


* Step2

不連続に変換し、フィルターに入れる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177920/2e6ac6d1-cac8-4c2b-9dba-f8e447aa0808.png)

#完成

2019 にすると、それ以外の年はビューには表示されず、かつ 前年(2018)のデータも反映された形で表示される （あまり意味は無いですが）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177920/187cb2d0-ea17-74e3-8883-bc6407624fc8.png)



あとは、各人のユースケースに合わせてお楽しみください。

#参考文献

* [参照元データをフィルターせずにビューをフィルターする](https://kb.tableau.com/articles/howto/filtering-view-without-filtering-underlying-data?lang=ja-jp)
python codeの自動整形をするアクションを作ってみた

# Why
* チーム開発をしていると、コードフォーマットの差が大きい
    * やる人もいれば、やらない人もいる
    * フォーマッタが異なる
* コード整形のみのコミットを入れたくない
* 開発者に手間を掛けさせず、且つローカル環境の依存をなくしたい
    * black, autopepなどのライブラリをローカル環境に依存したくない
    * vscodeやemacsなどエディタに依存したくない

* github actionsを触ってみたかった
    * 初めてのお題としては丁度いいと思った

# What
* 作ったもの
    * 所定のbranchにpushした時に、所定（今回の例だと、workspace/python以下）の*.pyコードをサーチし、対象となったpythonファイルにblackによるコード整形を実行する
    * プルリク→マージも想定して、マージ先のブランチにマージされた時にも、上記コード整形を実行する
    * [リポジトリ](https://github.com/unmo/codeformat_with_actions)
* 前提
    * コード整形にはblackを用いる
    * ブランチは適当に、main/developの2つ
* ディレクトリ構成
    * code-format.ymlが今回のアクションの中身

```
├─.github
│  └─workflows
│          code-format.yml
│
└─python
    │  pyproject.toml
    │
    └─source
            a.py
            b.py
```

# How
* code-format.ymlは以下のようにしました

```code-format.yml
name: python auto code format

on:
  push:
    branches: 
      - main
      - develop
    paths:
      - 'python/**'

  workflow_dispatch:

jobs:
  black:
    name: Check code style with Black
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: ./python
    steps:    
      - name: Checkout
        uses: actions/checkout@v2
      - name: Set up Python 3.6.8
        uses: actions/setup-python@v2
        with:
          python-version: 3.6.8
      - name: Install black
        run: pip install black
      - name: run code format
        run: find . -type f -name "*.py" | xargs black
      - name: git settings
        run: |
          git config --local user.email "github-actions[bot]@users.noreply.github.com"
          git config --local user.name "github-actions[bot]"
      - name: Extract branch name
        id: extract_branch
        run: echo "##[set-output name=BRANCH_NAME;]$(echo ${GITHUB_REF#refs/heads/})"
      - name: commit
        run: git commit -m "python modules changed auto format." -a || echo "No changes to commit."
      - name: push
        run: |
          echo target branch is ${{ steps.extract_branch.outputs.BRANCH_NAME }}
          git pull
          git push origin ${{ steps.extract_branch.outputs.BRANCH_NAME }}

```

* 確認方法
    1. developブランチから、適当なtopicブランチを作成する
    2. 適当なtopicブランチで、適当なコード(今回はb.py)編集（フォーマットを崩す）
    3. commit & push
    4. github上でプルリク生成
    5. 適当なtopicブランチ→developにmerge
    6. アクションが走る
    7. developブランチのb.pyが、コード整形された状態でpushされている

* actionsの様子
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59445/3428cc9c-ec40-0d3e-620c-37b4adec1a0a.png)

* developブランチのコミット履歴
    * ちょっとわかりにくいですが以下、github actionsがコミットした履歴が残っており、きれいにフォーマットされているのが確認できます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59445/d77027ea-e0f3-4a16-b309-95a24b779c95.png)

# lastly
今回はtopicブランチ→developブランチを想定して行いましたが、develop→mainも同様です
また、このケースだと、main or developブランチにダイレクトコミットした場合もactionsが走ります
【Android】センサーを使う方法

#プログラミング勉強日記
2021年1月20日
[一昨日の記事](https://qiita.com/mzmz__02/items/d5fc432fbc772866b2e8)でAndroidのセンサーAPIについてまとめた。今日はAndroidのセンサーの使い方を簡単にまとめる。

#Androidセンサーを使う方法
　Androidセンサーを使う処理を説明する。

##1. SensorManagerを取得
　SensorManagerを取得するためには、getSystemServiceメソッドを使う。引数には、android.contentパッケージのContextクラスの定数SENSOR_SERVICEを指定する。

```java:SensorManagerの取得
// SensorManagerインスタンス
private SensorManager sensorManager;

@Override
public void onCreate(Bundle savedInstanceState) {
  // SensorManagerのインスタンスを取得する
  sensorManager = (SensorManager) this.getSystemService(SENSOR_SERVICE);
}

```

##2. イベントリスナーの実装
　イベントリスナーは、何かしらのイベントが発生したときに呼ばれるクラスである。センサーイベントには、SensorEventListenerインタフェースをActivityに実装して具体的な処理をする。
　SensorEventListenerインタフェースにはonAccuracycahngedとonSensorCahngedの2つのメソッドが定義されている。


```java:イベントリスナーの実装
public class SensorActivity extends Activity implements SensorEventListener {

 
    @Override
    // センサーの精度が変更されると呼ばれる
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
       
    }
 
    @Override
    // センサーの値が変化すると呼ばれる
    public void onSensorChanged(SensorEvent event) {
        
    }
}
```

###イベントリスナーの登録と登録解除の方法
　リスナーの登録にはSensorManagerクラスのregisterListenerメソッドを使う。引数には、センサーイベントを取得するリスナー、取得するセンサーの種類、取得する頻度を設定する。

```java
registerListener(SensorEventListener listener, Sensor sensor, int rate)
```

　イベントリスナーの登録解除には、SensorManagerクラスのunregisterListenerメソッドを使う。

```java:イベントリスナーの登録を解除
protected void onPause() {
    super.onPause();
    if (sensorManager != null) {
        sensorManager.unregisterListener(this);
    }
}
```

#参考文献
[センサーを利用する / GETTING STARTED](https://techbooster.org/android/device/12524/)
【備忘録】Dart/Flutterの静的解析ルールのimplicit_dynamic_variable , implicit-dynamicへの対応

# implicit_dynamic_variable
*変数の型を明示的にする*

## 概要

```dart
// 変数（_createdAt）の型が明示的になっていない
final _createdAt = data['createdAt'];

// こんな感じにする
final _createdAt = data['createdAt'] as DateTime;
```

↑のようにするか、解析オプションファイルから implicit-dynamic を削除する
HMSスマホでLINE CLOVA Assistantを有効にする手順と機能紹介

# HMSスマホの音声アシスタント

音声アシスタントとは音声だけで端末を操作する機能です。

一般的に、Android端末ではGoogleアシスタントがプリインストールされ、使われています。ところが、ファーウェイの最新端末にGoogleのアプリがプリインストールされていないし、GMSも入っていないので、Googleアシスタントが利用できません。

ファーウェイは去年[セリア（Celia）](https://consumer.huawei.com/en/emui/celia/)という音声アシスタント機能をリリースしました。しかし、残念ながら、日本語がまだ対応されておらず、日本もまだサポート地域に入っていません。

幸い、HMS端末で使える音声アシスタントはほかにあります。それはLINE CLOVA Assistantです。しかも、以下の[HMS端末ではLINE CLOVA Assistantが標準搭載になっています](https://clova.line.me/huawei/)。

- [HUAWEI P40 Pro 5G](https://consumer.huawei.com/jp/phones/p40-pro/)
- [HUAWEI P40 lite 5G](https://consumer.huawei.com/jp/phones/p40-lite-5g/)
- [HUAWEI Mate 30 Pro 5G](https://consumer.huawei.com/jp/phones/mate30-pro-5g/)

![image.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704548/ed6e9f6e-5acc-8410-43fe-a41229aa09bf.png)

# HMS端末でLINE CLOVA Assistantを有効にする手順

[設定] -> [アプリ] -> [デフォルトアプリ] -> [アシスタント機能と音声入力] -> [アシストアプリ]　に入って、LINE CLOVA Assistantを選ぶだけです。

こちらはその手順の動画です：[https://twitter.com/i/status/1351829028173320192](https://twitter.com/i/status/1351829028173320192)

（LINE CLOVA Assistantを使うのに、LINE）

# HMS端末のLINE CLOVA Assistantで何ができるか？
以下のできることの例です。

|機能|コマンドの例|
|:---|:---|
|電話をかける|〇〇に電話かけて|
|通話履歴を表示する|通話履歴を表示して|
|スマホの設定を変更する|Bluetoothをオンにして|
|アプリを起動する|App Galleryを起動して|
|天気を調べる|今日の天気を教えて|
|事柄を調べる|〇〇について教えて|
|ニュースを知る|ニュースを教えて|
|翻訳する|○○語に翻訳して|
|日時などを確認する|いま何時|
|運行情報を調べる|山手線の運行情報を教えて|
|イベント情報を調べる|イベント情報教えて|

こちらはHMS端末でLINE CLOVA Assistantを使う動画です。

アプリ起動：[https://twitter.com/i/status/1351829397662121986](https://twitter.com/i/status/1351829397662121986)
百科事典：[https://twitter.com/i/status/1351829528914522115](https://twitter.com/i/status/1351829528914522115)
時間：[https://twitter.com/i/status/1351829624880132100](https://twitter.com/i/status/1351829624880132100)
【備忘録】Dart/Flutterの静的解析ルールのavoid_init_to_nullへの対応

# avoid_init_to_null
*DON'T explicitly initialize variables to null.*
*nullを使って初期化しない*

- [ドキュメント](https://dart-lang.github.io/linter/lints/avoid_init_to_null.html)

## 概要

Dartでは、明示的に初期化されていない変数やフィールドは、自動的にnullに初期化されます。
このため、nullを使って初期化することは冗長であり、不要です。
また、Dartには、初期化されていないメモリという概念はありません。

```dart
// nullで初期化してはいけない
int somethingNumber = null;

// こうする
int somethingNumber;
```
Ansible Tips: 複数ノードに対する接続状況により処理を別ける例

備忘

# 課題
2ノードで連携するSWの制御の為に、一部ノードが接続不可の場合に処理を別ける必要があった。

# 対応
wait_for_connectionをignore_errors: trueで実行し、結果を取得することで対応可能。


# tasksの例
```yaml

- name: "リストのnode_pairからローカルノードを除いて相手ノードをremote_nodeに設定"
  set_fact:
    remote_node: '{{ node_pair|difference([inventory_hostname])|first }}'
  vars:
    node_pair:
    - node1
    - node2

- name: "接続を確認"
  wait_for_connection:
    timeout: 30
  ignore_errors: true
  register: connection_result

- name: "接続失敗ノードでは処理をスキップさせる(includeは行われるが含まれるtaskそれぞれにおいてスキップとなる)"
  when: connection_result is succeeded
  block:

  - name: 相手ノードに接続できなかった場合、takeover.yml処理をinclude
    when: hostvars[remote_node].connection_result is failed
    include_tasks: takeover.yml

  - name: 相手ノードに接続できた場合、recover.yml処理をinclude
    when: hostvars[remote_node].connection_result is succeeded
    include_tasks: recover.yml
```
[JavaScript]書き方と基礎文法に関して(変数、四則演算、条件分岐、繰り返し処理)

今回は、JavaScriptの基礎文法について書いていきます！！
JavaScriptの文法はRubyと似ていて少し頭の中がごちゃごちゃします(笑)

なので、記憶が新しい内に整理していきます。
#Javascriptの書き方（2通り）

**scriptタグ**を使います。

その後からは、下記の2種類の方法で出来ます。

①htmlファイル内に書いていく。

```html:①.html:title
<!DOCTYPE html>
<html lang="ja">
  <head>  <meta charset="UTF-8">
  </head>
  <body>
    <script>..........</script> //scriptタグ内に書いていく。
  </body>
</html>
```

②〇〇.jsファイルに書いていく。　
　＊.js = javascript拡張子ファイルのことです。イメージとしては、cssファイルと同様です。

```html:②.html:title
<!DOCTYPE html>
<html lang="ja">
  <head>  <meta charset="UTF-8">
  </head>
  <body>
    <script src="app.js"></script>　//src=を用いて、jsファイルと繋げる。
  </body>
</html>
```

②の方が、ファイルないがごちゃごちゃせず、別ファイルにてJavaScriptのみ見れるので、
②で書いていくことが望ましいです。
（むしろ①で書くことなんてあるのかな、、、、。）

なので、これからの基礎文法は、.jsファイル内に書いていく事を想定して説明していきます。
#変数

今回は、　**hello**　を変数とした場合で書きます。

Rubyでいうと、下記の書き方でした。

```Ruby:Ruby.rb:title
   hello = "Hello world"
```
JavaScriptに関しては、少し異なります。

```Javascript:JavaScript.js:title
   var hello = "Hello World";      // var+変数　＝　値（文字もしくは数字）
```

相違点を下記の表でまとめました。

| 相違点 | 説明 |
|:-:|:-:|
|var| variable 英語で変数という意味。その略。 |
|  ; | 文の末には、；が必須。忘がち。  |

#四則演算
これは、Rubyとほぼ同じですね。

```Javascript:JavaScript.js:title;
   alert(2+4);   //　結果は、6
   alert(10-2);  //　結果は、8
   alert(3*4);   //　結果は、12
   alert(10/5);  //　結果は、2
```

ちなみに、 **alert** は、ブラウザの上にアラートを表示させるものです。
おそらくパソコンを使っている皆さんなら一度は見たことがあ流と思います。多分、、、、。
次の条件分岐の項目で、アラートの画像が出てきます。（結果の部分）

#条件分岐
if構文になります。
こちらもRubyと似ていますが、少しだけ違ったりしてややこしいです。
例を下記に記します。

```Javascript:JavaScript.js:title;
   var Tom = 20;
   var John = 18;

   if( Tom > John){                 //　（）の中には条件を記載
    alert('Tomは、Johnより年上です。');  //　どう処理するかを記載
   } else if( Tom == John) {        //  （）の中には条件を記載 
    alert('Tomは、Johnと同い年です。');  //　どう処理するかを記載　　
   } else {
    alert('Tomは、Johnより年下です。');
   }
```
`結果`
![スクリーンショット 2021-01-20 17.59.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1029483/b4c283e7-2cbd-a54f-f244-1b044b4b7a37.png)
とhtmlに表示される。

#繰り返し処理

こちらは、 **While** と **for** を使います。

・While構文

```Javascript:JavaScript.js:title;
   var max= 100;
   var num= 1;
   var count= 0;

   while(num < max){
     num = num * 2;
     count = count + 1;
   }
   alert('2を掛け続けて'+ max + 'を超えるのに必要だった回数は' + count + '回です');
```
`結果`
![スクリーンショット 2021-01-20 18.40.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1029483/071cc21d-8fea-f684-37bd-86bc17683074.png)


・For構文

```Javascript:JavaScript.js:title;
   var i;  
   var num = 0;

   for(i = 1; i < 101; i++){       //(初期値; 条件式; 増減値)で記載する。
     num = num + i;                //繰り返す度に＋1される。
   }
   alert('1から100まで足し算した結果は' + num + 'です。');   
                                  //条件式が当てはまらなくなったらalertが適応される。
```
`結果`
![スクリーンショット 2021-01-20 18.26.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1029483/ae170b8f-d669-5676-e7b2-125c2ac85189.png)

他にもありますが、一旦はこちらにて終わります。
以上、たにーでした。

よかったら、LGTMをよろしくお願いします！
守られるとモチベーションになります:joy:
manimの作法 その21

#概要

manimの作法、調べてみた。
ZoomedScene使ってみた。

#サンプルコード

```
from manimlib.imports import *

class test(ZoomedScene):
	CONFIG = {
		"zoom_factor": 0.3,
		"zoomed_display_height": 1,
		"zoomed_display_width": 6,
		"image_frame_stroke_width": 20,
		"zoomed_camera_config": {
			"default_frame_stroke_width": 3,
		},
	}
	def construct(self):
		dot = Dot().shift(UL * 2)
		image = ImageMobject(np.uint8([[0, 100, 30, 200], [255, 0, 5, 33]]))
		image.set_height(7)
		frame_text = TextMobject("Frame", color = PURPLE).scale(1.4)
		zoomed_camera_text = TextMobject("Zoomed camera", color = RED).scale(1.4)
		self.add(image, dot)
		zoomed_camera = self.zoomed_camera
		zoomed_display = self.zoomed_display
		frame = zoomed_camera.frame
		zoomed_display_frame = zoomed_display.display_frame
		frame.move_to(dot)
		frame.set_color(PURPLE)
		zoomed_display_frame.set_color(RED)
		zoomed_display.shift(DOWN)
		zd_rect = BackgroundRectangle(zoomed_display, fill_opacity = 0, buff = MED_SMALL_BUFF)
		self.add_foreground_mobject(zd_rect)
		unfold_camera = UpdateFromFunc(zd_rect, lambda rect: rect.replace(zoomed_display))
		frame_text.next_to(frame, DOWN)
		self.play(ShowCreation(frame), FadeInFrom(frame_text, direction = DOWN))
		self.activate_zooming()
		self.play(self.get_zoomed_display_pop_out_animation(), unfold_camera)
		zoomed_camera_text.next_to(zoomed_display_frame, DOWN)
		self.play(FadeInFrom(zoomed_camera_text, direction = DOWN))
		scale_factor = [0.5, 1.5, 0]
		self.play(frame.scale, scale_factor, zoomed_display.scale, scale_factor, FadeOut(zoomed_camera_text), FadeOut(frame_text))
		self.wait()
		self.play(ScaleInPlace(zoomed_display, 2))
		self.wait()
		self.play(frame.shift, 2.5 * DOWN)
		self.wait()
		self.play(self.get_zoomed_display_pop_out_animation(), unfold_camera, rate_func = lambda t: smooth(1 - t))
		self.play(Uncreate(zoomed_display_frame), FadeOut(frame))
		self.wait()


```

#生成した動画

https://www.youtube.com/watch?v=GetSZncd4lY

以上。
[Unity]AssemblyDefinitionを跨いだ共通クラスの作成

前提
・Assetをインポートしすぎて60個くらいAssemblyDefinitionできちまったぜ！てへっ！
・グローバルなDebugクラスはHighBridRender(ver8.2.0)で定義されててこっちで定義するとビルドエラー！うへっ！
　⇒やめてほしい
・AssemblyDefinitionに共通クラスを追加するの面倒だな（今後も含めて）
・ECSとか何万個のオブジェクトをゴリゴリ動かすから少しでも負荷になることは避けたい…ンゴ。

やることは大まかに以下の通り。
＜手順＞
１．クラスライブラリ(DLL)を作成。
　⇒VisualStudioで適当にプロジェクト作ってビルドでおｋ
２．クラスライブラリをAssets/Pluginsのどこかにおく。
　⇒Assets/Plugins/DLLとかネストしてておｋ
３．どこででも１．で作成したクラスライブラリが使えるようになる。
　⇒＼(^o^)／やた

＜メリット＞
・AssemblyDefinitionにわざわざ追加しなくていい。
　[Plugins]⇒[各AssemblyDefinition]⇒[Assembly-CSharp]の順で参照されるらしい。詳しくは知らんが動く。
　＃最初はクラスライブラリをUnityのクラスライブラリ群に突っ込んだりしていろいろ試してた。
　[Plugins]にAssemblyDefinition作って置けばいいんじゃね？っていってもできんかった。
　ワイももっと楽がしたかった

＜デメリット＞
・クラスライブラリのビルド忘れとかがある場合がある。
・クラスライブラリから[Assembly-CSharp]とか[各AssemblyDefinition]の参照ができない。
　⇒１回目はプレイボタンをエラーなく押すと動くけど、２回目以降は参照がおかしいとUnity様に怒られる。
　　バグだと思っているが直るの待つのは愚策なので参照できないと割り切って作る。
　　クラスライブラリなので処理を独立させましょう。

＜例＞
DebugLog用のオーバーラップクラスでいい感じに作れるんじゃないかと思われる。

```csharp:DebugS.cs

//　１．共通クラスライブラリ（DLL）
//  ネットのどこかにあるDebugLogのオーバーラップクラス
using UnityEngine;
public static class DebugS
{
#if !ENABLE_DEBUG_MODE
    private const string CONDITIONAL_TEXT = "UNITY_EDITOR";
#else
    private const string CONDITIONAL_TEXT = "ENABLE_DEBUG_MODE";
#endif
    /* 略 */
    [Conditional(CONDITIONAL_TEXT)]
    public static void Log(object message, LogLevel level)
    {
        if ((int)Ground.In.Value >= (int)level) UnityEngine.Debug.Log(message);
    }
    /* 略 */
}
namespace Ground
{
    public enum LogLevel { None,Low,Mid,High}
    public class In {public static LogLevel Value = LogLevel.None;}
}
```

使用例（上記DLLを[Assets/Plugins/DLL]とかに配置後）

```csharp:Hogehoge.cs
// UnityのどこかのDebugLog出力ソースコード
// 参照設定やUsingは不要（でーん！）
protected override void Initialize()
{
    if (!LoadThisData(SettingsSavePath))
    {
        DebugS.LogError($"Fail Load {SettingsSavePath}");
    }
    if (AutoSaveFlag)
    {
        StartAutoSave(DuloGames.UI.UIManager.Instance);
        DebugS.Log("AutoSave", Ground.LogLevel.High);
    }
    else DebugS.Log("Not AutoSave", Ground.LogLevel.High);
}
// ログ出力レベルの変更
void ChangeDebugLoglevel(Ground.LogLevel level)
{
    Ground.In.Value = level;
}

```

Unity標準のDebugクラスがオープンソースコードだったら喜んでたけど探してもなかったのであきらめた
（オーバーラップしたかった）

これが一番っょぃと思います。

元のDebugぶっ壊せてもユーザ環境壊せんから仕方ないな、これで勘弁してやろう。
俺より強いやつに会いに行く。（いまここ）
手軽にチャットを作成できるサービスをリリースした！

##初めに
今回はweb上で動くチャットアプリ　「スコーチチャット」を作りました。
アカウント登録不要
ダウンロード不要
で使い捨てで使われることを想定してます。

![chat-top.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480294/a3e7df9c-e0d8-251b-cdc0-44832a4cea7a.png)
パスワードも設定可能です

URL
https://scorch-chat.herokuapp.com/

##開発環境
rails6
ruby2.7
heroku 
postgresql
ActionCable
slim

いつもと同じです。

##開発期間
５日くらいです。
webアプリは当たる確率が6%程で質より量を打ったほうがいいといわれたのでなるべく早く作りました。

##チャット画面
![chat-smart.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480294/0f689b97-b0ea-6b43-8181-d67bce8b7666.png)

##[自分流]新しい技術の勉強法
結論から言うと、**元あるコードを改造すること**です。

初めて使う技術のコードを一気に書くのは難しいです。
なので作りたいアプリになるべく似たコードを
githubなどで落としてきてそれで開発を進めます。
するとインプットとアウトプットを実践でできるので
いい勉強法になると思ってます。

今回はじめてActionCableを使ったのですが最初は全く分かりませんでしたがもう
何となくわかるようになりました

##Railsはオワコンか？
ほかの記事で話題になっていたので取り上げます。

僕は**railsはオワコンではない**と思います。
結構昔から言われ続けてますが、まだオワコンにはなってないでしょう？
それが答えな気がします。

railsを圧倒するようなフレームワークが出ない限りオワコンにはならない気がします。

##終わりに
ここまで読んでくれてありがとうございました。

スコーチチャットをぜひ使ってみてください！
URL
https://scorch-chat.herokuapp.com/
Unityで行動分析

# はじめに
　「誰でも手を出せる・共有できる・改善できる」をモットーに、「Unity×行動分析」をUnity初心者でもわかりやすく記事にしてゆこうと思います。今回は、今後の記事内容について書いておきます。もしリクエストがあれば、いつになるかはわかりませんが、そちらにも対応したいと思います。

# 今後の予定
　強化スケジュールをUnityで作る方法を2月中に記事にする予定です。また、応用編として、ルール支配行動の実験や自由オペラント実験ができるような課題の作り方、分析方法についても3月中に記事にできればなと考えています。目次として、下図に記事にするものをまとめました。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555056/24ced102-9a57-b8fe-e53a-0ea0a13bd8aa.png" width=90%>

## その0：準備編
　その0では、強化スケジュール課題をUnityで作成するにあたって共通している手順の解説を行います。
URL： https://qiita.com/TeRa_YUKI/items/b9433da24af552d6b3e3

## その1：時隔スケジュール編
　その1では、「時隔スケジュール(interval schedule)」の中の、「固定時隔スケジュール(Fixed Interval schedule)」と「変動時隔スケジュール(Variable Interval schedule)」をUnityで作る方法の解説を行います。
URL： https://qiita.com/TeRa_YUKI/items/b53fa66e0972224678d1

## その2：比率スケジュール編
　その2では、「比率スケジュール(ratio schedule)」の中の、「固定比率スケジュール(Fixed Ratio schedule)」と「変動比率スケジュール(Variable Ratio schedule)」をUnityで作る方法の解説を行います。
URL： https://qiita.com/TeRa_YUKI/items/961f633d6f2306f2c544

## その3：時間スケジュール編
　その3では、「時間スケジュール(time schedule)」の中の、「固定時間スケジュール(Fixed Time schedule)」と「変動時間スケジュール(Variable Time schedule)」をUnityで作る方法の解説を行います。
URL： https://qiita.com/TeRa_YUKI/items/c6e492655e4f267d81f7

## その4：反応率分化強化スケジュール編
　その4では、「反応率分化強化スケジュール」の中の、「低反応率分化強化(Differential Reinforcement of Low rates)」と「低反応率分化強化(Differential Reinforcement of High rates)」をUnityで作る方法の解説を行います。
URL： https://qiita.com/TeRa_YUKI/items/c8d88547e864aca3a6ce

## その5：データの出力・保存編
　その5では、Unityで作成した課題の中で取得したデータをcsvに出力する方法の解説を行います。
URL： 3月中に投稿予定

## その6：分析編
　その6では、得られたデータをPythonで分析する方法の解説を行います。
URL： 3月中に投稿予定

## その7：ルール支配行動編
　その7では、教示による制御の実験研究ができるような課題をUnityで作る方法の解説を行います。
URL： 3月中に投稿予定

## その8：オペラント実験箱編
　その8では、自由オペラント実験が行えるような、疑似オペラント実験箱をUnityで作る方法の解説を行います。
URL： 3月中に投稿予定

# さいごに
　需要あるのか？ という感じですが、暇つぶしがてらカタカタ書いてゆきます。来年度には間に合う予定なので、興味のある方はお付き合いください。 ~~やる気が続けばいいなぁ…~~
Windows7でnpm install時のエラー


### npm installがうまくいかなかった場合
package-lock.jsonとnode_moduleフォルダを削除

```terminal
npm cache clean -f
```

もう一回

```terminal
npm  install
```

※node_moduleがファイル名が長すぎて削除できないとエラー出た場合、ネットワークを割り当てて削除してあげる

▼参考サイト
ファイル名が長すぎて削除できない場合
 https://increment-log.com/windows-is-long-file-name-cannot-delete/
ディレクトリがローカルの場合
http://replication.hatenablog.com/entry/20130118/1358561978


### npm install時にパーミッション系のエラーが出た
npm install時にパーミッション系のエラーが出たら

```
npm cache clean -f
```

それでも直らなかったら

```
npm install -g npm@5.0.3
```

https://qiita.com/MasamotoMiyata/items/0fdad60d80687fb01909

### JavaScript heap out of memory when building Vue.js app
```
npm run build NODE_OPTIONS=--max_old_space_size=4096
npm run serve NODE_OPTIONS=--max_old_space_size=4096
```
NotesとComコンポーネント

Notesメールにはステーショナリーという機能があって、定型メールを登録しておくと、すぐに呼び出して利用できて便利だったのですが、Outlookだと、テンプレートという似た機能はあるのですが、操作の手間が多くて使いづらいので、Notesの標準テンプレートにあるノートブックで文書を書いて、その内容をOutlook経由で転送させるというものを書いてみました。

````VB
Sub Click(Source As Button)
'現在の文書を取得
	Dim ws As New NotesUIWorkspace
	Dim uidoc As NotesUIDocument
	Set uidoc = ws.CurrentDocument
	
'現在の文書を保存してフィールドの値を確定する			
	If Not uidoc.EditMode Then
		uidoc.EditMode = True
	End If
	Call uidoc.Save
	Call uidoc.Refresh
	
	Dim doc As NotesDocument
	Set doc = uidoc.Document
	
'送信済フラグが有効の場合は終了
	If doc.sendflg(0) = "1" Then
		Exit Sub
	End If
	
'Outlookを起動して、メールの内容をセットして送信する
	Dim OutlookObject As Variant
	Set OutlookObject = CreateObject("Outlook.Application")
	
	Dim ObjectItem As Variant
	Set ObjectItem = OutlookObject.CreateItem(0)
	
	With ObjectItem
		.To = "Yamada.Taro@XXXX.onmicrosoft.com"       'メール宛先
		.Subject = doc.GetItemValue("Subject")(0)   'メール件名
		.Body = doc.Body     'メール本文
	End With
	ObjectItem.Send
	
'送信済フラグを設定して閉じる
	Dim item As NotesItem
	Set item = doc.ReplaceItemValue( "sendflg", "1" )
	
	doc.SaveOptions = "0"
	Call doc.Save(True,ture)
	
	Call uidoc.Close(True)
	
End Sub
````

#Comオブジェクト
ComオブジェクトはNotesでMicrosoftのアプリケーションを使いたいときに、メソッドやプロパティ込みで貸してくれる便利なヤツです。Notesと同世代の技術なので色々とお世話になってきました。ExcelはもちろんOffice製品は全てComで呼び出せます。

ただ、Notesと同世代の技術になるため、Edgeのような新しいMicrosoftのアプリケーションを呼び出すことはできません。ブラウザを呼び出すときは CreateObject(" InternetExplorer.Application") の一択です。もちろん、CromeやFireFoxのようなMicroSoft製品でないものは呼び出せません。
色々と複雑な処理をする場合は、バッチファイルを書いてからShell（バッチファイルまでのフルパス）みたいな使い方になります。
システムステータスチェックとインスタンスステータスチェックの失敗に備えた対処法

#タイトルの内容を設定する方法
ec2のコンソールを開き、画像のように選択。
![スクリーンショット 2021-01-19 17.48.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784921/3aa7658b-d0e1-7115-c462-d9bf5388d38d.png)

アラームアクションは、下記４種類が設定できるが、システムチェックか、インスタンスチェックかで方法が異なる。
システムチェックの場合は、「復旧」を。インスタンスチェックの場合は「再起動」を選択。
システムチェックとインスタンスチェックの詳細は、以下を参考に。
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/monitoring-system-instance-status-check.html#types-of-instance-status-checks

![スクリーンショット 2021-01-19 18.01.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784921/9cf02fc1-4eef-0ebb-c943-60c303952bb0.png)

Type of data to sampleの項目で、以下を選択
インスタンスチェックの場合→失敗したステータスチェック：インスタンス
システムチェックの場合→失敗したステータスチェック：システム

![スクリーンショット 2021-01-19 18.03.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784921/ff76bfdb-8835-11c0-ed6f-13f46203850f.png)
ちなみに、Type of data to sampleの項目で、インスタンスチェックの場合→「失敗したステータスチェック：インスタンス」を選択し、アラームアクションで「復旧」を選択すると下記画像のようにエラーが出力されるので、注意。

![スクリーンショット 2021-01-19 17.56.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784921/75eaad13-6a44-c17b-5862-7328d7365e2a.png)

#意図的にインスタンスステータスをエラーにする方法

インスタンスに接続した状態で、下記コマンドを実行し、ネットワークインターフェースを切断させる。（root権限)

```
ifconfig eth0 down
```
ifconfigコマンドに関しては、以下を参照。
https://www.atmarkit.co.jp/ait/articles/0109/29/news004.html

コマンドを実行して、インスタンスのステータスチェックを確認すると下記画像のように、エラーが確認できる。
![スクリーンショット 2021-01-19 18.05.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784921/7143ec2e-2831-d7ea-ed9a-a3af94c3cfc6.png)
OculusQuest2にアプリを入れようとしたときに起こったこと

## プロジェクトビルド時のエラー

新規プロジェクト作成し、buildsettingでplatformをandroidに変更し、buildしたが下記のようなエラーが出た。

```Access is denied.
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr)```

セキュリティソフトがjava.exeをブロックしていたのでホワイトリストに追加すると、ビルド通った。

## Oculus Integratonをimportする際、PCがブルースクリーンになった。

- ブルースクリーンになったが、文字が左上に一文字だけ表示されているだけのブルースクリーンだった。
- C:\Windows\Minidumpにはダンプファイルは生成されておらず、 C:\Windows\memory.dmpも更新日付が去年のままで更新されていなかった。
- chromeのハードウェアアクセラレーションをオフにしてやると直ったが、本当にハードウェアアクセラレーションが関係あるかどうかは分からない。
- 後日、ゲームプレイ中にブルースクリーンになってCPUのオーバークロックを解除すると直ったのでオーバークロックが原因だったぽい。ただオーバークロックのどういう設定が原因かはまだつかめていない。
PayjpでのInvalidRequestErrorについて

Payjpのカード決済機能の導入中にエラーが出現

[![Image from Gyazo](https://i.gyazo.com/4590bc6b92ae26dcdb7f0711d9716f91.png)](https://gyazo.com/4590bc6b92ae26dcdb7f0711d9716f91)

Payjp::InvalidRequestError 
今回はこちらについてやっていこうと思います。
（ちなみにapi_key = ENV[〜〜]の記述は環境変数となっています。ご自身で設定してる値になります。)

# まずエラーの内容の把握

InvalidRequestErrorとは：
無効なリクエスト、という意味。

ではその下の
Missing required param to chargeとは：
missing_paramというのが必要なパラメータがセットされていないと出るもの

すなわち、この場合chargeに必要なパラメータがないよ。という意味になります。


慣れている人からすればすんなり解決できるのでしょうが、よくわからなかったので、そのまま下に進むと

[![Image from Gyazo](https://i.gyazo.com/1e676adecae86773c954d025aa3b59a8.png)](https://gyazo.com/1e676adecae86773c954d025aa3b59a8)

という記述。

ここでステータスコードについてのおさらい

|ステータスコード|内容    |
|-------------|--------|
|100~	      |処理を継続中|
|200~	      |成功|
|300~	      |リダイレクト|
|400~	      |クライアント側のエラー|
|500~	      |サーバー側のエラー|

厳密にはもっと細かいですが大雑把にはこんな感じ

今回はステータスコード400ということでクライアント側が問題なのでは？と仮説を立てた。
まず仮説１つ目はform_withのmodelやurlの記載ミス
仮説２つ目は・・・・・

なんて数時間過ごした結果全て無駄なことでした。

# 原因
ステータスコードより見なければいけないところがありました。

```
      amount: user_order_params[:price],
      card: user_order_params[:token],
      currency: 'jpy'
```

の部分。
出品者が定めた金額を支払って購入する設定なので、金額を直接入力し送信したわけではないためにこちらのuser_order_paramsにはpriceの情報はありません。
ここがエラーの原因となってました。

# 解決法

今実装している機能において、priceという値はitemsテーブルという場所に保存するようになっています。
よって、

```
      amount: user_order_params[:price],
      ↓
      amount: @item.price,
```

これで無事解決しました。

# 終わりに
最後駆け足になってしまいましたが、理由は修正後にこの記事を書いていることにあります。
簡単にいうと、記事を書くために無理にエラー文を出して、元のコードがわからなくなったら困るからです。

次回は修正経過もきっちりとメモしたり、画像キャプチャですしながら進めたいです。
という反省でした。