OmniAICreator/Qiita-1.07M huggingface dataset:
GCPのVMインスタンスにssh接続しFTP, PhpMyAdminを利用する

###はじめに

GCP(Google Cloud Platform)操作されるような方は基本的にVMインスタンスにssh接続してCLIで処理される方が多いのではないかと思います。ただWordPressなどをGCPにホストした方は `Filezila`や`Cyberduck` DBは`PhpMyAdmin`などのGUIツールなど、慣れてる環境で作業したいのではないでしょうか。

---

###対象となる読者

`GCP`で `FTP` や `PhpMyAdmin` などGUIで操作されたい方。
`GCP` `FTP` `Filezila` `Cyberduck` `PhpMyAdmin` `接続` `ssh`などで検索されている方。

---

###まとめ

大きな流れは3つです。前提として、VMインスタンスは既に作られていることを想定しています。
1. GCPのVMインスタンスのIPアドレスを固定する
2. ローカル環境でSSHのキーを作成する
3. GCPのVMインスタンスにSSH認証鍵を作成する

ここまで出来ると、FTPやPhpMyAdminを使ってVMインスタンスを操作可能です。

---
###VMインスタンスにSSH接続
####GCPのIPアドレスの固定

GCPの管理画面 > VPCネットワーク > 外部IPアドレス
GCPのインスタンスは動的にIPアドレスが変化します。そのためまずはこのIPアドレスを固定しましょう。

![GCP外部IPアドレス.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170254/1af6b115-f0b7-4a9c-b863-df71e2fffa80.jpeg)

####ローカル環境でSSHのキーを作成する

CLIツールを立ち上げましょう。ここではMacのターミナルを想定して話を進めます。

```shell
ssh-keygen -t -rsa -f ~/.ssh/作成したいファイル名 -C admin
```

上記コマンドを打ち込むとパスワードを作成するか求められるので、パスワードを設定しましょう。すると、秘密鍵と公開鍵が作成されます。
続いて作成した公開鍵をコピーします。

```shell
cat ~/.ssh/作成したファイルの公開鍵 | pbcopy
```

####GCPのVMインスタンスにSSH認証鍵を作成する

GCP > Compute Engine >VMインスタンス
クリップボードにコピーされた公開鍵をSSH認証鍵に貼り付けます。

![GCP VMインスタンス.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170254/59570a9d-1a3c-54e5-30e6-d22a3818d2ed.jpeg)

ここまで設定が出来ると、ローカルのCLIからはアクセスできるので、確認してみましょう。

```shell
ssh -i ~/.ssh/秘密鍵のファイル admin@外部IPアドレス
#ex) ssh -i ~/.ssh/id_rsa admin@88.88.88.88 
```

設定したパスワードを入力するとVMインスタンスに接続ができます。

![VMインスタンスへのssh接続.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170254/aa5f1040-3de3-46bd-4208-ea5974d8eb68.jpeg)


###FTPを使ってVMインスタンスに接続

今回はCyberduckを使用します。

サーバーには`外部IP`、ユーザー名には`admin`(admin以外で設定した人はそのユーザー名)パスワードには`SSH鍵作成時のパスワード`、SSH Private Keyには`公開鍵ファイルのパス`を指定します。

![Cyberduck SFTP接続.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170254/9c5a6932-8544-12ad-0268-4174a73ab2c2.jpeg)

以下の動画はFileZilaのパターンで同様の流れが解説されています。

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

###PhpMyAdminを使ってVMインスタンスのDBに接続する

今回は`bitnami`を使用していたため、[bitnamiのドキュメント](https://docs.bitnami.com/google/apps/wordpress/get-started/access-phpmyadmin/)に従って、PhpMyAdminに接続します。

今回の環境はMacのため以下のコマンド入力して、PhpMyAdminのGUIから接続できるようにします。

```shell
ssh -N -L 8888:127.0.0.1:80 -i KEYFILE bitnami@SERVER-IP
# ex) ssh -N -L 8888:127.0.0.1:80 -i ~/.ssh/id_rsa admin@88.88.88.88
```

続いて、 `127.0.0.1:8888/phpmyadmin` にブラウザでアクセスしましょう。

ユーザー・パスワードはGCP > Deploy Manager > 対象のインスタンス から確認出来ます。

![GCP Deployment Management.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170254/93d6b499-bb6e-f8b5-705b-af050f2b6ca3.jpeg)

GCPから確認したユーザー・パスワードを入力しましょう。

![PhpMyAdminログイン.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170254/177a6b67-3028-935f-8cc2-bb3a9875d12f.jpeg)

これでPhpMyAdminを使ってDBに接続することが出来ました。

###最後に一言
GCPでWordPressのホスティングをすると、GCPの無料枠の恩恵を受けられるため**初期費用を抑えてスタート出来る**ことが良いと思いました。また今回は海外ユーザーが対象のサイトだったため、リージョンを海外に置けたり、CloudFlareなどのCDNサービスとも簡単に連携出来る点が非常に良いと感じました。
【テスト】herokuのログイン不良対策


Heroku login時にHerokuがインストールされておらず、HomeBrewを通してインストールを試みたところ、ターミナルのバージョンが古いとのレスポンスがあり、ターミナルアップデートを試みた際に躓いたので記録した。

##herokuのインストール


https://devcenter.heroku.com/articles/heroku-cli


```
$ brew tap heroku/brew && brew install heroku
```

途中で以下のようなWarningが表示されていた

```
Warning: A newer Command Line Tools release is available.
Update them from Software Update in System Preferences or run:
  softwareupdate --all --install --force

You should download the Command Line Tools for Xcode 13.1.
```
上記のコードを指示通りに書くと、

```
$ softwareupdate --all --install --force

Software Update Tool
Finding available software
Downloading Command Line Tools for Xcode
Downloaded Command Line Tools for Xcode
Installing Command Line Tools for Xcode
Done with Command Line Tools for Xcode
Done.
```

どうにかうまくCommand Line Toolsがアップデートできたらしいので
再度herokuのログインをトライ

```
% heroku login
heroku: Press any key to open up the browser to login or q to exit: 
Logging in... done
Logged in as ****
```
ブラウザでherokuが開き、ログインをすると、コマンド上でも上記のようにログイン完了の表示となった。
[JavaScript]forEachに弄ばれた話

# はじめに

JavaScriptを書いており、配列のループをしようとして弄ばれたときのメモ＆ネタ話です。

# 内容

## やりたいこと

最近JavaScriptを業務で使う中で、

> 配列を処理して配列内の値がtrueならエラーにしたい！
> 

ということがあったので、JavaScriptのループ処理についてググることがあった。

## やったこと

自分の普段のメイン言語はPHPなので検索ワードは

「JavaScript foreach」

で調べたところ、JavaSccriptの`forEach()`メソッドがあったので「キタコレ」という感じで実装

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

具体的な実装イメージは以下の通り。

```javascript
const hasDummys = [
	false,
    true,
	false
];

// 配列hasDummyの値にtrueであれば、アラートだす
hasDummys.forEach(function(hasDummy){
	if (hasDummy) {
		alert('不正な処理です。'); // （１
		return false;
	}
});

// 配列hasDummyの値に問題なければ、ログイン画面に遷移
window.location.href = '/login'; // （２
```

これで画面遷移前に配列内チェックができ、不正値であった場合は処理を止められる、と思っていた

## 結果

結論、想定外の挙動でした。

挙動としては、

> （１のアラートが発令されるが、**処理が止まらず**に（２のログイン画面へ遷移処理が実行


という状況。

PHPのforeachであれば処理は止まるはずなのになぜ？といった具合でした。

## 対策

JavaScriptの他のループ処理を使う

具体的には**for-of**を使いました。

※PHPなどのforeach的に使うなら直感的に使いやすい。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/for...of

コードを以下のように書き変えました。

```javascript
const hasDummys = [
	false,
    true,
	false
];

// [ 変更 ] forEachからfor...ofに変更
// 配列hasDummyの値にtrueであれば、アラート
for(hasDummy of hasDummys){ // ★
	if (hasDummy) {
		alert('不正な処理です。'); // （１
		return false;
	}
}

// 配列hasDummyの値に問題なければ、ログイン画面に遷移
window.location.href = '/login'; // （２
```

実行すると、

値がfalse：問題なくログイン画面へ遷移

値がtrue：アラートがでて、ログイン画面への遷移処理は実行されない

という想定通りの挙動をしてくれました。

## 補足

最初に使ったforEachではfor-ofと違ってづいう挙動をするかというとforEachの場合は**与えられた配列の値を一旦すべてループ処理する**らしいです

上記の実例で行くと★に処理が来ると

---

1巡目：値がfalseなのでif文に入らない＝何もしない

2巡目：値がtrueなのでif文に入り、アラート発生し`return false`で何も返さない
　　　＝何もしない

3巡目：**3巡目の処理に入り**、値がfalseなのでif文に入らない＝何もしない

↓

そのまま処理を続ける＝処理が③に入り、画面遷移がされる

---

といった挙動になります。

一方、for...ofは

---

1巡目：falseなのでif文に入らない＝何もしない

2巡目：trueなのでif文に入り、アラート発生し`return false`で何も返さない
　　　＝何もしない

3巡目：**2巡目で処理は止まるので、何も起きない**

---

といった挙動になります。

この違いは`forEach()`と`for...of`の処理の直後にconsole.logを置いて、出力されるか否かを見るとわかりやすいのでは、と思います。

# おわりに

PHPとJavaScriptで同じforeachでも処理の仕方が違うのかと驚きました。

JavaScriptはループ処理が充実していて`for...in`や`every`が用意されているので、選択肢が広がったな、と実感しました。

最後までお読みいただきありがとうございました。
VSCode Pythonのsuggestサジェストの予測候補が多いから少なくしたい！方法

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282788/755e1b59-a725-b708-1558-af9cdb928821.png)

いろんなモジュール（特に機械学習系）が入ってる環境で、この`Auto-import`候補がズラーーーーっと出てこられるとPCがカクつくし見ずらいし困ります。

ユーザセッティングで`auto import`で探したら見つかりました。以下を`settings.json`に追記すればOKです。

```json-doc:settings.json
{
...
...
...
"python.analysis.autoImportCompletions": false,
}
```
【Unity】端末がAndroidかiOSか判断をして個別に処理をする

完全に自分用メモです。

# はじめに
Unityで開発を進めていると、画像の保存時など端末によって処理を分けるケースが発生します。

今回はその方法を記述いたします。

https://docs.unity3d.com/ja/current/Manual/PlatformDependentCompilation.html

# 環境
- Windows10
- Unity Hub 2.4.5
- Unity 2020.3.25f1
- Android Studio 2020.3.1

# 端末を判定する
今回は端末を判定する方法を2種類紹介します。

## 1つめの方法
```csharp
using UnityEngine;
using System.Collections;

public class Terminal : MonoBehaviour {

    void OnClick() {
        if (Application.platform == RuntimePlatform.Android) {
            //端末がAndroidだった場合の処理
        } else if (Application.platform == RuntimePlatform.IPhonePlayer) {
            //端末がiOSだった場合の処理
        } else {
            //その他の端末での処理
        }
    }
}
```

上記のコードの `Application.platform ==` で判定ができます。

右辺の `RuntimePlatform.XXXX` は他の端末の判定も可能です。

詳しくはUnityのドキュメントを御覧ください。

https://docs.unity3d.com/ScriptReference/RuntimePlatform.html


## 2つめの方法
続いて2つ目の方法です。

さきほどより簡単な記述です。

```c#
using UnityEngine;
using System.Collections;

public class Terminal : MonoBehaviour {

    void OnClick(){
        #if UNITY_ANDROID // 端末がAndroidだった場合の処理
            // Androidの処理
        #endif　//アンドロイドの処理範囲終わり

        #if UNITY_IOS // 端末がiOSだった場合の処理
            // iOSの処理
        #endif //iOSの処理範囲終わり

        #if UNITY_EDITOR
            // Unity上での処理
        # endif
    }
}
```

ちなみに以下のように記述することもできます。

```csharp
using UnityEngine;
using System.Collections;

public class Terminal : MonoBehaviour {

    void OnClick(){
        #if UNITY_ANDROID
            // 端末がAndroidだった場合の処理
        #elif UNITY_IOS
            // 端末がiPhoneだった場合の処理
        #elif UNITY_EDITOR
            // Unity上での処理
        #endif //終了
    }
}
```

この方法では最後の `#endif` が必須です。
この `#endif` がないとエラーになります。

# UNITY_IPHONE は非推奨
先程のコードで、 `#if UNITY_IOS` の代わりに `#if UNITY_IPHONE` でも動作はしますが、公式ドキュメントでは「非推奨」となっています。
MacBookへのgitとGitHub環境準備

初めてMacBookにGitHubを使う環境をセットアップしたのでメモ。

# 前提
* 作業環境はMacBook Pro(Monterey 12.1)
* Homebrew は　[Homebrew インストール](https://qiita.com/nyanco/items/fe72307c2de8c730d836#homebrew-%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB "Homebrew インストール") で書いた通りにインストール済み
* GitHub には　[GitHub](https://github.com/) アカウント新規作成済み。

# Macbookにgitインストール

Homebrew が既にインストールされていれば、下記実行でOK。
```% brew install git```

gitのバージョンを確認しておく。

```
% git version
git version 2.32.0 (Apple Git-132)
```
# git初期設定

* Git のユーザ名を設定する
```% git config --global user.name "＜my name＞" ```

* Git で使うメールアドレスを設定する
```% git config --global user.email account@example.com```

* Git で使うエディタを設定する
```% git config --global core.editor vim```
emacs派の人はここでemacsを指定すれば良いらしい。

これらを実行すると、
```%　~/.gitconfig```
というファイルが生まれて、追加されていく。
もしもMacbookをクリーンインストール等した場合は、この　.gitconfig をバックアップしておき、配置すれば上記のコマンド実行しなくても復旧できる。

# .gitconfig を移動

移動せずそのまま使ってもいいが、　~/.config/ の下に設定ファイルを置く構成が流行り（？）らしいので、ディレクトリ用意してそちらに移動して使ってみる。

```
% mkdir -p ~/.config/git
% mv ~/.gitconfig ~/.config/git/config
```
これで設定ファイル移動は終わり。

# Gitで扱うファイル置き場を用意


```
%　mkdir ~/dev
% cd ~/dev
```
今回は　~/dev というディレクトリ以下にGitHubで扱うローカルディレクトリとした。

# GitHub にレポジトリを用意する

今回は師匠に用意してもらったので割愛。

# GitHub ２段階認証のトークン生成

今回はこちらのページを参考にさせていただきました。
@n_morioka様の記事[Personal access tokens](https://qiita.com/n_morioka/items/650d2950f527d594a00f#personal-access-tokens)

＊　[GiHub Personal access tokens](https://github.com/settings/tokens)

# git cloneする

```
% cd ~/dev
% git clone https://github.com/＜ユーザ名＞/＜用意されたレポジトリ名＞
Username for 'https://github.com': ＜自分のgithubユーザ名＞
Password for 'https://＜自分のgithubユーザ名＞@github.com':　（Personal access tokensで生成したトークンをコピペ）
Jenkinsを入れてみる

Jenkins知識ゼロの人向け。
とりあえず自分のPCにJenkins導入してみた記事です。


### （環境）
- Java8　（Java8 or Java11のみサポート）
- Windows 10 Home


### 1.ダウンロード
導入時点での安定版Jenkins 2.319.2 LTSのWinodows版 をダウンロード。
「jenkins.msi」がダウンロードされます
https://www.jenkins.io/download/

### 2.インストール
1.「jenkins.msi」をダブルクリック。以下のようなSetup画面がでてきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638048/d72e369a-2c62-1d8b-2d16-b66240aa08b6.png)
2. インストール先フォルダパスを指定する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638048/87c152cf-1e58-5a44-1bf3-536930edc486.png)
3. Service Logon Credentialsを選択する。ローカルPCで使うのみなので、非推奨だがとりあえず"LocalSystem”を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638048/38836f25-9f99-17a2-6310-36c3d714372a.png)
4. Port Selectionでポートを指定する。変える必要がなければそのまま "Test Port" をクリックして、問題なければ次に進める。今回は変えました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638048/c2b7839a-6ffa-5ebd-173a-873c3a25b934.png)
5. JDKかJREのディレクトリを指定する。
6.Custom Setupで、どの機能をインストールするか選択する。デフォルトのままで。 
7. インストールボタンをクリック。数秒で完了。

### 3.Jenkinsの起動
3-1．Jenkinsの起動
コマンドプロンプトを立ち上げ、Jenkinsをインストールした場所に移動し以下を実行

```
java -jar jenkins.war
```

※javaがうまくパス読み込めずエラーとなったので、フルパスで実行

```
C:\jre1.8.0_161\bin\java.exe -jar jenkins.war
```

3-2　ブラウザで以下URLを打鍵。Jenkinsの画面が表示されました。

```
http://localhost:18080
```

3-3　initialAdminPasswordを入力が求められるのが画面のとおり入力
ブラウザに表示されるパスの~\.jenkins\secrets\initialAdminPasswordを開き、値を入力する

3-3　Customize Jenkins　「Install　Suggested　plugins」を選択

3-4　Getting　Startedでpluginがインストールされます。しばらく待つ
  →※エラーになったので、インストールせずにスキップしました

3-5　Create First Admin User でユーザを作成　
　user1を作成

3-6　Instance Configuration　JenkinsURLを確認し、「Save and Finish」をクリック

↓↓↓↓完了！↓↓↓↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638048/8870b015-1888-9d10-ae4e-42b2d0245b24.png)
【GAS】ReferenceErrorでハマった忘備録

## 現象

GASで関数を単体実行した際にこのようなエラーが表示された。
`ReferenceError: xxx is not defined`
タイポかなと思って見返してみたけど、スクリプトエディタで書き直してみるとxxxが補完されるからコードは問題ない。

## 構成

* src
    * Sheet.gs　スプレットシートとやり取りするモジュール
    * Logs.gs　 スプレットシートにログを書き込むモジュール。Sheetモジュールを参照している
* test
    * TestLogger.gs　Logs.gsのユニットテスト目的のソースファイル

```Sheet.js
const SpreadSheet = SpreadsheetApp.getActiveSpreadsheet();

const Sheet = {
    Config: SpreadSheet.getSheetByName('config'),
    Logs: SpreadSheet.getSheetByName('logs')
};
```

```Logs.js
class Logs {
    WriteLog(message) {
        // 現在日時はUTC時間から日本時間へ変更する
        const dateformated = (dateitem) => {
            return (dateitem < 10 ? '0' : '') + dateitem;
        }
        const now = new Date(Date.now() + (new Date().getTimezoneOffset() + 9 * 60) * 60 * 1000);
        const nowstr = now.getFullYear() + '/' +
            dateformated(now.getMonth() + 1) + '/' +
            dateformated(now.getDate()) + ' ' +
            dateformated(now.getHours()) + ':' +
            dateformated(now.getMinutes()) + ':' +
            dateformated(now.getSeconds());
        Sheet.Logs.appendRow([nowstr, message]);
    }
}

const Logger = new Logs();
```

```TestLogger.js
function TestLogger() {
    const messages = ["hogehoge", "fugauga", "amazon"];
    messages.forEach(m => Logger.WriteLog(m));
}
```

## 原因

GASプロジェクト内のソースファイルの順序が正しくなかった。
関数を実行する際、どうやらファイル内の順序でスクリプトファイルがロードされているようで、
ロードされたスクリプトファイルが他のスクリプトファイルを参照する場合は先にロードしておく必要がある。
正しくは下記の順となるが、順序が間違っていると参照できなくてReferenceErrorとなる。

1. Sheet.gs
1. Logs.gs
1. TestLogger.gs

スクリプトエディタから直接編集する場合は順序を入れ替えることはないが、
claspからpushするとソースファイルの昇順で入れ替わるのでデプロイ後に並べ替えが必要。
FileSystemObjectを使ってテキストファイルを開く

#参照設定
メニューから「ツール」→「参照設定」で参照設定のウインドウが開くので、
「Microsoft Script Runtime」を選択して、「OK」ボタンでウインドウを閉じる。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684408/81c1d191-0a20-d672-6f6b-17e72b757e27.png)

#宣言
以下のように、宣言する。

```vb
    Dim FSO as New FileSystemObject
    ' または
    Dim FSO as FileSystemObject
    Set FSO = New FileSystemObject
    '参照設定をしない場合は、
    Dim FSO as Object
    Set FSO = CreateObject("Scripting.FileSystemObject")
```


#テキストファイルを開く
OpenTextFile関数を使ってテキストファイルを開く

```vb
    dim TS as TextStream
    'テキストファイルを読む
    Set TS = FSO.OpenTextFile(filename, [iomode], [create], [format])

```

引数について

| 引数名     | 省略可否 | 説明 |
|:---------:|:----------:|:------------:|
| filename  | 必須 | 読み込むファイルパスを文字列形式で指定する。 |
| iomode    | 省略可 | 入力/出力モード。 ForReading、ForWriting、または ForAppending のいずれかの定数を指定する。|
| create    | 省略可 | filenameで指定したファイルが存在しない場合に新しいファイルを作成するかどうかをBool値で指定する。 新しいファイルを作成する場合は True、作成しない場合は False を指定する。 既定値は False。|
| format    | 省略可 | 開くファイルの形式を示す Tristate の 3 つの値のいずれかを指定する。 省略すると、ASCII 形式でファイルを開く。 |

#TextStream
TextStreamを使って、テキストファイルを読んだり、書き込んだりできる。

```vb
    ' 5文字読む
    TS.Read 5
    ' 1行読む
    TS.ReadLine
    ' 全体を読む
    TS.ReadAll
    '　3文字スキップする
    TS.Skip 3
    ' 次の行をスキップする
    TS.SkipLine 
    ' 「test」という文字列を書き込む
    TS.Write "test" 
    ' 空行を4行書き込む（改行文字を4個追加する）
    TS.WriteBlankLine 4
    ' 「text」と改行を書き込む
    TS.WriteLine "text"
```
#後始末

##FileSystemObjectの破棄
通常は、プログラムの終了時にオブジェクトは破棄されるので、
下記のコードは不要だが、破棄することを明示したい場合や心配な人はおまじない的にでも書いておけばよい。

```vb
    Set FSO = Nothing
```

## ファイルを閉じる
テキストファイルを読むだけでも、編集した場合でも、TextStreamに保存するなどのメソッドはないので、Closeメソッドで自動的に保存される。Closeメソッドを使わなくても、プログラムの終了時に閉じるので、なくても大丈夫。

```vb
    TS.Close
```
1回のフォーム送信で複数のモデルを保存する方法

　今回は一つのリクエストで、2つのモデルに対して保存処理を行う方法についてまとめます。例えば購入記録を保持するテーブルと、それに紐づく住所を保持するテーブルがあるとします。この時、どうすれば一回のリクエスで二つのテーブルに対しえて保存処理を行えるのでしょうか。その解決方法としてFormフォームオブジェクトパターンを新しく学んだので、備忘録としてまとめます。

#Formフォームオブジェクトパターン
　Formフォームオブジェクトパターンとは、一つのフォーム送信で複数のモデルを操作したい時に使います。一つのフォーム送信で複数のモデルを操作する時には例えば以下のような問題が発生します。
①一度で複数のモデルのバリデーションを通過させないといけない
②バリデーションで弾かれた場合、複数のモデルのエラーメッセージを表示させないといけない。

これらを実装しようとすると複雑なコードを書かなくてはなりません。
そういった問題を解決するためにFormフォームオブジェクトパターンを使います。
使い方としては

①modelsディレクトリ直下に自作ファイルを作成し、複数のモデルに関する処理をまとめて記述する
②コントローラーに自作したクラスのインスタンス変数を渡す

順番に解説していきます。

『今回はどこかにお金を送金するような仕組みを考えます。
モデルとしては次の二つです。
①moneysテーブル（:money、:user_id）
②addressテーブル（:city, :house_number,:money_id）
この2つのモデルを1回のリクエストで保存するという処理です』


# 新たにmodelsディレクトリ直下にファイルを作成し、クラスを定義する
 まずはmdoels直下に自作ファイルを作ります。moneysテーブルとaddressテーブルをまとめて、「money_address.rb」とします。
そして次に、この自作したクラスの中に、２つのテーブルのカラムをまとめて記述します。

```money_address.rb
class OrderShipping
  include ActiveModel::Model
  attr_accessor :user_id, :money, :city, :house_number
end
```
ここでの注意点は、以下の二つです
①attr_accessor→ゲーターとセッターを定義してくれるメソッド。
②include ActiveModel::Model→ActiveModel::Modelをincludeすることで、form-withの引数にできたり、バリデーションの設定ができたりします。

#自作クラスにバリデーションを設定する
　次に自作したmoney_address.rbにmoneyテーブルとaddressテーブルのバリデーションを全て設定します。

```money_address.rb
 class MoneyAddress
  include ActiveModel::Model
  attr_accessor :user_id, :money, :city, :house_number
   with_options presence: true do
    validates :user_id
    validates :money
    validates :city
    validates :house_number
   end
```

自作したクラスにバリデーションが設定できるのは、ActiveModel::Modelをincludeしているからです。

#自作クラスに保存する処理を設定する
　次に自作したorder_shippng.rbにmoneyテーブルとaddressテーブル、両方を保存する処理を加えます。

```money_address.rb
class MoneyAddress
  include ActiveModel::Model
  attr_accessor :user_id, :money, :city, :house_number
   with_options presence: true do
    validates :user_id
    validates :money
    validates :city
    validates :house_number

  def save
    money = Money.create(user_id: user_id, money: money)

    Address.create(city: city, house_number: house_number, money_id: money_id)
  end
end
```

以上で自作クラスの設定は完了です。

#コントローラーで自作クラスを呼び出す
コントローラーで、以下のように自作クラスを呼び出します。

```money_controller.rb
class MoneyController < ApplicationController
 
  def index
  end

  def new
    @money_address = MoneyAddress.new
  end

  def create
    @money_address = MoneyAddress.new(money_params)
    if @money_address.valid?
      @money_address.save
      redirect_to root_path
    else
      render :new
    end
  end

  private

  def money_params
    params.require(:money_address).permit(city: city, house_number: house_number, money: money).merge(user_id: current_user.id)
  end

end
```
@money_address.valid?で自作クラスで定義したバリデーションを全て実行し、
@money_address.saveで自作クラスで定義した二つのモデルを保存しています。

Formフォームオブジェクトパターンの実装が完です。
これによりviewのform-withに@money_addressを渡すことができるので、

①一度で複数のモデルのバリデーションを通過させないといけない
②バリデーションで弾かれた場合、複数のモデルのエラーメッセージを表示させないといけない。
という問題を解決できます。

#まとめ
　今回は一つのフォーム送信で複数のモデルを操作する時に使う、Formフォームオブジェクトパターンについてまとめました。初学者にとっては迷いやすい部分だと思うので、今後も学んでいきたいと思います。
マルチスレッドとマルチコア

![SS 192.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/a41cd967-f549-8677-1efa-2e99bf69518d.png) がいねんのまとめ

# シングルスレッド

![SS 1372.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/e4ac1d25-508f-da3e-e78e-2c3c8be1ab1d.png)
英語の宿題が終わったら数学の宿題をやる。
これを毎日ループするイメージ。
ごく普通にプログラムを書くとこうなる。

# マルチスレッド

![SS 1373.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/55a21da6-999b-34d8-655b-76bd5aa4cc63.png)
分身の術のような感じで２つ以上のプログラムを同時に実行する。
プログラムはループするプロセスが複数が並立する感じになる。
プロセス同士の調整がキモ。

# マルチコア

![SS 1374.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/c48169e7-f93b-f77c-a4fe-680b42ea2e87.png)
デュアルコアならコアが２つあるので２つのプログラムを同時に実行できる。
２つのプログラムでデータをやり取りする場合には調整が必要になる。


# マルチコア＆マルチスレッド

![SS 1375.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/7dac1ebe-8eac-be77-9798-a1d6ab8a37b4.png)
マルチコアのそれぞれをマルチスレッド化することもできる。

# リアルタイム処理
それぞれのプロセスは、問い合わせがあった瞬間に即座に答えを出せるよう、決められた時間内にプロセスを終了させて待機している必要がある。
またやりとりするデータの書き換えなどが同時に起こると不都合なので、そこもケアしなくてはならない。
さらにデッドロックという、互いに互いの終了を待つという状態に入ると、システムがフリーズしてしまう。
μITRONやFreeRTOSなど、組み込みOSと呼ばれるものはこのリアルタイム処理が得意。


# 次回

実際にArduinoIDEとESP32でサンプルプログラムを実行してみます。

https://qiita.com/Ninagawa_Izumi/items/5c3a9d40996836bd825f

シリーズ記事：

https://qiita.com/Ninagawa_Izumi/items/f75400b579ef6fbcbdf4

https://qiita.com/Ninagawa_Izumi/items/cc9b960535ec87b7c2e3
rails newでコケたときの備忘　m1 mac macOS 12.1


#書いた理由

備忘のため。
ググってもダイレクトに出てこなかったので、同じところで詰まっている人の参考になれば。

#起こったこと

`rails new`
を叩いたら以下のメッセージでコケた

```
/Users/hoge/.rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/bootsnap-1.9.4/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `require': 
dlopen(/Users/hoge/.rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/bootsnap-1.9.4/lib/bootsnap/bootsnap.bundle, 0x0009): 
tried: '/Users/hoge/.rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/bootsnap-1.9.4/lib/bootsnap/bootsnap.bundle' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64e')), 
'/usr/local/lib/bootsnap.bundle' (no such file), '/usr/lib/bootsnap.bundle' (no such file) - /Users/hoge/.rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/bootsnap-1.9.4/lib/bootsnap/bootsnap.bundle (LoadError)
```

#解決したこと

railsのアップデート

`gem install rails`


#補足
rails tutorialを進めるにあたって、railsのバージョンを古いもので指定で入れていたので、
そのあたりがm1 macと折り合いが悪かったのではないかと推定。
インフラの基礎知識

#本記事の概要
本記事は筆者の備忘録的な位置付けの記事であり、本当に基礎的なことしか書いておりません。
たまに見返す程度の記事ですので、それでもよろしければご覧ください。

#インフラとは
`サーバー`や`ネットワーク`のこと。
infrastructure（基盤）の略称。

#サーバー
クライアントに対してサービスを提供するコンピュータのこと。
さまざまな役割があるため、その役割に応じて呼ばれ方が異なるが、結局はコンピュータのこと。
→スマホでwebページにアクセスする。サーバーがページを送り返してくれる。
ex)Dbサーバー、webサーバー等

#ネットワーク
複数のコンピュータを繋いでデータを送受信できるようにするもの。インターネットもそう。

#インターネットとは
>インターネットは、世界中のコンピュータなどの情報機器を接続するネットワークです。1990年ごろから、世界的に広く使われ始め、近年はその利活用が目覚しく進展してきました。現在では、私たちの生活や仕事などのさまざまな場面で使われる、不可欠な社会基盤（インフラ）となっています。

引用元：https://www.soumu.go.jp/main_sosiki/joho_tsusin/security/basic/service/01.html

#クラウドとは
クラウド（クラウドコンピュータ）とは、ネットワークを利用してコンピュータリソースを利用する形態のこと。
超初心者が２週間でPython3エンジニア認定基礎試験に合格してみた

超初心者が２週間でPython3エンジニア認定基礎試験に合格してみた

**★合格者のスペック★**
・国公立大学文系卒業
・業務でpythonは全く使用しない
・2021年12月25日から勉強を開始して、2022年1月15日に合格

**★勉強期間★**
3週間
平日に２時間、休日は５時間程度実施

**★勉強手順★**
書籍スッキリわかるPython入門を2時間程度で流し読み
→この段階ではわからなくてもOK

書籍スッキリわかるPython入門から大事そうなところをノートにまとめる
→わからなくてもとりあえずノートに書くことを意識

Jupyter Notebookで遊んで動かしてみる。
→まとめてというよりも、読んでいる途中途中で書いて、動かして自分を感動させる

UdemyのPython初心者講座を購入し、2倍速で流し見＋コードを書く
→とにかく流れをつかむ

過去問サイトで繰り返し演習（合計１０回以上は回答した）
→ほかのみなさんがあげている某サイトを使用。演習はこれだけでＯＫ。

過去問の解説は、ググる、もしくはyoutubeで解説をあげてくださっている方がいるのでそれを見る
→この、自分に適した動画、まとめを見つけることが一番重要だと思います。それを
ノートにまとめていく。UDEMYよりもわかりやすいものがたくさんあります。

寝る前にノートを読む。
通勤時間にＵＤＥＭＹを流す。

**★感想★**
Pythonの基本的な構文はこれで大丈夫、というくらいまでは理解できた
まずは慣れるまでがハードルなので、わからなくてもとりあえず聞く、流し読み
する、が大事だと思います。
合格だけを目的にするなら、コードを記載するのはそんなに重要じゃない。
最新の機械学習モデルはライブラリに集約されつつある Detectron2の使い方

#最新の機械学習は、Pytorchのラッパーライブラリを使うケースが多い
![ダウンロード (23).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/911006c0-d6b0-7317-6d5f-e3edc1d4f5ee.png)

ObjectDetectionタスクのモデルであれば、mmdetectionやdetectron2などのpytorchラッパーを通して使われていることが多い。
例えば、FaceBookResearchのモデルは、FaceBookResearchが使いやすいdetectron2を通して発表している。
以下のモデルはdetectron2で使えるモデルである。
>DensePose: Dense Human Pose Estimation In The Wild
Scale-Aware Trident Networks for Object Detection
TensorMask: A Foundation for Dense Object Segmentation
Mesh R-CNN
PointRend: Image Segmentation as Rendering
Momentum Contrast for Unsupervised Visual Representation Learning
DETR: End-to-End Object Detection with Transformers
Panoptic-DeepLab: A Simple, Strong, and Fast Baseline for Bottom-Up Panoptic Segmentation
D2Go (Detectron2Go), an end-to-end production system for training and deployment for mobile platforms.
Pointly-Supervised Instance Segmentation
Unbiased Teacher for Semi-Supervised Object Detection
Rethinking "Batch" in BatchNorm
Per-Pixel Classification is Not All You Need for Semantic Segmentation

#ラッパーライブラリの使い方を知れば、最新モデルが使いやすい

高精度の最新モデルを使うには、これらのラッパーライブラリの基本的な使い方に慣れておくと便利である。
覚えるのめんどくさそう？

#わりとかんたん
そもそもライブラリ自体かんたんに推論などを行えるようにラップされているので、割と使い方はかんたんである。

#使い方（Detectron2）

基本的には、
１、使いたいモデルのConfigファイルとWeightをAPIに渡してモデルをビルド
２、inference

という手順である。

```python
# build
cfg = get_cfg()
cfg.merge_from_file(model_zoo.get_config_file("COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml"))
cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.5  # set threshold for this model
# Find a model from detectron2's model zoo. You can use the https://dl.fbaipublicfiles... url as well
cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url("COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml")
predictor = DefaultPredictor(cfg)

# inference
im = cv2.imread("./input.jpg")
outputs = predictor(im)
```

![ダウンロード (24).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/33c3c553-ec5f-0e7a-2eed-91d781b8d488.png)

#覚えておくとお得
基本的に使いやすいように作ってくれたライブラリなので、覚えておくと便利である。

🐣
****
フリーランスエンジニアです。
お仕事のご相談こちらまで
rockyshikoku@gmail.com

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

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
UiPathのOrchestratorについて勉強しなおす (キュー及びトランザクションについて)

#はじめに

この記事は、UiPath Orchestrator（以下、OC）について、上級の課題は修了したけれども、OCについていまいちピンと来ていない部分がある自分が、将来OCを使用することになったときに困らないようにメモとして残すものです。
普段お仕事でOCを使用していないので、余計にピンと来ていないのだと思います。
頑張って勉強します。

認識齟齬がございましたら、お手数をおかけいたしますが、ご指摘いただけますと幸いです。
よろしくお願いいたします。

#参考文献

https://docs.uipath.com/orchestrator/lang-ja/docs/about-queues-and-transactions

やはり公式ドキュメントを読みこなせるようにならないとダメそうです。

#キュー及びトランザクションについて

まずは、公式から引用していきます。

>キューとは、無制限にアイテムを保持できる収納機能です。キュー アイテムには、インボイスの情報や顧客情報などさまざまな種類のデータを格納できます。この情報は、例として SAP や Salesforce などの他のシステムで処理することもできます。

ふんふん。
データの集まりであるトランザクションデータのクラウド版みたいな感じかな？

>キュー アイテムに格納され、キュー アイテムから出力されるデータは、既定では自由形式です。他のアプリケーションとの連携、マシン生成フォームの処理など、特定のスキーマが必要な状況では、カスタム JSON スキーマをアップロードして、すべてのキュー アイテム データが適切な形式になっていることを確認できます。

これはデータの型チェックを実施してくれるってことですかね…？

>Orchestrator で作成された新規のキューは、既定では中身は空です。キューへのアイテムの設定を行う場合は、Orchestrator のアップロード機能または Studio アクティビティを使用することができます。Studio アクティビティを使用するとステータスの変更、処理を行うこともできます。キュー アイテムを処理すると、それはトランザクションになります。

キューアイテムを処理するとトランザクションになる…？

キューについてまとめてみると、

* 顧客情報などのデータの集まり（データテーブルみたいな）のクラウド版
* 型チェックとかもやってくれる
* データの状態遷移が可視化できる(ステータスの管理はOCで行っている）
* これを処理する一連の流れをトランザクションと呼称している

といったところでしょうか。
続きます。
Nuxtで環境変数を使い分ける

開発をする中で、expressからmockを返したり、localのserverに繋いだり、本番環境に繋いでテストしたりと環境変数を使い分けたい時があると思います。

今回はNuxt.jsでコマンドで環境変数を使い分けたい時にどうするか？について記述いたします。

著者がzenn側で記述した、以下記事の環境変数設定方法になります。

https://zenn.dev/tak001/articles/2350c1e45edb02

色々なやり方がありますので、あくまで一例としてご拝読頂ければと思います。

# 環境
- PC: MacBook Pro (Intel Core 2016)
- OS: macOS Montery12.0.1
- フロントエンド:
    - Node.js 16.9.1
    - npm 7.21.1
    - Nuxt.js 2.15.8
    - TypeScript 4.5.4


# ライブラリのインストール
OSに関係なく環境変数を切り分けられるように、 `cross-env` をインストールします。

```
npm i -D cross-env
```

# ファイルの準備
続いて、コマンドごとに読み込む環境変数の値を変えたいのでファイルを作成します。

今回は以下の3ファイルをプロジェクトフォルダ直下に作成いたします。

```
touch .env.local.js
touch .env.development.js
touch .env.production.js
```

## ファイルの中身を作成
中身は適宜変更されて下さい。

```javascript:.env.local.js
module.exports = {
  API_URL: 'http://localhost:8881',
};
```

```javascript:.env.development.js
module.exports = {
  API_URL: 'http://localhost:8000',
};
```

```javascript:.env.production.js
module.exports = {
  API_URL: 'https://hoge.com',
};
```

## それぞれの役割
作成したファイルの役割は以下の通りで想定しています。

- .env.local.js： expressから固定のmockデータを返してフロントで完結させる
- .env.development.js： LaravelやJavaなどlocalでserverを立てて繋ぎこみ確認をする
- .env.production.js： 本番環境へ繋ぐ

# nuxt.config.jsの修正
nuxt.config.js を以下のように修正します。

```javascript:nuxt.config.js
const deploymentEnv = process.env.NUXT_ENV_DEPLOYMENT || 'development';
const environment = require(`./.env.${deploymentEnv}.js`);

export default {
  env: environment,
  axios: { proxy: true },
  proxy: {
    '/api': `${environment.API_URL}`,
  },
```

proxyの設定もしているので、CORS対策も考慮しています。

# package.jsonのscriptsを修正
package.jsonのscriptsを以下のように修正します。

```json:package.json
"scripts": {
  "local": "cross-env NUXT_ENV_DEPLOYMENT=local nuxt & npm run mock:api",
  "dev": "cross-env NUXT_ENV_DEPLOYMENT=development nuxt",
  "prod": "cross-env NUXT_ENV_DEPLOYMENT=production nuxt",
  "mock:api": "node ./infrastructure/mock/index.ts",
},
```

簡単に解説いたしますと、`cross-env` でcross-envを叩いて、 `NUXT_ENV_DEPLOYMENT=local` の部分がそれぞれの環境変数になります。

例えば、`npm run local` を叩いた時は、 `process.env.NUXT_ENV_DEPLOYMENT === 'local'` となります。

# .gitignoreの設定
そして、リポジトリにpushされないように `.gitignore` に以下を追加しておきましょう。

```
.env.*
```

これで、それぞれのコマンドを叩いた時は以下のようになります。

`npm run local > API_URL = 'http://localhost:8881'` 
`npm run dev > API_URL = 'http://localhost:8000'` 
`npm run local > API_URL = 'https://hoge.com'` 

以上でNuxtでの環境変数の使い分けの一例でした。

ご拝読有難うございました。
Strapi v4で管理画面を日本語にしてロゴも変える


https://github.com/strapi/strapi/issues/11912
※けっこう悩んでいる人多い？

https://docs.strapi.io/developer-docs/latest/development/admin-customization.html#configuration-options
※公式がけっこう分かりづらい

###### 
:::note warn
src/admin配下にextensionsフォルダを作成しロゴを配置する
:::

menu-logo.png 32x32の画像で良さそうでした。
auth-logo.png 434x120の画像を用意

###### 
:::note warn
app.jsに追記
:::

```
[src/admin/app.js]

import MenuLogo from "./extensions/menu-logo.png";
import AuthLogo from "./extensions/auth-logo.png";

export default {
  config: {
    locales: ["ja"],
    auth: {
      logo: AuthLogo,
    },
    menu: {
      logo: MenuLogo,
    },
  },
  bootstrap() {},
};

```

## yarn buildが必要

:::note warn
yarn build　or npm run buildが必要。これにハマりました。
:::
Laravel Mix で ERR_OSSL_EVP_UNSUPPORTED が出た時の対策

npm run dev　を行った時、次のようなエラーが出ます。

```text
 {
  opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ],
  library: 'digital envelope routines',
  reason: 'unsupported',
  code: 'ERR_OSSL_EVP_UNSUPPORTED'
}
```

これは次のバージョンで発生します。

```text
Node.js v17.3.1
Node.js v17.3.0
Node.js v17.2.0
Node.js v17.0.0
```

次のバージョンでは発生しないことを確認しました。

```text
Compiled Successfully
```

```text
v16.13.2
v16.10.0
v15.14.0
v15.0.0
v14.8.3
v14.8.2
v14.8.1
```
スムーススクロールさせる方法

今回は、jQueryを利用したスムーススクロールさせる方法を紹介していきます。
#スムーススロールとは
ヘッダーのメニューやトップへ戻るボタンなどをクリックした際に、ページ内のリンク先へ瞬時に飛ぶのではなく、<font color="DeepPink">ゆったり</font>飛んでいく挙動です。
#jQueryに記述
```:javascript
// #から始まるURLがクリックされた時
jQuery('a[href^="#"]').click(function() {
  // 移動速度を指定（ミリ秒）
  let speed = 300;
  // hrefで指定されたidを取得
  let id = jQuery(this).attr("href");
  // idの値が#のみだったらターゲットをhtmlタグにしてトップへ戻るようにする
  let target = jQuery("#" == id ? "html" : id);
  // ページのトップを基準にターゲットの位置を取得
  let position = jQuery(target).offset().top;
  // ターゲットの位置までspeedの速度で移動
  jQuery("html, body").animate(
    {
      scrollTop: position - $( '#js-header' ).outerHeight()　//htmlのheaderにid="js-header"
  },
    speed
  );
  return false;
});
  //wow
  new WOW().init()
```
上記の記述によって、スムーススクロールを実現できます！
最近読んだ情報系の本

最近読んだ本の中で、情報系に絞って「**読んでよかった**」と感じたものをメモしていこうと思います。
我ながら偏ったものを読んでいるなぁと思いますが、誰かの何かに参考になれば幸いです・・・

#1.コンピュータシステムの理論と実装―モダンなコンピュータの作り方
![picture_large978-4-87311-712-6.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2255713/338a25fb-26d3-e8cb-db9a-c519c01761c4.jpeg)

まずはオライリー出版の『**コンピュータシステムの理論と実装 ―モダンなコンピュータの作り方**』です。

https://www.oreilly.co.jp/books/9784873117126/

オライリー出版は言わずと知れた良書を大量に出版してる出版社です。本書も例に漏れずとにかく勉強になる内容でした。
※ちなみに著者（Shimon Schocken）のwebページにいくと、**無料講義**を視聴できたりもします。

https://www.nand2tetris.org/

##NANDからテトリスへ
本書のテーマにもなっているコピーですが、
**NANDなどのロジック素子→機械語→アセンブラ→VM→コンパイラ→OS→高水準言語**
という流れで自分の手で一から作成していくことになります。
コンピュータの原理的な仕組からJavaのような高級言語がコンパイルされるまでの手順を**実際に手を動かして学ぶ**ことができます。
ハードウェアの構築はHDLを用いるため、全て一台のPC上で完結するという素晴らしい仕組みも提供されます。
通常であれば、**『論理回路』『機械語』『高級言語のプログラミング』のようにバラバラに学ぶ必要がある内容を体系的にまとめられている**点が本書の超おすすめポイントです。

個人的には、ハードウェアを学ばずにソフトウェアだけをゴリゴリ進めていると、必ずどこかで躓くと思っているので**全てのソフトウェアエンジニアにおすすめの書籍**だと感じました。

#2.プログラムはなぜ動くのか
![S00190_thumb_pc (1).jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2255713/9045a04c-152d-a8c2-fa4e-3ad1ebe686c2.jpeg)

続いては日経BP出版の『**プログラムはなぜ動くのか**』です。先ほどの書籍に続きコンピュータアーキテクチャ系の書籍ですが、こちらの方がキャッチーで読みやすくなっています。

https://www.nikkeibp.co.jp/atclpubmkt/book/21/S00190/

##四角いメモリーは丸く使う
便利で使いやすいJAVAやPythonといった高級言語を書いているとついつい忘れてしまう、「**どうやってコードが解釈されて実行されるのか**」を理解することができます。

特にC言語の**ポインタの理解で苦戦している人**にはおすすめの書籍です。
私も高校生のときに初めてC言語に触れた際は、ポインタの理解のためにかなりの時間を費やしました。
結局のところ大学に進学して電子回路やら論理回路やら機械語やらを学び直してからやっと自分のものにできたような気がします。
しかし、本書籍を使えばそんなに無駄に時間を消費せずとも理解することができます。

#3.できる 仕事がはかどるGoogle Apps Script自動処理 全部入り。 (できる全部入り。)
![51RBj3zV4kL._SX350_BO1204203200_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2255713/d94d7f9e-0758-55af-6016-2cca2d97fefd.jpeg)

最後に紹介するのはGAS（Google Apps Script）の逆引き書である『**できる 仕事がはかどるGoogle Apps Script自動処理 全部入り。 (できる全部入り。)**』です。

https://libroworks.co.jp/?p=3369

##GASでWebアプリを作る
GASでWebアプリの構築をする際に、色々ググってもあんまりクリティカルな情報を見つけられずに本屋を彷徨っている時に出会えた書籍です。
GASの本は初心者向けの文法書みたいなものが多く、Webアプリを作るところまで踏み込んでいるものが多くはない印象のですが、本書は**実際に出退勤記録アプリを作成しながら必要なクラスやメソッドを紹介する**という実践的なものでした。
全体的に基本的なGASやJSの知識があることが前提で、便利なメソッドとアルゴリズムの組み合わせを紹介している内容なので、**「これからGASを学んでいきたい！」という方にはお勧めできません**。

#展望
今はセキュリティ系の書籍を読み漁っているので、また何冊かいいものを見つけたらメモしていこうと思います。
情報処理技術者試験対策で役立ったものとかも紹介できればなぁと思っていますが、数年前の記憶なので妄想で終わりそうです。
String(format:)にはCVarArg...と[CVarArg]の2パターン存在する

ほとんどの場合 `CVarArg...` のほうしか使わないと思うけど。

```swift:
// まったく相応しくない例
let price = "5000兆"
let unit = "円"
let formatted = String(format: "%@%@欲しい！！", price, unit)
```

可変引数部分もラップした関数を用意したとき、こう書いちゃだめ。

```swift:
// ❌意図した動作にならない
// argumentの中身は[CVarArg]であり、String(format:)には1つ目の可変引数と解釈されてしまう
func localized(format: String, _ arguments: CVarArg...) -> String {
    return String(
        format: NSLocalizedString(format, comment: ""),
        arguments
    )
}
```

`arguments: キーを付けると `[CVarArg]` を引数として取るので、こっちが正解。

```swift:
// ✅
func localized(format: String, _ arguments: CVarArg...) -> String {
    return String(
        format: NSLocalizedString(format, comment: ""),
        arguments: arguments    // argumentsキーをつけて渡す
    )
}
```

ビルドエラーも出ないし、動作不定なので分かりづらいよね...
【Django】testファイルをtestsディレクトリ内に移動したらtestが実行されない

# 目的
DjangoRestframeworkでAPIを作成している際にやはり単体testを行う必要があると感じた。

デフォルトではアプリディレクトリにtests.pyが一つあるだけで、正直個人で遊ぶにはそれでも良いかもしれないが多くのテストがある実務を想定してtestsディレクトリの中にtest_●●●●.pyというファイルを作成した。

が、```python manage.py test```でこのファイルが認識されていない模様。。。
これをなんとかしたい。

```console
.
├── __init__.py
├── admin.py
├── apps.py
├── migrations
├── models.py
├── serializer.py
├── tests
│   └── test_models.py
├── urls.py
└── views.py
```


# 結論
単純明快。
空の```__init__.py```を同ディレクトリに追加することで解決できる。

# 実施環境
### ハードウェア環境
| 項目 | 情報 |
|:-:|:-:|
| OS  |macOS Catalina(10.15.7)   |
|ハードウェア   |  MacBook Air (11-inch, Early 2015) |
|プロセッサ   | 1.6 GHz デュアルコアIntel Core i5|
|メモリ   |  4 GB 1600 MHz DDR3 |
|グラフィックス   |  intel HD Graphics 6000 1536 MB |
### ソフトウェア環境
| 項目 | 情報 |
|:-:|:-:|
| homebrew  | 3.3.8 |
| mysql | Ver 8.0.27 for macos10.15 on x86_64 |
| python  | 3.8.12 |
| django  | 3.0.0 |
| anaconda  | 4.10.1 |
| pip  | 21.2.4 |



# 原因究明
### コマンドは正しいか？？
```python manage.py test```と公式ドキュメントの通りに打っているから問題なさそうだ。

### ファイル名/関数名は正しいか？？
テストを行うファイル名とテストケースの関数名の最初はtestから始まる必要がある。
そうしないとDjangoがそれをテストだと読み込んでくれない。

問題なさそう。


# 解決
参考にしていた[この記事](https://zenn.dev/tmasuyama1114/articles/django-how-to-unit-test#%E3%83%A6%E3%83%8B%E3%83%83%E3%83%88%E3%83%86%E3%82%B9%E3%83%88%E4%BD%9C%E6%88%90)にもちゃんと書いてあった。

空の```__init__.py```を同ディレクトリに追加すること.

[このコメント](https://stackoverflow.com/questions/448271/what-is-init-py-for)によると、
> If you remove the __init__.py file, Python will no longer look for submodules inside that directory, so attempts to import the module will fail.

__init__.pyがディレクトリにないとモジュールのimportが失敗してしまい先ほどのようなエラーになるため、ディレクトリ作成時は__init__.pyを入れた方が良い。


```console
.
├── __init__.py
├── admin.py
├── apps.py
├── migrations
├── models.py
├── serializer.py
├── tests
│   ├── __init__.py
│   └── test_models.py
├── urls.py
└── views.py
```
無事テストが実行された。

```
======================================================================
FAIL: test_is_empty (tinder.tests.test_models.JobModelTests)
初期状態では何も登録されていないことをチェック
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/Yuto/dev/api_practice/tinder_api/tinder/tests/test_models.py", line 13, in test_is_empty
    self.assertEqual(saved_jobs.count(), 1)
AssertionError: 0 != 1

----------------------------------------------------------------------
Ran 1 test in 0.014s

FAILED (failures=1)
```

https://zenn.dev/tmasuyama1114/articles/django-how-to-unit-test#%E3%83%A6%E3%83%8B%E3%83%83%E3%83%88%E3%83%86%E3%82%B9%E3%83%88%E4%BD%9C%E6%88%90
AWS Cloud Practitioner Essential まとめ3

# [AWS Cloud Practitiner Essential] (https://explore.skillbuilder.aws/learn/course/1875/play/27620/aws-cloud-practitioner-essentials-japanese-ri-ben-yu-shi-xie-ban) 殴りがき


### VPC(Virtual Private Cloud)
- AWSユーザー専用のプライベートネットワーク
- VPC内に、EC2やELBなどを配置できる
- ゲートウェイがないと、VPC内のリソースには誰もアクセス出来ない。

#### サブネット
- VPC内のIPアドレスの集合
- インターネットに公開するか、プライベートにするか。

※　サブネットによって複数のネットワーク空間に分けているため、ゲートウェイはVPCに複数設置される可能性がある。

#### パブリックサブネット
- インターネットゲートウェイからのアクセス権がある。

#### プライベートサブネット
- インターネットゲートウェイからのアクセス権がない。

#### インターネットゲートウェイ
- インターネットからVPCにアクセスを可能にするには、インターネットゲートウェイを設置する必要がある。
- インターネットからインターネットゲートウェイを通してELBに対してのリクエストを可能とする。

#### 仮想プライベートゲートウェイ
- プライベートネットワーク(指定された社内ネットワークなどVPN接続)からのアクセスだけ許可する
- インターネットからのアクセスは拒否する
- プライベートネットワークから仮想プライベートゲートウェイを通してELBに対してのリクエストを可能とする。
    - 配置位置はインターネットゲートウェイと同じ感じ。
- <b>イメージは、インターネットを使ってリクエストを送るが、VPNのようにリクエストは暗号化され、周りからは守られる。ただし、インターネットと同じ経路を使うため、リクエストの渋滞などに巻き込まれる可能性はある。</b>


#### AWS Direct Connect
- データセンターから直接VPCに繋げ、Direct Connectを通してELBに対してのリクエストを可能とする。
    - 配置位置はインターネットゲートウェイと同じ感じ。
- <b>イメージは、インターネットを使わないため、他のリクエストの渋滞に巻き込まれる可能性はない。接続元からの直通通路を使うイメージ</b>

#### ネットワーク ACL
- パケットの送信者、通信方法によりサブネットに通すか判断する。
- 入国、出国を検査するファイヤウォール。
- ゲートウェイは、どこからのリクエストを許可するのかを判別するイメージ。
- ネットワーク ACLは、リクエストの内容に応じて許可するかを判別するイメージ。
- ブラックリストやホワイトリストなどを設定して、特定のリクエストをはじく。
- リクエストを迎える、レスポンスを送る。それぞれに対して許可するかを判断する。
- <b>ステートレス: 通過するパケットの一つ一つをチェックする</b>
    - 出国したからといって、帰国する際にも必ずチェックする。　⇦　ステートレスで覚えてないから。
- <b>ACLは、AWSが提供するデフォルトACLと、自分でカスタマイズするカスタムネットワークACLがある。</b>
- <b>デフォルトACLでは、全てのトラフィックの入国・出国を許可する</b>
    - ルールを加えることで変更はできる
- <b>カスタムネットワークACLでは、全てのトラフィックの入国・出国を拒否する</b>
    - ルールを加えることで許可するものを登録できる。

#### セキュリティグループ
- インスタンス単位のセキュリティ。パケット情報に対して？
- デフォルトでは、全ての入国を拒否、全ての出国を許可。
- 同じサブネット内の特定のインスタンスには許可する。セキュリティグループという設定をインスタンスに付与する。
    - デフォルトでは全てのポートが閉じられ、全てのリクエストを許可しない設定となっている。
- リクエストを迎え際は許可するか判断するが、レスポンスを送る際は判断しない。
- <b>ステートフル: 許可するかどうかを記憶によって判断する = 以前通過したものはチェックしない</b>
    - リクエストに対してチェックを入れ、そのリクエストを覚えておく。レスポンスを通す際はチェックしない。　⇦　ステートレスでチェックしたこと覚えてるし。


### Route53

DNS。

- レイテンシーベースのルーティング
- 位置情報DNS
    - リクエスト先に近いリージョンにルーティングする
- 地理的近接性ルーティング
- 加重ラウンドロビン 


### Amazon CloudFront

エッジロケーション。コピーデータをキャッシュして、遠いリージョンにアクセスしなくても高速でリクエストを処理して返すことができる。 -> CDNと呼ばれる技術。

###
トンガでの火山噴火による衝撃波の検出に成功? (追記)

#ニュース
ウェザーニュースより「トンガでの火山噴火による衝撃波か」という見出しのニュースと気圧変化の映像があった。
[トンガでの火山噴火による衝撃波か　日本各地で急激な気圧変化](https://news.yahoo.co.jp/articles/d5f8737ed4e17c53165a17be19710eb5ca255938)

#計測システム
[ESP-01で部屋の湿度を制御する](https://qiita.com/tlab/items/ad689ddcb77275932e55)で作成したシステムで、BME280というセンサーで気温、湿度のほか気圧も計測している。BME280の気圧分解能は0.18Pa(=0.0018hPa)、ノイズは1.3Pa(=0.013hPa)ということで微気圧波が届いていれば検出できている可能性があります。

#実際の気圧変化
下記実際の気圧変化です。東京とトンガの距離は7,800kmほどで20時すぎに到着したとのことになっています。
~~計測地はトンガとの距離9,300km、GMT+8Hrsで音速を1,255km/hとすると、1,500kmにかかる時間は1時間13分であり、20:22(21:22JST)のピーク値が微気圧波の到着時刻と考えられます。~~(距離間違えてました。下記音速も追記にある1100km/hで再計算しています。)
計測地はトンガとの距離9,100km、GMT+8Hrsで音速を1,100km/hとすると、1,300kmにかかる時間は1時間11分であり、20:22(21:22JST)のピーク値が微気圧波の到着時刻と考えられます。微気圧波は1.5hPaほどでしょうか。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211703/91d640f6-951a-3e01-c0f6-b8c0db37239a.png)


#おわりに
BMP280の性能すごい!


#地球一周後は検出できず(追記)
(追記 2022/01/17)
裏側から一周してくるのは (40,000 - 9,300)/1225 = 25.06hrs後で16日21:30ころ。21時ころにギャップがあるものの気圧が下り元に戻っているのでノイズと考えられる。
20:22で検出したのが一周してくるのは40,000/1225 = 32.65hrs後で17日05:00ころ。こちらは確認できず。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211703/b1180a43-9c49-7f68-4014-061e4e13a69c.png)

是非ともウェザーニュースのソラテナでの観測結果と比較したいところです。ソラテナならば面で観測しているので通過したことがはっきりします。1週した時間がわかれば、このグラフのどのタイミングなのか捉えられているのかがわかります。公開してくれないかな。

#地球一周後も記録できてるっぽい(再追記)
(追記 2022/01/17)
[Weather instruments around southern New England detect Hunga Tonga shockwave](https://www.wcvb.com/article/weather-instruments-around-southern-new-england-detect-hunga-tonga-shockwave/38784108)によると、衝撃波は平均速度1100km/hで広がったとのこと。
40,000kmと31,000kmを再計算すると36:22と28:11。1,225km/hで計算したものと比較すると、それぞれ＋3:00と＋3:43の差となる。
ズレた位置では丁度ピークが確認でき、これが反対側を回ってきた衝撃波と一周した衝撃波と考えられる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211703/1893e2e0-0f39-a7a2-65cf-9ab67ac6c008.png)
AtCoder Beginner Contest 235をやった(Java)

AtCoder Beginner Contest 235をやった。
記事投稿サボってました。自己満投稿ですが、これからもよろしくお願いします。
C問題はTLEになったので参考にしないでください。
※もし、Javaで解かれた方いましたら、コメントいただきたく！！

##[A](https://atcoder.jp/contests/abc235/tasks/abc235_a)
3つの数字の並び替え問題
詳細は例題にある通り。直感的に3回並び替えて足し算する方法が楽かなと思ったのでそれでやりました。

```Java
import java.util.*;
 
public class Main {
    public static void main(String[] args) throws Exception {
        Scanner scan = new Scanner(System.in);
        String abc = scan.nextLine();
        int sum = 0;
        
        for(int i = 0; i < 3; i++){
            sum += Integer.parseInt(abc);
            abc = abc.concat(abc.substring(0, 1));
            abc = abc.substring(1, 4);
        }
 
        System.out.println(sum);
    }
}
```

##[B](https://atcoder.jp/contests/abc235/tasks/abc235_b)
高さを求める問題、日本語にするのは難しいので詳細は問題を確認してください
制約が最大でも10^5ループとあったので、単純なforループで行けると思い決行

```Java
import java.util.*;
 
public class Main {
    public static void main(String[] args) throws Exception {
        Scanner scan = new Scanner(System.in);
        int N = scan.nextInt();
        int[] Hi = new int[N];
        int ans = 0;
        
        for(int i = 0; i < N; i++){
            Hi[i] = scan.nextInt();
            if(i >= 1){
                if(Hi[i-1] < Hi[i]){
                    ans = Hi[i];    
                } else {
                    ans = Hi[i-1];
                    break;
                }
            } 
        }
 
        System.out.println(ans);
    }
}
```

##[C](https://atcoder.jp/contests/abc235/tasks/abc235_c)
上にも書きましたが、参考にはしないでください。TLEがでます。
PHPなどにある連想配列ベースでやればたぶんできるんだろうなーとは思いましたがJavaのMapの使い方に挫折。。。

```Java
import java.util.*;
 
public class Main {
    public static void main(String[] args) throws Exception {
        Scanner scan = new Scanner(System.in);
        long N = scan.nextLong();
        long Q = scan.nextLong();
        long[] aIndex = new long[(int) N];
        
        for(int i = 0; i < N; i++){
            aIndex[i] = scan.nextLong();
        }
        
        for(int i = 0; i < Q; i++){
            int cnt = 0;
            long xNum = scan.nextLong();
            long kNum = scan.nextLong();
            for(int j = 0; j < aIndex.length; j++){
                if(aIndex[j] == xNum){
                    cnt++;
                    if(cnt == kNum){
                        System.out.println(j+1);
                        break;
                    }
                }    
            }
            if(cnt < kNum){
                System.out.println(-1);
            }
        }
    }
}
```
CloudFormationでDynamoDBを使う


##はじめに
DynamoDBをCloudFormatinで使うときの留意点をまとめてみました

##DynamoDBでのBillingMode

Billingモードは`PROVISIONED`と`PAY_PER_REQUEST`のふた通りあります。
`PAY_PER_REQUEST`は従量課金になります。

Billingモードを指定しない場合はデフォルトの`PROVISIONED`が選択されます。

`PROVISIONED`が指定された場合は`ProvisionedThroughput`の項目が必須になります。

```yaml
    DynamoDBUserTable:
      Type: AWS::DynamoDB::Table
      Properties:
        AttributeDefinitions:
          - AttributeName: id
            AttributeType: S
        KeySchema:
          - AttributeName: id
            KeyType: HASH
        ProvisionedThroughput:
          ReadCapacityUnits: 5
          WriteCapacityUnits: 5
        TableName:
          Fn::Sub: "User"
```

`BillingMode`の項目がないため`PROVISIONED`が指定され、`ProvisionedThroughput`の`ReadCapacityUnits`と`WriteCapacityUnits`を５にしています。


##最後に
従量課金はアクセス数が予測できない時に使うと良さそうですが、開発段階では必要なさそうです。

##参考文献

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-dynamodb-table.html#cfn-dynamodb-table-billingmode

https://dev.classmethod.jp/articles/dynamodb-cfn-ondemand-reinvent-2018/
INDEX＆MATCHなどの参照関数の参照先をダブルクリックで開きにいくマクロ【ExcelVBA、WS関数】




## 作り方（参照セルアドレスまで表示させる方法）

https://qiita.com/taleau/items/e397ee03923788c37489

前回の
`=INDEX(INDIRECT([@検索DB]),[@MACTH行],[@MACTH列])`
でもこれ以上関数を簡素化できないレベルまで簡素化しましたが、**参照関数の検算**まで考慮するともう一押し欲しくなったのでこんなの作りました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281933/5f206c8d-d9f5-558c-ff83-74defb03b85e.png)

|参照セル|**値Indirect**|
|---|---|
|=udf指定範囲の指定位置アドレス([@検索DB],[@MACTH行],[@MACTH列])|**=INDIRECT([@参照セル])**|

参照セルの値をコピーしておいて、ジャンプ機能(`Ctrl+G`か`F5`)で参照DBの参照アドレスに飛ぶとすぐに値がわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281933/d1acb27a-2ca8-d497-1af9-7ac509b65480.png)

### コード（標準モジュール）
参照セル列の関数をワークシート関数だけで作ろうとすると骨が折れるのでユーザ定義関数でサボりました。
指定範囲の先頭セルを吐く関数がパッと作れません。
そこの悩みがVBAだとこんなアッサリかけてしまうので得意なやつにやらせた方がいいと判断しました。

また、シート名を返すのもワークシート関数だとクソ長くなっちゃうのでやる気が起きませんが、VBAだと`Range.Parent.Name`で瞬殺です。

``` vb:指定範囲の先頭セルを吐く部分
  Dim Area As Range: Set Area = Range(AreaName)
  Dim rr, cc
  rr = Area(1, 1).Row
  cc = Area(1, 1).Column
```

僕の職場の共同改修者がワークシート関数よりVBAの方が読み慣れている、というのもありますが、そもそもワークシート関数の可読性はLET関数なしだと頑張り用がないと思っていて、ある程度の複雑さを帯びてきたらデータをクリーニングするか参照列を増やすか業務フローから見直すかした方がいいです。

``` vb
Option Explicit

Function udf指定範囲の指定位置アドレス(AreaName As String, _
                        MatchRow As Long, _
                        MatchColumn As Long)
  
  Dim ws As Worksheet: Set ws = Range(AreaName).Parent
  Dim wsName As String
  wsName = ws.Name
  
  Dim Area As Range: Set Area = Range(AreaName)
  Dim rr, cc
  rr = Area(1, 1).Row
  cc = Area(1, 1).Column
  
  Dim myCell As String
  myCell = ws.Cells(rr + MatchRow - 1, cc + MatchColumn - 1).Address
  
  udf指定範囲の指定位置アドレス = GetWsCellFullname(wsName, myCell)
  
End Function

Private Function GetWsCellFullname(wsName As String, clName As String) As String
  GetWsCellFullname = "'" & wsName & "'!" & clName
End Function

```

## ジャンプ機能をマクロでダブルクリックイベントに付与する
関数内に名前付き範囲を入れたり、名前付き範囲をジャンプで検索することは僕にとっては自然な動作なのですが、なかなか他の方には定着しないだろうと指摘を受けたのでもう一押し。

**もうダブルクリックで参照先にジャンプすればよくね？**

これはさすがに誰でもできるでしょ


### コード（標準モジュール）
上のudfのコードの下に下記を追加して下さい。

``` vb

Sub Activate指定セル(Target As Range)
  On Error GoTo ErrLabel
  'セル参照UDFがないセルに対しては実行しない
  Const str = "udf指定範囲の指定位置アドレス"
  If InStr(Target.Formula, str) = 0 Then Exit Sub
  
  Dim x開くセル As Range
  Set x開くセル = Range(Target.Value)
  With x開くセル
    .Parent.Visible = True
    .Parent.Activate
    .Select
  End With
  
  Exit Sub
ErrLabel:
  Select Case Err.Number
    Case Is = 1004: '何もしない
    Case Else: MsgBox "エラーNo." & Err.Number & ":" & Err.Description
  End Select
  
End Sub
```

### コード（シートモジュール）
ダブルクリックイベント用に下記をシートモジュールにコピペしてください。

ここもサボってるところがあります。
値セルをダブルクリックすると参照先を`Select`するようにしていますが、値列の左隣に参照セル列をもっておく必要があります。

値列の関数の中身から参照列を読み込んで...なども考えましたが作りこみすぎるのも良くないのでここらで止めました。

``` vb
Option Explicit

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
  ' 参照結果の列１つ左隣セルの値(参照先セル名)を開く
  Call Activate指定セル(Target.Offset(0, -1))
End Sub
```
検索列を超丁寧に挟んでINDEX＆MATCHなどの参照関数の改修容易性をグンと上げてみた【WS関数】

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">マイクロソフトさん、XLOOKUPはINDEXとMATCH関数で実現するので、この黄色いところを求める関数を作って下さい。 <a href="https://t.co/eod42hlFWG">pic.twitter.com/eod42hlFWG</a></p>&mdash; 佐藤嘉浩承旨/MOS365&amp;2019全試験コンプ・日商PCプロフェッショナル@Officeの魔法使い (@yosatonet) <a href="https://twitter.com/yosatonet/status/1482285691736190977?ref_src=twsrc%5Etfw">January 15, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">いばらの道は避けられるに越したことはないです...<br><br>最近まで検索列面倒くさがってましたが、今の職場だと別の方も改修するのでその方も分かりやすいように姿勢を改めてます。<br><br>検索列はグループ化して非表示/表示を切り替えられるようにしてこまめに検索列作るとわりとみんなハッピーかなと</p>&mdash; 青と緑のVBAer (@mechkawa) <a href="https://twitter.com/mechkawa/status/1482320755157520384?ref_src=twsrc%5Etfw">January 15, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

昨日このようなやりとりがある数日前にタイムリーに作っていたものがあり、記事化しようと思っていた矢先だったのでまとめてみました。


参照関数
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281933/205c1265-e942-d81e-144c-eed34c15d6f4.png)

参照DB
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281933/1590489b-eee6-48e1-2c1c-b741c5627c8d.png)

## 作り方（普通にINDEX＆MATCH）

### セル範囲に名前を付けておく

ここまでやる必要もないかもしれませんが、僕が職場でつかっているものはこんな表が機種ごとに複数ある上、PowerQueryで束ねるなどが他の改修者に不評だったのでこの方法に戻ってきました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281933/88070a30-a0d3-9231-3afe-3a6588ecd6c3.png)


### 参照関数側に計算列を追加しておく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281933/671e35ba-3f76-cb3d-2c26-f02856c23cf6.png)

|機種|検索値行|検索値列|MACTH行|検索DB|MACTH列|**値IndexMacth**|
|---|---|---|---|---|---|---|
|機種1|検索値1|列1|=MATCH([@検索値行],INDIRECT([@機種]&"_検索値"),0)|=[@機種]&"_DB"|=MATCH([@検索値列],INDIRECT([@機種]&"_検索列"),0)|**=INDEX(INDIRECT([@検索DB]),[@MACTH行],[@MACTH列])**|

### 計算列はグループ化して折りたためるようにしておく
`Shift`+`Alt`+`→`でグループ化できます。
あとは参照列は灰色とかにして展開時も見分けがつくようにします。


## 参照先をダブルクリックで開く検算用マクロも作ったのでこちらもどうぞ

https://qiita.com/taleau/items/6b09e6a3e90f65e1b2fc