OmniAICreator/Qiita-1.07M huggingface dataset:
「内分点(internal division point)」について入試問題を調べてみた。

オリジナル

https://en.wikipedia.org/wiki/Section_formula


# 検索方法
M.E.T.A.様サイト内検索(「内分点」他より)

https://mathexamtest.web.fc2.com/index.html

# 入試問題(ちょっと戸惑うかも)

線分BCをt:(1-t)に内分する点をとする．

https://mathmathmass.exblog.jp/32131961/

辺BCをにm:nに内分する点をとする．

https://mathexamtest.web.fc2.com/1995/199510272/1995102720100mj.html#top-0102

# 入試問題
線分 AC を 1-t:t に内分する点を F とする．（ **0 ≦t≦1** ， ただし t =0 のとき E= A ，F =C ， t=1 のとき E= B ，F =A とする．）

https://mathexamtest.web.fc2.com/1996/199611491/1996114910200.html#top-0205

p，q，rを**0<p<1,0<q<1,0<r<1を満たす実数**とし，辺をに内分する点を,辺ABをp:(1-P)....

https://mathexamtest.web.fc2.com/2019/201914991/2019149910600mj.html#top-0603

線分PGをs:(1-s)に内分する点...ただし，**0<s<1**とする

https://mathexamtest.web.fc2.com/2021/202110761/2021107610100mj.html#top-0102


# 入試問題他

**m, nを正の数とするとき，** 異なる２点z1 , z2をm:nに内分する点を表す複素数は...

https://www.geisya.or.jp/~mwm48961/koukou/division_point1.htm

**m, n は正の数とする。** 点Pが線分AB上にあり、AP:PB=m:n  を満たすとき、「点 P は線分 AB を  m:nに内分する」

https://manapedia.jp/m/text/2954

# 感想

定義は、見当たりませんでした。
**正の数** かつ **実数** という条件が必要な気がします。
条件が問題に書いてないと、「ちょっと戸惑う」かもしれません。
【Rails】Action Mailerのプレビュー時に発生したエラーの解決方法

## 環境

OS: macOS Bir Sur
Ruby: 3.1.2
Rials: 7.0.3.1
rspec-rails: 5.1.2

## 発生した問題

Railsチュートリアルの11章を進めていた際、Action Mailerのプレビューコードを実装後に「[http://localhost:3000/rails/mailers/user_mailer/account_activation](http://localhost:3000/rails/mailers/user_mailer/account_activation)」を確認した際に「Unknown action **Mailer preview 'user_mailer/account_activation' not found**」というエラーが発生した。

## 原因と解決方法

原因はテストをデフォルトで使用されるminitestではなく、RSpecに変更したこと。
「rails generate mailer コントローラ名 アクション名」を実行した際に、デフォルトでは、*test/mailers/previews/コントローラ名_preview.rbファイルが作成されるが、testファイル以下を削除していたせいか、またはRSpecを導入したことで、「spec/mailers/previews/user_mailer_preview.rb」に上記ファイルが作成された。*

Railsガイドでは、

> これらのプレビュー用クラスは、デフォルトで`test/mailers/previews`
に配置されます。このパスは`preview_path`
オプションで設定できます。たとえば`lib/mailer_previews`
に変更したい場合は`config/application.rb`
に以下の設定を追加します。
> 

```bash
config.action_mailer.preview_path = "#{Rails.root}/lib/mailer_previews"
```

と説明されていました。

[https://railsguides.jp/action_mailer_basics.html#メールのプレビュー](https://railsguides.jp/action_mailer_basics.html#%E3%83%A1%E3%83%BC%E3%83%AB%E3%81%AE%E3%83%97%E3%83%AC%E3%83%93%E3%83%A5%E3%83%BC)

説明通りに下記のように、プレビュー用クラスの配置を以下のように設定したところ問題は解決しました。

```:spec/mailers/previews/user_mailer_preview.rb
require_relative "boot"

require "rails/all"

Bundler.require(*Rails.groups)

module SampleApp
  class Application < Rails::Application
    config.load_defaults 7.0

    config.action_mailer.preview_path = "#{Rails.root}/spec/mailers/previews" #追加

  end
end
```

## 参考記事

[Action Mailer の基礎](https://railsguides.jp/action_mailer_basics.html)
100日後くらいに個人開発するぞ！day068

## 今日はレイアウトを学んでみた！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2632394/9b3abf87-6029-f6da-20c8-0c8b4b5824dc.png)


## 今日の学び
### CSSファイルの保存
* `rails generate controller home …`コマンドを実行したときCSSファイル(home.scss)も自動生成される
* CSSファイルは「app/assets/stylesheets」フォルダにある
* 「scss」はCSSを拡張したものでCSSを効率的に書く文法も使用できる


### 画像を保存する方法
* 画像は`public`フォルダに配置しておくと`<img src="/画像フォルダ名" >」や「background-image: url("/画像フォルダ名");`のように画像名を指定するだけで簡単に画像を表示することができる

### URLを変更する方法
* 後ろに/○○がないURLに対応するルーティングは、`get "/" => "コントローラ名#アクション名"`というように、URLに"/"を指定することで可能

### リンクを作成する方法
* ルーティングのURL部分と同じURLを`<a href="URL">`で指定する
多重ループからの脱出（continueとbreakの違い）

# はじめに
ネストされたfor文の中でcontinueとbreakの挙動の違いを整理しました。
JavaScriptで記載していますが、Javaでも同様に記載できます。

# 目次
[1. サンプル](#1-サンプル)
[2. continue](#2-continue)
[3. break](#3-break)
[4. さらに深いループ](#4-さらに深いループ)
[5. ラベルを使用したcontinue](#5-ラベルを使用したcontinue)
[6. ラベルを使用したbreak](#6-ラベルを使用したbreak)
[7. まとめ](#7-まとめ)

# 1. サンプル
次のような簡単な配列の多重ループを例にします。
```js
const loopA = [1, 2];
const loopB = [1, 2, 3];

for (const a of loopA) {
    for (const b of loopB) {
        console.log(`A${a}-B${b}`);
    }
}

// 出力結果↓↓
// A1-B1
// A1-B2
// A1-B3
// A2-B1
// A2-B2
// A2-B3
```

# 2. continue
continueはそのループの残りの処理をスキップして次のループへ移ります。
この例では内側のループ（`loopB`）が`2`のときは出力しません。
```js
const loopA = [1, 2];
const loopB = [1, 2, 3];

for (const a of loopA) {
    for (const b of loopB) {
        if (b === 2) {
            continue;
        }
        console.log(`A${a}-B${b}`);
    }
}

// 出力結果↓↓
// A1-B1
// A1-B3
// A2-B1
// A2-B3
```

# 3. break
breakではそのループ自体が終了します。
先ほどの`continue`と同じ場所でbreakを使用すると、内側のループ（`loopB`）はそこで終了し、`2`以降は出力されず外側のループ(`loopA`)の次のループに移ります。
```js
const loopA = [1, 2];
const loopB = [1, 2, 3];

for (const a of loopA) {
    for (const b of loopB) {
        if (b === 2) {
            break;
        }
        console.log(`A${a}-B${b}`);
    }
}

// 出力結果↓↓
// A1-B1
// A2-B1
```

# 4. さらに深いループ
今回はcontinueとbreakの違いを確認するため、さらに深く潜ってみます。
```js
const loopA = [1, 2];
const loopB = [1, 2];
const loopC = [1, 2, 3];

for (const a of loopA) {
    for (const b of loopB) {
        for (const c of loopC) {
            console.log(`A${a}-B${b}-C${c}`);
        }
    }
}

// 出力結果↓↓
// A1-B1-C1
// A1-B1-C2
// A1-B1-C3
// A1-B2-C1
// A1-B2-C2
// A1-B2-C3
// A2-B1-C1
// A2-B1-C2
// A2-B1-C3
// A2-B2-C1
// A2-B2-C2
// A2-B2-C3
```
これをサンプルに挙動の違いを確認していきます。

# 5. ラベルを使用したcontinue
ラベルを使用することで任意の場所でループを終了することができます。
今回は`LABEL`としていますが、ラベルには任意の文字列を指定することができます。
```js
const loopA = [1, 2];
const loopB = [1, 2];
const loopC = [1, 2, 3];

LABEL:for (const a of loopA) {
    for (const b of loopB) {
        for (const c of loopC) {
            console.log(`A${a}-B${b}-C${c}`);
            if (b === 2 && c === 1) {
                continue LABEL;
            }
        }
    }
}

// 出力結果↓↓
// A1-B1-C1
// A1-B1-C2
// A1-B1-C3
// A1-B2-C1
// A2-B1-C1
// A2-B1-C2
// A2-B1-C3
// A2-B2-C1
```
この例では2番目のループ（`loopB`）が`2`、3番目のループ(`loopC`)が`1`のときに1番目のループ(`loopA`)の残りの処理をスキップして次のループへ移っています。

# 6. ラベルを使用したbreak
次は先ほどのcontinueと同じ位置、同じ条件でbreakを使用してみます。
```js
const loopA = [1, 2];
const loopB = [1, 2];
const loopC = [1, 2, 3];

LABEL:for (const a of loopA) {
    for (const b of loopB) {
        for (const c of loopC) {
            console.log(`A${a}-B${b}-C${c}`);
            if (b === 2 && c === 1) {
                break LABEL;
            }
        }
    }
}

// 出力結果↓↓
// A1-B1-C1
// A1-B1-C2
// A1-B1-C3
// A1-B2-C1
```
条件を満たすことでラベルをつけた`loopA`がbreakされ、それ以降の処理が実行されなくなります。

# 7. まとめ
今回のような単純な例でも「どこのループだっけ？」と可読性が落ちているように感じました。
ラベルの使い方を理解しておくことでループの扱い方の幅が広がるかと思います。
Mapbox GL JS スタイル変更後にレイヤーを再セットする

各種レイヤーを追加後にスタイルを変更すると、レイヤーが消えてしまいます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/718cc278-0235-b351-d1c5-c44e7674519e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/40c89d0d-ba70-8be6-1ad1-0fb1bb3bff3e.png)
そこで、

```
function onstyledatafunc(){
    map.off('styledata', onstyledatafunc); // 'styledata'イベント削除
    Foo(); // すべてのレイヤーを削除,再セットする 
}

document.getElementById('iSelStyle').onchange=function(){ // ドロップダウンリストを変更したらレイヤー変更
    var style = 'mapbox://styles/' + this.options[this.selectedIndex].value;
    map.on('styledata', onstyledatafunc); // 'styledata'イベント追加
    map.setStyle(style); // スタイル変更
}
```

のようにして、スタイル変更のたびにレイヤーを再セットするようにしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/4f10cae7-e1fe-4097-6242-d4def206bbef.png)

他に良い方法がありましたら教えてください。
値が上昇から下降に転じたら反転フラグを作成する(SPSS Modeler データ加工逆引き4-9)

# 値が上昇から下降に転じたら反転フラグを作成する

![スクリーンショット 2022-08-01 11.20.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/c03a4844-bb0e-b071-1181-5ecdbe16c929.png)

## 1.想定される利用目的

・顧客の特定行動から特徴量を作成する
・設備ログから特定イベントの有無を特徴量にする

## 2.サンプルストリームのダウンロード

https://github.com/yoichiro0903n/blue/blob/main/turn_over.str?raw=true

## 3.サンプルストリームの説明

![スクリーンショット 2022-08-01 11.21.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/0ac9a735-7df7-da04-8db1-7c5321680cf7.png)

a.入力するデータは以下の通りです。
![スクリーンショット 2022-08-01 11.26.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/f809fbbb-1013-93e1-abed-285c1ed1332e.png)

b.[時系列グラフ]ノードを編集します。
![スクリーンショット 2022-08-01 11.23.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/3304f7f5-bbf0-95bc-694b-cb047bb7e945.png)

[実行]します。２箇所で値が反転しています（赤丸）。
![スクリーンショット 2022-08-01 11.24.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/287a6b7f-fe7d-3a78-db87-2cb751d24140.png)

c.[フィールド作成]ノードを編集します。[派生]モードを[フラグ型]にします。フラグが立つのは①1行上から当該レコードの差と②当該レコードから1行下の差の①②を掛け算して負になる条件にします。値の1行上は[@&#xFFF0;OFFSET(value,1)]で値の1行下は[@&#xFFF0;OFFSET(value,-1)]と記述します。@&#xFFF0;OFFSET(列,1)は列の1行上を参照する関数です。
![スクリーンショット 2022-08-01 11.50.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/75614d0c-b820-4978-e5d2-95cb57daa4a8.png)

式ビルダーから@&#xFFF0;関数を探すと簡単に入力できます。
![スクリーンショット 2022-08-01 11.51.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/bb760698-ecde-2dbe-e8cd-cc57e80fc39d.png)

[プレビュー]します。
![スクリーンショット 2022-08-01 11.26.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/9ae2a002-0c1d-3676-09f3-9176b5be150c.png)

d.[散布図]ノードを編集します。
![スクリーンショット 2022-08-01 11.56.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/18c80ceb-9d71-e0f2-3a54-c61f85bf0d5e.png)

[実行]します。
![スクリーンショット 2022-08-01 11.54.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/5b53335f-ea67-c1c1-b2bb-1c8b6ae34c8b.png)

#### 注意点
cの式の①と②をあらかじめ[フィールド作成]ノードで列にしておくと上との差と下との差の掛け算が負になる条件を説明する際にわかりやすくなります。プラスとマイナス、マイナスとプラスの掛け算がマイナスになる特性を活かしています。
![スクリーンショット 2022-08-01 11.58.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/32d36f03-769e-a255-5160-5cec6c1b3b1a.png)


## 4.参考情報

#### 値の反転（ジグザグ）を扱った記事

https://qiita.com/kawada2017/items/7b3c279963d39043214a#2m-%E3%83%95%E3%83%A9%E3%82%B0%E5%9E%8B%E9%9B%BB%E5%8A%9B%E3%81%8C%E5%A2%97%E6%B8%9B%E3%81%99%E3%82%8B%E3%82%B8%E3%82%B0%E3%82%B6%E3%82%AF%E3%82%92%E6%8D%89%E3%81%88%E3%82%8B%E3%83%95%E3%83%A9%E3%82%B0modeler%E7%89%88

#### SPSS Modeler ノードリファレンス目次

https://qiita.com/416nishimaki/private/503037195081d3323eee

#### SPSS Modeler 逆引きストリーム集（データ加工）

https://qiita.com/416nishimaki/private/4bf813e6cba84b2a1008
【Unity】TextMeshProの値をC#で変更する方法

TextMeshProの値をC#スクリプトから設定や変更を行う手順を説明する
今回は、ボタンが押された回数を表示するTextMeshProを作成する

## TextMeshProとButtonを作成する
1. HierarchyビューでTextMeshProとButtonを追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1719666/101e9e79-d807-f74c-8e44-4fa003c7ab85.png)
1. 位置やサイズを調節
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1719666/ccfd18db-31a0-035c-f9f0-48a43082e48b.png)

## C#スクリプトを作成する

1. ProjectビューでC# Scriptを好きなフォルダに作成する
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1719666/cc3a739b-9aa4-2ece-9ed9-af3e27192fd3.png)
1. 作成したC#ファイルを開く
1. ボタンが押されたときに呼び出す関数を作成する
    1. usingの追加
    TextMeshProのクラスを使用するために下記のusingをファイルの先頭に追加
        ```csharp
        using TMPro;
        ```
    1. 変数・オブジェクトの宣言
        ```csharp
        //ボタンが押された回数
        private int count = 0;
        //TextMeshProのオブジェクト
        public TextMeshProUGUI countText;
        ```
    1. 関数の作成
        ```csharp
        public void PushButton()
        {
            count++;
            countText.text = "Score:" + count;
        }
        ```
C#スクリプトが完成
```csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;

public class UpdateText : MonoBehaviour
{
    //ボタンが押された回数
    private int count = 0;
    //TextMeshProのオブジェクト
    public TextMeshProUGUI countText;

    public void PushButton()
    {
        count++;
        countText.text = "Score:" + count;
    }
}
```

## 作成したスクリプトをオブジェクトに適用する
1. Hierarchyビューで空のGameObjectを作成する
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1719666/ed4b62da-bb68-4af8-843c-ce9738d05d14.png)
1. ProjectビューのC#スクリプトをGameObjectにドラッグ＆ドロップ
1. HierarchyビューのGameObjectをクリックして、Inspectorビューに作成したスクリプトが適用されているか確認
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1719666/6ac3a4bd-f65e-b41c-7d44-5aa9d19b1a0e.png)
1. Inspectorビューで表示しているGameObjectの[Update Text]-[Count Text]に値を変更するTextMeshProをドラッグ＆ドロップ
1. ProjectビューでButtonをクリックして、Inspectorビューを表示する
1. On Click ()のObjectにスクリプトを適用したGameObjectをドラッグ＆ドロップ
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1719666/8f578272-a5ee-a6a3-6d82-6da85371d7d2.png)
1. Functionに作成した関数を指定する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1719666/82ac19cc-3d25-0162-4945-5cab72b412de.png)

## 実行してみる

![gif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1719666/14e0fc2a-b729-29e7-b46e-aa02e0c176d6.gif)
2022年のDelphi 7にまつわる覚書

https://ja.wikipedia.org/wiki/Delphi#Delphi_7_/_7.1

> Delphi 7 は 2002 年に Borland からリリースされました

[Delphi 7 (7.1) を Windows 10 / 11 にインストールする - Qiita](https://qiita.com/ht_deko/items/a815f81c83068ba2fb7c)
[Delphi 7 is a lot slower on Windows 10 (compared to Win7) - Delphi IDE and APIs - Delphi-PRAXiS [en]](https://en.delphipraxis.net/topic/3389-delphi-7-is-a-lot-slower-on-windows-10-compared-to-win7/)
[Make older apps or programs compatible with Windows 10](https://support.microsoft.com/en-us/windows/make-older-apps-or-programs-compatible-with-windows-10-783d6dd7-b439-bdb0-0490-54eea0f45938)
[Maintaining old project on Delphi 7 - Stack Overflow](https://stackoverflow.com/questions/67306502/maintaining-old-project-on-delphi-7)

> You could always make an XP VM and install D7 into that. It will be quite comfortable in there.
> XPのVMを作って、そこにD7をインストールすればいいです。かなり快適でしょう。

[Windows XP - Microsoft Lifecycle | Microsoft Docs](https://docs.microsoft.com/ja-jp/lifecycle/products/windows-xp)

何かあったら追記する。
【Webアプリ】個人開発したWebアプリを公開

皆さんに使っていただきたく、こうして個人制作したWebアプリを公開します。是非フィードバックをいただけるとありがたいです！

# 概要
気軽に議論するためのプラットフォーム「yes or no」を作りました。議題を整理しながら、討論できるTwitterのようなものをイメージして下さい。yes or noにおいては、議題に対して賛成・反対のポジションを取ることでコメントの投稿をすることができます。
![スクリーンショット 2022-08-10 1.35.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2707093/5e7270da-0b27-e698-645b-53ce8d080b2e.png)
誰かが立てた議論には時間制限があり、それを過ぎるとコメントすることができません。
議題の作成やコメントにはユーザー登録が必要になります。
ユーザー登録する際のEmailですが、＠を含めているのならどのような文字列でもいけます。忘れなければ問題ありません。

# URL
Webアプリ「yes or no」のURL
https://discussion-app-2022.herokuapp.com/

制作者のTwitter
https://twitter.com/harukipow225

# なぜこのアプリを作ろうと思ったのか
### 問題意識
Twitter上での不毛な議論や炎上を見て、ちゃんと話し合えばお互いに消耗しなくて済むのではないかという問題意識からyes or noというWebアプリを作成することにしました。

### 原因として考えられるもの
Twitter上での話し合いがうまく行かない原因として考えられるものは複数あります。
・140文字しか投稿できない
・発言者の立ち位置（ポジション）が不明瞭
・どの観点からの発言かわからない
・話し合いに必要なソースが分散しており、話し合いに参加しているすべての人がそのソースにアクセスできない
・デマ・誤情報の拡散
・重要な発言や情報が他のコメントに流されてしまう。

このような理由から話し合いが大規模になるほど、集団での合意形成や話し合いが難しくなっているのではないかと思っています。

### 解決するために
yes or noでは上記原因を解決するために３つの工夫をしてみました。
・文字制限2000文字
・発言は必ず賛成・反対のポジションを取る必要がある
・議題とその議題の側面を論ずるルームを複数作成できる。下写真だと「Twitterは話し合うのに不向きか？」という議題に対して、「140文字の制限はあってないような・・・」という論点を追加している。論点はいくらでも追加可能。
![スクリーンショット 2022-08-10 3.23.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2707093/79948311-2fe9-40bb-5191-3636663293e8.png)

# アプリで解決できる問題点・ニーズ
### ニーズ１：議論って無駄が多い
口頭で長時間話すと、論点があやふやで、どのような発言があったかも忘れてしまう。何度も同じことを繰り返し発言し、議論に参加していない他者への共有もスムーズに行かない。活発な議論をした割には碌な結論が出ない。
→議論した内容を文章で残せます。

### ニーズ２：自分とは反対の意見を集め、見聞を広めたい
昨今、自分の関心のあるものや、自分にとってポジティブな情報が目につきやすくなっています。
→だからこそ、反対意見もわかりやすく可視化できる場所があってもいいのでは？

### ニーズ３：ある物・事に興味があるが、それに興味を持った人が集まらない
→議題を設定できるので、作った議題をSNSに拡散したら、興味を持ってくれる人が集まるかも

# 利用方法
このページに書かれています。
https://discussion-app-2022.herokuapp.com/rooms/this_site
大まかな流れとしては
①ユーザー登録
②議題（ルーム）の作成
③賛成（yes）・反対（no）のポジションを取りコメント
④議論をしている中で気になる側面が出てきたら、論点を追加し、議論を整理する。
となります。

# 機能
・議題（ルーム）作成
・ポジション取得
・コメント
・論点追加
・いいね
・リプライ
・マイページ
・フォロー、フォロワー
・ユーザー情報編集

# 利用言語
Rails,JavaScript,html,css

# ER図
![スクリーンショット 2022-08-10 3.41.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2707093/2afac6fa-cf52-95e7-43e7-a8ecaab27e0b.png)

# 画面遷移図
![スクリーンショット 2022-08-10 3.46.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2707093/d59c0b7f-02b1-b067-93c4-3e059efdd727.png)

# 最後にこのアプリの制作者について
テックキャンプ受講生で7月中旬に卒業しました。このアプリを開発するのに1ヶ月と2週間かかってます（就活や新しい言語の勉強等を同時並行していた時期もあります）。バグ等あれば、QittaかTwitterでDMを送ってくださるとありがたいです。Twitter：https://twitter.com/harukipow225
ここまでお読みいただきありがとうございます。
LaravelのEloquentが実際にどんなクエリを発行しているか調べてみた

## 概要
Laravel組み込みのORMであるEloquentが実際どんなクエリを発行しているのか、理解を深めるために調べてみました。
今回はリレーションに関わる基本的な部分を記載しています。

## 環境
Laravel v6.20.26

## ER図
![er.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593942/559f6e01-e2ff-fd20-63f0-f6d67c621813.png)

## モデルへ定義したリレーション
```Country.php
    public function posts()
    {
        return $this->hasManyThrough('App\Post', 'App\User');
    }
```
```User.php
  public function posts()
  {
    return $this->hasMany('App\Post');
  }

  public function favorite_posts()
  {
    return $this->belongsToMany('App\Post', 'favorite', 'user_id', 'post_id');
  }
```
```Post.php
    public function user()
    {
        return $this->belongsTo('App\User');
    }

    public function favorite_users()
    {
      return $this->belongsToMany('App\User', 'favorite', 'post_id', 'user_id');
    }
```

## クエリ一覧
基本的に各テーブルはid=1のデータを利用しています。
### hasMany
```php
$user->posts;
```
```sql
select * from `posts` where `posts`.`user_id` = 1 and `posts`.`user_id` is not null
```

### belongsTo
```php
$post->user;
```
```sql
select * from `users` where `users`.`id` = 1 limit 1
```
### hasManyThrough
```php
$country->posts;
```
```sql
select
    `posts`.*,
    `users`.`country_id` as `laravel_through_key`
from
    `posts`
    inner join
        `users`
    on  `users`.`id` = `posts`.`user_id`
where
    `users`.`country_id` = 1
```
### belongsToMany
```php
$user->favorite_posts;
```
```sql
select
    `posts`.*,
    `favorite`.`user_id` as `pivot_user_id`,
    `favorite`.`post_id` as `pivot_post_id`
from
    `posts`
    inner join
        `favorite`
    on  `posts`.`id` = `favorite`.`post_id`
where
    `favorite`.`user_id` = 1
```
#### attach/detach/sync
syncがattachとdetachの組み合わせなのでそちらだけ紹介します。
事前にpost_id=1,2がattachされています。事前にユーザーに紐づくfavoriteを全て取得し、内部でレコードの有無を判断して作成・削除をしています。
```php
$user->favorite_posts()->sync([1,3]);
```
```sql
select * from `favorite` where `favorite`.`user_id` = 1;
delete from `favorite` where `favorite`.`user_id` = 1 and `favorite`.`post_id` in (2);
insert into `favorite` (`post_id`, `user_id`) values (3, 1);
```
### with(Eager Load)
```php
User::with(['posts'])->get();
```
```sql
select * from `users`;
select * from `posts` where `posts`.`user_id` in (1, 2);
```
条件に合致するuserを全て取得した後、対応するposを全て取得し内部で紐付けています。
データベースへの問い合わせが一度で済むので、N+1問題への対処として利用されます。

## まとめ
シンプルなリレーションに関しては予想通りだと思いますが、syncなどはクエリでの処理とアプリでの処理がどのように分離されているのかがわからなかったので勉強になりました。
備忘録代わりに今後もまとめていきたいです。
Colab メモ

# google spreadseet - df

## google spreadseetとgoogle colabの連携
```py
!pip install gspread

from google.colab import auth
import gspread
from google.auth import default

#認証
auth.authenticate_user()
creds, _ = default()
gc = gspread.authorize(creds)

#スプレッドシート取得
url = "スプレッドシートのURL"
ss = gc.open_by_url(url)
worksheet_list = ss.worksheets()
for worksheet in worksheet_list:
  print(worksheet)
#<Worksheet 'シート1' id:0>
```

## google spreadseet→df
```py
#シート取得
worksheet = ss.worksheet('シート1')
df = pd.DataFrame(worksheet.get_all_values()[1:],
    columns=worksheet.get_all_values()[0])
df.head(5)
```

# JSONL - df
## df→jsonl
```py
df[['in','out']].to_json('file.jsonl', force_ascii=False, orient='records', lines=True)
```

## jsonl→df
```py
df = pd.read_json('file.jsonl', orient='records', lines=True)
df.head()
```

# Gitの非公開リポジトリClone
```bash
%env TOKEN=パーソナルアクセストークン
!git clone https://$$TOKEN@github.com/ユーザ名/リポジトリ名.git
```


# dfの操作
## train,test,validデータ分割
```py
from sklearn.model_selection import train_test_split

df_train, df_test = train_test_split(df,test_size=0.7,random_state=0)
df_test, df_valid = train_test_split(df_test,test_size=0.5,random_state=0)

print('train:',len(df_train))
print('test:',len(df_test))
print('valid:',len(df_valid))
```

## 重複した行を削除
```py
df = df.drop_duplicates()

#特定の列
df = df.drop_duplicates(subset='列名')
```
いつも忘れるソフトウェアの品質特性を改めて自分なりに整理した際の備忘録

いつも忘れるソフトウェアの品質特性を改めて自分なりに整理した際の備忘録

> https://webrage.jp/techblog/external_quality_inner_quality/

整理

```
■機能性：
ソフトウェアを指定された条件のもとで動作するとき、要求されている仕様を満たす能力のこと。
要は、必要な機能がどれくらい備わっているか。

■信頼性：
ソフトウェアを指定された条件のもとで動作するとき、達成水準を維持し続ける能力のこと。
誤作動時の復旧や、障害に対する許容性をあらわす場合もある。
要は、障害なく利用可能し続られる力がどれだけあるか。

■使用性：
ソフトウェアを指定された条件のもとで動作するとき、利用者が理解、習得、利用がスムーズにおこなえる能力こと。
いわゆる「使い勝手」や「使いやすさ」、「操作性」のこと。
要は、どれだけ人が便利に使いこなしやすいか。

■効率性：
与えられたリソースに対して、適切な性能を発揮する能力のこと。
たとえば、決められた処理時間の中でいかに早く、数多くの処理ができるか、などがあります。
要は、純粋に処理性能がどれくらい備わっているか。

■保守性：
できたソフトウェアの修正のしやすさの能力のこと。
作った本人しか理解できないプログラムでは、改修が発生した際に多くのコストがかかってしまいます。
これは利用者には直接は関係しない特性のように見えますが、最終的なサービスリリースまでにかかるコストの軽減は、利用者へのメリットにつながることが多くあります。
要は、どれだけメンテし易いか。

■移植性：
別な環境へ移すことになった際に、容易に移せる能力のこと。
サーバーの移行や、使うフレームワークが変更になった場合などに重要になってくる。
要は、どれだけ移植し易いか
```

副特性を含めた表

|  品質特性モデル  |  概要  | 副特性 |
| ---- | ---- | ---- |
|  機能性（functionality）  |  必要な機能がどれくらい備わっているか  | 合目的性（suitability）  |
|    |  |  正確性（accuracy）  |
|    |  |  相互運用性（interoperability）  |
|    |  |  機密性（security）  |
|    |  |  標準適合性（compliance）  |
|  信頼性（reliability）  | 障害なく利用可能し続られる力がどれだけあるか |  成熟性（maturity）  |
|    |  |  障害許容性（fault tolerance）  |
|    |  |  回復性（recoverability）  |
|    |  |  標準適合性（compliance）  |
|  使用性（usability）  | どれだけ人が便利に使いこなしやすいか |  理解性（understandability）  |
|    |  |  習得性（learnability）  |
|    |  |  運用性（operability）  |
|    |  |  注目性 (attractiveness)  |
|    |  |  標準適合性（compliance）  |
|  効率性（efficiency）  | 純粋に処理性能がどれくらい備わっているか |  時間効率性（time behaviour）  |
|    |  |  資源効率性（resource behaviour）  |
|    |  |  標準適合性（compliance）  |
|  保守性（maintainability）  | どれだけメンテし易いか |  解析性（analyzability）  |
|    |  |  変更性（changeability）  |
|    |  |  安定性（stability）  |
|    |  |  試験性（testability）  |
|    |  |  標準適合性（compliance）  |
|  移植性（portability）  | どれだけ移植し易いか |  環境適応性（adaptability）  |
|    |  |  設置性（installability）  |
|    |  |  共存性 (co-existence)  |
|    |  |  置換性（replaceability）  |
|    |  |  標準適合性（compliance）  |

所感
- 機能性や効率性は分かりやすい
- 信頼性も分かりやすい（可用性と信頼性は同じ意味で使われてる？？）
- ユーザビリティって今までなんとなく言葉を使っていたけど、ちゃんと定義されているんですね、、（当然といえば当然ですが、、））
- 保守性や移植性は見落としがちだけどここをしっかり作ることが競争力に繋がるような気もする。ソフト環境はコロコロ変わるので重要）
- ソフトウェア開発に限らず、システムに共通する要素のように思える。（関係ないけどエクセル帳票１つ作成する際でもこれらを意識できると生産性に資するのではないか。。IPAの試験とは関係ないですが。。）

# 参考
[ISO/IEC 9126](https://ja.wikipedia.org/wiki/ISO/IEC_9126)
[外部品質、内部品質とは？ソフトウェア品質特性について](https://webrage.jp/techblog/external_quality_inner_quality/)
Apple Silicon(M1, M2) MacBookAirでDocker上にMySQLサーバを立てる

自分用のメモになりますので、早速結論を書く。
何か誤りがありましたら、編集リクエストかコメント下さい。

# Dockerfileの場合

```Dockerfile
FROM --platform=linux/arm64/v8 mysql/mysql-server:latest

# 追加で実行する処理(参考)
ENV TZ=Asia/Tokyo
ENV MYSQL_ROOT_PASSWORD=password
COPY ./docker/mysql/my.cnf /etc/mysql/conf.d/my.cnf
COPY ./docker/mysql/initdb.d /docker-entrypoint-initdb.d
```

# docker-composeの場合

```docker-compose.yml
version: '3'
services:
  mysql:
    image: mysql/mysql-server:latest
    platform: linux/arm64/v8
    environment:
      MYSQL_ROOT_PASSWORD: password
    ports:
      - 127.0.0.1:3306:3306
```
API Gatewayで公開したAPIにCognitoの認証を付ける

# 前提

[Amazon FargateのアプリケーションをAPI Gateway経由で公開する](/ykdevs/items/fa84ec68491d2e1273e7)
で公開したAPIに対してCognitoの認証がないと認証エラーになるようにする。

# CognitoのUserPoolを作る

Cognitoの設定は以下のページを元に作ってみました。感謝です。

[Amazon Cognitoを使ってシンプルなログイン画面を作ってみる](/fkooo/items/660cab0090a80861155b)

このページでIdTokenを取得できていることが前提となります。

# API Gatewayにオーソライザーを作成してアタッチする

![スクリーンショット 2022-08-10 0.33.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81113/db8681ff-f8e2-5737-d677-fde14d66e1a6.png)

![スクリーンショット 2022-08-10 0.33.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81113/5afcc2b3-529b-c5a2-b370-ce818585fe60.png)

オーソライザの発行元URLにはCognitoのIDプールのURL、対象者にはクライアントIDを設定します。

![スクリーンショット 2022-08-10 0.39.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81113/c09a94a4-31ee-f694-76a4-c4f46b961df1.png)

![スクリーンショット 2022-08-10 0.40.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81113/9c785573-e32a-9e4d-6e4b-9ef6cf2806b5.png)

ルートにJWT認証が設定されます。

![スクリーンショット 2022-08-10 0.40.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81113/2a52aa4c-6aa7-3023-ca87-575c6ba7ad70.png)

# アクセス確認

Authorizationヘッダなしでアクセスすると401エラーとなる。

![スクリーンショット 2022-08-10 1.02.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81113/03a7b19c-eb12-b870-3fc2-2430f00226ad.png)


AuthorizationヘッダにIdTokenをつけてアクセスすると成功する。

![スクリーンショット 2022-08-10 0.59.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81113/39c091f0-1ff6-005f-728f-25752fd60a21.png)
ReactのuseMemoについて

ReactのuseMemoについてまとめます。

参考記事
https://qiita.com/seira/items/42576765aecc9fa6b2f8


useMemoとは、関数の結果を保持するためのフックで、何回やっても結果が同じ場合の値などをメモ化し、そこから値を再取得します。
不要な再計算をスキップできるため、レンダリングの回数を減らせます。
useCallbackとの違いは、関数自体をメモ化しますが、useMemoは関数の結果を保持することです。

自分のポートフォリオでも以下のように利用しています。

```JavaScript
export const Loginbutton = React.memo(() => {
  const loginContext = useContext<Context>(LoginContext);
  return (
    <div>
      <Button variant="outlined" className="m-auto w-50 my-2">
        <Link href="/login">{loginContext.text}</Link>
      </Button>
    </div>
  );
});

```
基本的にはコンポーネントに使います。こうすることによりレンダリングの回数が減るためおすすめです。

コンポーネントなどに導入してみてください。
ぷよぷよAIに関して色々検索してみた際の備忘録

ぷよぷよAIに関して色々検索してみた際の備忘録です

#### ぷよぷよAIの歴史

https://puyo-euphonic.com/puyo-history-ai

#### ぷよAI勉強会

https://connpass.com/event/17870/presentation/
> ぷよぷよAIの新しい探索法
> ぷよぷよ AI (mayah) の実装
> ぷよAI勉強会、ぷよ初心者（５連鎖以下）の方向け資料

https://www.slideshare.net/mayahjp/puyoai-gpw2015

#### 全自動ぷよぷよプレイヤー （ AI vs AI ）

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

#### AlphaZeroで最強のターン制ぷよぷよAIを作る！

https://ykicisk.hatenablog.com/entry/2020/04/05/193356

#### puyoai

https://github.com/puyoai/puyoai

#### [SEGA]ぷよぷよプログラミング

https://puyo.sega.jp/program_2020/

> サンプルコード
> https://puyo.sega.jp/program_2020/dl/puyo-programming-code.pdf


#### ぷよぷよ敵AIの歴史

> 13日目：ぷよぷよ敵AIの歴史
> http://www.rcc.ritsumei.ac.jp/2020/1213_11080/

#### 論文

> 深層学習を用いたぷよぷよ AI の開発
https://www.jstage.jst.go.jp/article/fss/35/0/35_386/_pdf/-char/ja

> DQNを用いたぷよぷよの連鎖構築AI
https://www.jstage.jst.go.jp/article/fss/33/0/33_467/_pdf/-char/ja

#### ぷよぷよクローン

> http://baker-street.jugem.jp/?eid=481

#### ぷよぷよe-sports（steam版）

https://store.steampowered.com/app/971620/_e/?l=japanese&curator_clanid=8347187

# 参考

> ぷよぷよAIを作りやすくしてみた
https://qiita.com/TukamotoRyuzo/items/acbbbe059af2e382837d
> https://github.com/TukamotoRyuzo/upi-engine
> https://github.com/TukamotoRyuzo/upi-gui

> ぷよぷよAIをつくる授業で学んだこと
https://qiita.com/acta/items/455a0bdc5236684b9ba5

> ACぷよぷよ通 スコアアタックWiki
https://seesaawiki.jp/puyoscore_wiki/d/%B4%F0%CB%DC%C3%CE%BC%B1

> ぷよスポAI「Tぷよふら」に迫る
https://puyo-euphonic.com/puyo-ai-t-puyohura
> 「Tぷよふら」youtube channel
> https://www.youtube.com/channel/UCkZ_UAY-hLcc68PuSanTuuQ/featured
The Analytics Engineering Guide  「What is analytics engineering?」 を読んでみた

# What is analytics engineering? を読んでみた

dbtがリリースしていた[`What is analytics engineering?`](https://www.getdbt.com/what-is-analytics-engineering/)を読もうと思ったので、その要約と感想をつらつらと書き進めていきます.


## はじめに
dbtの使い方を学んでいる際に、`analytics engineer`がこれから新しい役割として求められると紹介されていた。analytics engineerとは何ぞやと思い、上記の記事を読んだ。

その記事曰く、これまでのデータ分析における役割は主に2つと考えられてきた。それは`data analytst`と`data engineering`である。だがこれからはこの2つの役割に加えて新しく`analytics engineering`という役割が加わるだろうと言っているのでその詳細を以降で確認してみる。

## 記事の要約

### Analytics Engineersとは

> Analytics engineers provide clean data sets to end users, modeling data in a way that empowers end users to answer their own questions. 
> エンドユーザー(データを使用する役割の人(BI/MLなど))にクリーンなデータを提供する、また彼らの要望に添えるようにデータモデリングを行う.

### Analytics Engineersの仕事とは

>an analytics engineer spends their time transforming, testing, deploying, and documenting data.
 アナリティクスエンジニアはデータの変換、テスト、デプロイ、文書化に時間を費やす.

### Analytics Engineersが生まれるまで

- Traditional Data Team
Traditional Data Teamには2つの役割が存在する
  - データエンジニア
    - PostgresデータベースやSaaSツールからデータを抽出し、そのデータを変換してデータウェアハウスにロードするというインフラを構築する
  - データアナリスト
    - SQLファイルを大量に保持したり、SQLウェブエディタでクエリを実行することで意味のあるデータを生成する

その後2010年代に以下のツールの革新が起こった。
- データツールの革新
  - Cloud-based data warehouses
    - Redshift, followed by BigQuery and Snowflake
    - データの保存と処理を手頃な価格で高速に行うことができるようになった
  - Data pipeline services
    - Stitch, Fivetran
    - データ抽出が数クリックでできるようになった
  - Business intelligence (BI) tools
    - Looker、Mode、Chartio
    - ステークホルダーのセルフユーザーの分析が容易になりつつある

この革新を経て、modern data teamを以下のように定義する。
>data warehousesでデータを大量に保持することができ、またデータの抽出が簡単にできるようになったため、data warehousesにとりあえずデータを格納し、そこからTransform(変換)を行えば良いという風潮になっている(そこで"T"の役割を担うのがdbt)
- The modern data team = 上記の2つの役割＋`analytics engineer`
- モダンデータチームに必要な新たな役割
  - データスタック全体を管理することになる人
  - 十分に定義され、変換され、テストされ、文書化され、コードレビューされたデータセットを提供する人
    - ビジネスユーザーは高品質の文書を読み,BIツールで分析が可能となる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1451692/5209a742-439e-21ab-c647-70e3f897a9ab.png)

### Data Engineerに必要な素養
- 技術
  - dbt、Snowflake/BigQuery/Redshift、Stitch/Fivetran など
- 課題意識の関心範囲
  - ビジネス上の質問にすべて答えられるようなテーブルを1つ作ることは可能だろうか？
  - 倉庫内のテーブルの命名規則で最も明確なものは何か？
  - ビジネス・ユーザーがLookerで壊れたチャートを見つける前に、データの問題を通知することができたらどうだろうか？
  - アナリストや他のビジネス・ユーザーがこのテーブルを迅速に使用するためには、何を理解する必要があるか？
  - 下流でクリーニングするのではなく、生産時にデータの品質を向上させるにはどうしたらよいでしょうか？

### まとめ
Analytics Engineerとは図書館の司書みたいな存在.
→ 組織のデータを管理し、それを利用する人々が使いやすいようにメンテナンスを行う人

## 参考文献
- [`What is analytics engineering?`](https://www.getdbt.com/what-is-analytics-engineering/)
学生・教職員向けPro Appバンドル　はお値打ちか

# 学生・教職員向けPro Appバンドル 24,000円
 
Final Cut Pro
>オールデジタルのワークフローのためにデザインされた、革新的なビデオ編集ソフトウェアです。

  
Motion
>Final Cut Proのためのタイトル、エフェクト、トランジションを作成できる、パワフルなモーショングラフィックスツールです。

  
Compressor
>エンコーディングのためのFinal Cut Proのパートナー。幅広いコーデックとファイルフォーマットでビデオを書き出せます。

  
Logic Pro
>あなたのMacをプロ仕様のレコーディングスタジオに変身させる、先進的な音楽制作ソフトウェアです。

  
MainStage
>Logic Proで作ったお気に入りのサウンドを、コンサートのステージで再現できるライブ演奏用アプリケーションです。


# 一般　

Final Cut Pro 36,800
Logic Pro   24,000
---------------------
小計   60,800

他の３つを含むか含まないかわからなかった。
Apple Storeでは、次の値段になっている。

Motion 6,100
Compressor 6,100
MainStage 3,680
-------
小計 15,880

合計しなきゃいけないのなら、学生・教職員向けPro Appバンドルはお値打ちなのだろうか。つかわなければ、意味がないが。

合計 76,600


以前、Adobeのいろいろつきセットを購入したことがある。　
半分以上のソフトを３年の間に使うことはなかった。　
そのソフトが必要な仕事を取れなかったことによる。　

ソフトを使うことが目的であれば、十分元は取れると思う。　
一つでも仕事が取れれば。
VBS覚え書き

Dim xml, AttrValue,HardwareID,AtDate,AtTime,Imput

Set xml = WScript.CreateObject("MSXML2.DOMDocument")
xml.load("sample.xml")

HardwareID = xml.getElementsByTagName("Computer")(0).text
AttrValue = xml.getElementsByTagName("TimeCreated")(0).getAttribute("SystemTime")

AttrValue = FormatDateTime(replace(mid(AttrValue,1,19),"T"," "))
AttrValue = DateAdd("h", 9, AttrValue )
msgbox AttrValue

AtDate = CDate(mid(AttrValue,1,10))
AtTime = CDate(mid(AttrValue,12,19))

Imput = Msgbox("OK?" & vbCr & vbCr & vbCr & "Date:"& AtDate & vbCr & "Time:" & AtTime)
vue-infinite-loadingで無限ローディングされる

# 問題点
データベースからデータを5件ずつ取得して、vue-infinite-loadingで無限スクロールすることを想定。
しかし、以下のようにすると無限に繰り返されてしまった。
```:a.vue
    infiniteHandler($state) {
      if(!this.$store.getters.isAllTask) {
        this.$store.dispatch('getTasks');
        $state.loaded();
      } else {
        $state.complete();
      }
    },
```

# 解決策
非同期処理にすれば良い。
```
async infiniteHandler($state) {                   // async追加
      if(!this.$store.getters.isAllTask) {
        // 非同期にしないと無限ローティングするので注意
        await this.$store.dispatch('getTasks');   // await追加
        $state.loaded();
      } else {
        $state.complete();
      }
    },
```
async/awaitじゃなくても
・公式リファレンスのように.then()の中に記載する
https://peachscript.github.io/vue-infinite-loading/guide/start-with-hn.html
・Promiseを使用する
でも対応可能。

# おわりに
公式リファレンスのように.then()とするのがわかりやすいと思うが、私の場合Vuexを使用していたりaxios用ファイルを作っているので個人的にasync/awaitの方がやりやすい。もっと良い方法があるのだろうか。。
Postmanでステータスコードを表示&連続実行する方法

## 経緯
SalesforceのRest **APIのコール数の限度** まで達した場合に、どんなレスポンスが返却されるか知りたかった

そのため、
・APIコール数を消費したい
・Httpステータスコードも知りたい
を手軽にやりたかった

## ステータスコードを表示する方法
### 簡単な手順
![スクリーンショット 2022-08-09 23.14.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2701305/ca5064b9-d7ae-56ba-333f-5126597a33ac.png)

1 Testsタブの中に、javacriptが書けるので、こちらに
> pm.test(pm.response.code)

と記載する。

2 この状態で通常通り「Send」してリクエスト投げる

3 結果が、Test Resultsの中に記載される


### 軽く解説
「pm.test」が出力
「pm.response」の中に、結果が入っている
codeがHTTPステータスコードで、headersがヘッダーの中身

### postmanのリファレンスはこちら
https://learning.postman.com/docs/writing-scripts/script-references/postman-sandbox-api-reference/#scripting-with-request-info

## 連続でAPIコールする方法
### 手順
![スクリーンショット 2022-08-09 23.34.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2701305/63c83150-8635-cb59-e35b-f8050b208312.png)

1 自分で作成したリクエストのフォルダの3点リーダーを右クリック 
2 一覧の中の、「Run Collection」をタップすると右のような表示がされるので、実行したいリクエストにチェックがついてることを確認
3 何回実行するか数値を入れる。ここを5000とかにすると5000回リクエストが実行される
4 クッキーとかキャッシュ的なものが残るのが嫌な場合はこちらのチェックを外す
（自分の場合、このチェックを外さずに実行するとSalesforceのAPI消費数とコール数が一致しなかったためチェック外した）


### 実行結果
![スクリーンショット 2022-08-09 23.34.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2701305/41b7fe07-1d67-b732-5f94-04b2912e66c1.png)

Itertionのところに、何回目の実行かが記載される
Testタブでステータスコードなどの表示をするよう設定しているとこちらにも結果が表示される
（今回は、401でアクセストークン切れw APIコール限度数を突破している403が返却されました）

## まとめ
無事APIコール数を消費して、結果を確認することができました。（15000回ww）
結果は、
ステータスコード403
bodyの中身は、以下のような感じでした。
```
[
    {
        "message": "TotalRequests Limit exceeded.",
        "errorCode": "REQUEST_LIMIT_EXCEEDED"
    }
]
```

postman、かなり優秀でした！！
これできなかったら、自前でAPI作成して15000回ループさせるところでしたw

postmanのtestタブに記載できるコードをもっと勉強できればさらに使えそうです！
testタブの右側にsampleも載ってたのでそこも参考にすると良いかも。


### Salesforceのエラー内容
https://developer.salesforce.com/docs/atlas.ja-jp.api_rest.meta/api_rest/errorcodes.htm
RxJS7のsortedオペレータを自作する

# はじめに
RxJavaのObservableにはsortedメソッドが入っているのに、RxJSにはsort関係のオペレータがありません。そのため自作することにしました。対象はrxjs7です。

以下は、RxJava3のObservableのjavadocのマーブル図を引用です。

![マーブル図](https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/sorted.png)

# 実装
```js
import {from, toArray, map, mergeMap, of} from 'rxjs'

function sorted(f){
    return x => x.pipe(
        toArray(),
        map(x => [...x].sort(f)),
        mergeMap(x => from(x)), 
    )
}
```

利用例
```js
from([5, 3, 1, 4, 2])
.pipe(
    sorted((a, b) => a - b),
)
.subscribe(console.log)
```

実行結果
```shell
1
2
3
4
5
```

# 注意点（引数なしのソート）
数値のソートは注意が必要です。数値ソートをしようと思って引数を指定しないsortを実行すると、数値で比較するのではなく、辞書順で比較するようです。RxJSとは無関係な挙動です。JSのArrays.sortメソッドの仕様のようです。

```js
from([5, 3, 1, 100, 4, 2])
.pipe(
    sorted(),
)
.subscribe(console.log)
```

実行結果
```shell
1
100
2
3
4
5
```
したがいまして、数値ソートをするには、コンパレータを引数に渡す必要があります。


# おまけ
RxJavaのObservableにreversedメソッドはありません。もちろん、RxJSにも。
ついでなのでreversedオペレータも自作します。sortedと、ほとんど同じです。
```js
import {from, toArray, map, mergeMap, of} from 'rxjs'

function reversed(f){
    return x => x.pipe(
        toArray(),
        map(x => [...x].reverse(f)),
        mergeMap(x => from(x)), 
    )
}
```
秘密鍵と公開鍵のペアを作る。

# はじめに
秘密鍵と公開鍵のペアを作ります。

# 最終更新日
2022年8月9日

# 環境の情報
OS
Ubuntu20.04

# 注意
最新の状態を確認して下さい。


# 参考さまはこちら
https://atmarkit.itmedia.co.jp/ait/articles/1908/02/news015.html
https://knowledge.sakura.ad.jp/3543/
https://manpages.ubuntu.com/manpages/trusty/man5/ssh_config.5.html
https://zenn.dev/wsuzume/articles/26b26106c3925e
https://tech-blog.rakus.co.jp/entry/20210512/ssh
https://nxmnpg.lemoda.net/ja/5/ssh_config
https://git-scm.com/book/ja/v2/Git%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC-SSH-%E5%85%AC%E9%96%8B%E9%8D%B5%E3%81%AE%E4%BD%9C%E6%88%90
https://docs.github.com/ja/authentication/connecting-to-github-with-ssh

# 実際に

コマンドを打ちます。
```
$ ssh-keygen
Generating public/private rsa key pair.
```

エンターを押します。
```
Enter file in which to save the key (/home/user/.ssh/id_rsa): 
```

passphraseを入力します。
```
Enter passphrase (empty for no passphrase): 
```

passphraseを入力します。
```
Enter same passphrase again: 
```

鍵ができました。
```
Your identification has been saved in /home/user/.ssh/id_rsa
Your public key has been saved in /home/user/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

The key's randomart image is:
+---[RSA 0000]----+
|     ..          |
|   . ..          |
|    o. .         |
|    o.o..        |
| 　XXXXXXX       |
|   XXXXXX        |
|  XXXXXXX        |
|XXXXXXXX         |
|XXXXXXXXXX       |
+----[SHA256]-----+
```

移動します。
```
$ cd /home/user/.ssh
```

見てみると、できています。
```
.ssh$ ls
id_rsa  id_rsa.pub  known_hosts
```

# その他まとめ 

###### Q パスフレーズってなに
A 設定しておくと、SSHの不正な利用がされにくい。

###### Q 鍵はどっちがどっち？
A id_rsaファイルが秘密鍵ファイル。id_rsa.pubファイルが公開鍵ファイル。

###### Q RSAとは
A 暗号化のやり方の1つ。

###### Q .ssh/configはなんでいるの
A どのユーザーでどの秘密鍵を使うかを指定できる。
【Windows】Gitでリモートにアクセスができない時の解決方法（Support for password authentication was removed on August 13, 2021.）

# 事象
SourcetreeなどでGitHubにpullやpushしようとすると、以下のエラーが表示されました。

```
remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/jw-sd-dev/DocumentManagementSystem.git/'
```

# 原因
2021年8月13日からGitにローカルからGitにアクセスするためには、これまでのパスワードではアクセスできなくなりました。
その対応として、以降はアクセストークンと呼ばれるパスワードのようなモノを発行する必要があります。

# 解決方法
自分がやったことを手順として残しておきます。

## 1.gitにログイン
下記URLから、自分のgitにログインする。
https://github.com/login

## 2.Settingsを開く
右上のアイコンからメニューを開き、Settingsを選択する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646368/7cc4e16a-5593-fcc6-3bd4-d0435443376a.png)

## 3.Developer settingsを開く
Developer settingsをクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646368/bc954985-4a51-1ab4-2336-bab8084b582d.png)

## 4.Personal access tokensを開く
Personal access tokensをクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646368/6d6bb6d7-af7b-2246-1ba7-41962b592ff2.png)

## 5.トークンを新しく作成する
Generate new tokenをクリック
※パスワードが聞かれたらgitのパスワードを入力する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646368/76125332-d9fe-787c-4de7-d3fc5133df5c.png)

## 6.New personal access tokenの発行画面になるため、以下入力＆選択を行う。

Note：任意の名称を入れてください。
Expiration：何日の有効にするかを決めてください。（悩むなら30日でいいです）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646368/ee101602-f00d-b55c-0b4c-1a8f7a95f5b4.png)

Select scopes：repoと、admin:repoとdelete:repoは必須でチェックを入れる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646368/7764d4b3-2094-b251-15ee-e87a65732568.png)

## 7.トークン作成
設定が終わったら「generate token」を押してアクセスコードを発行する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646368/2df92d26-a8f2-0c4f-706d-6e649d5e65f0.png)

## 8.トークンをコピー
作成したトークンをコピーする
![アクセストークン.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646368/4d03b302-545d-4b7e-9776-05fcf391e9d4.png)


## 9.コントロールパネルを開く
検索窓などからコントロールパネルを開く

## 10.ユーザーアカウントを開く
コントロール パネル ＞ すべてのコントロール パネル項目　から　ユーザーアカウントをクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646368/559d1ffc-c8ee-96e3-e7a3-649697a775bb.png)

## 11.資格情報の管理を開く
左上の資格情報の管理をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646368/eb7a4dbd-0c3e-b5d9-51fa-c1fc06413d93.png)

## 12.Windows 資格情報を選択し、git:https://github.com を開く
Windows 資格情報 をクリックし、git:https://github.com をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646368/4ab3fd4e-b369-cbdd-0cb2-2d437c30e69a.png)

## 13.編集画面からパスワードを手順8でコピーしたアクセストークンに変更し保存する
編集をクリックし下記画面が表示されたら、パスワードをアクセストークンに変更し保存する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646368/d3b005e2-6096-ce07-6eb9-575cfe4ee385.png)

# まとめ
以上で手順は完了なので、gitとコントロールパネルは閉じてOKです。
gitのリモートに接続できるか確認してみてください。
Salesforceでフローを作成しよう～レコード情報を取得しユーザレコードに計算しよう～

Salesfroceにはフローという機能があります。

今回はフローを使用し

・ユーザが所有者となっている取引先レコードのレコード数をユーザレコードの値に更新

というフローを作成します

「備考」
※所有者の変更はややこしくなるので今回は考慮しません
※フローなのでフロー作成後に取引先の作成or更新がないとユーザレコードの更新は無いです
※通常、単純に所有者ごとの取引先レコード数を計算したいのであればレポートやダッシュボードで表示が可能です
※前提としてユーザレコードに「Count__c」項目という数値カスタム項目がございます


#### フロー概要
![フロー01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/99ba36db-a95d-c151-9e33-03097064d920.png)


#### 起動条件
![フロー02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/2b3237df-4109-b941-f4cc-7be589073561.png)

「作成または更新された」と設定します


#### レコードの取得
取引先の所有者が一致するすべての取引先レコードを取得します
![フロー０３.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/e0e4f5d6-e65e-90df-cf8e-2a1f34102a40.png)


#### 割り当て
![フロー04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/1bf18400-0b2e-1648-c802-f2e07e51a449.png)

変数で割り当てます。
なお、変数は以下のようになります
![フロー05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/7200586d-e333-e4b7-6f2f-8d5331bfe31a.png)


#### レコードの更新
![フロー06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/43076185-8d04-6deb-7169-2d434bc750f0.png)

Count__cに取得したレコード数を更新します
M2 MacにOpenShift LocalをインストールしたがOCPは動かなかった（Podmanのみ動いた）

## やったこと

* 2022/08/09 時点の情報
* ローカルのマシン（M2 MacBook Pro）に、ARM版インストーラを用いてOpenShift Localをインストールした
* Podmanのランタイムは動くが、OpenShiftはセットアップ未対応だった

## OpenShift Local

* OpenShift LocalはOpenShift Container Platform 4（OCP4） + Podmanの実行ランタイムを提供する
* あくまで開発とテストの目的でのみ使用できる
* 以前、[Code Ready Container（CRC）を動かした](https://qiita.com/1ksen/items/d6f840e3786b32a2836b)けど、あれの後継と思われる

## 通常のOCPと異なるところ

* ほぼ、[CRCの時と同じ](https://qiita.com/1ksen/items/d6f840e3786b32a2836b#本番向けとの違い)と思われる

## ハードウェアの要件

なるほど、M1はサポートされないと。まぁ、[PodmanでMinikubeは動いた訳だから](https://qiita.com/1ksen/items/7c7cf598345f3ef327ea)いいとこまで行けないかな？

* OpenShift Localは、AMD64 および Intel 64でのみサポートされてる
* Red Hat OpenShift Local は、ARM ベースの M1 アーキテクチャをサポートしていない
* 物理 CPU コア 4 個
* 空きメモリー 9 GB
* ストレージ領域の 35 GB
* macOSでは macOS 11 Big Sur 以降が必要

## インストール（１回目）

Hybrid Cloud ConsoleからARM版のOpenShift Localをダウンロードしてインストール。
（ん？ARM版あるんじゃん。）

![スクリーンショット 2022-08-09 22.53.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325101/d563c784-be0e-bd67-454c-d36e54055f6c.png)

以下のとおりインストールを進めたものの、どうも普通にインストールするだけだとPodmanのランタイムしか導入されないみたい。
`crc config set preset`でopenshiftに切り替える必要がありそう。

```zsh
% crc setup
# ...snip...
Would you like to contribute anonymous usage statistics? [y/N]: <ENTER>
# ...snip...
Your system is correctly setup for using CRC. Use 'crc start' to start the instance

% crc start
# ...snip...
podman runtime is now running.

Use the 'podman' command line interface:
  $ eval $(crc podman-env)
  $ podman COMMAND

% crc status
CRC VM:          Running
OpenShift:       
Podman:          4.1.0
Disk Usage:      1.827GB of 32.74GB (Inside the CRC VM)
Cache Usage:     34.25GB
Cache Directory: /Users/1ksen/.crc/cache
```

## presetの切り替えを調査

大元の[crc.devのハードウェアの要件](https://crc.dev/crc/#minimum-system-requirements-hardware_gsg)に違うことが書いてあった。
どうも、ARM版のインストーラはあるにはあるけど、PodmanのPresetしか選択できないみたい。つらたん。

* CRC is supported on AMD64 and Intel 64 processor architectures.
* The Podman container runtime preset is supported on the ARM-based M1 architecture.
* The OpenShift Container Platform preset is not supported on the M1 architecture.

確かに、presetっていうKEYがARM版のインストーラーには存在していない模様。

```zsh
% crc config set preset openshift
Configuration property 'preset' does not exist
```

## 結論

* 2022/08/09 時点ではPodmanはM1/M2で動くけど、OpenShiftは動かない。
* （それなら、`brew podman`だけでいいやんけ・・・）
* また、どこかでやろ。
C++におけるCUDAのメモリ管理を楽にする

CUDA関数は、引数が多くて煩雑で、使うのが大変だ（例えばcudaMemcpy2D）

そこで、以下のコードを作ったら、メモリ管理が楽になった
https://github.com/rueiwoqpqpwoeiru/image-process-CUDA/blob/main/Mem.h

（工夫した点）CUDA関数をブラックボックス化して、使わなくて済むようにした
111, 112行目：デバイスメモリと、ホストメモリをペアで持つ (※メモリにゆとりが必要）
118, 120行目：ペアのメモリは同時に確保され、ホスト側はページロックされて転送が高速化(19行目)
　　　　　　（※メモリ確保は時間が掛かるので、1回確保した後は同サイズのデータのみ扱う）
```C++:110行目以降
template<typename T> struct D_mem {  // 110行目
	D_data<T> d_data;                // 111行目
	H_data<T> h_data;                // 112行目
	// open memory
	void open_2d(unsigned int w, unsigned int h, unsigned int ch, const cudaTextureFilterMode& interpolation = cudaFilterModePoint) {
		if (nullptr == d_data.ptr) {
		    d_data.w = w; d_data.h = h;	d_data.ch = ch;
		    Stopwatch sw;
		    CUDA_CHECK(cudaMallocPitch(&(d_data.ptr), &(d_data.pitch), sizeof(T) * d_data.w, d_data.h * d_data.ch));  // 118行目（デバイス側のメモリ確保）
		    sw.print_time(__FUNCTION__);
		    h_data.open(d_data.w, d_data.h, d_data.ch);  // 120行目（ホスト側のメモリ確保）
		    this->use_tex(interpolation);
		}
	}
    ...
```

189, 199行目：データ転送は、h2d()やd2h()を呼ぶだけなので、引数のミスが起こらない

```C++:189行目以降
	void h2d() const {  // 189行目（D_memクラスのメンバ関数）
		Stopwatch sw;
		if (1 < d_data.h) {
			CUDA_CHECK(cudaMemcpy2D(d_data.ptr, d_data.pitch, h_data.ptr, sizeof(T) * d_data.w, sizeof(T) * d_data.w, d_data.h * d_data.ch, cudaMemcpyHostToDevice));
		}
		else {
			CUDA_CHECK(cudaMemcpy(d_data.ptr, h_data.ptr, sizeof(T) * d_data.w * d_data.ch, cudaMemcpyHostToDevice));
		}
		sw.print_time(__FUNCTION__);
	}
```

210, 236行目：画像やcsvを指定するだけで、必要に応じてメモリを確保し、デバイスに転送

```C++:210行目以降
	void imread(const std::string& file_name) {  // 210行目（D_memクラスのメンバ関数）
		// for get size
		Img_io img(file_name);
		// alloc memory if empty
		if (nullptr == d_data.ptr) {
			if (img.tag.bit == sizeof(T) * 8) {
				this->open_2d(img.tag.w, img.tag.h, img.tag.ch);  // メモリ確保（デバイスとホスト）
			}
			else {
				assert(false);
			}
		}
		// read img if size is OK
		if (img.tag.w == d_data.w && img.tag.h == d_data.h && img.tag.ch == d_data.ch && img.tag.bit == sizeof(T) * 8) {
			h_data.imread(file_name);
			this->h2d();   // ホストからデバイスに転送
		}
		else {
			assert(false);
		}
	}
```

231, 252行目：画像やcsvを指定するだけで、ホストにデータを転送してファイルに出力

```C++:231行目以降
	void imwrite(const std::string& file_name, const int metric = PHOTOMETRIC_MINISBLACK) const {  // 231行目（D_memクラスのメンバ関数）
		this->d2h();  // デバイスからホストに転送
		h_data.imwrite(file_name, metric);  // ホスト側のimwriteを呼ぶ
	}
```
　　　　　　　　　画像はtifで、αチャンネルを使うことで、数十チャンネルの画像も入出力可能
　　　　　　　　　（参考）libtiffをソースからビルドする方法は以下に書いた
　　　　　　　　　　　　　https://qiita.com/rueiwoqpqpwoeiru/items/e0eda6752ac259484288
　　　　　　　　　libtiff以外を使用するには、ホスト側のimread（41行目）とimwrite（55行目）を修正

（補足）
　11, 97行目：多チャンネルの画像は、平面内で縦方向に連結したつもりで保持（※メモリは1次元）
　50, 65行目：画素の配置順の変更は、デバイス側で行うべき
104, 106行目：読み取りだけの場合、乗算が1つ少ない分、106行目の方が高速（ここは意外に重要）

上記コードを用いた画像処理について以下に記載
https://qiita.com/rueiwoqpqpwoeiru/items/69a931e4042a4f9d4434
日記アプリリリースしました！

## はじめに

この度、初めてのスマホアプリである「テンプレ日記」という日記アプリをリリースしたので紹介します！

「**テンプレ日記**」で検索すると一番上に出てくるので、興味を持った方は是非インストールして見てください！

## ios版

https://apps.apple.com/jp/app/%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E6%97%A5%E8%A8%98/id1638009071

## Android版

https://play.google.com/store/apps/details?id=com.hayatosato.diary


## 「テンプレ日記」の特徴

早速ですが、今回リリースした「**テンプレ日記**」の特徴を紹介します。
「**テンプレ日記**」の特徴は以下の通りです。

1. テンプレート機能付き
1. csv＆text形式でのダウンロード可能
1. csvファイルによってデータ引き継ぎを行うため、ios ⇄ Android間の移行もできる！
1. 完全無料（バナー広告のみ）
1. 最低限の機能しか含まれない

### 1. テンプレート機能

まず１番の特徴は「テンプレート機能」が付いていることです。
テンプレート機能により、あらかじめ何を書くか大まかに決めておけるので、スラスラ日記が書けるようになります。また、日記のフォーマットが揃うことで日記の振り返りもしやすくなります。

実際に自分も開発の途中から使っているのですが、何もないところから書くよりもすごく楽に書けるため、すでに2ヶ月以上続いています。

### 2. csv＆text形式でのダウンロード可能
「**テンプレ日記**」では、日記データを無料でtextまたはcsvファイルとしてダウンロードすることができます。そのため、このアプリを使わなくなった場合や、スマホが使われなくなったときにもデータは常に手元に残ります。


### 3. csvファイルによってデータ引き継ぎを行うため、ios ⇄ Android間の移行もできる！


ダウンロードしたcsvファイルをクラウド上に保存し、新しいデバイスにアップロードすることで、簡単にandroid<->ios間のデータ移行もできます。

### 4. 完全無料（バナー広告のみ）
バナー広告以外にデカデカとした広告を表示させたり、アプリ内課金を促したりすることは一生ないため安心してください！

### 5. 最低限の機能しか含まれない
良い点でもあり悪い点でもあるかもしれませんが、「**テンプレ日記**」は最低限の機能しかありません。
そのため、非常にシンプルなデザインになっており、設定に悩んだりすることもありません。
一方で、要望の多い機能については追加していく予定ですので、どしどしフィードバックをお待ちしております！


## 開発の動機

「テンプレ日記」を開発しようと思ったきっかけは、自分好みの日記アプリが存在しなかったからです。
僕の不満は以下の通りです。

1. 広告が多い
1. 課金への誘導がある
1. 無駄な機能が多い
1. データを自分の手元に保存することができない
1. android<->ios間のデータ移行ができないもしくは有料
1. 毎日何から書き始めるのか悩むため、すぐにめんどくさくなってやめてしまう

「**テンプレ日記**」はこのような不満を全て解決してくれます！

1. 広告が多い　 
   → **「4. 完全無料（バナー広告のみ）」で解決！**
1. 課金への誘導がある 
   → **「4. 完全無料（バナー広告のみ）」で解決！**
1. 無駄な機能が多い 
   → **「3. 最低限の機能しか含まれない」で解決！**
1. データを自分の手元に保存することができない 
   → **「2. csvダウンロード可能」で解決！**
1. android<->ios間のデータ移行ができないもしくは有料 
   → **「2. csvダウンロード可能」で解決！**
1. 毎日何から書き始めるのか悩むため、すぐにめんどくさくなってやめてしまう 
   → **「1. テンプレート機能」で解決！**


自分のために作ったようなものなので、解決してくれないと困りますが笑

## 技術スタックについて

全てFlutterで実装しています。
Androidとiosはほとんど同じコードでリリースできるので物凄く楽でした。
ダウンロード機能など、ちょっとOS依存しそうな機能についてもしっかりライブラリが揃っているので、ネイティブで実装した箇所は１つもありません！

## まとめ

最後までお読みいただきありがとうございました。
是非、「**テンプレ日記**」で検索してインストールしてみてください！


## ios版

https://apps.apple.com/jp/app/%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E6%97%A5%E8%A8%98/id1638009071

## Android版

https://play.google.com/store/apps/details?id=com.hayatosato.diary