OmniAICreator/Qiita-1.07M huggingface dataset:
【iOS15】IDFA許諾ダイアログ表示できなくった件

#何をするか？
iOS15以降からIDFA許諾ダイアログを表示する方法が少し変わったのでメモ

#原因
```
Calls to the API only prompt when the application state is: UIApplicationStateActive. Calls to the API through an app extension do not prompt.
```
iOS15から新たな制限が加わり、「アプリの状態がActiveの時しか表示しない」ようになった模様。
以下公式ドキュメントになります。
https://developer.apple.com/documentation/apptrackingtransparency/attrackingmanager/3547037-requesttrackingauthorization

#これまでの実装
**AppDelegte**の**didFinishLaunchingWithOptions**でidfaの許諾処理を行なっていたが、ここが呼ばれる時点ではアプリの状態はInactiveなのでダイアログは表示されない。

```swift
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        if #available(iOS 14, *) {
            ATTrackingManager.requestTrackingAuthorization(completionHandler: { status in
                GADMobileAds.sharedInstance().start(completionHandler: nil)
            })
        } else {
            // Fallback on earlier versions
            GADMobileAds.sharedInstance().start(completionHandler: nil)
        }
        return true
    }
```

#対応内容
**ScenceDelegate**の**sceneDidBecomeActive**でidfa許諾処理を行うことで対応。
Active状態のはずだが、普通に処理を走らせるだけだとダイアログが表示されないので、処理を1秒遅らせることでidfa許諾ダイアログが表示されるようになりました。

```swift
func sceneDidBecomeActive(_ scene: UIScene) {
    DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
        if #available(iOS 14, *) {
            ATTrackingManager.requestTrackingAuthorization(completionHandler: { status in
                GADMobileAds.sharedInstance().start(completionHandler: nil)
            })
        } else {
            GADMobileAds.sharedInstance().start(completionHandler: nil)
        }
    }
}
```
NumCpp のメモ

## 背景

numpy っぽいコードを C++ でやりたい.

https://github.com/dpilger26/NumCpp

NumCpp つかいます. C++14 or later
ドキュメントは Doxygen で激しく見づらい...

利点としては svg など linalg 系もいくつか自前で用意されています(Eigen 非依存).

Boost を一部使っていますが `NUMCPP_NO_USE_BOOST` で使わないようにできます.
Boost はベッセル関数など特殊数学関数や Python interface で使っています.
(python interface については pybind11 を使うのもできる) 
 
## 用例

頻度高いのは github README に一覧あります.

### ndarray は二次元まで

`NdArray` とありますが, 対応は 2 次元まです.
独自のメソッドとして `numCols()`, `numRows()` などがあります.


### 各要素に処理を適用.

`begin()`, `end()` のイテレータを使ってもいけますが, `nc::applyFunction` もあります. ただ C++17 でも明示的な型指定しないとなぜかコンパイルできませんでした.
(引数の `NdArray` 変数の型から推論してくれそうであるが)

```
nc::NdArray<double> a = nc::linspace<double>(-10.0, 10.0, 100);

// テンプレート型の明示的指定が必要
nc::applyFuncion<double>(a, [](double v) { return v * v; });

```


中身は `std::transform` を使って実装しているので, ちょこっと書き換えて C++17 + parallel STL で処理するのも手かもしれません.
(明示的にマルチスレッド処理する `numpy.vectorize` 相当は無い)


 
## ファイル入出力

text or binary でいけます.

ただ, binary は生データそのままなので, shape 情報などありません(2D のデータを書いて読み直すと 1D になってしまう). したがって python で生成した .npy を NumCpp で読むやその逆はできないです.

npy(npz) フォーマットを扱いたいときは cnpy などを使うとよいでしょう.

https://github.com/rogersce/cnpy

その他 Python とデータやりとりしたいとなると shape などの情報は JSON に書いてやりとりとか, でしょうかね.

## 計測

Timer があります.

https://github.com/dpilger26/NumCpp/blob/7f466b4cad8fa6cc9e01464a44acb3b9d45300f3/test/src/NumCppPy.cpp#L6002

## Python binding

https://github.com/dpilger26/NumCpp/tree/master/include/NumCpp/PythonInterface

Boost or pybind11 で Python 用バインディングがありますが, ある程度自前でバインディングを書かないとだめかもです.
【GitHub CLI】ghコマンドでPR番号からブランチ名を取得する

[GitHub CLI](https://github.com/cli/cli) を用いて、PR 番号からブランチ名を取得する方法を紹介します。

# 動作確認バージョン
```shell-session
$ gh --version
gh version 2.0.0 (2021-08-24)
https://github.com/cli/cli/releases/tag/v2.0.0
```

# PR 番号からブランチ名を取得するコマンド

```text
gh pr view --json headRefName --jq .headRefName [<pr-number> | <url>]
```


```shell-session:実行例
$ gh pr view --json headRefName --jq .headRefName 1234
feature/foo-bar-baz
$ gh pr view --json headRefName --jq .headRefName https://github.com/cli/cli/pull/1222
api-pagination
```

gh version 2.0.0 からは [gh extension](https://docs.github.com/ja/github-cli/github-cli/creating-github-cli-extensions) でカスタムコマンドを追加できるようになったので、`gh get-branch-name` で上記と同じことができるようにしてみました。

https://github.com/mascii/gh-get-branch-name

```shell-session:カスタムコマンドのインストールと実行例
$ gh extension install mascii/gh-get-branch-name
$ gh get-branch-name 1234
feature/foo-bar-baz
$ gh get-branch-name https://github.com/cli/cli/pull/1222
api-pagination
```

## 活用例
PR 番号を用いてリモートブランチをローカルブランチにマージすることができます:

```shell
git merge origin/$(gh get-branch-name 1234)
```
WordPressの投稿記事・固定ページ本文中にショートコードでテーマ内のphpを呼び出す

#PHPファイルを読み込むショートコード
function.phpに以下を追加

```
function my_tmp_code($atts) {
 extract(shortcode_atts(array('file' => 'default'), $atts));
 ob_start();
 include(STYLESHEETPATH . "/$file.php");
 return ob_get_clean();
}
add_shortcode('my_tmp', 'my_tmp_code');
```

#本文で呼び出すときのコード
```
[my_tmp file='ここにテーマ内のphp名（phpを除く']
```
Elasticsearchの全文検索のしくみ

# この記事を書いた背景・目的
業務でElasticsearchを触る機会が有りました。
全文検索エンジンというものを初めて触り、全文検索の仕組み、「どのように曖昧な検索を実現しているのか」といった点に興味を持ったので記事にしようと思いました。

---

まず、Elasticsearchの全文検索を理解する上で前提知識となるText analysisと転置インデックスについて解説します。

# Text analysis
Text analysisは以下の３つの処理から構成されます。文書から単語（token）に変換する処理を指します。
1. Character filter
1. Tokenizer
1. Token Filter

## Character filter
文書全体の前処理を行います。
たとえば、HTMLタグを除外する[HTML strip character filter](https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-htmlstrip-charfilter.html)
、日本語の繰り返し文字（「ゝ」や「々」）を修正する[kuromoji_iteration_mark](https://www.elastic.co/guide/en/elasticsearch/plugins/current/analysis-kuromoji-charfilter.html)などがあります。

## Tokenizer
文書を個々の単語に分割します。文書から分割された単語をtokenと言います。

```tex:Tokenization例
例： 
もとの文章: A full-text search engine!
Tokenizer: [A, full, text, search, engine]
```

Tokenizerには様々な選択肢があります。特に日本語のように単語の切れ目がわかりづらい言語に対しては、[N-gram tokenizer](https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-ngram-tokenizer.html)や形態素解析による[kuromoji_tokenizer](https://www.elastic.co/guide/en/elasticsearch/plugins/current/analysis-kuromoji-tokenizer.html)を用います。

## Token Filter
tokenの加工を行います。
例えばアポストロフィを取り除く[Apostorophe token filter](https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-apostrophe-tokenfilter.html)、tokenを小文字にする[Lowercase token filter](https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-lowercase-tokenfilter.html)、ストップワード（a や theなど、特に意味を持たない単語）を取り除く[Stop token filter](https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-stop-tokenfilter.html#analysis-stop-tokenfilter)などがあります。

# 転置インデックス
転置インデックスをWikipediaで検索すると以下のように記載されています。
> 全文検索を行う対象となる文書群から単語の位置情報を格納するための索引構造をいう

今まで出てきた用語で言い換えると「tokenがどのドキュメントで使われているかを格納するためのインデックス」となります。

例：
次のような、文書をドキュメント登録するとします。

|  id  |  text  |
| ---- | ---- |
|  1  |  Full-text search engine!  |
|  2  |  Car engine |

転置インデックスは以下のようになります。

|  token  |  id  |
| ---- | ---- |
|  full  |  1  |
|  text  |  1 |
|  search |  1 |
|  engine  |  1,2 |
|  car  |  2 |

## 全文検索による検索
上記に説明したText Analysisと転置インデックスの仕組みを用いてElasticsearchは全文検索することができます。
① document登録時：Text Analysisした結果を転置インデックスに格納します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404375/0a4fdc1c-ff58-ece1-730a-d72d358a902e.png)

② 全文検索：文書解析の結果のTokenを転置インデックスで検索します。より多くの転置インデックスにヒットしたdocumentを、より検索にマッチした結果として返却します。（検索とのマッチ度合いはscoreというパラメータで表現されます）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404375/5d687db0-8118-31fc-fb8b-8c3c53fd77c8.png)

# 検索観点での全文検索エンジンの特徴
データストアとしてよく用いられるRDBと比較して、全文検索エンジンの特徴を以下にあげます。

* 曖昧な検索が可能
    * RDBの検索では指定した条件に完全に合致したもののみが返却されます。一方で、全文検索を用いた検索では、一部の検索キーワードに合致したものも返却することができます。
* スコアリング
    * RDBの検索では条件に合致したレコードのリストが返りますが、そのリストの中で優劣はありません。全文検索の場合、「score」により検索条件とのマッチ度合いを表現することができます。

# 参考
- [Elasticseach Guide: Text analysis](https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis.html)
- [Qiita：Elasticsearch analyzerを使う前に把握しておきたい内容まとめ](https://qiita.com/C_HERO/items/094af261db4725b4baa9)
【Jest】プライベート関数のテストとモック化

# プライベート関数のテストとモック化をしよう

単体テストを行う際に、プライベートな関数をテストすることはほとんどありませんが、なにかしら仕様をテストする際など、プライベート関数をテストしたいときがあります。Jestでプライベート関数をテストする方法をまとめていきます。

## babel-plugin-rewireをインストール
はじめにパッケージをインストールします。

```sh:terminal
$ npm install --save-dev babel-plugin-rewire
```
次に```babel.config.js```に、このプラグインを追加します。

```javascript:babel.config.js
module.exports = {
  presets: [["@babel/preset-env", { targets: { node: "current" } }]],
  env: {
    test: {
      plugins: ["babel-plugin-rewire"],
    },
  },
};

```

## 実際にプライベートな関数をテストしてみる

下記のgreeter.jsのexportをしていない、プライベートな```capitalize関数```をモック化とテストします。引数で与えた文字列の１文字目を大文字にして返す関数です。

```javascript:greeter.js
const capitalize = (str) => {
  return str.slice(0, 1).toUpperCase() + str.slice(1, str.length);
};

export const greet = (name) => {
  const capitalizedName = capitalize(name);
  const hour = new Date().getHours();
  const greetMessage = hour >= 6 && hour < 12 ? "Good morning" : "Hello";
  return `${greetMessage} ${capitalizedName}!`;
};
```


```javascript:greeter.test.js
describe("#testing greet function with babel-plugin-rewire", () => {
// capitalizeをモック化
  beforeAll(() => {
    greeter.__set__({
      capitalize: jest.fn().mockImplementation(() => "Foo"),
    });
  });

//前後のテストに影響が出ないようにリセット
  afterAll(() => {
    greeter.__ResetDependency__("capitalize");
  });

// プライベート関数のモック化の確認
  it("return `Hello Foo`", () => {
    expect(greet("foo")).toBe("Hello Foo!");
  });
});

// プライベート関数のテスト
describe("#capitalize", () => {
  const capitalize = greeter.__get__("capitalize");

  it("return string which the first char is capitalized", () => {
    expect(capitalize("hoge")).toBe("Hoge");
  });
});

```

モジュールをインポートした変数に対して、```__get__```を使って、指定した関数を取得することができます。

```javascript
const capitalize = greeter.__get__("capitalize");
```


モジュールをインポートした変数に対して、```__set__```を使って、指定した関数をモック化することができます。下記のコードのでは、capitalize関数をモック化し、文字列のFooを返すように設定しております。

```javascript
greeter.__set__({
      capitalize: jest.fn().mockImplementation(() => "Foo"),
    });
```

前後のテストに影響が出ないようにafterAll()で```__ResetDependency__```を使ってリセットしています。

```javascript
afterAll(() => {
    greeter.__ResetDependency__("capitalize");
  });
```
Unityにアタッチできなくなった時の雑な対処方法

VisualStudioでUnityをデバッグしようと思った時に、アタッチできなくなることがあります。
![2021-10-05_184300.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/8c34f27f-86a4-046b-6719-6e4d261e38bb.png)

そんなときは**Unityを再起動する**とアタッチできるようになるのですが、
もうちょっとだけマシな方法として、

１．デバッグ > Unityデバッガ―のアタッチ　を選択
![2021-10-05_184407.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/a8fb5bc7-cf90-2a0e-6a07-3813db70b09f.png)

２．すると候補が複数現れるのでいずれかを選択
![2021-10-05_184510.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/c245fa12-a206-987c-4d5d-9f67bc016c24.png)

３．赤かったブレークポイントが白くなったら**ハズレ**
![2021-10-05_184554.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/3fb979b1-700c-0a11-afcd-6ca61549bafe.png)

４．その場合はデバッグモードを終了し、他の候補を選択、ブレークポイントが赤ければ**アタリ！** デバッグできます。
![2021-10-05_184643.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/5b3fcee4-1ae4-8a6b-44a6-a093198debec.png)
cloudwatch 標準メトリクス・カスタムメトリクスの違い

## 勉強前イメージ

違いはよくわかってない。。。。

## 調査

### cloudwatch とは

AWSで利用しているリソースの監視を行う機能で、
EC2やRDSの各サービスについて
CPU・トラフィック量などOSより下位のリソースの監視をしています。

### 標準メトリクス

標準メトリクスは使用するサービスによって取得される情報は異なりますが、
基本的なデータを取得することができます。
例えばEC2ではCPU利用率やハードウェアのネットワークのステータス情報が出力されます。

![12021-10-05CloudWatch Management Console - Google Chrome 2021.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/cc6aa1fd-d988-6d29-5174-4764b16c9e7c.png)


### カスタムメトリクス

カスタムメトリクスは、標準メトリクスでは収集されない情報を
PutMetricData API というものを使用してcloudwatchへ書き込むことができます。
例としてはウェブページのロード時間やインスタンスのプロセス数などがあり、
cloudwatchプラグイン集やAWSパートナーからもアプリケーションやツールが出ています。
また、cloudWatchへメトリクスを書き込むプログラムはcloudWatchエージェントとして提供されてます。

メトリクスを分解能1秒までプッシュして保存することができます。
以下2つの種類でできます。

- 標準分解能
	- データの粒度 : 1分
- 高分解能
	- データの粒度 : 1秒

標準分解能も高分解能も
標準のカスタムメトリクスと同様の費用になります。

## 勉強後イメージ

分解能ってあるの知らなかった・・・・
1秒単位で取れるようになるのか
カスタムメトリクスは基本的に標準で取れないものを取るようにスクリプト書いたりするって感じかな

## 参考

- [Amazon CloudWatch よくある質問](https://aws.amazon.com/jp/cloudwatch/faqs/)
- [AWS｜AWSのCloudWatchについてまとめました【解説】](https://dev83.com/aws-cloudwatch/)
Athena「返されたレコードはゼロです(Zero records returned)」が出るケース「マネコンから作成したフォルダ」配下を探索しようとすると出てしまう

Athena超便利で活用しているのですが、あるクエリーをかけると「返されたレコードはゼロです(Zero records returned)」というエラーになりました。

このエラーが出る原因はいろいろありますが、今回は「そのものズバリ」なブログやドキュメントが引っ掛からなかったので、過去の自分のためにも記載します。

結論から言うと「マネージメントコンソールからフォルダを作って、そのフォルダ配下をクエリ対象先に指定しようとしたから」でした。

以降、「マネージメントコンソール」は「マネコン」と略します。

# 返されたレコードはゼロです(Zero records returned) が返るケース

https://aws.amazon.com/jp/premiumsupport/knowledge-center/athena-empty-results/

発生し得る一般的な原因は上記の公式ドキュメントにまとめられています。

そして今回、私が発生させた原因は「意図せず0byteのオブジェクトをクエリ対象としていたから」だと考えています。
0byteのオブジェクトをクエリ対象としてしまったらそれはZero records returned返ってきて当たり前なので上記ドキュメントには載っていません。

# ハマったケース

## 手順
1. xxxというバケット直下にマネコンからtmpというフォルダを作る
2. tmpフォルダの配下にクエリのターゲットとなるオブジェクトを格納する
3. LOCATIONを s3://xxx/tmp/ としたテーブルを作成してクエリをかける

### 期待結果
s3://xxx/tmp/　配下のオブジェクトにスキャンが走る。
### 実際の結果
Zero records returned になる。(スキャン0KB)

### 原因(推測)

S3はキーバリューなので「階層」という概念は本来ないはずですが構造を分かりやすくするため[S3コンソールではグループ化の方法としてフォルダの概念をサポートしています](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/using-folders.html)。

このためマネコンから「フォルダ」を作成することができます。このとき作成されるのは 「フォルダを表現した0byteのオブジェクト」であるという理解を私はしています

このため手順2.では xxxバケット直下に `tmp/` という0byteのオブジェクトができます。

この状態で LOCATIONを s3://xxx/tmp/ と指定すると
「s3://xxx/tmp/」というプレフィックスを指定したつもりが「s3://xxx/tmp/」という0byteのオブジェクトそのものを指定したと解釈され、その0byteのオブジェクトだけスキャンしてZero records returnedになってしまう。

`tmp/target.json` のようなオブジェクトを格納していたとしても、それはスキャンされない。

### 解決方法

マネコンから「フォルダ」を作成しない
たとえば以下のようにcliで直接アップロードする

```
aws s3 cp ./target.json s3://xxx/tmp/target.json
```

このやり方であれば
xxxバケットに `tmp/target.json`  というキーでオブジェクトが作られる
余計な `tmp/` という0byteのオブジェクトは作成されない
クエリをかけたときに `tmp/` といプレフィックスを持つオブジェクト群にスキャンがかかる。

## そもそも何故、マネコンからフォルダ作ったのか

Athenaで分析対象とするようなオブジェクトは普段はプログラムか何かしらのサービスで生成や格納しています。
ただこのときは、手元で編集したファイルで試験的にGlueクローラーやAthenaクエリの挙動を確認するため、マネコンでぽちぽちS3の階層構成を作ってファイルアップロードしました。

厄介だったのはGlueクローラーはこの場合でも配下のファイルを認識して、テーブルを作ってくれたことです。
原因を理解するのにちょっと時間を使ってしまいました :wink:
redashをhelm chartでEKSにデプロイするレシピ(with https化)

# TL; DR
Redash公式のhelmチャートでデプロイする際、https化に躓いたため備忘として残します

# 手順

　1. AWS Load Balancer Controllerをセットアップする.  
https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/aws-load-balancer-controller.html

　2. helm install

```sh
$ helm repo add redash https://getredash.github.io/contrib-helm-chart/
$ helm install redash/redash --values values.yaml
```

```values.yaml
ingress:
  enabled: true
  hosts:
  - host: "redash.example.com"
    paths:
    - /*
  annotations: {
    "kubernetes.io/ingress.class": "alb",
    "alb.ingress.kubernetes.io/certificate-arn": "arn:aws:acm:ap-northeast-1:111111111111:certificate/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", # ACMのARN
    "alb.ingress.kubernetes.io/scheme": "internet-facing",
    "alb.ingress.kubernetes.io/target-type": "ip"
  }
```

　3. Route53の設定

Load Balancer ControllerによってIngressに対応するALBが作成されているので、Route53で `redash.example.com`とこのALBを紐付けるAレコードエイリアスを作成します


以上

---
当初はService LoadBalancerをTLS終端にしようとしていましたが、SAMLログインのリダイレクトURLが `http://~`となってしまう問題に直面しました。
Ingressであればnginx.confをいじる必要もなく、ALBがよしなにしてくれます。
別ファイルのシートを結合してワークブックを作る

```
Sub mk_workbook()
　　Dim myObj As Object
　　Dim myDir As String, myFle As String
　　Dim ws As Worksheet, mb As Workbook, wb As Workbook
　　Set myObj = CreateObject("Shell.Application"). _
　　BrowseForFolder(0, "フォルダを選択してください", 0)
　　If myObj Is Nothing Then Exit Sub
　　If myObj = "デスクトップ" Then
　　　　myDir = CreateObject("WScript.Shell").SpecialFolders("Desktop")
　　Else
　　　　myDir = myObj.Items.Item.Path
　　End If
　　Application.ScreenUpdating = False '画面更新を一時停止
　　Set mb = ThisWorkbook
　　myFle = Dir(myDir & "\*.xls*") 'フォルダ内のExcelブックを検索
　　Do Until myFle = Empty '全て検索
　　　　If myFle <> ThisWorkbook.Name Then 'ブック名がこのブックの名前でなければ
　　　　　　Set wb = Workbooks.Open(myDir & "\" & myFle) 'そのブックを開きwbとする。
　　　　　　wb.Worksheets(1).Copy After:=mb.Sheets(mb.Sheets.Count) '1枚目のシートをコピー
　　　　　　Set ws = mb.Sheets(mb.Sheets.Count)
　　　　　　ws.Name = wb.Name '名前をwbのBook名に
　　　　　　wb.Close (False) 'wbを保存しないで閉じる
　　　　End If
　　　　myFle = Dir 'フォルダ内の次のExcelブックを検索
　　Loop '繰り返す
　　Application.ScreenUpdating = True '画面更新一時停止を解除
End Sub
```

https://oshiete.goo.ne.jp/qa/6487957.html
docker compose up すると `strconv.Atoi: parsing "": invalid syntax` とエラーが出る

# 概要
タイトルの通り、 `docker compose up` しようとすると以下のようにエラーが出ます。

```
strconv.Atoi: parsing "": invalid syntax
```

# 環境
- macOS Big Sur 11.6
- Mac mini (M1, 2020)
- Docker Engine 20.10.5
- Docker Compose 1.29.0

# 解決
compose のリポジトリに同じような現象に遭っている [issue](https://github.com/docker/compose-cli/issues/1537) が見つかりました。

コンテナの起動中などに Ctrl+C 等で強制停止すると発生するようです。
というわけで、とりあえず `docker compose down` したところ、解決しました。

単純な問題でしたが、 gg って出る情報が少なかったため、ここに残しておきます。
Uipath 引数の値が設定されない　（例外発生時）



Mainからinvoke workflowfileする際に、呼び出し先から値を受け取りたい。

引数をout　にて設定し、ワークフローの中で値をセットした。

その後何らかの条件でthrow または terminate worklow を発生させる。

すると、Mainに戻った際にoutの引数の中の値が設定されない。

つまり、例外が発生すると引数で値を返すことができない。
全シートをpdf化するマクロ

ファイル出力印刷にせよF12からの指定保存にせよ全シートの印刷が地味に面倒なのでマクロ化した

バージョン管理用にファイル末尾に▲nを付与するようにしてある。((n)だと区切りが面倒なので)



`Sub PDF化(Optional ByRef myButton As IRibbonControl)`
にある引数はアドイン化の際にリボンから起動したとき用だが`Optional`をつけてあるので単独で実行しても良い

### コード 標準モジュール
``` vb
Option Explicit

Sub PDF化(Optional ByRef myButton As IRibbonControl)
  On Error GoTo Err
  With ActiveWorkbook
    Dim wbPath: wbPath = .path
    Dim wbName: wbName = .Name
    
    Dim pdfPath
    pdfPath = wbPath & "\" & 拡張子変換(wbName, "pdf")
    
    Do Until ファイル存在確認(pdfPath) = False
      pdfPath = 追番付与(pdfPath)
    Loop
        
      .ExportAsFixedFormat Type:=xlTypePDF, _
          Filename:=pdfPath, Quality:=xlQualityStandard, _
          IncludeDocProperties:=True, IgnorePrintAreas:=False, _
          OpenAfterPublish:=True
  End With
Err:
  Select Case Err.Number
    Case Is = 1004: MsgBox "ブックを保存後実行してください。"
  End Select
End Sub

Private Function 追番付与(TargetPath)
  Dim buf1, ub, buf2
  buf1 = Split(TargetPath, ".")
  ub = UBound(buf1)
  
  buf2 = buf1(ub - 1)
  If InStr(buf2, "▲") = 0 Then   'すでに▲があるか否かで分岐
    buf2 = buf2 & "▲1"           'なければ▲1を付与
  Else
    buf2 = Split(buf2, "▲")      'あるなら▲までで区切ってその後をインクリメントする
    buf2(1) = buf2(1) + 1
    buf2 = Join(buf2, "▲")       '分割したものを戻す
  End If
  
  buf1(ub - 1) = buf2             '拡張子以前を元の形にまとめ直す
  追番付与 = Join(buf1, ".")      '分割したものを戻す
End Function

Private Function 拡張子変換(Target, 指定拡張子)
  Dim buf, ub
  buf = Split(Target, ".")
  ub = UBound(buf)
  buf(ub) = 指定拡張子
  拡張子変換 = Join(buf, ".")
End Function

Private Function ファイル存在確認(TargetPath) As Boolean
  Dim flg As Boolean
  If Dir(TargetPath) <> "" Then
    flg = True
  Else
    flg = False
  End If
  ファイル存在確認 = flg
End Function



```
CFnでCloudWatch Alarm書く時に知っておきたいパラメータ

# 背景
CloudFormationでCloudWatchAlarmを作成するために公式ドキュメント見ていて、一瞬よくわからなかったパラメータや、地味に使いそうなパラメータがあったので備忘録的にまとめます。

# パラメータ
###1. EvaluationPeriods と DatapointsToAlarm
・`EvaluationPeriods`：閾値を超えたかどうかを評価する直近の評価期間
・`DatapointsToAlarm`：アラームを発生させるデータポイント数

評価期間中、（`EvaluationPeriods` - `DatapointsToAlarm`）回は閾値を超えてもアラームは発生しない。

**例えば…**

```
EvaluationPeriods: 5
DatapointsToAlarm: 3
```
このようにCFnで設定した場合、直近の評価するデータポイント5個中、3回以上閾値超えるとアラーム発生することになります。

```
データポイント（右から直近） ： 結果
○○x○x 　　　　　　　　　　　         → OK
○x○xx 　　　         　　　　　　　　→ Alarm
```
ちなみに、`DatapointsToAlarm`を書かなかった場合は自動的に、

```
DatapointsToAlarm　=　{EvaluationPeriodsで設定した値}
```
となるみたいです。（つまり、一回でも閾値超えるとAlarm発生）

###2. TreatMissingData
CloudWatch Alarmで評価したいデータが取得できず欠落データになる場合があります。（アラームで監視する対象のサーバがダウンしたり、通信障害が発生した時など）
欠落データでは閾値を超えたかどうか判定できません。
そんな時アラームを出すかどうかを判断するパラメータです。

**設定可能な値**
・`notBreaching`：欠落データは「良好」と判断される
・`breaching`：欠落データは「不良」とされる
・`ignore`：現在のアラーム状態が維持される
・`missing`:評価期間内にデータポイントが一つもない場合、アラームは`INSUFFICIENT_DATA（データ数不足）`に移行する

`INSUFFICIENT_DATA`はアラーム状態ではないので、この状態に移行しても通知を飛ばしてくれません。

**`TreatMissingData`はCFnで必須のパラメータではありませんが、書かないと自動的に`'missing'`設定となりデータ欠落時にすぐSNS等に通知してくれないので、できるだけ以下のように書いた方が良いと個人的には思います。**

```
TreatMissingData: breaching
```



###3. OKActions
CloudWatch Alarm設定するということは、アラーム発生時にSNS等に通知したいことが多いはずなので`AlarmActions `は記述することは多いと思います。
一方、見落としがちなのが`OKActions`です。
これは**Alarm状態からOK状態に遷移した時**に通知する通知先を設定するパラメータです。
CFnでは必須のパラメータではありませんが、運用的にこっちも書いておいた方が何かと便利そうです。

例↓

```
AlarmActions:
  - <SNSトピックのARN>
OKActions
  - <SNSトピックのARN>
```

# 最後に
何か間違っていること等あればコメントいただけると幸いです…！

[参考1：CloudWatchアラームのCloudFormation](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-cw-alarm.html)
[参考2：CloudWatchアラーム欠落データの取扱い](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html)
GPUに制限があるサーバー(CentOS)にparaviewをインストールして，ローカルPCからリモートで接続する

# はじめに
paraviewを可視化ツールとして使っている人は多いと思いますが，クラスターマシンによっては積んでいるGPUが古く，paraviewをそのままインストールしても動かないということがあります．

この記事では，[OSMesa](https://docs.mesa3d.org/osmesa.html)と呼ばれるCPUで動くレンダリングライブラリと"pvserver"を用いることで，GPUに制限のあるサーバー環境でもparaviewを動かせるようにします．

qiitaではビルドから行ってカスタマイズしている[先駆者様](https://qiita.com/nqomorita/items/788ae28b444390229536)もいますが，今は公式側がGUIがないバージョンも用意してくれているため，そんなに難しいことはしません（バイナリをコピペするだけ）．

さらに，paraviewのClient/Serverモードを使うことで，X転送を行わなくても遠隔で操作できるようにします．これに関しては，こちらの[個人の方のサイト](https://kurenaif.hatenablog.com/entry/2018/01/09/155607)を参考にさせていただきました．

# 前提
- ローカルPCとサーバーはsshでアクセスできること．
- サーバーのスーパーユーザーであること．

# 目次
<!-- タイトルとアンカー名を編集 -->
1. [サーバー用のparaviewのインストール](#Chapter1)
1. [サーバー側の設定](#Chapter2)
1. [ローカルPCの設定](#Chapter3)
1. [接続先が外部サーバーの場合](#Chapter4)

<!-- 各チャプター -->
<a id="#Chapter1"></a>
# サーバー用のparaviewのインストール
最初にparaviewを[公式](https://www.paraview.org/download/)から落としてきますが，必ず下のスクショのように"osmesa"と書かれたものを落としてください．
![スクリーンショット 2021-09-24 18.41.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035656/d0c23115-1f70-0648-8595-c64bdef864db.png)


<a id="#Chapter2"></a>
# サーバー側の設定
tar.gzファイルをサーバー先で展開し，<your paraview>/bin/*を/usr/local/binにコピーします．

~~~bash
tar -zxvf <your paraview>.tar.gz
#インストールする物の中身を確認
cd <your paraview>/bin
cd ..
sudo cp -rf <your paraview>/bin/* /usr/local/bin
~~~

同様に，lib,shareの中身も/usr/local/lib, /usr/local/shareにコピーします．

~~~bash
cd <your paraview>/lib
cd ..
sudo cp -rf <your paraview>/lib/* /usr/local/lib
cd <your paraview>/share
cd ..
sudo cp -rf <your paraview>/share/* /usr/local/share
~~~

端末を再起動して,以下のコマンドを打つことで，下のような待機状態になれば成功です．
"12345"の部分は，最初が1の，好きな５桁の数字を入れてください．

~~~
 pvserver --use-offscreen-rendering --server-port=12345
~~~

~~~
Waiting for client...
Connection URL: cs://<マシン名>:12345
Accepting connection(s): <マシン名>:12345
Client connected.
~~~

<a id="#reference"></a>
# ローカルPCの設定
次に，ローカルPC側の設定を行います．

設定の前に，リモート先のマシン名がローカルPCに登録されているか確認してください．

~~~
sudo vim /etc/hosts
~~~

なければ，リモート先で名前を確認した後，

~~~
hostname
~~~

ローカルPCに登録してください．

~~~bash:/etc/hosts
<リモート先のIPアドレス> <リモート先のマシン名>
~~~


まず，***"サーバー用のparaviewのインストール"で落としてきたバージョンと同じバージョンのparaview***を落としてきます．

また，***こちらは普通のGUI付きのもの***を選びます．

普通にインストール＆起動した後，左上ののボタンを押します．
![スクリーンショット 2021-10-05 18.01.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035656/477fd33e-5a59-9727-ec75-41e170fe78a3.png)

"Add Server"をクリックし、Name（任意）、Server Type（Client / Server）、Host（サーバ名）、Port（先程設定したポート番号…12345など）を指定し、Configure後Saveします．


最後に，"connect"を押して１０秒ほど待ち，左上の"built-in"が"リモート先のマシン名"になったら接続成功です．

<a id="#Chapter4"></a>
# 接続先が外部のサーバーの場合

以上の操作は，サーバーとローカルのPCがローカルネットワークである場合に動きます．
外部ネットワークののサーバーと繋ぐ場合は，ートフォワーディングを使うため，やや面倒です．

1 サーバー側のルーターの設定で，ポートの開放をする．(上記例に従うと12345)

2 以下のようなssh接続コマンドを用いてサーバーに接続(ローカルフォワード，[参考](https://qiita.com/mechamogera/items/b1bb9130273deb9426f5))


~~~
ssh -L 12345:<サーバ名>:12345 <ユーザー名>@<リモート先のマシン名>
~~~

3 paraviewを起動して同様に接続
Node.js: MQTT クライアントのサンプル

こちらで定めた仕様を満たすクライアントです。
[IOT: MQTT クライアントのサンプル](https://qiita.com/ekzemplaro/items/949fea7247b90bf531aa)

Raspberry Pi で確認しました。
>GPIO16 に接続した LED を ON/OFF します。

プログラム

```js:subscribe.js
#! /usr/local/bin/node
// ---------------------------------------------------------------
//	subscribe.js
//
//					Oct/05/2021
//
// ---------------------------------------------------------------
'use strict'

console.error ("*** 開始 ***")
var mqtt = require('mqtt')
const client  = mqtt.connect('mqtt://example.com')
const topic = 'example/test01'

var Gpio = require('onoff').Gpio
var led = new Gpio(16, 'out')

// ---------------------------------------------------------------
client.on('connect', function () {
	client.subscribe(topic)
})

// ---------------------------------------------------------------
client.on('message', function (topic, message) {
	const json_str = message.toString()
	const dict_aa = JSON.parse (json_str)

	if ('desired' in dict_aa['state'])
		{
		const desired = dict_aa['state']['desired']
		led_proc(desired)
		}
})

// ---------------------------------------------------------------
function led_proc(desired)
{
	console.log(desired)
	console.log(desired['led'])
	const on_off = desired['led']

	if (on_off == "on")
		{
		led.writeSync(1)
		}
	else if (on_off == "off")
		{
		led.writeSync(0)
		}

	report_proc(on_off)
}

// ---------------------------------------------------------------
function report_proc(on_off)
{
	var dict_aa = new Object ()
	dict_aa["state"] = new Object ()
	dict_aa["state"]["reported"] = new Object()
	dict_aa["state"]["reported"]["led"] = on_off
	const json_str = JSON.stringify(dict_aa) 
	console.log(json_str)
	console.log()
	client.publish(topic, json_str)
}

// ---------------------------------------------------------------
```

実行スクリプト

```bash
export NODE_PATH=/usr/local/lib/node_modules
./subscribe.js
```

次のパージョンで確認しました。

```text
$ node -v
v14.17.6
```
[Ruby] AtCoder過去問 B - String Rotation

##はじめに
AtCoder過去問B問題をRubyで解いてみました。
よろしくお願いします。

問題はこちらから確認してください

https://atcoder.jp/contests/abc103/tasks/abc103_b

##B - String Rotation
まずは入力を受け取ります。また答えとなる変数ansに```No```を代入しておきます。
sとtは一文字ずつを一つの要素とした配列として受け取っています。

```ruby
s = gets.chomp.chars
t = gets.chomp.chars
ans = "No"
```

この問題の回転というのがよくわからなかったのですが、一文字ずつずらしていけば、、、っという意味ですね。
つまり、一回の操作は一番最後の文字を先頭に持ってくるということです。
上記の操作をコードにすると下記のようになります。

```ruby
s.unshift(s[s.length-1])
s.delete_at(s.length-1)
```

unshiftというメソッドを使用して引数に配列sの末尾の文字を先頭に挿入しています。
このメソッドは引数で指定した要素を削除しているわけではないので、delete_atメソッドで末尾を削除します。

上記のコードを利用してtimesメソッドとif文を作成します。

```ruby
s = gets.chomp.chars
t = gets.chomp.chars
ans = "No"

s.length.times do
  if s == t
    ans = "Yes"
    break
  else
    s.unshift(s[s.length-1])
    s.delete_at(s.length-1)
  end
end

puts ans
```

配列sの文字数回timesメソッドで繰り返します。
もし配列sとtが同じになればansの中身をYesに上書きします。同じでなかったら一文字ずらして、比較を繰り返します。

s.length分繰り返してもs==tにならなければansは上書きされていないのでNoが出力されます。
【Python】for文でリスト繰り返し処理

Pythonのリスト繰り返し処理は二種類あるので、簡単にメモします。
### 自分の定義したリストです
```python
db_names = ['MySQL', 'PostgreSQL', 'SQLite', 'MariaDB']
```

### 1. for文とin文で繰り返し処理
```python
for db_name in db_names:
    print(db_name)
"""
結果:
MySQL
PostgreSQL
SQLite
MariaDB
"""
```

### 2. for文とindexで繰り返し処理
説明: リストの長さは4で、rangeは**最後の数字-1**までを含めるから、
db_names[0]、db_names[1]、db_names[2]、db_names[3]がアクセスされます。

```python
for i in range(len(db_names)):
    print(db_names[i])

"""
結果:
MySQL
PostgreSQL
SQLite
MariaDB
"""
```

以上、好きな方を使いましょう。
久々にcocoapodsでpod initしたらエラーなった


久々にプロジェクト立ち上げて、pod initしたらエラー出た

# どんなエラー出た

こんなの

```
### Error
RuntimeError - [Xcodeproj] Unknown object version.
/Library/Ruby/Gems/2.6.0/gems/xcodeproj-1.19.0/lib/xcodeproj/project.rb:227:in `initialize_from_file'
/Library/Ruby/Gems/2.6.0/gems/xcodeproj-1.19.0/lib/xcodeproj/project.rb:112:in `open'
/Library/Ruby/Gems/2.6.0/gems/cocoapods-1.10.0/lib/cocoapods/command/init.rb:41:in `validate!'
/Library/Ruby/Gems/2.6.0/gems/claide-1.0.3/lib/claide/command.rb:333:in `run'
/Library/Ruby/Gems/2.6.0/gems/cocoapods-1.10.0/lib/cocoapods/command.rb:52:in `run'
/Library/Ruby/Gems/2.6.0/gems/cocoapods-1.10.0/bin/pod:55:in `<top (required)>'
/usr/local/bin/pod:23:in `load'
/usr/local/bin/pod:23:in `<main>'
```

# どうやって解決した
xcodeprojのバージョン古そうなので取り敢えずアップデートした

```
% sudo gem update xcodeproj
```

これで解決した。

#　備考
あとついでに、cocoapodsのバージョンも上げといた

```
% sudo gem update -n /usr/local/bin cocoapods
```
FirebaseとSSSAPIでプレスリリースを送ったサイトを記録できるWebサービスを作ってみた 

開発しているGoogleスプレッドシートのAPI化サービス「[SSSAPI](https://sssapi.app)」をβ版リリースしたときに、
プレスリリースをいろんなメディアに送ってみてた。

せっかく調べてまとめたし、次も使う機会があるだろうと思ったので、
Nuxt/Firebase/SSSAPIの構成でWebサービス化してみた。

プレスリリースを受け付けてるサイトを調べるのは大変なので、
どこに送れるのかな〜と思った方は使ってみてもらえるとうれしいです(*´ω｀*)

### 作ったサービス

https://press-done.memory-lovers.com

送付するプレスリリースごとに、どのサイトへ送ったかの状態管理ができます。
それだけのシンプルなWebサービス。

![スクリーンショット 2021-10-04 23.35.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/b52d95a8-788f-5625-c536-4ecd6cc147b5.png)


### システム構成

基本構成はこんな感じ。

- フロントエンド: Nuxt+Buefy
- 認証: Firebase Authentication
- ユーザデータ: Firestore
- マスターデータ: [SSSAPI](https://sssapi.app)

![スクリーンショット 2021-10-04 23.40.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/d9f069c4-7d32-5ea8-aea5-91300fea7030.png)


ユーザが更新しないマスターデータはSSSAPIを利用している感じ。

メディアサイトのデータをFirestoreに入れておく形もあるけど、
Firebaseコンソールで追加や編集するより、
スプレッドシートを更新するほうが楽なので、この形にしている。

スプレッドシートの中身はこんな感じ。

![スクリーンショット 2021-10-04 23.43.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/e130e233-915d-e105-0e75-48249f002a13.png)


SSSAPIはこんなJSONを返してくれる。

```json
[
  {
    "id": 1,
    "サイト名": "TechCrunch Japan",
    "サイトURL": "https://jp.techcrunch.com",
    "送付方法": "メール",
    "isActive": true
  },
  {
    "id": 2,
    "サイト名": "日経クロステック",
    "サイトURL": "https://xtech.nikkei.com",
    "送付方法": "メール",
    "isActive": true
  },
  {
    "id": 3,
    "サイト名": "ITmedia",
    "サイトURL": "https://www.itmedia.co.jp/",
    "送付方法": "メール",
    "isActive": true
  },
]
```

※「行数をIDとして追加」オプションを使ってるので、idが自動で付与されています。

このスプレッドシートは登録依頼のGoogleフォームと連動しているので、
追加依頼があったら内容を確認して`isActive`を`true`にすれば反映されます。

![スクリーンショット 2021-10-04 23.56.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/39ce3a05-cd7b-2ed8-81e1-af76025e6175.png)

こういった構成は割と多く、本の貸し出し管理と備品管理とかでも使える。
Webサービスからスプレッドシートを編集できないので、
管理者権限とか不要なので、その分フロント側も楽に作れた(*´ω｀*)

プレスリリースってどこに送れるのかな〜と思った方は、
ぜひ使ってみてもらえるとうれしいです(*´ω｀*)

https://press-done.memory-lovers.com

### SSSAPIはβ版ユーザを募集しています!!

β期間中はプレミアムプランの内容を無料で使えるのでお得！
ぜひぜひ、この機会にお試しいただければ！

わからないところやこんなのあったらいいなぁ〜などあれば、
Twitterやお問い合わせなどからお気軽にご連絡ください〜

GoogleスプレッドシートのAPI化サービス
『[SSSAPI](https://sssapi.app)』
Twitter: [@sssapi_app](https://twitter.com/sssapi_app)

https://sssapi.app

開発の励みや記事を書くモチベにもなるので、
いいねやシェア、はてブなどしてもらえるとかなりよろこびます!!
TensorFlowでGPUを使えるようにする(Linux編）

# 検証環境
OS | GPU
--- | ---
Ubuntu20.04(x86_64 | Quadro M4000

Linuxなら大体同じ方法で大丈夫と思います

# ステップ

1. ドライバのインストール
2. cuDNNのインストール
3. Cuda Toolkitのインストール

## GPUの確認
```bash:GPUの確認
lspci  | grep NVIDIA
# 1:00.0 VGA compatible controller: NVIDIA Corporation TU106 [GeForce RTX 2060 SUPER] (rev a1)
```

## CPUアーキテクチャの確認

```bash:CPUアーキテクチャの確認
uname -p
```

## OSディストリビューションの確認

```bash:OSディストリビューションの確認
lsb_release -d
```

## ドライバインストール
aptから取得できますが、バージョンが複数あります。
```bash:バージョンが複数ある
 apt-cache search nvidia | grep nvidia-driver | grep -v server
```

まず対応するバージョンを[ここ](https://www.nvidia.com/download/index.aspx?lang=en-us#)で確認
インストールするマシンのOSやGPUの種類をを選んで[Search]を押してください

ここでダウンロードできる.runファイルを実行してもいいらしいですが自分はaptでやりました

今回はバージョン470なので

```bash:バージョン470インストール
apt-get install nvidia-driver-470
```

## aptでドライバが見つからない場合
[ここ](https://www.nvidia.com/download/index.aspx?lang=en-us#)からダウンロードした.runファイルを実行してインストールできる。
novelu-kernelのエラーが出る場合は指示に従ってinitramfsを更新後再起動して再度実行する

```bash:initramfsを更新
sudo update-initramfs -u
reboot
```


## CUDA Toolkitのインストール
https://developer.nvidia.com/cuda-downloads?target_os=Linux&target_arch=x86_64&Distribution=Ubuntu&target_version=20.04&target_type=deb_local

ここの指示にしたがってレポジトリ追加してapt-getしてください

```bash:CUDA Toolkitのインストール
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/cuda-ubuntu2004.pin
sudo mv cuda-ubuntu2004.pin /etc/apt/preferences.d/cuda-repository-pin-600
wget https://developer.download.nvidia.com/compute/cuda/11.4.2/local_installers/cuda-repo-ubuntu2004-11-4-local_11.4.2-470.57.02-1_amd64.deb
sudo dpkg -i cuda-repo-ubuntu2004-11-4-local_11.4.2-470.57.02-1_amd64.deb
sudo apt-key add /var/cuda-repo-ubuntu2004-11-4-local/7fa2af80.pub
sudo apt-get update
sudo apt-get -y install cuda
```

## cuDNNのインストール
https://developer.nvidia.com/rdp/cudnn-download

runtime libraryを選びました
.debか.tarで選べるみたいですが.tarの方にしました

```bash:cuDNNのインストール
tar xvf cudnn-11.4-linux-x64-v8.2.4.15.tgz
sudo cp cuda/include/cudnn*.h /usr/local/cuda/include 
sudo cp -P cuda/lib64/libcudnn* /usr/local/cuda/lib64 
sudo chmod a+r /usr/local/cuda/include/cudnn*.h /usr/local/cuda/lib64/libcudnn*
```

あとはパスを通してください

```bash:パスを通す
export LD_LIBRARY_PATH=/usr/local/cuda/lib64:${LD_LIBRARY_PATH}
```

# インストール後にGUIで起動するようになってしまう問題
CUI環境でNVIDIAドライバをインストールすると、自動的にXがインストールされGUIで起動するようになってしまいます。
自分はUbuntu Serverを使っており常時稼働させており、デフォルトで20分経過後にサスペンドされてしまい大変不便でした。
以下CUIブートへの切り替え手順です。

```bash:CUIブートへの切り替え
systemctl get-default 
grapycal.target #GUIで起動する状態

#CUIで起動するように変更
systemctl set-default multi-user
```
IBM Cloudの新マスタリー試験IBM Cloud Satellite Specialty v1を受けてみた

# IBM Cloud Satellite Specialty v1とは

IBMのマスタリー試験（特定製品スペシャリストの適格認定試験）の1つで、つい最近受験可能になりました。

<img width="160" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/66c2415f-17bd-f410-ee87-94e560685ad4.png">

試験の概要はこちらです。

> https://www.ibm.com/certify/specialty?id=S2000-013

# 学習方法

難易度は高めです。実務経験なしでの合格はかなり難しいと思います。専門家の認定試験なので当たり前といえば当たり前ですが。

公式のラーニングパスは下記サイトですが、残念ながらほとんどのコンテンツがComing Soonです。私はぶっつけ本番で受けに行きました。

> https://www.ibm.com/training/path/ibmcloudsatellite

# 受験方法

いつものようにPeasronVUEで予約して受験となります。マスタリー試験はいつもの認定試験とは異なるカテゴリにありますのでご注意ください。``S2000-013: IBM Cloud Satellite Specialty v1``が該当の試験です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/971ac73a-422c-2c96-aff4-c4497a6605d9.png)

# 合格点

41問中27問以上の正解で合格です。正答率は65%です。私は本当にぎりぎりで合格しました。

# 出題内容

試験規約により具体的な内容は書けませんが、細かい問いも多かったので、IBM Cloud Satelliteのドキュメントは全て目を通すのがいいでしょう。

> https://cloud.ibm.com/docs/satellite?topic=satellite-getting-started

雰囲気ですが、次の内容は理解しておくといいかもしれません。まあ、個別サービスに限定した試験なので、範囲は広くはありません。むしろ全部です・・・。

* IBM Cloud Satelliteの価値
* ホスト要件
* ロギング、モニタリング
* Satellite Link
* Config、Subscription
* アプリデプロイ
* バージョンアップ

# 感想

IBM Cloud Satellite自体、東京リージョンで使えるようになったのはつい最近ですし、ラーニングコンテンツもまだ揃っていないので、もう少し熟してから受験するのがよいでしょう（私は少々焦り過ぎました）。
PowerAutomateDesktopを用いてexcelの表まとめの自動化までのメモ　その5

エクセルの読み込みのアクションでは**インスタンスが表示されない**ので
どうしてだろうとウンウン唸っていました。

結構同じミスをしてしまうので自戒のためメモ失礼いたします。
SIGVerseチュートリアル

# SIGVerseセットアップ
## Handyman
- Unityインストール
    - Ver_2020.3.14
    - ダウンロード手順
    - http://www.sigverse.org/wiki/jp/index.php?Tutorial%20for%20ver.3
    - 環境構築→Unityのインストール
- ROSパッケージ
    - 下の手順通り
    - https://github.com/RoboCupatHomeSim/handyman-ros#how-to-install
- 共通パッケージのダウンロード
    - 下の手順通り
    - https://github.com/RoboCupatHomeSim/common-unity
- Unityビルド
    - 基本的には下の手順通り
    - https://github.com/RoboCupatHomeSim/handyman-unity#how-to-set-up
    - Buildする前にユーザー登録を行う（仮）
僕が面接で意識したポイント【就活】

# はじめに

こんにちは、坂内太一と申します。
プロフィールにも書いてあるようにこのたび東京の渋谷駅近くのIT企業から内定をいただくことができました。
このアカウントは元々、エンジニア就活のために作ったものなのですがこれからは僕自身がIT業界でプログラミング等を学んでいく中でなるほどと思った点やためになると感じた点を記事にしていこうと思います。

そんな中で今回はタイトルにもあるようにエンジニア面接のポイントを僕が人から教えてもらったり、僕自身で実際に大切だと感じた点を中心にまとめてみました。
エンジニア以外の面接でも役立つ点がたくさんあるのでこれから就活を控えている人や現在就活に悩んでいる人にも参考になる内容になっているかと思います。
最後まで読んでもらえたら嬉しいです。


# 自己紹介

まずは僕の簡単な自己紹介をしていこうと思います。
僕は新潟県の文系私立大学に通う大学４年生です。大学では野球部で部長をしていて趣味はファッション、特技がカードゲームのごくごく一般的な大学生です。
文系大学の為、IT業界やプログラミングに関しての学習は全て独学で行なっています。
また、エンジニア就活をするにあたって必要なポートフォリオはRuby on Railsを使って制作しました。
以上が僕の簡単な自己紹介になります。


#この記事を書こうと思った経緯

本題に入る前に僕がこの記事を書こうと思った経緯についてです。
この記事を書こうと思った動機は僕が実際に面接を重ねていく中で後からこうしておけばよかったと感じる部分がたくさんあり、そのような点を少しでも多くの人に知ってもらいたいと思ったからです。
内容は最初にも述べた通り、エンジニアならではというものはほとんどありませんが僕がエンジニア就活をやってきて特に重要だと思ったことばかりなので是非読んでみてください。


#僕が面接で意識したこと


### 1. ピクチャートークを心掛ける

僕が面接で意識したことの1つ目はピクチャートークです。
ピクチャートークとは相手の頭の中に絵が浮かぶように話をすることを指します。これは主に営業などで使われており、相手に話の内容をしっかりとイメージさせることで納得してもらいやすくなる効果があります。
下記が具体的にピクチャートークを使った時と使わなかった時の例です。

*ピクチャートークを使っていない*
>今日はお客さんが多かった

*ピクチャートークを使っている*
>今日の来客数は300人で、いつもよりも3割ほど多かった

少し極端な例にはなりましたがこのように具体的な数字や状況を交えて話すことで面接官はその学生の自己PRなどの話したことを頭の中でイメージしやすくなります。
ではそもそもなぜ面接においてピクチャートークが重要なのかについてです。
面接において面接官は学生の自己PRを聞いてその学生の能力や会社に入ってから活躍することができるか等を推測します。つまり面接でピクチャートークを意識することは面接官に対して自分自身の魅力をしっかりと伝えることにつながります。
そしてこれらのピクチャートークに加え、自分なりに工夫した点や問題意識を交えてただ事実の羅列にならないように話すことも重要です。
最後に基本的なことにはなりますが話は要点を交えて結論から話すように心掛けましょう。


### 2. 見た目が第一

見た目が第一というと顔などの容姿についてと思われがちですがここではそのような意味ではありません。
皆さんはメラビアンの法則を知っていますか？
メラビアンの法則はカリフォルニア大学ロサンゼルス校の心理学名誉教授であったアルバート・メラビアンによって発表されたもので話し手が聞き手に与える影響の割合を数値化したものです。
そしてその割合を示したのが下記のグラフになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247999/85c47c44-932b-fbc3-43ae-fc8d7c96c73e.png)
https://motivation-up.com/motivation/images/merabian01.gif

グラフを見ると視覚情報と聴覚情報が大部分を占めているのがわかります。つまりこれは面接で面接官に影響を与える要素として視覚情報と聴覚情報などの見た目の部分が多くを占めており、自己PRなどの言語情報は面接官にそこまで影響を与えることはありません。

皆さんの中には面接の際に自己PR等を噛むことなくハキハキと喋ることを重要視していた人も多いかと思います。しかしメラビアンの法則が示すように面接で多少噛んだところで結果にほとんど影響はありません。ですので面接では噛まないことを意識して硬い表情で話すのではなく、学校の仲の良い先輩と話す時のように笑顔で元気よく話をすることの方がはるかに重要です。

最後に補足ですがここでの話は自己分析や自己PRがきちんとできている前提で話をしているので面接の内容を濃くしていくためにも自己分析等の準備は今まで通りきちんと行うようにしましょう。


### 3. 継続力をアピール

ここの項目はWEBエンジニアにとって特に重要です。
IT業界では常に技術が進化し続けていて、それについていくためにも常に新しいことを学び続けなくてはなりません。そのような背景から面接官は常に新しい技術を学んでいくことのできる継続力があるかをとても重要視しています。
継続力があることをアピールする方法として部活動やバイトなどの長く続けてきたことを話すことが一般的になりますがエンジニアはその他にも

* GitHubへのコミットを毎日行う
* QiitaやTwitterに学習内容を高い頻度で投稿する

などでアピールをすることが可能です。
これらを行うことによって面接官にこの学生は継続して学習をしていて入社してからも学習を続けていくことができると思ってもらえます。僕自身はプログラミングに関しての学習は行ってはいたものの、GitHubへのコミットや投稿などが疎かになっており、就活をした中での反省点だと感じています。
繰り返しにはなりますがWEBエンジニアにとって継続力をアピールすることはとても重要なことなので皆さんもぜひ意識して取り組んでみてください。



#まとめ

今回は僕がエンジニア就活における面接で実際に心掛けていたポイントをまとめてみました。
皆さんがエンジニア就活をする上で少しでも参考になれば幸いです。
次回はエンジニア面接で実際に聞かれた質問内容をまとめていこうと思うので気になる方はフォローの方もよろしくお願いします。
最後まで読んでくださりありがとうございました。

#参考文献


ポイントは3つ！今日からできる「説明上手」になるためのコツ
https://lab.pasona.co.jp/haken-basic/skill/79/

メラビアンの法則
https://motivation-up.com/motivation/merabian.html
UnityをGPUインスタンスで動かす時に苦労した人へのメモ

# UnityをGPUインスタンスで動かす時nvidia driverの選択には気をつけろ

可なり稀なケースかもしれないですが、AWSのGPUインスタンスを積んだインスタンスを使ってUnityを動かしたいと思った時に苦労した話と簡単なTipsを備忘録として残します。
cloudXRなどの実現のために困っている方は使えるかもしれないです。
特にNvidia driverをAWSの手順通り入れようとして困った方には役に立つかと思います。
あと調べると意外とAWSのインスタンス上でUnity動かす話は出てこないので、役に立てば幸いです。
## 対象
Unityのことはわかるけどインフラ周りなどAWSはわからんの人

## 結論
windows serverで動かすなら、公式AMIsを使った方がいい。
https://aws.amazon.com/marketplace/pp/prodview-xrrke4dwueqv6
Ubuntuで動かすなら公式AMIsはおすすめできない。
こちらでインスタンスを立てて、UnityをDLするのが現状おすすめ。
どうしてもの方は「NVIDIA ゲームドライバー」を使っていれてみてください。
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/WindowsGuide/install-nvidia-driver.html

ubuntuは検証中（後日追記します）

## やりたかったこと
OS縛りなしでGPUインスタンス(G4dn)上でUnityEditorの起動

## 躓いたこと
### Amazon linux2で動かそうとした
結果…失敗
MateによりリモートDesktop環境を構築してUnityをDLするところまでは行ったが、
Unityがクラッシュを繰り返す。
原因として考えられるのはUnityがOSに対応していない可能性（ベースがCentOSなので行けるかと思ったが無理でした）

### Ubuntu で動かそうとした
結果…ドライバーを間違えると処理が遅くなる。
awsの提供しているNividaドライバーには3種類のものがある
・Tesla ドライバー
・GRID ドライバー
・ゲームドライバー
どれでも公式ドライバーなのだから問題なく動くのだが、
3Dグラフィックを用いる場合には問題なく動いているように見えて、パフォーマンスを最大限発揮できないということがあるので、この選択は注意
G4dnのインスタンススペックは以下のような値
・OS:Ubuntu20
・CPU:  Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz ×4
・RAM:16GB
・GPU:Tesla T4 

初めTeslaドライバーを入れて動かそうとしたが、
エラーなどで落ちることなくUnity自体は動く。
ただし処理が異様に遅くなる。
Mateなどの関係によるものかと考えたがそうではなく単純に処理できていないといった様子で、
CPU使用率が常にフルのような状態になる。
cubeを置いた初期プロジェクトでfps値は1661ms
次にGRIDドライバーを入れて動かしたがこれもTelaドライバーと同じような結果になる。


### Windows serverで動かそうとした
Ubuntuと同じくTeslaドライバーで動かそうとしたが、Ubuntuで同様にfpsが以上に低いため動かない。
GRIDドライバーではまだ検証できていない。

### 公式AMIsで試した
公式AMIsを用いてインスタンスを立てれば問題ないかと思い、
Ubuntuの方のAMIsを使用したが
ただしこれは、VNCのタスクがキルされてるよくわからないエラーによって阻まれた。
下記にVNCが構成できないみたいコメントを見かけたのでいったん保留
https://aws.amazon.com/marketplace/pp/prodview-p64lyuknl2pys

windowsserverのNividia公式AMIsのみが快適にUnityを使うことが出来た。
AWS認定セキュリティスペシャリティ(AWS Certified Security - Specialty) 合格体験記


## はじめに
2021年6月にAWS認定セキュリティスペシャリティに合格しました。今後受験する方々の参考になればと思い、本稿を書かせていただきました。

## AWS認定セキュリティスペシャリティとは

AWS認定試験に設けられたアソシエイトからプロフェッショナルとは別枠の高度な専門知識を問われる試験の中のセキュリティ分野の認定資格になります。

評価される能力は次のようなものになります。

>• 専門的なデータの分類と AWS のデータ保護の仕組みに関する知識。
• データ暗号化の手法とそれを実現する AWS の仕組みに関する知識。
• セキュアなインターネットプロトコルとそれを実現する AWS の仕組みに関する知識。
• AWS のセキュリティサービスとセキュアな運用環境を実現するサービスの機能に関する実践
的な知識。
• AWS のセキュリティに関するサービスおよび機能を使用した、運用環境における 2 年以上の
経験を通じて得られたコンピテンシー。
• 一連のアプリケーション要件に応じて、コスト、セキュリティ、導入の複雑さのバランスを
勘案した意思決定を行える能力。
• セキュリティの運用とリスクに関する知識。

続きは下のリンクよりご確認ください。

https://aws.amazon.com/jp/certification/certified-security-specialty/

試験ガイドは[こちら](https://d1.awsstatic.com/training-and-certification/docs-security-spec/AWS%20Certified%20Security%20-%20Specialty%20Exam%20Guide%20001%20v1.5%20FINAL%20JPN.pdf)です。


## なぜ勉強しようと思ったのか
セキュリティ系のタスク増加に伴い、取得しておく必要がありました。また就活でも使えるのでは？というちょっとした期待もあり受験しました。

## 勉強方法
教材は次のものを使用しました。

- Udemy  
- 書籍「要点整理から攻略する『AWS認定 セキュリティ-専門知識」
- black belt

学習期間は大体2~3週間くらいでした。

### Udemy
私が受講した講座は次の2つになります。

- **AWS Certified Security Specialty 2021** 

https://www.udemy.com/course/aws-certified-security-specialty/

- **Amazon AWS Security Specialty Practice Exams | 2021**

https://www.udemy.com/course/amazon-aws-security-specialty-practice-exams-2021/

1点目の**[AWS Certified Security Specialty 2021](https://www.udemy.com/course/aws-certified-security-specialty/)**はAWSのセキュリティ関連のサービスをハンズオン形式で学べる講座です。なお全て英語ですが、講師の方の英語は比較的聞きやすいため特に支障はなかったです。この講座はあくまでも全体像を把握するものとして活用しました。講座には確認問題がついていますが、問題のレベルが本番よりかなり簡単であるため、問題演習に関しては別の講座を購入することを勧めます。

2点目の**[Amazon AWS Security Specialty Practice Exams | 2021](https://www.udemy.com/course/amazon-aws-security-specialty-practice-exams-2021/)** は実践問題集になります。この問題集をやれば、十分試験で戦えるレベルになると思います。なぜその答えになるのかを理解することがとても重要です。

### 「要点整理から攻略する『AWS認定 セキュリティ-専門知識」
かなり有名なセキュリティ試験対策本になります。日本語で書かれている対策本はおそらくこれ以外にはありません。内容も充実しており、理解しやすかったです。巻末には試験問題もついてきます。試験直前の最終チェックで使用しました。

書店やamazonで購入することができます。

https://www.amazon.co.jp/%E8%A6%81%E7%82%B9%E6%95%B4%E7%90%86%E3%81%8B%E3%82%89%E6%94%BB%E7%95%A5%E3%81%99%E3%82%8B%E3%80%8EAWS%E8%AA%8D%E5%AE%9A-%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3-%E5%B0%82%E9%96%80%E7%9F%A5%E8%AD%98%E3%80%8F-NRI%E3%83%8D%E3%83%83%E3%83%88%E3%82%B3%E3%83%A0%E6%A0%AA%E5%BC%8F%E4%BC%9A%E7%A4%BE/dp/4839970947

### black belt
AWS試験対策のマストアイテムです。セキュリティ関連のサービスは必ず抑えておきましょう。


## 試験結果

**結果：921点** *合否ボーダーは750点あたり

|  セクション  | スコアリングされた項目の%   | コンピテンシーを満たしている  |
| ---- | ---- | ---- |
| 分野 1: インシデント対応  | 12%  | ◎  | 
|  分野 2: ログと監視   | 20%  | ◎  |
|  分野 3: インフラストラクチャのセキュリティ  | 26% | ◎  |
|  分野 4: ID およびアクセス管理  | 20%  | ◎  |
|  分野 5: データ保護  | 22%  | ◎  |

試験結果はこんなかんじでした。得点は921点と余裕を持って合格することができました。大体9割の問題に対して自信を持って答えられたと思います。時間も1時間以上余りました。ソリューションアーキテクトアソシエイト(SAA)の方が難しく感じました。


### 終わりに
試験対策で学んだことの多くが実務で生かせる内容であるため、合否に関係なくAWSを使用しているエンジニアの方におすすめの試験だと思いました。時間があれば次は機械学習の専門知識試験を受けようかと思います。
React + Reduxを基本からまとめてみた【3】【Fluxフロー】【随時更新】

##Fluxフローとは

- データフロー設計の１つ
- データが常に１方向に流れる
- イベントによってデータが変化(イベント駆動)

####Flux思想をreactの状態管理に適したライブラリー = Redux


##Fluxフロー図
![flux_flow.png]
(https://camo.qiitausercontent.com/cdd0824a85a48f51dacc8ec20fa5cf5ce6ec8093/68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3434303539332f33313139643830622d383163642d633664382d636233312d6132383837386261313738312e706e67)

#####Container<br/>⇨ Storeと接続されたコンポーネント

#####Action<br/>⇨ 要求を受けて変更を依頼

#####Reducer<br/>⇨ 変更を管理する

#####Store<br/>⇨ 状態を保存する

#####mapState To Props / mapDispatch To Props<br/>⇨ 状態をコンテナーに渡す


##ReduxにおけるFluxフローの流れ

① ユーザーがwebページにアクセス
　　　　　　　
② URLに応じたContainerが表示される
　　　　　　
③ Containerの中にComponentがあり、ユーザーが購入ボタンなどをクリックする

④ 購入ボタンなどをクリックするイベントが発生した時、Actionが実行される

⑤ Actionが状態の変更したい内容をReducerに伝える

⑥ Reducerは変更の内容を受けて内容をStoreに伝える

⑦ Storeで状態が変わったら、状態をmapState To Props / mapDispatch To Propsを通して、Containerに伝わる

⑧ Containerの中では、状態が変わり表示がされる

⑨  ①へ戻る


##参考サイト
[日本一わかりやすいReact-Redux入門#3...Fluxフローは絶対に知っておいて]
(https://www.youtube.com/watch?v=so0JgVToRLk)
python タイムスタンプ

# サンプルコード

```python
from datetime import datetime, timedelta, timezone
from datetime import date

time_stamp = round(datetime.now().timestamp())
print("タイムスタンプ ... " + str(time_stamp))
print("タイムスタンプを日付に変換 ... " + str(date.fromtimestamp(time_stamp)))
```

- 実行結果

```
タイムスタンプ ... 1633416587
タイムスタンプを日付に変換 ... 2021-10-05
```

以上。
Let’s encryptのルート証明書が切れたため curl ができなくなった問題

## 症状
- ubuntu16のサーバで定期的にcurlを使って協力会社からデータを取得していたが、10月に入りデータが取得できなくなった(CentOS7,AmazonLinuxの場合は後述)

- 以下のエラーが出る

```
curl: (60) server certificate verification failed. CAfile: /etc/ssl/certs/ca-certificates.crt CRLfile: none
```
- PCのブラウザで該当の web API を開くと普通にデータは取得できるのでAPI側の問題ではなさそう

## 原因
協力会社のAPIがLet's encryptの証明書を使っていて、そのルート証明書 DST_Root_CA_X3 の期限が9月30日で切れたのが原因らしい
普通ならこれの期限が切れても新しいルート証明書である ISRG_Root_X1 を信用していればそれでいいことになるのだが、opensshのバージョンが古い(1.0.2)とそうならずDST_Root_CA_X3の期限が切れたせいで有効な証明書であるISRG_Root_X1まで信用しなくなってしまうという問題があるらしくて、それが真の原因だったみたいです
[ワルブリックスさん](https://www.walbrix.co.jp/article/openssl-102-letsencrypt-crisis.html)の記事がわかりやすくて、ようやく事態を飲み込めましたが、それまでは新しい証明書がca-certificatesに入ってないだけの問題だと勘違いしていたのでハマってしまいました
なんでルート証明書がこんなややこしいことになっているかは[こちら](https://ssl.sakura.ad.jp/column/letsencrypt-root-certificate/)がわかりやすかったです

## 対策 (ubuntu16)
今回の私の件の場合[ワルブリックスさんの記事](https://www.walbrix.co.jp/article/openssl-102-letsencrypt-crisis.html)の「対策」のところに書いてある２番目の

- クライアント側で DST Root CA X3 を信頼済みCA一覧から削除する

というのがやるべき対策になる

具体的には以下の通り

- 以下のコマンドでTUI(テキストユーザーインターフェイス）のca-certificates設定画面を出す

```
sudo dpkg-reconfigure ca-certificates
```
![スクリーンショット 2021-10-05 15.09.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31813/b674d4e5-aca1-7430-d434-496630076352.png)

- 「はい」を選択すると、信用してる証明書一覧が出てくるのでDST_Root_CA_X3でスペースを押し、アスタリスクを外す

![スクリーンショット 2021-10-05 15.10.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31813/f4beb2a0-45de-4b31-4fa5-44ff8e0634a1.png)

- 「了解」を選択

事情によってTUIが使えない場合は`/etc/ca-certificates.conf`を編集してDST Root CA X3を!マークでコメントアウトしてから`sudo update-ca-certificates`でもいいみたいです

## 対策 (CentOS7, AmazonLinux)
CentOS7も古いAmazonLinuxもopensslのバージョンが1.0.2なので同様の問題がある
CentOS7のcurlはopensslを使ってないようなので問題が出ないが、wgetは同様の問題が発生する
こちらはちゃんとリポジトリが対応してくれてるので、yumでca-certificatesを更新すれば完了

```
sudo yum update ca-certificates
```
【jp_prefecture】rails_adminで都道府県一覧セレクトボックスを表示する

RailsAdminでjp_prefecture gemを使用して、都道府県一覧セレクトボックスを作成するのに少しハマったのでメモ。
下記のようにEnumとして定義してあげれば無事動作できました。

```ruby
class City < ApplicationRecord
  include JpPrefecture
  jp_prefecture :prefecture_code

  rails_admin do
    create do
      field :prefecture_code, :enum do
        enum JpPrefecture::Prefecture.all.collect { |p| [p.name, p.code] }
      end
      field :name
      field :description
    end

    edit do
      field :prefecture_code, :enum do
        enum JpPrefecture::Prefecture.all.collect { |p| [p.name, p.code] }
      end
      field :name
      field :description
    end
  end
end

```