OmniAICreator/Qiita-1.07M huggingface dataset:
Unity + PlayFab を Android で利用した時に実行時にクラッシュする問題

# 発生する問題

Unity で PlayFab を Android 環境で実行する際に以下のようなエラーが発生しクラッシュした場合は対処が必要です。

```
AndroidRuntime FATAL EXCEPTION: Thread-6
AndroidRuntime Process: <Bundle Name>, PID: 32155
AndroidRuntime java.lang.NoClassDefFoundError: Failed resolution of: Lokhttp3/OkHttpClient$Builder;
AndroidRuntime     at com.microsoft.xplatcppsdk_internal.HttpRequest.<clinit>(HttpRequest.java:24)
AndroidRuntime Caused by: java.lang.ClassNotFoundException: Didn't find class "okhttp3.OkHttpClient$Builder" on path: DexPathList[[zip file "/data/app/~~IERiCRFwm_VPFsbzhguiaw==/<Bundle Name>-Lfb8xW5gDLcZdsvLTswOBw==/base.apk"],nativeLibraryDirectories=[/data/app/~~IERiCRFwm_VPFsbzhguiaw==/<Bundle Name>-Lfb8xW5gDLcZdsvLTswOBw==/lib/arm64, /data/app/~~IERiCRFwm_VPFsbzhguiaw==/<Bundle Name>-Lfb8xW5gDLcZdsvLTswOBw==/base.apk!/lib/arm64-v8a, /system/lib64, /system_ext/lib64]]
AndroidRuntime     at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:207)
AndroidRuntime     at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
AndroidRuntime     at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
AndroidRuntime     ... 1 more
```

# 解決方法

Android の Publishing Settings の『Custom Main Gradle Template』を有効にする事で解消されます。

同じような問題が以下のフォーラムでも上がっています。

https://forum.unity.com/threads/lokhttp3-crash-after-adding-googleplaygames-plugin.1076351/

フォーラムでも記載がある通り、`com.squareup.okhttp3:okhttp:3.10.0` がリンクされていないことが原因です。

https://github.com/PlayFab/XPlatCppSdk/blob/master/build/Android/XPlatCppSdk/build.gradle

上記が依存関係を解決するための Gradle ですが、これを利用するために『Custom Main Gradle Template』を有効にする必要があります。
ドキュメントに記載はないのですが、PlayFab の公式の回答としては『**事実上設定が必須**』ということのようです。
【SharePoint Online】[BUG] カスタムリストの表示フォームを印刷しようとすると「メイン コンテンツにスキップ」と表示される

# カスタムリストの表示フォームを印刷しようとすると

カスタムリストでリストアイテムの表示フォーム (DispForm.aspx) を印刷しようとすると「メイン コンテンツにスキップ」と表示されてしまう。

https://feedbackportal.microsoft.com/feedback/idea/61a00e8d-3c82-ec11-a81b-6045bd7bf64c

ニュースなどの通知は旧来のカスタムリストを使わずに、ニュースページを活用して下さいということなのでしょう。

# 事象

表示フォーム (DispForm.aspx) でリストアイテムを表示した状態で、ブラウザの印刷を選択します。するとプレビューの時点でおかしな表示が紛れていることがわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111975/7e73f191-4814-c2cb-bfc0-bc7e6cead914.png)

スタイルを確認すると、座標が `top: -999px;` に設定されて画面外に存在しています。

```html
<a href="javascript:;" class="sp-skipToContent" id="sp-skipToContent">メイン コンテンツにスキップ</a>
```

```css
.sp-skipToContent {
    display: block;
    box-sizing: border-box;
    padding: 0 16px;
    font-size: 14px;
    font-weight: 400;
    z-index: 999999;
    height: 50px;
    line-height: 50px;
    position: fixed;
    width: 100%;
    top: -999px;
    color: #025c5f;
    background-color: #f3f2f1;
}
```

# 対処方法

Power Apps の Print 関数を利用することを検討しましたが、１ページ内に収まらない場合に全体を印刷することができませんでした。(2022/01 現在)

https://docs.microsoft.com/ja-jp/powerapps/maker/canvas-apps/functions/function-print

MS サポートからの回答を以下に抜粋します。(2022/01)

> 本件の回答といたしましては、本事象はモダン UI で発生する固有の問題であり、SharePoint Online の標準機能にて実現可能な回避策としては印刷をする前にクラシック UI へ切り替えていただく方法となります。

クラシックで表示させればフォーム全体を印刷することが可能なので、"従来の対象ユーザー設定の有効化" を利用してフォームの表示を強制的にクラシックにします。

https://qiita.com/MakotoIshikawa/items/15d6f74153f61ae3146e
Kotlin（+Chart.js）で地図アプリ（ゴミ拾いアプリ）。（15日目）


#今日やったこと

・Korlinで音を鳴らす（送信成功 or 失敗時に効果音を再生）
・設定画面に、効果音に関する項目を作成
・WEBにChart.jsを使ってグラフを作成

#効果音を付けた理由

クルマで移動中に見つけた、ポイ捨てゴミを回収する際に、車内に設置しているタブレット端末で、位置情報を登録しているのですが、ボタンをタップした後、送信が成功したかどうかの確認の際に、画面を見るのが面倒だったので、音で確認出来たら便利だと思い、効果音機能を付けてみました。




#Kotlinで音を鳴らす方法

ネットで調べると「MediaPlayer」「AudioTrack」「SoundPool」を使えば良さそうです。
今回は、MediaPlayerを使ってみます。

https://developer.android.com/guide/topics/media/mediaplayer?hl=ja



#リソース作成

リソースフォルダに「raw」フォルダを作成して、その中に音楽ファイルを入れると動くようです。

[res]
->[raw]
->[音楽ファイル]

効果音用のデータは、以下の商用利用可能なフリー素材を配布されているサイトからお借りました。

https://soundeffect-lab.info/


この中の

>・メニューを開く１　アニメ風
>・メニューを開く２　ブォン。重低音

この２つを、送信成功用と、失敗用で使わせてもらいます。


[raw]フォルダに保存
![イメージ7526.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503948/a18414c1-9ba2-91be-f06a-5c5575c83697.jpeg)


リネーム
![イメージ7521.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503948/49a42c65-4959-fb21-b55e-37bedd04e167.jpeg)



#コード

OKとERRORの場合で、異なる効果音を出すだけのシンプルな関数を作ってみました。
setOnCompletionListener  で、再生終了後、release()を呼び出しています。
kotlinは、まだよくわかってないので書き方はよくないかもです。

※修正[2022-01-06 19:03]

```kotlin:（sample）
     private fun soundPlay(flg:String){
        var sound:MediaPlayer? = when(flg){
            "OK"    -> MediaPlayer.create(this,R.raw.send_ok)
            "ERROR" -> MediaPlayer.create(this,R.raw.send_error)
            else    -> return
        }
        sound?.start()
        sound?.setOnCompletionListener  { _ ->  sound?.release() }
    }
```

#エミュレーターのボリューム調整

説明不要かもですが、エミュレーターでもサウンド再生可能です。
音が出ない場合は、ミュートや、ボリュームが下がっているかもしれません。

![イメージ7524.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503948/b9f002c2-2631-c2da-446a-5f415f3da01a.jpeg)


#設定画面に効果音の項目追加

先日作成した設定画面に効果音の項目を追加

※画像をクリックするとGIF動画を再生できます

![効果音設定.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503948/138c458e-a372-31f7-8861-e8068d9b0226.gif)


これで、一応完成。


#その他

停止や、シークなど、再生を制御するメソッドがあったので、ちょっとした音楽再生プレイヤーソフトなら、MediaPlayerを使う事で、簡単に作れそうな気がします。


#JavaScript + Chart.jsでグラフを作成

WEBサイトに、Chart.jsを使ってグラフを追加してみました。


参考サイト：

https://paiza.hatenablog.com/entry/2016/06/07/javascript%E3%81%A7%E3%82%B0%E3%83%A9%E3%83%95%E6%8F%8F%E7%94%BB%E5%85%A5%E9%96%80%EF%BC%81%E5%85%A8%EF%BC%98%E5%80%8B%E3%81%AE%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E3%82%92%E3%82%B3%E3%83%BC


MySQLデータベース上のデータ量が少ないので、サンプルコードをほぼそのまま使っています。

![イメージ7531.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503948/270194cd-a096-7cdf-302b-3eceea61566f.png)

動作画面：

※画像をクリックするとGIF動画を再生できます

![JavaScript -Chat.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503948/2846f822-d306-c3fc-3f1b-ff706da14018.gif)
tf_rosrustにBroadcaster追加してみた

# tf_rosrustとは

ROS1のRust Clientである[rosrust](https://github.com/adnanademovic/rosrust)を使ったRustの[tf2](http://wiki.ros.org/tf2)実装です。

https://github.com/smilerobotics/tf_rosrust

arjo129さんの[rustros_tf](https://github.com/arjo129/rustros_tf)にはじまり、Forkにフォークを重ね、[smilerobotics](https://www.smilerobotics)で名前を変えて独自路線で開発を継続しています。

# Broadcast実装してみた

tf_rosrustはまだListenerのほうしか実装がなかったので、Broadcasterのほうを実装してみました。(まだ私の個人リポジトリのブランチです（2021/01/07追記：smileroboticsリポジトリにマージされました。）)

https://github.com/OTL/tf_rosrust/tree/broadcast

これが正しい実装なのかよく分かっていませんがrvizで見た感じ動いてそうでした。

![画面収録-2022-01-06-18.11.26.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58926/87f5c57b-671e-d2af-17e8-e2529ea66a4d.gif)


## 実装内容

tf_broadcaster.rs

```rust
use crate::{
    tf_error::TfError,
    transforms::{geometry_msgs::TransformStamped, tf2_msgs::TFMessage},
};

pub struct TfBroadcaster {
    publisher: rosrust::Publisher<TFMessage>,
}

impl TfBroadcaster {
    /// Create a new TfBroadcaster
    pub fn new() -> Self {
        Self {
            publisher: rosrust::publish("/tf", 1000).unwrap(),
        }
    }

    /// Broadcast transform
    pub fn send_transform(&self, tf: TransformStamped) -> Result<(), TfError> {
        let tf_message = TFMessage {
            transforms: vec![tf],
        };
        // TODO: handle error correctly
        self.publisher
            .send(tf_message)
            .map_err(|err| TfError::Rosrust(err.description().to_string()))
    }
}
```

## Example

```rust
use tf_rosrust::{TfBroadcaster, TransformStamped};

fn main() {
    rosrust::init("broadcaster");
    let broadcaster = TfBroadcaster::new();

    let rate = rosrust::rate(100.0);
    let mut tf = TransformStamped::default();
    tf.header.frame_id = "base_link".to_string();
    tf.child_frame_id = "camera".to_string();
    tf.transform.rotation.w = 1.0;
    let mut theta = 0.01_f64;
    while rosrust::is_ok() {
        theta += 0.01;
        tf.header.stamp = rosrust::now();
        tf.transform.translation.x = theta.sin();
        tf.transform.translation.y = theta.cos();
        broadcaster.send_transform(tf.clone()).unwrap();
        println!("{:?}", tf);
        rate.sleep();
    }
}
```

# 感想

思ってたより簡単に出来ました。ROS１の新しい言語のClientを実用化する上で割と足りてないのがactionとtfなんでtfがあるとよりROS1の言語としてしっかりしますね。


### 蛇足

この記事は2021年アドベントカレンダーとして書きました。

最初はtf_rosrustをROS2対応をさせようとしたのですが、きれいにROS1と統合するのにめんどくなってBroadcaster実装にしてしまいました。そのうちROS2対応もやってみたいと思ってはいます。
ディレクターとしての動き方考察（Webシステムのアジャイル開発における）

:::note info
Webシステムの受託開発のディレクター（PjM）として、
アジャイル開発案件に関し、現場で実際にどういう動きをしているか整理、考察してみました。
:::

## 利用ツール
* backlog
    * タスク管理用
* Googleドキュメント
    * 進捗報告用の議事録

## １週間の流れ（プロジェクト毎）
（例）スプリントが1週間単位の場合

| 曜日 | ディレクターの行動 |
|:-----------|:------------|
| 日 | :zzz: しっかりと休養しましょう |
| 月 | :busts_in_silhouette: 進捗報告MTG（クライアント含む）<br>:back: 今週のタスクと優先度をエンジニアに共有<br> :pencil: 次週の報告議事録を作成（今週分をコピー）|
| 火 | :muscle: エンジニアに開発を集中してもらう |
| 水 | :muscle: エンジニアに開発を集中してもらう |
| 木 | :eyes: エンジニアの進捗状況を確認<br>遅れが出ているタスクがある場合、どこまで進行できるか、いつまでに対応が可能かを確認 |
| 金 | :pencil: 次週の報告議事録を最終更新 |
| 土 | :zzz: しっかりと休養しましょう |


### 進捗報告MTG（Delivery）
* 各タスク（backlogのチケット毎）の進捗状況を報告
    * 先週に進行予定としていたタスクについて
* 遅れが発生しているタスクについては、どこまで進行したか、次週までに対応が可能かを連絡
* 新たに発生した要望や課題をヒアリング、仕様検討、タスク化
* 新規タスクと進行予定タスクを合わせて、優先度を確認し、次週までに実施するタスクを確認

### QAについて（Quality）
* テスト環境へアップ後に随時実施

## 考察（改善点など）
※ スプリントが1週間の場合

* ビルドトラップにハマってしまう
    * １週間だと期間が短く、より良いプロダクトを作るということよりも、いかにタスク進行できたかにフォーカスしがちになってしまう
* QAの実施計画が立てられていない
    * 現状だと、テスト環境へアップ後にQAを実施している。
    * プロジェクト専任のエンジニアやテスターがいるわけではなく、１週間の中でQA実施までは回せないため。
    * プロジェクト自体の予算が多く、専任のリソースを確保できる場合には、QA計画まで立てていけることが理想

:::note info
できるだけ、スプリントは2~4週間で回したほうがより良いプロジェクトになる場合が多いと思います。
スプリントが短くなっている理由は、早く機能をリリースしたい、細かく進捗を確認したい、という意図があると思うのですが、これは開発する機能や状況によって変わってくるところなので、基本は長めに期間を取っておき、必要に応じて細かく状況報告の時間を確保していくかたちが、現時点のプロジェクトでは良さそうではないかと考えています。
:::
[アルゴリズム]挿入ソートで配列の中身を小さい順に並べるプログラム

アウトプット用！！

＃第4回目は挿入ソートで配列の中身を小さい順に並べるプログラムを作っていく！！

今回も前回と同様にアルゴリズムを意識してプログラミングしてみました。
早速作っていきます。

```Sort.java
class Sort3 {
    public static void main(String[] args) {
    	int Sort[] = {9,5,3,1};
    	
    	int i;
    	int j;
    	int x;
    	for(i = 1; i <= Sort.length-1; i++) { //配列[0]は自動的に整列済み。なので[1]から配列の最後まで値をずらす
    		j = i;
    		while( j >= 1 && Sort[j-1] > Sort[j]) { //
    			x = Sort[j];
    			Sort[j] = Sort[j-1];
    			Sort[j-1] = x;
    			j = j -1;
    		}
    	}
    	i = i + 1;
       System.out.println(Arrays.toString(Sort));
   }
    
}
```

# ①配列の宣言と初期化

```Sort.java
int Sort[] = {9,5,3,1};

```

# ②メンバ変数の定義

```Sort.java
int i;
int j;
int x;
```
# ③外側のループと内側ループ
外側ループ
ループカウンタをiとして、iは配列の要素二番目から配列の最後の要素に向かって後ろに進む。

内側のループ
ループカウンタをjとして、配列の要素二番目に向かって前に進む。
そこで一つ前と比較して大きければ交換する。

次に値を直接入れながら処理の流れを確認してみる。
ノートに書きながらだと処理の流れをイメージしやすいです。


```Sort.java

for(i = 1; i <= Sort.length-1; i++) { //配列[0]は自動的に整列済みになるので配列[1]から配列の最後配列の要素まで値をずらす
    		j = i;
    		while( j >= 1 && Sort[j-1] > Sort[j]) { //
    			x = Sort[j];
    			Sort[j] = Sort[j-1];
    			Sort[j-1] = x;
    			j = j -1;
    		}
    	}
    	i = i + 1;

```
アルゴリズムを意識。


まず
変数iに1が入る。
for文から
1 <= 3　はtrueなので繰り返しを実行。
変数jに１が入る。
while文から
1 >= 1 かつ Sort[0] > Sort[1]
1 >= 1　はtrueで, 9 > 5 は9が大きいので交換
すると配列の中身は
`[5,9,3,1]`になる。
j = 1 - 1
j = 0
内側ループに戻り
0 >= 1　で成り立たないので内側のループを抜ける。

i = i + 1
i = 2

一巡目終了。

二巡目スタート
i = 2
for文から
2 <= 3 はtureなので繰り返し実行。
変数jに2が入る。
while文から
2 >= 1 かつ Sort[1] > Sort[2]
2 >= 1はtrueで,　9 > 3 は9が大きいので交換
すると、
`[5,3,9,1]`になる。
j = 2 - 1
j = 1
内側ループに戻り
1 >= 1は成り立つので、
1 >= 1 かつ Sort[0] > Sort[1]
1 >= 1はtrueで、　5 > 3　は5が大きいので交換
すると、
`[3,5,9,1]`になる。
j = 1 - 1
j = 0
内側ループに戻り
0 >= 1で成り立たないので内側ループを抜ける。

i = 3

二巡目終了。

三巡目スタート
i = 3
for文から
3 <= 3はtrueなので繰り返し実行
変数jに3が入る。
while文から
3 >= 1　かつ Sort[2] > Sort[3]
3 >= 1はtrueで、9 > 1は9が大きいので交換
すると、
`[3,5,1,9]`になる。
j = 3 - 1
j = 2
内側ループに戻り
2 >= 1は成り立つので、
2 >= 1　かつ　Sort[1] > Sort[2]
2 >= 1はtrueで、5 > 1は5が大きいので交換
すると、
`[3,1,5,9]`になる。
j = 2 - 1
j = 1
内側ループに戻り
1 >= 1は成り立つので、
1 >= 1かつSort[0] > Sort[1]
1 >= 1はtrueで、3 > 1は3が大きいので交換
すると
`[1,3,5,9]`になる。
j = 1 - 1
j = 0
0 >= 1で成り立たないので内側のループを抜ける。

i = 3 + 1
i = 4

外側ループ
4 <= 3　は成り立たないので

ループを抜けて終了

コンソールを実行すると
配列の中身が小さい順に並べることができているとおもいます。

```コンソール.java
[1,3,4,6]
```

以上です。
今回もアルゴリズムを意識してプログラミングをしてみました。
一つ一つ値を入れて動きを確認していくことは骨の折れる作業ですがどのようにプログラムが動いているのかを理解していくためにはすごく効果的な学習方法かなと個人的には思っています。

これからも楽しみながらプログラミングしていきます！

おつかれさまでした。
[SCSS] selectorのinner ruleは1階層までが良い（親要素参照の `＆`）

## 概要

すごいざっくりですが、下記のようなHTMLがあったとします（タグは全て`div`に統一しました）。

```html
<div class="root">
  <div class="icon">icon</div>
  <div class="caption">caption</div>
</div>
```

ここにCSS（今回はSCSS）でスタイルをつけたいとします。

![component.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1480416/09c39156-4ff3-c193-c850-665a4fe01826.png)

- 作成したいcomponentは上記の画像のような感じ。
- hover時にrootはyellowに、iconはredに、captionはblueにしたい（実際にはそんなことはないが、、、）。

### 改善前

まずは、今まで自分がやっていた感じに記載します。

```scss
.root {
  background-color: gray;
  height: 100%;
  width: 100%;

  &:hover {
    background-color: yellow;

    .icon {
      color: red;
    }

    .caption {
      color: blue;
    }
  }
}

.icon {
  height: 48px;
  width: 48px;
}

.caption {
  font-size: 18px;
}
```

実際にはこれでも十分動きますが、上記の何がいけないのかというと、

- 階層が深くなってしまうことで、componentが増えた場合にstyleが当たる優先順位や記載箇所がわかりづらくなってしまう。
- `.root`のhoverにまとめてiconとcaptionの挙動も書いているが、まだこのclassは記載箇所より上には出ておらず、コードとしてはこれもわかりづらい要因となってしまう。

### 改善後

```scss
.root {
  background-color: gray;
  height: 100%;
  width: 100%;

  &:hover {
    background-color: yellow;
  }
}

.icon {
  height: 48px;
  width: 48px;

  .root:hover & {
    color: red;
  }
}

.caption {
  font-size: 18px;

  .root:hover & {
    color: blue;
  }
}
```

実際にpropertiesが当たるのはどのclassなのかということが、これで明確になる。scssにおいて、親要素を参照したい場合は、

```scss
.親要素 {}

.子要素 {
  .親要素 & {
    // 親要素と連動して当てたい子要素のproperties
  }
}
```

と記載すれば、割とスッキリする。
qiita apiを叩く。 その２

# 概要

javascriptで、qiita apiを叩いてみた。
itemsをpostしてみた。

# サンプルコード

```
var src = document.getElementById('src');
var prm = document.getElementById('prm');
var out = document.getElementById('out');
var endpoint = "https://qiita.com/api/v2/items";
function run() {
	var token = src.value;
	var xhr = new XMLHttpRequest();
	xhr.onreadystatechange = function() {
		if (xhr.readyState == 4 && xhr.status == 201)
		{
			out.value = xhr.responseText;
		}
		else
		{
			//alert(xhr.readyState);
			//alert(xhr.status);
		}
	};
	xhr.open("POST", endpoint, true);
	xhr.setRequestHeader('Authorization', 'Bearer ' + token);
	xhr.setRequestHeader('Content-Type', 'application/json');
	xhr.send(prm.value);
	//alert("ok");
}

```

# 成果物

https://embed.plnkr.co/plunk/goR5lWRTgsQfHDP5

以上。
Firestore サブコレクションのドキュメント数をカウントする方法

Firestoreを利用していて、コレクションの数を取得する機会が何回かあったのでメモとして記録しておきます。

# 必要なものをインポートする

まだFirestoreのセットアップができていない方は、セットアップの方法の記事もあげているので是非ご覧ください。
[Firebaseを使い始めるために必要な手順](https://qiita.com/ohanawb/items/40c5b114e0ed32f1746a)

```typescript:sample
import firebase from "firebase/compat";
const db = firebase.firestore();
```

# Firestoreのコレクションのドキュメント数を取得してみる

例えば、usersコレクション>userIDドキュメント>ordersコレクションという階層になっているコレクションから、
あるユーザーの注文回数を取得したい場合は下記にようにすれば取得することができます。

```typescript:sample
async getOrderCount(): Promise<void> {
    let orderCount = 0;
    await db
      .collection("users")
      .doc("userID")
      .collection("orders")
      .get()
      .then((snap) => {
        orderCount = snap.size;
      });
}
```

# 同じ方法でサブコレクションのドキュメント数を取得することもできる

usersコレクション>userIDドキュメント>ordersコレクション>orderIDドキュメント>orderItemコレクションという階層になっているコレクションで、あるユーザーのある注文の注文商品個数を取得したいときは以下のようにすれば取得することができます。


```typescript:sample
async getOrderItemCount(): Promise<void> {
     let orderItemCount = 0;
      await db
        .collection("users")
        .doc("userID")
        .collection("orders")
        .doc("orderID")
        .collection("orderItem")
        .get()
        .then((snap) => {
          orderItemCount = snap.size;
        });
}
```
パワハラおじさんと縁を切る方法

僕は普通のプログラマーとして勤めているが、なぜか僕につきまとってウザい上司がいた。あいつと縁を切って久しい。今回は、僕がどうやってオッサンと縁を切ったか書こうと思う。

# ある日の会話

オッサン「やあやあ山田くん」

僕「おはようございます、鈴木先輩」

オッサン「君のツイッターのフォロワー結構少ないんだね。俺が絡んであげてるからもっと増えてると思ってたよ」

オッサンの得意技はマウンティングである。僕は礼儀正しくこう返事する。

僕「鈴木先輩にはかないません」

オッサン「最近、俺達の企業に入社したという嘘をつくバカが増えているらしいが、まあ俺達ぐらい優秀じゃなきゃ当然入れないわけだし、周囲はバカと俺達をちゃんと区別できているから問題ないな。一応、世間様にバカの特徴を列挙して啓発しとこうな」

# 我慢できない

鈴木先輩は確かに能力はあるが、その傲慢な態度があまりにもひどいので我慢できない。ツイッターを見てみると、あのオッサンのマウントがひどいとか、あのオッサンのツイートを見ると死ねと思うとか、そういう話がちらほらある。

僕はついつい、こんな内容の書き込みをしてしまった。

「僕の会社に入りたいけど入れないという優秀な人は、大抵は傲慢な嫌な人がいるという理由で面接受けに来ないんだよな...」

鈴木先輩もこの書き込みを見て僕にこんなことを言ってきた。

「傲慢って俺のことか？まあ俺を嫌いという奴が入ってこないなら良い話だと思うが、山田くんも精神病のゴミ無能者には入ってきてほしくないだろ？俺達の企業は良くも悪くも公平に面接するから、ゴミ無能者は面接さえする気が失せてくれたほうが良い」

僕は鈴木先輩にかなり失望した。

僕「鈴木先輩はなんであんなにトゲのあるツイートをするんですか？」

オッサン「フォロワーもいいねも増えるし、燃えてくれたほうが学びがあるからな。情報を明かさないやつは攻撃することで情報を明かさせる。バカに限って罵倒すれば情報をべらべら話し出す」

# 作戦決行

日本人である僕は、やはりダイレクトに何かを伝えることができない。だからこういう作戦を立てることにした。

まず、ツイッター上で「パワハラ上司についての発言」をする。誰がとか具体的な情報は抜きにして、「パワハラをする人ってこういうことをするよね」というような内容だ。例えば、

「パワハラ上司ってパワハラをしているという自覚がないみたいですよね。しんどい...」

みたいな具合だ。こうやって、オッサン側にパワハラ(と傲慢さ)の事実を気が付かせる。要するに、僕に付きまとわないでくれということをやんわりと伝えたいわけだ。

これを大体2ヶ月ぐらい続けていたら、オッサンの行動に変化が生じ始めた。僕に対してリプライを送ってこなくなったのだ。家族がいる人間というのは、パワハラを若者に訴えられることを怯える傾向にある。それをうまく使った形だ。

# 一般化
上司がパワハラを辞めてくれる可能性は、その上司の属性に依存する面が大きい。

- 家族や子供がいる
- 持ち家がある
- 所属している会社のネームバリューを誇っている
- 所属している会社の給料がいい

など。要するに、辞めることがリスクになる属性と、辞めない利点が大きいという属性がセットになっているなら、「パワハラだと思われてますよ」ということを自覚させるだけで行動を改善してくれる可能性が高いはず。

これは良い企業に勤めている人のほうが心理的安全性が高い傾向にある理由だと思っている。環境が人の性格の軌道を修正することができるので、ドギツイ人たちが良い環境の会社にいるなら、もはやツイッター上でしか暴れることができなくなるだろう。あの人たちが会社の中では良い人間なのに、ツイッター上では傲慢なのはそういうわけだと思ってる。

たぶん、鈴木先輩はツイッターと職場の境界線があいまいな僕に対してパワハラしてしまったんだろう。反省してほしい。
CASLⅡで再帰を実行する

#CASLⅡで再帰を実行する

CASLⅡにおける再帰の例を挙げる。

##'Hi!'と3回繰り返す。

```
; 'Hi!'と3回表示する
MAIN	START
		LAD  GR0,3
		CALL HI
		RET
;		
;GR0回、'Hi!'と表示する
HI		START   
		LD GR0,GR0
		JZE FIN
;
		OUT  HIMSG,LEN
		SUBA GR0,=1
		CALL HI
FIN		RET 
;
HIMSG   DC   'Hi! '
LEN     DC   4
		END
```

##フィボナッチ数列をGR1とGR2に求める

```
; フィボナッチ数列をGR1とGR2に求める
; 0, 1, 1, 2, 3, 5 ……
MAIN	START
		LAD  GR0,4		; GR1=0, GR2=1から数えて、4回目のGR1=3,GR2=5を求める
		LAD  GR1,0
		LAD  GR2,1 
		CALL FIB
		RET
;
FIB		START  
		LD GR0,GR0
		JZE FIN
;
		XOR   GR1,GR2	; GR1とGR2を交換する
		XOR   GR2,GR1
		XOR   GR1,GR2
;
		ADDA  GR2,GR1
;
		SUBA GR0,=1
		CALL FIB
FIN  	RET 
;
		END
```
Webの勉強はじめてみた その19 ～Node.js編 導入～

N予備校「プログラミング入門Webアプリ」を受講しています。
今回は第3章2,3節です。

<h2>Node.js</h2>
:::note
JavaScript でプログラミングすることのできる、サーバーサイド向けのプラットフォーム
:::

<h3>nvmのインストール</h3>
Node.jsのバージョンを管理するツール

```bash
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh | bash
```

`-o-` : このオプション、調べ方が悪いのかいまいち理解できてないです。
`-o`　は指定したファイル名に保存というのはわかるんですが。

```bash
source ~/.bashrc
```

再起動せずに`.bashrc`ファイルを読み込ませる

<h3>Node.jsのインストール</h3>

```
nvm install v10.14.2
nvm use v10.14.2
```

`node --version` : バージョン確認
`node` : コンソールが入力を受け付ける状態になる。

:::note
REPL(レプル) : Read-Eval-Print Loop（リード・イーバル・プリント・ループ）の略称で、入力したコードをその場で実行して、結果を表示するツール
:::


終了は`ctrl + C`

<h2>練習</h2>

<h3>その1 入力された値まで加算</h3>

```javascript
'use strict';
const number = process.argv[2] || 0;
let sum = 0;
for(let i = 1; i <= number; i++){
    sum = sum + i;
} 
console.log(sum);
```

選択的代入
`const number = process.argv[2] || 0;`
無効な値が入った場合(falseの場合)に0が入る。
`process.argv`
コマンドラインの引数が入った配列。
0 番には node コマンドのファイルのパスが入り、
1 番には実行しているプログラムのファイルのパスが入る

<h3>その2 フィボナッチ数列</h3>

```javascript
'use strict';
function fib(n){
    if(n === 0){
        return 0;
    }else if(n === 1){
        return 1;
    }
    return fib(n - 1) + fib(n - 2);
}
//40まで出力
const length = 40;
for(let i = 0; i <= length; i++){
    console.log(fib(i));
}
```

`time node app.js` 
実際の処理にかかった時間がわかる。
`node --prof app.js`
処理に時間がかかっている様子やどれ位メモリを使っているのか
`node --prof-process xxxx.log`
プロファイル結果を表示

<h4>アルゴリズムの修正</h4>
:::note
アルゴリズムとは、問題を解くための手順を定式化した形で表現したもの。
回を重ねると後に倍々に計算回数が増えるような処理の増え方を指数（しすう）オーダーという。
:::

```javascript
'use strict';
const memo = new Map();
memo.set(0, 0);
memo.set(1, 1);

function fib(n){
    if(memo.has(n)){
        return memo.get(n);
    }
    const value = fib(n - 1) + fib(n - 2);
    memo.set(n, value);
    return value;
}
//40まで出力
const length = 40;
for(let i = 0; i <= length; i++){
    console.log(fib(i));
}
```

`Map` 連想配列として使えるオブジェクト
一度計算した結果を保存しておく方法を「メモ化」という

<h2>まとめ</h2>
重い処理が速くなるとちょっと爽快。
Node.jsは初めてなのといきなり数学の話で少し面食らいましたが、できることが増えていくと楽しいです。
Genie: 簡単な WebAPI を作成

こちらと同様の機能を Genie で実装します。
[FastAPI: 簡単な WebAPI を作成](https://qiita.com/ekzemplaro/items/6df0d64d5eab5632dd24)

```julia:get02.jl
# --------------------------------------------------------------------
#	get02.jl
#
#						Jan/06/2022
# --------------------------------------------------------------------
using Genie
using Genie.Router
using Genie.Renderer.Json
using Genie.Requests

function launchServer(port)

	Genie.config.run_as_server = true
	Genie.config.server_host = "0.0.0.0"
	Genie.config.server_port = port
#
data = Dict("t101" => Dict("name" => "草枕", "author" => "夏目漱石"),
"t102" => Dict("name" => "走れメロス", "author" => "太宰治"),
"t103" => Dict("name" => "千曲川のスケッチ", "author" => "島崎藤村"),
"t104" => Dict("name" => "高瀬舟", "author" => "森鴎外")
)
#
	println("port set to $(port)")

	route("/") do
		"Hello."
	end

	route("/authors/:author_id") do
		key = payload(:author_id)
		json(data[key])
	end

	route("/all") do
		json(data)
	end

	Genie.AppServer.startup()
end

# --------------------------------------------------------------------
launchServer(parse(Int, ARGS[1]))

# --------------------------------------------------------------------
```

サーバーの実行

```bash
julia get02.jl 8000
```

クライアントからアクセス

全件取得

```text
$ http http://127.0.0.1:8000/all
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Server: Genie/Julia/1.7.1
Transfer-Encoding: chunked

{
    "t101": {
        "author": "夏目漱石",
        "name": "草枕"
    },
    "t102": {
        "author": "太宰治",
        "name": "走れメロス"
    },
    "t103": {
        "author": "島崎藤村",
        "name": "千曲川のスケッチ"
    },
    "t104": {
        "author": "森鴎外",
        "name": "高瀬舟"
    }
}
```

id を指定して取得

```text
$ http http://127.0.0.1:8000/authors/t102
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Server: Genie/Julia/1.7.1
Transfer-Encoding: chunked

{
    "author": "太宰治",
    "name": "走れメロス"
}
```

参考ページ
[Advanced routing techniques](https://docs.juliahub.com/Genie/8eazC/1.15.1/tutorials/12--Advanced_Routing_Techniques.html)
Helm Chartのダウンロード方法

# Chartの取得コマンド
`helm pull repo/chartname`とすれば、Helm Chartの書庫ファイルがダウンロードできる
あとは`tar zxvf`で書庫を展開すればOK

`helm pull [chart URL | repo/chartname] [...] [flags]`

https://helm.sh/docs/helm/helm_pull/
音楽だって立派なHack！　作曲初歩の初歩２

# 作曲したい

という方のための第2回です。
今回は、調に必要な情報をまとめます。
前回は[こちら](https://qiita.com/johnny-shaman/items/36157304e1452287d35a)

# 音階について

## 音階の定義

音階というものは、2つの音がどれだけ離れているか？
の関係性を指す言葉として使われています。
今回は、隣り合う音との関係性だけに絞ります。

## 12音階が全て
### ピアノの例

ピアノの鍵盤を見たことがある方は、ご存知だと思うのですが…

__白鍵の隣に、黒鍵がある所と、無い所がありますね。__
それは、間に黒鍵を置くことが出来ないという理由からです。

### 12音階とピアノ

前回、基準の音から3倍ずつ上がっていくだけで、
12音階全ての音が出てくると、お話しました。

12音階とは、黒鍵を含んだ全ての音の事です。
（13音階目は1音階目の1オクターブ上なので、13音階目は1音階目とします）
その時に、ドの音を1音階目、シの音を12音階目とすると…

__12音階目と1音階目（13音階目）の間には黒鍵がありません！__

同じように考えて、レの音は3音階目になります。

__1音階目と3音階目は、黒鍵がありますね！__

音階が一つ上がっているのは同じです。
音階を掴むのが直感的ではない理由の一つは、上述のためです。

しかし、12音階で数字にして表すと一目瞭然で、一つ離れているのが分かります。

## 全音と半音

12音階で1つ音が上下する関係を「__半音__」、
12音階で2つ音が上下する関係を「__全音__」と言います。

良く、略して、「全」「半」と表記します。

# 調

これでようやく、調の話しに入れます。

## 調は2種類

調は、大きく分けて、2種類です。
そして、隣り合う音との音階の関係性が決まっているものを言います。

### 長調（メジャー）

1音階目から、
__全　全　半　全　全　全　半__
と上がって行くと、長調音階になります。
具体的には、ドの音から白鍵だけを順番に叩いて鳴らしていくと、
自然にこの順番で上がっています。

下がるときは、
__半　全　全　全　半　全　全__
になっていることを確認してください。

### 短調（マイナー）

1音階目から、
__全　半　全　全　半　全　全__
と上がって行くと、短調音階になります。
具体的には、ラの音から白鍵だけを順番に叩いて鳴らしていくと、
自然にこの順番で上がっています。

下がるときは、
__全　全　半　全　全　半　全__
になっていることを確認してください。

## どこの音から始まるか

### 黒鍵は何者か？

先ほど、白鍵だけで、調を具体化しました。
例えば、ドの音から始めたものを、__ファの音から__始めてみましょう。
長調で指定された音階を保つためには、__シに♭（フラット）__を付けて弾きます。

つまり、黒鍵とは、調を維持するための苦肉の策とも言えます。
この、♯（シャープ）または♭は、その調では必ずその音階に付くので、楽譜の冒頭に書き込みます。　これを、__調号__と言います。

調合は…

__♯__が付く場合は、「__5度圏__」
__♭__が付く場合は、「__4度圏__」

の順番に書かれます。（作曲した時には、その順番に書きます。）

### 12音階から、7音階へ

調が定義済みの場合は、始まりの音を1とした、7音階として数えることが出来ます。
一般的に__音階__というときには、12音階ではなく、この__7音階__の事になります。
ここから先は、7音階で話をさせてください。
この場合は、8音階目が1音階目のオクターブ上ですので、8音階目を1音階目とします。

世界共通としては、ラの音が基準ですので、基準の音から順番に、

イ　ロ　ハ　ニ　ホ　へ　ト
A　～　G

で、音名を言います。

例外として…
イタリア読みが一般的な、ドレミです。
ドイツ語では、ちょっと読みが違いますが、一旦省略します。

そして初めて、◯度離れているという音階の表現が出来るようになります。
この場合…

__半音__離れている事を、__短２度__
__全音__離れている事を、__長２度__

離れていると言います。

### 調合と始まりの音との関係性の覚え方

♯の場合は、最後に付いた♯の__半音上の音__
つまり最後に付いた#を7音階目の音とします。

♭の場合は、最後に付いた♭の__5度上の音__
つまり最後に付いた♭を4音階目の音とします。

## 調の名前

今までの話を踏まえると、調の名前が分かるようになります。
__[始まりの音]　[長か短か]　調__
と表現している訳です。
白鍵だけを使用した場合、ハ長調（Cメジャー）かイ短調（Aマイナー）
ということになります。

### 補足
♯の事を、日本語では、「__嬰__」
♭の事を、日本語では、「__変__」と言います。
変ニ長調とか、嬰ハ長調という場合に参考にしてください。

# 次回

調のことは、以上です。
次回は、一先ず転調に触れます。
ありがとうございました。
redirect_toとrenderメソッドの違い 　

#はじめに
　『なぜredirect_toではなくてrenderを使うのだろう？？』
　「renderのメリットは何？？」
画面遷移を行うrenderメソッドとredirect_toメソッドについて、このような疑問が湧いたのでまとめてみました。

#renderメソッドとredirect_toの違い
　画面遷移を行うメソッドはrenderとredirect_toの二つがあります。２つのメソッドの違いは
①render→リクエストを送らず、そのままviewを表示
②redirect_to→再度リクエストを送り、routing→controllerを通りviewを表示させる
です。


#renderとredirect_toの使い方
　renderとredirect_toはそれぞれどのように使うのでしょうか。1つの例として、updateアクションで更新に成功したらredirect_toでトップページに戻る。ブランクなどで更新に失敗したらrenderでeditページに戻るという実装があります。

```hoge_controller.rb
  def update
    @hoge = Hoge.find(params[:id])
    if @hoge.update(hoge_params)
      redirect_to prototype_path(params[:id])
    else
      render :edit
    end
  end
```
この時更新失敗時にrenderを使うメリットとしては、入力値を保持したままeditを再表示できることです。

※注意点としては、変数をインスタンス変数にしておく事です。renderでそのままviewを表示させるのでインスタンス変数を指定しないとエラーになります。

#まとめ
　画面遷移を行う2つのメソッドについてまとめました。redirect_toは単純に１から再表示させたい時などに使い、renderは入力値を残したまま再表示したい時に使うことができます。
今回の記事が少しでも誰かのお役に立てれば幸いです。
静的ページあれこれ


Netlify
----
静的ページを置くことができるサービス

https://dev.classmethod.jp/articles/try-netlify-cms/


FireBase 
----

本当に爆速で静的ページを作成できます。

https://dev.classmethod.jp/articles/hugo-super-fast-static-webpage/#toc-4

https://dev.classmethod.jp/articles/github-actions-hugo-firebase

このページが助けになります。

https://zenn.dev/watarukun/articles/8f3e318bacf97cabf879

AWS Amplify
---
大変便利。静的ページだけでなくアプリも簡単にデプロイできます。
鍵もCloudFrontもRoute53も全自動です。

https://aws.amazon.com/jp/builders-flash/202103/amplify-app-development/?awsf.filter-name=*all


https://qiita.com/changeworld/items/27bc292ec96da53fbc47



S3 と　GitHub Pages　についてもまとめたい
Windows10にDockerをインストールした



※追記
結局UbuntuやVSCodeからDockerを使うことが多い


前提
-
AWS CLIは導入初期設定ずみ


教材
-

https://zukucode.com/2020/08/docker-install-windows.html

https://dev.classmethod.jp/articles/win10_docker_python_ecs_cfn/




コマンドプロンプトで確認
-

docker --version


実作業
-



docker run hello-world

docker pull python:3.6

docker run --name python36 -i -t python:3.6 /bin/bash


python --version

exit

docker run -it python:2.7 /bin/bash

python --version

exit



docker start python36
docker attach python36

pip install awscli --upgrade --user

echo 'export PATH=~/.local/bin:$PATH' >> ~/.bashrc

source ~/.bashrc

aws --version

exit




docker commit python36 my_awscli

PCのCドライブにdataというフォルダを作る

docker run -it -v C:\\data:/root/data my_awscli /bin/bash


root@***:/# aws configure
AWS Access Key ID [None]: HOGEHOGE  <== ここ
AWS Secret Access Key [None]: FUGAFUGA <== ここ
Default region name [None]:ap-northeast-1
Default output format [None]:（Enter)

(疎通確認)
root@df2f35df4933:~# aws s3 ls


cd
aws ec2 create-key-pair --key-name ecs --query 'KeyMaterial' --output text > /root/data/ecs.pem
cp /root/data/ecs.pem ~/ecs.pem
chmod 400 ~/ecs.pem

cd /root/data/


cd /root/data/
 wget https://raw.githubusercontent.com/ambasad/devio-blog-cfn/master/ecs/EC2ContainerService.json
 wget https://raw.githubusercontent.com/ambasad/devio-blog-cfn/master/ecs/EC2ContainerService-param.json

チェック

aws cloudformation validate-template --template-body file://EC2ContainerService.json
qiita apiを叩く

# 概要

javascriptで、qiita apiを叩いてみた。
authenticated_userをgetしてみた。


# サンプルコード

```
var src = document.getElementById('src');
var out = document.getElementById('out');
var endpoint = "https://qiita.com/api/v2/authenticated_user";
function run() {
	var token = src.value;
	//alert(token);
	var xhr = new XMLHttpRequest();
	xhr.onreadystatechange = function() {
		if (xhr.readyState == 4 && xhr.status == 200)
		{
			out.value = xhr.responseText;
		}
		else
		{
			//alert(xhr.readyState);
			//alert(xhr.status);
		}
	};
	xhr.open("GET", endpoint, true);
	xhr.setRequestHeader('Authorization', 'Bearer ' + token);
	xhr.send();
	//alert("ok");
}

```

# 成果物

https://embed.plnkr.co/plunk/pArTYN2rAa1Hu1W9

以上。
CloudFront - ALB - EC2 構成を作る


完成図
--

![Untitled (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178985/f9fc7560-ab19-4ee4-11da-033901f01819.png)



下準備
--

①VPC・サブネット・igw・ルートテーブル・EC2を作成して
EC2内のapacheとかnginxを起動してブラウザでページが見えるようにしておく

②マネコンでRoute53・ACM（東京）・ACL（バージニア）・ALB・CloudFrontを
別タブで開いておく

③ドメインを設定するサイトを開いておく
ムームードメインとか。freenomとか。

ALB作成
--
ACM証明書を作成します。（東京・バージニア両方で）
作成したら③ドメインを設定するサイトに証明書のCNAMEを登録します。
少し待つと、証明書のステータスが発行済みになります。

ALBを作成します。

リスナー80番は443番にリダイレクトさせて、
リスナー443番はさきほど作成したACM証明書（東京）を指定します。
ALBのセキュリティグループを作成して80と443を全許可します。

ターゲットグループを作成します。用意しておいたEC2を参加させます。

ALBを作成し終えたら、さきほど作成したALBのセキュリティグループを
EC2にアタッチします。

ALBのDNS名でブラウザ表示できること
ヘルスチェックが正常なことを確認します

ALBにサブドメインをつける
--

Route53にて、表示したいドメインのホストゾーンを作成します。
レコードの追加で、Aレコードをさきほど作成したALBを指定し、作成します。
aaa.domain.com 
Route53の「値/トラフィックのルーティング先」をコピっておきます。

③ドメインを設定するサイトにサブドメインを
CNAMEとして、コピっておいたALBのルーティング先の値を登録します。

aaa.domain.com でブラウザ表示できること確認します。

CloudFront にもサブドメインをつける
--

CloudFrontを作成します。

オリジンはALBを指定します。aaa.domain.com を指定
代替CNAMEはbbb.domain.comを指定します。
ACM証明書は、バージニアで作成しておいた証明書をあてることになります。

オリジンを追加します


プロトコルはマッチビューアにします。

ビヘイビアを追加します

ビューワはHTTPSにします。

Legacy cache settingsは
ヘッダー→すべてにしておきます。※開発中のみ


Route53にて、表示したいドメインのホストゾーンを作成します。
--

レコードの追加で、Aレコードをさきほど作成したCloudFrontを指定し、作成します。
候補に出てこなければ、dから始まるCloudFrontのディストリビューションドメイン名を貼り付けます。
bbb.domain.com 

ドメインを設定するサイトにサブドメインを
CNAMEとして、コピっておいたCloudFrontのディストリビューションドメイン名の値を登録します。

bbb.domain.com でブラウザ表示できること確認します。

キャッシュ動作を確認したいときは、cache settingsを調整します。


所感
--

自動化したい。
[ターミナル]GUIとCLIについて

##初めに
####なぜこの記事を書きたかったのか
・何気に使っていたけど、いざ説明してくださいと聞かれたらつまづきそうだったので一度言語化して記憶に定着をしたかった。

####環境
・Macbook Air (Retina, 13-inch,2019)
・プロセッサ 1.6GHz デュアルコアIntel Core i5
・メモリ　8GB 2133 Mhz LPDDR3
・MacOS Big Sur　バージョン 11.5.2

####記事の目次
**１）GUIとは**
**２）CLIとは**
**３）最後に**

##GUIについて　
####GUI（Graphical User Interface）とは、デスクトップに配置してあるアイコンをマウスで操作することを言う。例えば、このページのQittaのアイコンや、Macに最初から配置されているリンゴのアイコン、車のカーナビのボタン、映画館や空港においてあるタッチパネルもこのGUIに当てはまります。

**(例：パソコンのGUI例）**
![samplegui.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1102030/5bad35a5-9004-249e-a9ca-99342a5b5356.png)

##CLIとは
####CLI(Character-based User Interface)とは、決まった命令式を命令できる場所に記入してパソコンに指示を出すことを言う。GUIは絵やアイコンを利用して指示を出しているのに対して、CLIは文字を利用して指示を出しています。

**※命令できる場所：（Macの場合）最初からついてる→ターミナル（windowsの場合） インストール必要がある→Azure CLI**
**※CLIは決まった命令式（コマンド）さえわかればGUIと比べてできることが多い！**

##最後に
**なにか物足りない、ちょっと違うぞ？って思うところがございましたらメッセージ飛ばしてくれると幸いです!ここまで読んでくださいましてありがとうございます！**
GASからCloud Storageにアクセスする

1. [サービスアカウントの作成](https://console.cloud.google.com/iam-admin/serviceaccounts?hl=ja)（作成済みのアカウントがある場合はIAMからロールを追加）
2. [apps-script-oauth2](https://github.com/googleworkspace/apps-script-oauth2)をライブラリに追加
3. [apps-script-oauth2/GoogleServiceAccount.gs](https://github.com/googleworkspace/apps-script-oauth2/blob/master/samples/GoogleServiceAccount.gs)を参考に認証部分を実装
4. [Cloud StorageのAPIリファレンス](https://cloud.google.com/storage/docs/json_api/v1?hl=ja)を参考に必要な機能を実装する

GASからCloud Storageに繋ぐまでの最小の流れだけ。

## FAQ

Q. APIリクエスト時に403エラーが返ってきた
A. ロールが正しいか確認 & [curlで問題ないか](https://cloud.google.com/storage/docs/authentication?hl=ja#apiauth)確認

## 参考

https://officeforest.org/wp/2019/05/27/google-apps-script%E3%81%A7cloud-storage%E3%81%AB%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E3%82%A2%E3%83%83%E3%83%97%E3%81%99%E3%82%8B/#OAuth20

https://qiita.com/yunaaktk/items/b169c7afbee0dc6b3168

## その他

GASからFirestoreを更新する場合は以下のライブラリが使いやすい。

https://github.com/grahamearley/FirestoreGoogleAppsScript

GASからGoogleDriveは備わっているDrive APIを利用する。
Railsでログの改行を削除して出力

## やったこと

SQLなどヒアドキュメントで記述されたテキストが出力されたログが非常に見づらかったので、
改行を削除したログを別途出力するようにした。（ついでに処理時刻とpidも）

## コード

```ruby:config/application.rb
require_relative 'custom_formatter.rb'

class Application < Rails::Application
	config.logger = Logger.new('log/custom.log')
	config.logger.formatter = CustomFormatter.new
	# config.log_formatter = CustomFormatter.new
end
```
```ruby:config/custom_formatter.rb
class CustomFormatter < Logger::Formatter
	cattr_accessor(:datetime_format) { "%Y/%m/%d %H:%M:%S" }
	def call(severity, timestamp, _progname, msg)
		"[#{timestamp.strftime(datetime_format)}.#{format('%06d', timestamp.usec)}] (pid=#{$PROCESS_ID}) #{severity} -- : #{msg.class == String ? msg.squish : msg.inspect}\n"
	end
end
```
SaaS　＋　iPaaS時代 is coming

IaaSは　Infrastructure as a Service
PaaSは　Platform　as a Service
SaaSは　Solution as a Service
であることは誰も分かるかと思います。

AWS/Azureの業績からも分かるように、
IaaSは少しでも変革したい企業はほとんど導入済みか導入中であるかと思います。

また、一部の企業はすでにSaaSの検討を始まている。
Databrics,Snowflakeを代表するData領域のServiceProviderの評価額を調べれば多少想像つくかと思います。

上記のようにSaaSを幅広く利用すると、つなぐフローなど要件が出てきますので、
iPaaSの登場となります。
iPaaSとは　Integration Platform as a Serviceの略称で、
簡単に言えば、クラウド内およびクラウドと企業間の統合を構築・展開するためのプラットフォームである。iPaaSを利用することで、ユーザーはクラウドやオンプレミスにあるアプリケーションをつなぐ統合フローを開発し、ハードウェアやミドルウェアのインストールや管理をすることなく、それらを展開することができます。

今年は注目したいです。
apache2環境構築に関することのメモ

RaspberryPi OS 64bitで確認。

# Access-Control-Allow-Origin ヘッダーの追加方法
Access-Control-Allow-Originとは：https://qiita.com/att55/items/2154a8aad8bf1409db2b

```
from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
```
ともかくJavascriptからデータをロードする際出てくる上記エラーの対処のためにサーバー側にAccess-Control-Allow-Origin ヘッダー追加する。

```sh:
$ cd /var/www/html
#htaccessに書く
$ sudo nano .htaccess
Header set Access-Control-Allow-Origin "*"
#apache2のモジュール有効化
$ sudo a2enmod headers
#apache2再起動
$ systemctl restart apache2
```
参考：https://phaier.github.io/school/engineering/platform/server/apache/how-to/cors.html
【Unity】シェーダーグラフ関連トラブルシューティング

# Unity2020.2以降でPBR Graphが見つからない・Createできない

Create時に下記PBR Graphが表示されなくなっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1336886/1b9e0713-0921-271b-7d5e-2de9dce61d1e.png)

Unity2021ではこんな感じになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1336886/a30a8d1a-d7f3-f9b5-51c3-0067928edce2.png)

2020.2以降にLitShaderGraphというものにアップグレードされているようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1336886/442f4fc1-bef7-574d-ff7d-2e0393e03bf9.png)

開くとこんな感じのシェーダーグラフのベースが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1336886/6e8d7a0c-4be7-4d10-bb10-ae577002b7a9.png)

デフォルトではAlphaが表示されていませんが、GraphSettingsのSurfaceをTransparentに設定すると表示されるようになります。
CreateNodeからでも追加することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1336886/eafafb6e-a711-3c3b-9980-88907743abef.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1336886/ddc9f074-3a39-b916-c9c2-6ce2be7e7df4.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1336886/44f4523b-0a13-bf4c-bb17-b4aaa015d07e.png)
表面実装部品の剥がし方

SPI Flashを大きくするとかSDRAMを大きくするなどの場合、元の表面実装部品を剥がす必要があります。

# ヒートガンを使う

Amazonなどで安価に販売されているヒートガンで熱して剥がす方法です。ターゲットのチップの周りに実装された部品がない場合はこちらがお勧めです。かなり綺麗にとれます。注意しなければならないのは、近くに電解コンデンサーがある場合などで、電解コンデンサーを熱すると破裂するので注意してください。防護グラスをするのがよいかもしれません。あまり熱しすぎると基板がゆがむ事があります。プラスチック部品は解けるので事前に外しておくなどするのが良いです、高温になるので、火災などにも注意しましょう。匂いで判断するもの重要です。

# 低温ハンダを使う

ターゲットチップの周りに実装部品がある場合で、そのまま再利用する場合は、低温ハンダを使うのが良いです。半田ごては二丁あると良いでしょう。力をかけて剥がすと元のパターンを傷めてしまうことがあるので注意しましょう。低温ハンダは高価なので、ヒートガンが使えない場合に使うのが良いです。

![写真（2022-07-26 7.22）.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/15ee01df-3225-0185-800c-f388998ada53.jpeg)

![写真（2022-07-26 7.51）.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/9967e46f-49e2-199d-bc82-53c27a4db151.jpeg)

後から確認できる様に、剥がす前の状態の写真を撮っておくと良いです。

ピンが多くなると難易度高くなります。sop 8ピンのflashは比較的簡単に剥がせますが、16ピンはちょっと難しくなります。低温ハンダでもSDRAMは剥がせますが、かなり高度な技術が必要になります。

# 天ぷら油で揚げる

天ぷら油に付けて熱する方法もあるようですが、私は試した事はありません。
Androidで背景タップ時にキーボードを閉じる

Androidの文字入力がある画面で表示されたソフトウェアキーボードは、デフォルトではユーザが閉じる操作をしない限り表示され続けます。
EditTextなどの対象のView以外をタップしたときにフォーカスを外してキーボードを非表示にしたい、という要件に対応します。
__注: composeは考慮していません__

# タップイベントをフックする

`Activity.dispatchTouchEvent(MotionEvent)`を使います。
筆者は執筆時にnavigationを利用していたので、目的のFragmentではなく親のActivityに実装しました

```kotlin
    override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
        binding.navHostFragment.requestFocus()
        return super.dispatchTouchEvent(ev)
    }

```

`requestFocus()`ではフォーカスを移動しています。フォーカスを移動することで、キーボードを非表示にしていい操作なのかどうかを判別しています。逆に言うと、何をしてもキーボードを閉じてもいい場合は`requestFocus()`は実装しなくて良いと思います。
フォーカスさせるViewはフォーカス可能である必要があるので、設定を加えます。`focusable`と`android:focusableInTouchMode`が目的の設定です

```xml
    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:focusable="true"
        android:focusableInTouchMode="true"
        app:defaultNavHost="true"
        app:navGraph="@navigation/navigation_graph"
        />
```

# キーボードを閉じる
先程の実装によって実装されたフォーカスの変更をフックして、閉じる処理を書いていきます。
webで調べるとEditTextからフォーカスが外れた時、を起点にしている記事が多く見かけますがそれだとすべてのEditTextに実装を追加する必要があります。


こんな感じ

```kotlin
       binding.editText.setOnFocusChangeListener { view, b ->
            if (!b) {
                val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
                imm.hideSoftInputFromWindow(view.windowToken, 0)
            }
        }
```

それでも良いですがフォーカスさせたView自体に実装を加えると、少し楽になります。

```kotlin
       binding.navHostFragment.setOnFocusChangeListener { view, b ->
            if (b) { // 条件を反転させた
                val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
                imm.hideSoftInputFromWindow(view.windowToken, 0)
            }
        }
```

制御フローとしては

1. タップする
1. Activity(View)でハンドリングする
1. フォーカスを移動させる
1. 移動先はキーボード表示不要なViewなので、フォーカスされている場合は閉じる処理を実行する

# 参考

https://developer.android.com/guide/topics/ui/ui-events?hl=ja#EventHandlers
【転職】コーディングテスト を　攻略　せよ　！！

（感想）
私が採用側または、大手なら課す。
現職で採択するなら、
チームで使っている技術スタックの問題を選択形式で出題したい。（即戦力がほしい）



#◆チェックリスト & PRPoint
「実装ができる」だけは自己中な状態
→影響範囲が広くなり保守が大変(未然に防ぐ実装)


#◆コーディング面接・試験

1.1～2次面接など、選考の序盤~中盤の段階(４５分)

> コンピュータサイエンスに関連した知識を問われる技術面接もある
 （codingなし）
 事前課題を解き、面接官にその実装について解説をする面接
 （事前のコーディングに3,4時間かかるものもあり）



##流れ

1. 問題の確認
↓
2. 解法を考える
↓
3. 実際にコーディング
↓
4. 解説(工夫点)
↓
5. ディスカッション

```
- 問題の一部が変わったらどのようにコードを変えるか
- 計算量
- 更に改善できるコードがあるかどうか
- エッジケースに対応できているか
- コードを書く際に気をつけたこと(コーディング規約など)
```

##評価ポイント

企業により評価方法はさまざまですが、
以下の項目については共通していると思ってよいでしょう。

```

1. アルゴリズムとデータ構造に関する基礎知識を持っているか
そもそも基礎知識がなければ解けない問題が出題されるので

2. 全てのテストケースを制限時間内に通す実装力を持っているか
→ 入出力例には出ていないエッジケースや例外ケースに気づけるか
→ 計算量を意識して効率がよく実行時間の制約を満たす実装ができるか

3. 変数名や関数名を適切に命名するなど、他人が読みやすいコードを書けるか
一度のコーディング試験で書く必要のあるコードの量はそう多くありません。関数自体を作らなかったり、変数もxやｙなど単純なものを使う場合が多いです。
```


また、コーディング試験の形式によっては
以下のようなポイントも評価されます。

```
・コードを書き慣れているか
オフラインで実施する場合や、コーディング中の画面をその場で映す形式の場合、コードがスラスラと書けるかを見られる場合もあります。

・ディスカッションの中で、自分が書いたコードを分かりやすく説明できるか
コミュニケーション能力やカルチャーフィットについては中盤以降の面接で見られるため、あくまでそれ以前の足切り的な位置づけであるコーディング試験では重要視しない企業が多いと思われます。
```


##おすすめ使用言語
よほど使い慣れている言語が無い限りは、pythonがおすすめ。
> 圧倒的に楽。

業務でjavaを使ってますが、効率重視であえてpythonを選択

#◆対策◆
##　　✖Paizaのスキルチェック
就活サービスとしては良いと思いますが、コーディング試験対策には向いていません。 なぜかというと、模範解答が無いため、復習ができないためです。



```LeetCodeは、海外で有名なコーディング試験対策サイト
(高評価のeasy問題を解きまくる。)
https://leetcode.com/
※goodの比率が50%以上の問題を良問
※力づくではなく、
しっかりとアルゴリズムを理解しながら解くことをオススメします。bruteforceは、誰でもできてしまうので

Codilityで苦手な問題の種類を解く。
楽天などが採用しているらしいコーディング試験サイト


Atcoder(ビギナーコンテストくらいのレベル)やproject eulerなど利用してもいいかもしれません。
```


#要はセンター試験のようなもの
 アルゴリズムをごりごり活用するような会社だと、勉強する価値は大いにある。
ただし、ある程度の企業規模になれば

 
> ※ただし受けた人曰く
　　新しく勉強したアルゴリズムを業務で使ったことは一度もないです。とのこと。



#コーディングテストが実施される企業
（コーディングテストの選考があった）企業

↑難

```
SmartNews（競技プログラミング慣れしていないと難しい)
Recruit
BizReach
Rakuten
Wantedly
```

↓易
その他コーディングテストが実施されることを知っている企業

```
Google
Line
Yahoo
```

プログラミングテストでの選考も可能な企業

```
teamLab
```

（他に知っている方がいたら教えてください）


体感として、ある程度有名なWeb系の企業だと、
コーディングテストが必要な割合は3、4割な気がします。
mediasoup-demo ことはじめ

## 書くこと

[mediasoup](https://mediasoup.org/documentation/) のドキュメントを読みつつ、Localでサンプルを動かしてみようと思ったら微妙に苦戦したので備忘録。

なお使用環境は ThinkPad, Debian Bullseye。

```bash
$ npm -v
8.3.0
$ node -v
v16.13.1
```

## 手順

基本的にREADMEに従えば良いが、自分が追加でやった手順も説明する。

```bash
git clone https://github.com/versatica/mediasoup-demo.git
```

Clone したら、ServerをまずはLocalで立ち上げる。

```bash
cd mediasoup-demo/server
npm install --legacy-peer-deps ## 1
npm install

## 2
mkdir certs && cd certs
openssl genrsa > privkey.pem 
openssl req -new -x509 -key privkey.pem > fullchain.pem 
cd ..

cp config.example.js config.js
export MEDIASOUP_LISTEN_IP=192.168.68.116 ## 3

npm start
```

1. npm v7 以降で peerDependencies の挙動が変わったので、それを古い挙動に変える。
1. おれおれ証明書を作成する。
1. serverが動く（localの）アドレスを指定する。自分の場合 `192.168.68.116` だった。


次に別のターミナルでClientを起動する。

```bash
cd mediasoup-demo/app
mkdir 
npm install
npm start
```

こちらは特に気にすることはなし。うまく行けば勝手にデフォルトブラウザが起動して、サンプルアプリ（ビデオ会議ツール）が動く。
動画に好きな処理をしたい！ そんなライブラリがあったので、実写をアニメにした

# かんたんに動画の全てのフレームに任意の処理ができるフレームワーク
既存の動画ファイルに好きな処理ができるフレームワークを使って、実写をアニメにします。
<img src=https://user-images.githubusercontent.com/23278992/148341103-a44f2b04-2f93-4c69-8cfd-f5ba36801075.gif>

# 動画処理はややこしそう？
動画の読み出し→加工→書き込みの処理は、いろいろ書かなくてはいけなさそうなイメージでややこしそうではないですか？

# 全てのフレームを処理することなんてできるのか？
結局、動画はすごくたくさんの量の画像が集まったパラパラ漫画のようなもので、
動画を加工するには、その全てのフレームに加工処理を加えないといけないのでは？

# SemanticImageで、かんたんに、動画に好きな処理ができる
[**SemanticImage**](https://github.com/john-rocky/SemanticImage)というライブラリなら、数行のコードでかんたんに動画処理ができます。
パラパラ漫画の一枚（動画の1フレーム）にしたい処理を書くだけで、全てのフレームを加工してくれます。

https://github.com/john-rocky/SemanticImage

#具体的手順

SwiftPackageManagerでSemanticImageをプロジェクトに加え、importします。
あとは、動画処理関数を呼ぶだけです。

```swift
SemanticImage().applyProcessingOnVideo(videoURL: url, { ciImage in
    // 動画のフレームをciImageとして、ここにciImageを加工する処理を書く
    return newImage
}, {  err, editedURL in
   // 加工ずみの動画URLが返ってくる
})
```

# 実写をアニメにしてみた

上記関数のフレーム加工部分に、[**CoreML-Models**](https://github.com/john-rocky/CoreML-Models)からダウンロードしたAnimeGANで加工をするコードを入れてみました。
<img src=https://user-images.githubusercontent.com/23278992/148341103-a44f2b04-2f93-4c69-8cfd-f5ba36801075.gif>

https://github.com/john-rocky/CoreML-Models


# フィルターや機械学習画像処理にも
フレーム加工部分に、CIFilterや他の機械学習モデルの処理を入れると、かんたんにいろいろな動画加工ができます。
🐣
****
フリーランスエンジニアです。
お仕事のご相談こちらまで
rockyshikoku@gmail.com

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

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
Is Banking Heading Towards Digital Transformation in the Near Future?

Digital Banking is no more a talk of the future, and we all have witnessed the transformation of the Indian banking system. There was a time when visits to the banks were an essential part of our weekly schedules but it has almost become a phenomenon of the bygone era now. With most banking services available literally at our fingertips, digital banking has now become an inseparable part of our lifestyle. As just within the last decade the technological advancements like cloud computing in BFSI and many others, have brought about impeccable changes in the banking sector. From cards to digital payments, the digitization of the core banking services and not to forget the ground-breaking UPI payments mode, have become clearly synonymous with day-to-day business in the banking sector.

The Present Status of Digital Banking in India

Talking about Digitization in the present day in Banking System, yes the sector has come a long way ahead of both in terms of the Core Banking System and various other administrative services in the daily business of the banking and finance organizations. Especially with the updates in the cloud banking solutions in India, banking administration has simplified and most importantly has brought about a remarkable change which has made the ease of doing banking business a thing of the present. Otherwise, who would have thought of real-time payments, easy or same-day loan procedures, or even a completely paperless Core Banking System? All becoming a common phenomenon in today’s banking system. Not just words but even numbers prove it with statistics from Statista about the “Total number of digital payments across India from the financial year 2018 to 2021” which clearly proves the exponential growth of digital payments in India, i.e. from USD 14.59Bn in FY 2018 to USD 43.71Bn in FY 2021.

Source:https://www.esds.co.in/blog/is-banking-heading-towards-digital-transformation-in-the-near-future/
Genie: GET の引数の処理

こちらと同じことを Genie で行いました。
[https://qiita.com/ekzemplaro/items/3f892bf7ff53d8b0ca02](https://qiita.com/ekzemplaro/items/3f892bf7ff53d8b0ca02)

```julia:get01.jl
# --------------------------------------------------------------------
#	get01.jl
#
#						Jan/06/2022
# --------------------------------------------------------------------
using Genie
using Genie.Router
using Genie.Renderer.Json
using Genie.Requests

function launchServer(port)

	Genie.config.run_as_server = true
	Genie.config.server_host = "0.0.0.0"
	Genie.config.server_port = port

	println("port set to $(port)")

	route("/") do
		"Hello."
	end

	route("/sum") do
  	aa = getpayload(:aa, "0.0")
  	bb = getpayload(:bb, "0.0")
	sum = parse(Float64,aa) + parse(Float64,bb)
	rvalue = Dict()
	rvalue["wa"] = sum
	json(rvalue)
	end

	route("/diff") do
  	aa = getpayload(:aa, "0.0")
  	bb = getpayload(:bb, "0.0")
	diff = parse(Float64,aa) - parse(Float64,bb)
	rvalue = Dict()
	rvalue["sa"] = diff
	json(rvalue)
	end

	Genie.AppServer.startup()
end

# --------------------------------------------------------------------
launchServer(parse(Int, ARGS[1]))

# --------------------------------------------------------------------
```

サーバーの起動

```bash
julia get01.jl 8000
```

HTTPie のクライアント

```bash
http http://127.0.0.1:8000/sum aa==21.3 bb==82.1
http http://127.0.0.1:8000/diff aa==21.3 bb==82.1
```

Curl のクライアント

```bash
curl 'http://127.0.0.1:8000/sum?aa=21.3&bb=82.1'
curl 'http://127.0.0.1:8000/diff?aa=21.3&bb=82.1'
```
【IBM Security Verify 】CSVを使用したグループ登録を行う

# はじめに
IBM Security Verify のAPIを利用して、CSVからグループ登録を行う方法についてご紹介します。

# CSV作成時に把握しておくこと
CSVインポートにあたり、以下の条件があります。

- A maximum of 256 first-level, nested group members is allowed 
- A maximum of 2,500 users members is allowed in the input payload （CSV 1行で指定できるグループのメンバーは2500名まで）
- The maximum file size is 10MB
- Multiple group members are specified with a '|' delimiter. (メンバーを複数指定する場合は|を区切り文字にする)
- The members may be specified by name or ID
![csv-group.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/8b20a166-23f3-2ba4-fa5d-f5dc2aac0994.png)
- Attribute values that contain a special character (i.e. comma) must be enclosed in double quotes.

また、動作確認した結果では、実行にあたっては以下の制約がありました。

- グループのインポートAPI(/v2.0/CSV/importGroups）を複数同時実行できません
- ユーザーのインポートAPIとの同時実行できません。

# APIのリファレンス
IBM Security Verify API Documentationから確認できます。

Import groups for the specified tenant from a comma separated value (CSV) file.
https://docs.verify.ibm.com/verify/reference/importgroups

# 1.事前準備について
APIクライアントの準備や、アクセストークンの発行は、
 - [IBM Security Verify API で ユーザーのアカウントを無効化する](https://qiita.com/fitz/items/7874a95245eea3ecef13)を参照ください。

# 2.CSVの準備

CSVには1行目に属性値を記載し、2行目から登録するデータを指定します。
登録したい属性値にあわせて1行目を変更します。

今回の例では、以下の2つのグループを登録します。
- testuser01/testuser01ユーザーを含むtest1210groupv1を登録
- test1210groupv1を含むtest1210groupv1nestグループを登録


```group_nest.csv
displayName,members.user,members.group
test1210groupv1,testuser01|testuser02,
test1210groupv1nest,,test1210groupv1
```
![csv-group.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/ba1c5ed0-2f42-bae6-35fa-13ae7822c9c8.png)


# 3.CSVによるユーザー登録

CSVのインポートは、/v2.0/CSV/importGroups を利用します。

実行するリクエストは以下のような形になります。

```
curl -X POST https://<テナント名＞.verify.ibm.com/v2.0/CSV/importGroups  -H "Content-Type: multipart/form-data;charset=UTF-8" -H "Authorization: Bearer <アクセストークン>" -F file=@<CSVのファイルパス＞
```

戻り値としてrequest IDが返ってきます。
![csv-group2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/e393a7de-327b-5289-45fb-b382dc8b2886.png)


# 4.処理結果の確認
CSVの処理結果は、/v2.0/CSV/jobs で確認できます。

```
curl -X GET https://<テナント名＞.verify.ibm.com/v2.0/CSV/jobs/<request ID> -H "Authorization: Bearer <アクセストークン>"
```
![csv-group3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/b989515d-6280-474f-3b84-743be27b5522.png)

管理者画面でグループ、および、メンバーの登録内容を確認します。
![csv-group4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/bd2aa89d-7b5b-1196-171b-64751637d8af.png)

![csv-group5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/cd08ff64-e971-6cb3-5713-748b33018ac2.png)



# 最後に
IBM Security VerifyのAPIを利用してCSVからグループを一括登録する方法についてについてご紹介しました。