OmniAICreator/Qiita-1.07M huggingface dataset:
Quantum-secured blockchain ①


突然ですが，皆さんブロックチェーンしていますか？ビットコインの価値が上がったり下がったりが時々話題になりますよね．

そんなビットコインなど暗号資産の背景にあるブロックチェーンですが，途中で用いられる署名方式がECDSAだったりと，このままでは量子コンピュータの台頭以降では安全性が破られてしまいます．

もちろん，耐量子性のある署名方式へ取り替える動きもあります．例えば，

https://arxiv.org/pdf/2012.15799.pdf

このプレプリントは，NISTのPQC第３ラウンドに残っている Rainbow という多変数多項式暗号ベースの署名方式をブロックチェーンに使用しています．

しかし，いずれは到来するであろう，量子の時代ですから，せっかくなら量子プロトコルを前提にしたブロックチェーンの研究がもう進んでいても良いのではないだろうか？と思い，色々勉強していこうと思います．

不定期で量子ブロックチェーンの話題を投稿します．理論解説がメインになると思いますが，Qiitaらしく？適宜Githubも参考にして，コードも挟んで行こうと思います．

## 参照
初めに以下の論文を参照にします．

E. O. Kiktenko, N. O. Pozhar, M. N. Anufriev, A. S. Trushechkin,R. R. Yunusov, Y. V. Kurochkin, A. I. Lvovsky, and A. K. Fedorov,
‘‘Quantum-secured blockchain,’’ 
Quantum Sci. Technol., vol. 3, no. 3,2018, Art. no. 035004

おそらく量子通信を前提としたブロックチェーンの理論はこの論文が初なんじゃないかと思います（間違っていたら早急に削除します()）．

さらっと見た感じだとQKDが分かっていれば理解できるようですね．

あと，さすがにブロックチェーンの知識は前提とします．具体的には[ビットコインとブロックチェーン:暗号通貨を支える技術](https://www.amazon.co.jp/%E3%83%93%E3%83%83%E3%83%88%E3%82%B3%E3%82%A4%E3%83%B3%E3%81%A8%E3%83%96%E3%83%AD%E3%83%83%E3%82%AF%E3%83%81%E3%82%A7%E3%83%BC%E3%83%B3-%E6%9A%97%E5%8F%B7%E9%80%9A%E8%B2%A8%E3%82%92%E6%94%AF%E3%81%88%E3%82%8B%E6%8A%80%E8%A1%93-%E3%82%A2%E3%83%B3%E3%83%89%E3%83%AC%E3%82%A2%E3%82%B9%E3%83%BBM%E3%83%BB%E3%82%A2%E3%83%B3%E3%83%88%E3%83%8E%E3%83%97%E3%83%AD%E3%82%B9/dp/4757103670) ぐらいですかね．マスタリング・ビットコインです．

## 背景
上でも書きましたが，現在のブロックチェーンはECDSA（楕円曲線を使った暗号方式）やRSA（素因数分解の困難さに基づく暗号方式）がほとんどなので，Shorのアルゴリズムを使うと，多項式時間で解読されてしまいます．
これは単に鍵長を伸ばせば解決する話ではないので，新たな暗号化方式を考える必要があります．

＊Shorのアルゴリズムは以前に記事を書いたので，そちらも（唐突な宣伝）．
[量子アルゴリズム①　Shorの素因数分解アルゴリズム](https://qiita.com/0917laplace/items/982f171d023ef2fe6320)

そこで，量子コンピュータでも簡単には解読できないような古典でできる暗号化方式を考える必要がある（僕の研究テーマ）のですが，
実は，QKDという量子コンピュータの通信プロトコルを使用すると，「情報理論的な安全性」のもとで秘密鍵を配送することができます．
「情報理論的な安全性」なので，攻撃者が古典だろうが量子だろうが関係ない，ということですね．

＊現状だと，初めに紹介したRainbowという多変数多項式暗号ベースの署名方式やCRYSTALS-Kyberという格子暗号ベースの署名方式などが有力だったりします
Rainbowはつい最近も話題になりましたね（それよりも鍵長を短くしたというものですが）
[話題のやつ]
(https://www.jst.go.jp/pr/announce/20211124-2/index.html)

＊QKDも以前に（以下略）．
[量子アルゴリズム④　量子鍵配送](https://qiita.com/0917laplace/items/b2ad19c134d8a6afbb7d)

QKDでは基本的に２人の間に量子チャネルと古典チャネルを使うので，QKDを扱う際にはチャネルは２つ出てくることになります．

## まとめ
今回の論文で出てくるブロックチェーンの特徴などをまとめます．

- 個人のマイナーが新たなブロックを作るのではなく，全てのノードが同じ条件で新しいブロックの合意をするプロトコル
- その結果，トランザクションの透明性が維持できる
- デジタル署名を使わない（broadcast protocol）

デジタル署名を使わなくても，QKDで秘密鍵を配送できるから，全員でチェックできる，というイメージなんですかね（間違っていたらすみません）．
本題に入っていないため，この辺はまだ「おまじない」ですが，次回の記事が終わったらもう一度振り返ります．

＊デジタル署名などの話は参考文献にも書かれています
[参考文献のURL](https://honto.jp/netstore/pd-book_27435104.html)

## 最後に
QKDを使うと情報理論的な安全性を確保できるので，こういう発想は今後増えてきそうですね．
次回から具体的なプロトコルに迫っていきます．

## 参考文献
- 西野哲朗，岡本龍明，三原孝志，『ナチュラルコンピューティング・シリーズ 第６巻 量子計算』，近代科学社，2015年
システム開発を外注するときはゴールを明確にしよう

# 何が起きたか

外部APIからデータを抽出してDBに保存する処理を業務委託で外注にお願いしていたときの話。

----

外注さん「開発完了しました。」
わい「単体テストまで行いましたか？」
外注さん「単体テスト実行しました」
わい「では、ちょっと動作確認しますね〜」

----

試しに実行してみたところ、何もDBに保存されない・・・。

----

わい「これ開発環境では動きました？」
外注さん「動きました」
わい「なんか何も保存されないんですよね〜。DBにデータ入りました？」
外注さん「そこまでは確認して無いです」
わい「えっ・・・。じゃあ何を単体テストしたんですか？」
外注さん**「バッチを実行してエラーが出ないことを確認しました」**

----

軽くソースみたところ単純なバグで何もせずに終了するようなバッチになっていた。
外注さんの中ではsyntaxエラーを無くすまでが単体テストだったようです・・・。
せめてDBに値が保存されるところまでは確認して欲しかった・・・。

# 何が問題だったのか

こちらもテスト仕様書のようなものは作っていなかったので、単体テストのゴールが不明確でした。
「基本機能くらいは何も言わなくてもテストしてくれるだろう」と勝手に期待していたのが問題でした。

テスト仕様書を作るまでしなくとも、最低限**「これができるようになることがゴール」**くらいは指示しておけば良かったです。

# ちなみに

駆け出しエンジニアなどではなく、エンジニア歴30年のベテランさんでした。この30年一体何をしてきたのか気になりました。
RDKitで原子の特徴を計算しPandasに取り込んで使い倒そう

#はじめに
以前、[原子の特徴を計算するプログラムを作成してみた](https://qiita.com/kimisyo/items/ccdd62a7b76cc493d85f) という記事を書いたがそこではCDKを使った。今回はRDKitでそれをやってみたい。

#環境
- RDKit 2021.09.2

#対象記述子
- MorganFingerprint
- AtomPairFingerprint

対象記述子とはいいながらもフィンガープリントである。
MrogainFingerprintはある原子を中心とした一定の半径内の環境を表現するものであり、AtomPairFingerprintは原子同士のペアを表現するものである。これらは通常は分子を指定して計算するが、引数を指定することで特定の原子に関連するものだけを計算することもできる。

今回は原子単位でそれらのフィンガープリントを計算し、結果をPandasのデータフレームに取り込む方法を解説する。
 
#ソース

まず、いつものようにライブラリをインポートしよう。

```python
import numpy as np
import pandas as pd
from rdkit import rdBase, Chem
from rdkit import DataStructs
from rdkit.DataStructs import ExplicitBitVect
from rdkit.Chem import AllChem, Descriptors
from rdkit.ML.Descriptors import MoleculeDescriptors                  
from collections import defaultdict
```

続いてsmilesの格納されたcsvを読み込もう。

```python
# ファイルの読み込み
import codecs
with codecs.open('./datas/bace.csv', 'r', 'utf-8', 'ignore') as f:
    df = pd.read_csv(f)
```

続いてSMILESと名前を取り出そう

```python
# SMILESのデータを取り出す
smiles_list = df["mol"].values
# 名前を取り出す
names_list = df["CID"].values
```

RDKitのMOLオブジェクトに変換しよう。

```python
# SMILESのリストをMOLに変換
mols = []

for i, smiles in enumerate(smiles_list):
    mol = Chem.MolFromSmiles(smiles)
    if mol:
        mols.append(mol)
    else:
        print("{0} th mol is not valid".format(i))
```

さぁ、いよいよFingerPrintの計算だ。やり方は、分子内の原子を```GetAtoms```メソッドで順次取り出し、```fromAtoms```に原子のインデックスを指定して、フィンガープリント計算関数を呼び出すだけだ。

```python
mg_fps_tmp = []
ap_fps_tmp = []
mg_keys = set()
ap_keys = set()
atom_names = []

# 分子でループ
for i, (mol, name) in enumerate(zip(mols, names_list)):   
    # 分子内の原子でループ
    for atom in mol.GetAtoms():
        # 一意な原子名を付ける
        atom_name = str(name) + "_" + str(atom.GetIdx())
        atom_names.append(atom_name)
        # MorganFingerprintの計算
        mg_fp = AllChem.GetMorganFingerprint(mol, 2, fromAtoms=[atom.GetIdx()])
        mg_fps_tmp.append(mg_fp.GetNonzeroElements())
        for key in mg_fp.GetNonzeroElements():
            mg_keys.add(key)
        # AtomPairFingerprintの計算
        ap_fp = AllChem.GetAtomPairFingerprint(mol, fromAtoms=[atom.GetIdx()])
        ap_fps_tmp.append(ap_fp.GetNonzeroElements())
        for key in ap_fp.GetNonzeroElements():
            ap_keys.add(key)

#結果をまとめる
fp_dict = defaultdict(list)
for i, (mg_fp, ap_fp) in enumerate(zip(mg_fps_tmp, ap_fps_tmp)):
    print(i, len(mg_fps_tmp))
    for mg_key in mg_keys:
        if mg_key in mg_fp:
            fp_dict["mg." + str(mg_key)].append(mg_fp[mg_key])
        else:
            fp_dict["mg." + str(mg_key)].append(0)

    for ap_key in ap_keys:
        if ap_key in ap_fp:
            fp_dict["ap." + str(ap_key)].append(ap_fp[ap_key])
        else:
            fp_dict["ap." + str(ap_key)].append(0)
            
#データフレームの構築
df_fp = pd.DataFrame(data=fp_dict, index=atom_names)
```

このデータフレームを表示すると、こんな感じで原子毎にフィンガープリントが得られる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329816/addda413-99c7-304d-1613-5b5dad43032a.png)

さぁ、これで原子の性質を予測するモデルを作ってみよう！


#おわりに
今回は2種類のフィンガープリントで試したが、他のフィンガープリントもできるかもしれない。
クラウド上のサーバのセキュリティ設定ミスると制御不能になる

## 何がおきてしまったか
- クラウド上のサーバでiptableとか公開鍵認証とかSELinuxの設定ミスると、サービスは動き続けるのに誰もログインできない制御不能のサーバになってしまう

## しくじりはなぜおこってしまったのか

- iptableですべてのsshを拒否してしまう
- アクセス可能な公開鍵をすべて消してしまう
- SELinixをめっちゃ強固にしてしまう

## 二度としくじらないためにどうしたのか(どうしようと思っているか)
- ネットワーク、セキュリティ設定いじる時は必ずログインしっぱなしのターミナルを一つ残しておく
    - すでに繋がっているターミナルが設定変更で切断されることはない。NIC落とされない限り
        - 何もしてないとサーバ側から切断されちゃう時があるので、`top d 1` とかで何かを動かし続ける
- 最近はそういうことやるバカのためにシリアルポートアクセスができるようになっている
    - [EC2 シリアルポートアクセスが可能になりました | DevelopersIO](https://dev.classmethod.jp/articles/ec2-serial-console-linux/)

## その他
- これで何個かEC2潰した
データ通信カードで300万円の請求が来た昔話

## 何がおきてしまったか
- 出張で半年ほどホテル暮らしすることになった際に、会社から支給された某社のデータ通信カード（今でいうポケットwifiみたいなもの）使っていたら、1ヶ月分で某社から300万円の請求が来た

## しくじりはなぜおこってしまったのか
- 出張に伴い、使い放題プランを契約しているという某社のデータ通信カードを支給される
- 設定マニュアルがなく試行錯誤してどうにかつなげる
- その時された設定が実は**使い放題プランの対象外の高速プラン的な設定**だったが、気づかずに使い続ける
- さらにPCの電源を切らずに、1ヶ月24時間通信し続けた

## 二度としくじらないためにどうしたのか(どうしようと思っているか)
- 設定マニュアルはちゃんと用意しましょう
- 使い放題とはいえ、使っていない時はOFFにしましょう。データ通信カードもPCも。

## その他
- 設定マニュアルを用意していなかった会社の責任ということでお咎めはなかったものの、そのプロジェクトの粗利が300万円だったらしく、受注した意味のないプロジェクトになってしまった。
初心者エンジニアが多用したGitコマンド

この記事は、入社してすぐの、右も左も分からない自分のような人に向けて書きます。
中級者・上級者の方には参考にならないと思いますが、逆にここはこうだろとか、違うよとか、このコマンドは多用した方がいいとかありましたらコメメントしていただけると幸いです。

<h4 style="margin-bootom:0px;">この記事の対象者</h4>
1.git初心者
2.プログラミング初学者



#頻繁に使用するGitコマンド




__ローカルの変更を確認する__

```
git status
```
僕が半年間で一番使用したgitコマンド。現在どのファイルを変更したかを確認できる

__リモートとローカルのファイルの差分を抽出する__

```
git diff
```
どのファイルの、どの箇所を変更したの確認できるので、作業後、無駄な変更点、改行やconsole.logの消し忘れなどを探す時に使用する。特定のファイルの変更点のみ、表示したい場合は、「git diff　ファイル名」でok。

__ファイルの登録（コミットするため）__

```
git add .
```
説明が自分でもあまりできないのだが、「git status」で表示される赤くなっている変更されたファイルを緑色にしてコミットできるようにする

__ファイルの変更や追加をコミット__

```
git commit -m "コミットメッセージなんでも良い"
```

__リモートにプッシュ__

```
git push origin ブランチ名
```
pushすることによりプルリクエストが作成できたり、プルリクエストに変更点が反映されたりする。

__ブランチの一覧表示__

```
git branch
```
自分が作成したブランチ一覧を表示できる。現在いるブランチは色が緑色になる。

__指定したブランチに移動__

```
git checkout ブランチ名
```


__新しいブランチを作成__

```
git checkout -b ブランチ名
```

__指定したブランチから変更を取得する__

```
git pull origin ブランチ名
```
このコマンドを使用することにより、他ブランチの変更点を取得することができる。私は、
①作業が終わりdevelopブランチに移動しとき
②久しぶりに作業を再開するブランチに移動したとき
の２場面でよく使用する

#たまに使用したGitコマンド

__変更点を一旦退避させる__

```
git stash apply
```
他のブランチに移動したいけど、現在いるブランチの変更点をコミットしたくない!という時に一時的に変更点を退避できるコマンド。

__退避した作業の一覧を見る__

```
git stash list
```

__退避した作業のを元に戻す__

```
git stash apply stash名
```

__ブランチ名の変更1__

```
git branch -m <新しいブランチ名>
```
今いるブランチ名の変更するときはこれ!

__ブランチ名の変更2__

```
git branch -m <古いブランチ名> <新しいブランチ名>
```
他のブランチの名前を変えたいときはこっち!

__直前のコミット内容を修正したい__

```
git reset --soft HEAD^
```
直前のコミット内容を変更削除したい時に使用するコマンド。初学者は、よくわからずいろんなコマンドをとりあえず打って、取り返しがつかないことになる可能性があるからreset系を使うときは先輩に質問した方がいいと思う。


#終わりに
以上が私が入社半年で頻繁にたまに使用したGitコマンドの紹介でした。
もちろんこれの数十倍のコマンドがあるとは思いますが、初学者はとりあえずこの頻繁に使うGitコマンドは覚えておきましょう。
最後まで読んでいただきありがとうございました☺︎
inとかnot inは遅い

## 何がおきてしまったか
- しくじりってほどじゃないけど、実装してて気づいたこと
- データが多いテーブルへの`in`とか`not in`は遅い。

```sample.sql
select r0.id from reserves r0 
where
r0.reserved_at is not null
and r0.member_cd not in (select member_cd from members)
```

## しくじりはなぜおこってしまったのか
- オプティマイザがいい感じにしてくれるかと思ったらそんなことなかった
- explainかけたら全然index効いてなかった

## 二度としくじらないためにどうしたのか(どうしようと思っているか)
- `join`すればちゃんとindex効いて速い。
- クエリの検証はまあまあデータ入ってるテーブルでやろう。
    - データ少ないとクソクエリでも高速に動いてしまう。

```sample.sql
select r0.id from reserves r0 
left outer join members m on m.member_cd = r0.member_cd 
where
r0.reserved_ts is not null
and m.member_cd is null
```
New Relic を使って問題の原因を特定し、一瞬で処理を爆速にした

# 概要

みなさんこちらの絵は何に見えるでしょうか。

![スクリーンショット 2021-12-06 19.31.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218682/79f29aea-722a-915f-80f2-8613ea639ceb.png)

カントリーマアムの断面にも見えますよね? おしい!! これは New Relic 上に残された API サーバのレスポンスタイムです。

弊社サービスは簡単に図で表すと、AWS に配置された以下のような構成となっています。
(図の EC2 のところは一部 ECS に置き換わっているのですが、とりあえず雰囲気が伝われば。)

![イメージ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218682/8d5ce99d-ebc6-4b50-d702-eba78ab64c0b.png)

今回、問題になったのは 上記図における API のところです。
なんだかレスポンスが遅くなったぞという話があがってきました。

API サーバですので、インターネットからの1リクエストに対して、ウェブサーバから何回か API サーバへリクエストがいくわけですから
API に対する 1 リクエストのレスポンスが 300ms だとしても、
ユーザのブラウザ側への応答時点で、5〜10秒のレスポンスになりますので、もうサービスとして致命的になってきます。

そこでどれだけこのカントリーマアム、、、もとい、New Relic のグラフからサクッと原因を突き止め、改善したかを共有します。

# 調査

まずあからさまにグラフの盛り上がっている箇所にマウスオーバーすると、Memcached と表示されます。
![スクリーンショット 2021-12-06 19.54.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218682/39c00cd0-cd41-4baf-edbb-a52942623cc1.png)

さらに、Transactions 一覧に重かったリクエストの代表選手がいるので、上位のものをクリックします。

![スクリーンショット 2021-12-06 19.56.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218682/c084c7ea-0f7e-f469-1eda-14b924cd1d39.png)

クリックすると、Throughput うちデータベースへのリクエストが表示されました

![スクリーンショット 2021-12-06 19.58.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218682/68beb394-d655-c117-0286-648c996466fe.png)

Memcached get が1秒近くかかっている。これはなんだ。。。
ウェブサーバが セッションや API応答結果を保存するために Memcached 使う想定はあったが、API サーバから Memcached を呼ばれている想定はなかった。
その上で、セキュリティグループで不要なポートや接続元を整備していました。検証が不十分だったということが反省点ではあるものの、
New Relic を使うことで一瞬で原因の特定ができました。

APIサーバで Memcached を使う処理を無効化することで、問題は難なく収束しました。(ウェブサーバでキャッシュしているものを、API サーバでも同じデータをキャッシュするような処理になっていたため無効化した)
【Rails】OpenSSLが1.1.1なのにLet’s Encryptの証明書でverify errorが発生する

2021年9月30日に発生した、Let’s Encryptのルート証明書の切り替え問題。
Amazon Linux1（OpesnSSL 1.0.2）上で稼働する弊社のRailsアプリケーションもしっかり影響を受けました。
AWSから対応方法についてアナウンスがあったのでその手順に従ってみたものの、イマイチうまくいかず、、、

そこで、ちょうどインスタンスをUbuntu20.04（OpesnSSL 1.1.1）に移行させる予定があったため、
Ubuntu上で稼働するようにアプリケーションを調整して入れ替えれば解決！
と思いきや、依然としてverify errorが発生。

以下は、Ubuntu上で奮闘した対応の記録です。

### 環境
- Amazon Linux1（OpesnSSL 1.0.2）
- Ubuntu 20.04（OpenSSL 1.1.1）
- Ruby 2.5.1
- Rails 6.0.3.6

## OpenSSLのアップデートを試みる
OpenSSLのバージョンが低いと問題が起こるらしいので、バージョン1.1.1といえどアップデートしてみる。

```bash
$ sudo apt update && sudo apt upgrade openssl
```

しかしアップデートは起こらず。最新のものが入っているようです。
念のためopensslコマンドで接続してみる。

```bash
$ openssl s_client -connect XXXXX.com:443
```

Amazon Linux1の方ではこのコマンドでverify errorが出ましたが、Ubuntuの方では発生せず。
よって、OpenSSL 1.1.1自体は問題なさそう。

## RubyがOpenSSL 1.1.1を見ていないのではないか？
1.1.1より古いバージョンのOpenSSLがシステム内に入っていて、Rubyがそちらを参照してしまっているのではないか？という仮説のもとに確認。

```bash
$ ruby -ropenssl -e "p OpenSSL::OPENSSL_VERSION"
```

しかし、問題なく1.1.1を参照しているようでした。

## Rubyがルート証明書のリストを正常に認識できていないのではないか？
ルート証明書のリストに`DST Root CA X3`が存在する、もしくは`ISRG Root X1`が存在しない、などの理由で問題が起こっているのではないか？と疑ったので、デフォルトのCA証明書ファイルを確認。

```bash
$ ruby -ropenssl -e "p OpenSSL::X509::DEFAULT_CERT_FILE"
```
しかしこちらも問題なし。

## rubyコマンドではなくてプログラムファイルから実行する時に何か問題あるんじゃないか？
上記は全てrubyコマンドで実行したので、https接続確認用の簡単なプログラムを書いて実行してみる。
（参考： https://qiita.com/takano-h/items/dd10818eb7e09161bc29）

```ruby
require "net/http"

uri = URI.parse("https://XXXX.com/")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = uri.scheme === "https"

headers = { "Content-Type" => "application/json", "Authorization" => "Basic XXXXXXX" }
response = http.get(uri.path, headers)

puts response.code # status code
puts response.body # response body
```
こちらもverify errorは発生しないので問題なさそう。

## よくわからないが、たぶんアプリケーション側が悪いんじゃないか
- OpenSSLは問題なし
- Rubyも問題なし
- 証明書リストも問題なし
- プログラムファイルを実行しても問題なし

インフラ側でできることがもう何も無い気がしてきたので、アプリケーション側を疑うことに。
Railsは詳しくないので、`最新のBundlerをインストール→Gemfile.lockを削除してbundle install`という強硬手段に出ました。

すると見事にverify errorが解消されてしまいました。
どうやらアプリケーション側で使用しているgemに問題があったようです。

## 問題は`openid_connect`のgemが古かったこと
改めて開発側に事情を説明し、http通信に関係するgemを洗い出してもらいました。
その中のgemを順にアップデートしてみたところ、`openid_connect`をアップデートしたところで問題が解消されました。

Amazon Linux1の方でも`openid_connect`をアップデートしたところ、こちらもverify errorが解消されて問題なく稼働してくれました。

## おわりに
上記はサラッと書きましたが、原因究明までにはかなり時間を要してしまいました。
OpenSSLやRuby/Railsまわりの知識があれば、もっと早く辿り着けたかもしれません。

日常的なインフラ対応は経験則でなんとかなる部分も多いですが、イレギュラーな事態へ対応していくには、基礎的な知識をもっとつけていく必要があるなと感じました。
Unityで他のスクリプト上の関数を別のスクリプトから呼び出す方法のまとめ

#他のスクリプトの関数ってどうやって呼び出すんだっけ？
何回かゲームを作っていても、どうしても忘れてしまうので自分の健忘録を兼ねて記事にまとめます。

##他のスクリプトをアタッチする方法
Demoscript.cs上の関数Hogehogeを、Demomanager.cs上の関数DemomanagerHogehogeで呼び出す方法を記載します。

```C#:Demoscript.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Demoscript : MonoBehaviour
{
 public void Hogehoge()
    {
        Debug.Log("Hogeoge");
    }
}
```

```C#:Demomanager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Demomanager : MonoBehaviour
{
    public Demoscript demoscript;

    public void DemomanagerHogehoge()
    {
        demoscript.Hogehoge();
    }
}
```

それぞれをヒエラルキー上の空のオブジェクトにアタッチし、Demomanagerオブジェクト内のDemomanager(Script)コンポーネント内にあるDemoscriptに、Demoscript.csをアタッチしたDemoscriptオブジェクトを入れます。
これで、関数の呼び出しが可能になります。

##シングルトンを利用する方法

```C#:Demoscript.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Demoscript : MonoBehaviour
{

    public static Demoscript instance;

    private void Awake()
    {
        if (instance == null)
        {
            instance = this;
            DontDestroyOnLoad(this.gameObject);
        }
        else
        {
            Destroy(this.gameObject);
        }
    }
    public void Hogehoge()
    {
        Debug.Log("Hogeoge");
    }
}
```

```C#:Demomanager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Demomanager : MonoBehaviour
{
    public void DemomanagerHogehoge()
    {
        Demoscript.instance.Hogehoge();
    }
}
```
それぞれのスクリプを空のオブジェクトにアタッチすることで関数の呼び出しが可能です。
個人的には、シングルトンを利用する方法が汎用性が高く好きです。


##シングルトン利用時の注意点
シングルトンで呼び出される関数はシーンの移動時に壊されてしまうので、そのまま関数をボタンなどに貼り付けると、シーンの移動時にミッシングになってしまいます。
そのためにも、シーン毎に独立したスクリプトを作成し、そこからシングルトンで生成されたスクリプトの関数を呼び出すように癖をつけると良いと思います。
NISサーバ とは

## 勉強前イメージ

初めて聞いた・・・！

## 調査

### そもそも NIS とは

Network Information Service の略で、日本語ではネットワーク情報サービスになります。
同じネットワークに接続された複数のコンピュータ間でシステムの設定情報を共有することができるサービスをディレクトリサービスと言い、
UNIX系OSで使用されるディレクトリサービスをNISと言います。
セキュリティ機能などを改良した後継機が NIS+ といいます。
元々はSun Microsystems社がSolaris用にYellow Pagesという名前で開発したもので、
その後他社のUNIX OSにも提供された。

### ディレクトリサービスとは？

ディレクトリサービスとは、ネットワーク上にある機器の情報を一元管理するサービスで、
NISの他にもOpenLDAPがあります。
ディレクトリサービスのメリットはアプリケーションを呼び出す際にサーバの場所を意識せずに名前だけでアプリケーションを呼び出せます。
また、ユーザ名やパスワードも一元管理できるのできるのでログイン時に共通のアカウントでログインできます。

### NISのタイプ

- NISマスターサーバ

NISサーバのマスターになります。
マスターサーバにはNIS管理者が作成したマップが保存されており、
各NISドメインにはマスターが1つだけ存在します。
マスターはスレーブにNISの更新を伝搬します。

- NISスレーブサーバ

NISのスレーブサーバになります。
スレーブサーバはNISマップのコピーが存在し、マップが更新されるとマスターから伝搬されます。

- NISクライアント

マスターからマップデータを要求されます。

### NISの要素

- NISドメイン

マップを共有してるマシンの集合で、
各ドメイン名が指定されていて、各マシンは共通のマップセットを共有しています。

- NISデーモン

NISは5つのデーモンで提供されています。
それぞれ無効化・有効化を行うことができます。

- NISマップ

NISはマップと呼ばれるファイルに情報を保存します。
NISマップは2列からなるテーブルで、キーと値で構成されています。
キーを検索してクライアントの情報を保存されます。

## 勉強後イメージ

そういうのあるんや・・・知らんかった。

## 参考

- [NIS 【Network Information Service】](https://e-words.jp/w/NIS.html)
- [第 4 章 ネットワーク情報サービス (NIS) (概要)](https://docs.oracle.com/cd/E19253-01/819-0382/anis1-25461/index.html)
中国語 GEC

# 概要

中国語に関する文法誤り訂正の状況について紹介します。

# ニューラル以前

英語文法誤り訂正と比べると、中国語の文法誤り訂正の研究は盛んではありませんでした。2014年に開催された NLP-TEA というアジア圏での自然言語処理の教育応用に関するワークショップで、台湾の中学生が書いた作文に対する文法誤り検出の共通タスクが開催され、少しずつ研究が増えてきました。

# ニューラル以降

上記に加えて断続的に中国語誤り検出・訂正の共通タスクが開催されており、NLPCC という（ほぼ中国語でしか情報がありませんが）国際会議でも共通タスクが開催されており、もっとも新しい共通タスクは NLP-TEA 2020（AACL のワークショップ）で開催されたものです。NLPCC では Lang-8 から抽出したデータが訓練データとして提供され、北京大学中国語学習者コーパスから取られた2000文がテストデータとして使われていて、最近の研究では NLPCC 2018 のデータを使うのが主流になっています。（ちなみに Lang-8 コーパスは再配布不可です）

Lang-8 コーパスが使われるようになってからは、（ニューラル）機械翻訳の手法を使うのが一般的であり、2021年現在はほぼ全ての研究が深層学習を用いています。

最近の手法に関しては、以下のリンクがまとまっています。中国語以外を対象にしたものも混ざっていますが、ニューラル以降の中国語を対象にした研究で、英語で書かれているものは網羅されていると思います。

https://github.com/Chunngai/gec-papers

# 雑感

中国語文法誤り訂正は中国語でしか論文がなかったりする場合もあるので、ちょっとサーベイが難しいことがあるのですが、中国語 NLP の層の厚さも実感します。また、中国語はスペリング誤り訂正の研究は昔から盛んで、字の形や音の類似性を考慮した手法が繰り返し提案されていて、英語の文法誤り訂正の手法と違う発展を遂げていて、言語による違いがおもしろいです。

ちなみに MaskGEC (AAAI 2020) が SoTA のようですが、この論文で報告されている精度が再現できず、著者に聞いても返事がないので困っています。再現できた人がいたら教えてください。（我々と同じく、これのスコアがなかなか再現できない、というブログ記事はあるようです）
TypeScript/Reactをやってみて思ったこと

これは[株式会社POLテックカレンダー2021](https://qiita.com/advent-calendar/2021/pol) 7日目の記事です。
前回の記事は[こちら](https://qiita.com/yiwi/items/b1b0e37252bff94249b5)です。

はじめに
---------------------------------------
今年10月より株式会社POLでフロントエンジニアをしているアビスです。
前職では2年半の間ほぼバックエンドをやってきたので、最初は勉強からでした！

今回は私がPOLに入り始めてTypeScript/Reactを使用して思ったことを書いていこうと思います。

これからTypeScript/Reactをやりたい！といった方に参考になれば嬉しいです。


1.TypeScriptとは？
---------------------------------------
JavaScriptを知ってる方は多いと思いますが、TypeScript知らないという方も多いと思います。

TypeScriptとは、AltJS (Alternative JavaScript) の一つで、
2012年頃にマイクロソフトが開発したJavaScriptを進化させたプログラミング言語です。

大きく違う点は、TypeScriptは静的型付け言語です。
また、JavaScriptと互換性があります。

参考：[【入門】TypeScriptとは？言語の特徴やJavaScriptとの違いを解説](https://www.pasonatech.co.jp/workstyle/column/detail.html?p=2761)

2.TypeScript/React基礎～応用
---------------------------------------
POLの一番お世話になっている先輩"ゲバラ先輩"に頂いたりあクト！という本を熟読しました！
[りあクト！ TypeScriptで始めるつらくないReact開発 第2版](https://booth.pm/ja/items/1312652)

また、新版の[第三版](https://oukayuka.booth.pm/items/2368045)も読ませていただきました。(1～3部構成になっています)
内容についてですが特に4章が特に良かったです。

4章ではTypeScriptの歴史から型について解説
一部紹介します。
TypeScriptでクラスを定義するとinterface宣言とコンストラクター関数の宣言となります。

````typescript:hoge.ts
const permissions = { 
  r: 0b100,
  w: 0b010,
  x: 0b001,
};
typePermsChar = keyof typeof permissions; //'r'|'w'|'x' 
const readable: PermsChar = 'r';
const writable: PermsChar = 'z';  // not assignable !
```
型を操作することができます。

良い点まとめ
・ReactのAPIやlibraryが登場してきた背景の解説がある
・実際にコードを書く上で助けになることが多かった
・楽しくReactを学べる

3.参考になった記事
---------------------------------------
[TypeScriptの型入門](https://qiita.com/uhyo/items/e2fdef2d3236b9bfe74a) -記事自体は長いですが、勉強になります。

[React Hooks/TypeScript + Django REST APIで作るオリジナルJIRA
](https://www.udemy.com/share/103MvR3@iphXDP8D-7aSOwxbpIYbIfw5PQvb5ia-yEZojNQVFCi1S_oYNoQHyWj2_lxXIWu8/) - 有料ですがとても良かったです。


4.TypeScript/React業務をやってみる -フィードバック
---------------------------------------
POLに入って初めてTypeScript/Reactを触らせて頂きました。
皆さんバグが発生した際やわからないことがあった際には即レスを頂けるのでとても助かっています！
いつもありがとうございます！POLに入ってよかったです！

最初はフロントエンドをやることになって戸惑っていましたが、現在はとても楽しく大好きです。

5.TypeScript/Reactをやってみて思ったこと
---------------------------------------
前職ではJavaを触っていたので、自由度の高さに驚きました。
そこが良さだと思います。裏を返せばコードを書く人が設計をガチガチにしなければいけません。

ですので私は、TypeScript/Reactで一番大事なのは"設計段階でどこまで詰めることができるか"と結論付けました。

今後は、設計についても理解をもっと深めていこうと思います！

最後に
---------------------------------------
今回は私のロードマップのような記事になってしまいましたね。
次回（来年）は技術的な記事を書こうと思っています！

POL楽しく仕事をしている人が多いと思います！
そんなPOLの[株式会社POLテックカレンダー2021](https://qiita.com/advent-calendar/2021/pol) 残り18日間楽しんでいってください！


明日
---------------------------------------
明日8日目はボドゲ仲間で先輩の[チートイさん](https://qiita.com/nkg)です！
よろしくお願いします！
Pythonチュートリアル on Jupyter Notebook

Pythonチュートリアル(3.9)のWebサイトの内容を<font color=blue>Jupyter Notebookで実際に動かしながら学習できる</font>ように編集しました。

元にしたWebサイトはこちら
[https://docs.python.org/ja/3.9/tutorial/](https://docs.python.org/ja/3.9/tutorial/)

&nbsp;
オリジナルのサイトに加え、<font color=blue>わかりにくいと思われる箇所の補足説明</font>や、<font color=blue>全てのコードが実行できるようにテストデータを作成するコードの追加等</font>を実施しています。

Pythonの自己学習や、Python３エンジニア認定試験の学習ツールとして活用ください。

:arrow_down: <b>下記のGithubのサイトからファイルをダウンロードして、Jupyter notebook環境、またはGoogleコラボ上で実行してください。</b>


[https://github.com/DeepAelurus/Python_Leraning](https://github.com/DeepAelurus/Python_Leraning)

Pythonチュートリアル_1_4.ipynb : １章から４章までJupyter notebookで実行可能
Pythonチュートリアル_5_8.ipynb : ５章から８章までJupyter notebookで実行可能
Pythonチュートリアル_9_16.ipynb : ９章から１６章までJupyter notebookで実行可能

# サンプルイメージ

上記コンテンツのサンプルイメージです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1413278/becb1ec3-03ca-752f-38bc-5ecc5921887d.png)

・・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1413278/3831cb1a-44e6-1114-edec-4431e76e46c6.png)

・・・


## 補足説明の例

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1413278/5ff7856e-2a82-b021-b4d2-99ba580e7576.png)



## テストデータ生成の例

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1413278/a49cf8b1-cc28-a08a-9301-248513049515.png)

# 参考

## Googleコラボをまだ使ったことがない方は下記を参考にしてください。

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


## Googleコラボのインストールは、以下の手順で簡単に行えます。

- Googleアカウトを作成（まだ持っていない場合）
- Googleドライブ上で左上のメニューから「アプリで開く」->「アプリを追加」で、Googleコラボ　　を選んでインストール

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1413278/5da58c21-830f-4628-08ca-c01eaff6c0fa.png)

- Githubからアップロードしたファイルを実行するとGoogleコラボで起動します

誤りや不足、加筆修正すべきところがありましたらぜひご指摘ください。継続してブラッシュアップしていきます。
© 2021 [NPO法人AI開発推進協会](https://sites.google.com/deepaelurus.com/aboutus/home)
plotlyでゲージを二つ

　plotlyライブラリは、図形をWebに表示します。
![2021-12-06 (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/ee0357ce-ef56-91b6-c5ac-b133bc56b411.png)


###環境

- ラズパイ4　5.10.63
- Python　3.9.2
- plotly　5.4.0

###Gaugeはsubplotsでは複数の表示ができないみたいな気がする
　iframeをつかって二つのGaugeデータを、一つのWebページに表示します。
　図形Gaugeの一つは、ラズパイのCPUのクロックです。1.5GHzや1.8GHzが最高クロックで、CPUが熱くなると700MHzなどに下がります。もう一つのGaugeはCPUの温度です。どちらも``vcgencmd``コマンドで取得できますが、数値以外に文字が引っ付いているので、除去します。
　どちらも関数にしました。関数の最後で、``fig.write_html("/home/pi/temp-plot.html")``と``fig2.write_html("/home/pi/temp-plot2.html")``のうように、それぞれのページに画像データをhtmlで書き込んでいます。
　それらを/home/pi/index.htmlページに、iframeで合成します。
``f.write('<iframe id="igraph1" scrolling="no" style="border:none;" seamless="seamless" src="/home/pi/temp-plot.html" height="525" width="500"></iframe>')
f.write('<iframe id="igraph2" scrolling="no" style="border:none;" seamless="seamless" src="/home/pi/temp-plot2.html" height="525" width="500"></iframe>')``




```python
import plotly.graph_objects as go
import subprocess
import time

def p1():
    clk = subprocess.getoutput("vcgencmd measure_clock arm").split('=')
    CLK = int(clk[1])/1000000.0
    fig = go.Figure(go.Indicator(
        mode = "gauge+number",
        value = CLK,
        legendgrouptitle_text = 'hPa',
        domain = {'x': [0, 1], 'y': [0, 0.9]},
        gauge_axis_dtick= 200,
        gauge_axis_tickwidth=3,
        gauge_bar_color='red',
        gauge_bar_line_width=1,
        gauge_bar_thickness=0.85,gauge_bgcolor='#efd',
        gauge_axis_range=list([400,2000]),
        title = {'text': "クロック[MHz]"}
        ))
    fig.write_html("/home/pi/temp-plot.html")

def p2():
    temp = subprocess.getoutput("vcgencmd measure_temp").split('=')
    T = float(temp[1].split("'")[0])
    fig2 = go.Figure(go.Indicator(
        mode = "gauge+number",
        value = T,
        legendgrouptitle_text = 'hPa',
        domain = {'x': [0, 1], 'y': [0, 0.9]},
        gauge_axis_dtick= 20,
        gauge_axis_tickwidth=3,
        gauge_bar_color='red',
        gauge_bar_line_width=1,
        gauge_bar_thickness=0.85,gauge_bgcolor='#dfd',
        gauge_axis_range=list([-20,110]),
        title = {'text': "温度[℃]"}
        ))
    fig2.write_html("/home/pi/temp-plot2.html")

f = open('/home/pi/index.html','w')
f.write('<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">')
#f.write('<META HTTP-EQUIV="Refresh" CONTENT="5">')
f.write('<iframe id="igraph1" scrolling="no" style="border:none;" seamless="seamless" src="/home/pi/temp-plot.html" height="525" width="500"></iframe>')
f.write('<iframe id="igraph2" scrolling="no" style="border:none;" seamless="seamless" src="/home/pi/temp-plot2.html" height="525" width="500"></iframe>')

while 1:
    p1()
    p2()
    time.sleep(5)
    f.close()
```

　``f.write('<META HTTP-EQUIV="Refresh" CONTENT="5">')``で自動リフレッシュをさせたのですが、Gaugeの描画に時間がかかるため、Webが真っ白になっている時間が長かったので、見ている人が自分でリロードするようにしました。

![2021-12-06 (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/a1011fe3-908d-6265-8020-24e2d33d84e6.png)
新規に Google Apps Script を作成するたびにコピーしている便利な関数 

この記事は [N・S高等学校 Advent Calendar 2021](https://qiita.com/advent-calendar/2021/n-s-highschool-1) の 7日目の記事です。

わたしは学校法人角川ドワンゴ学園でプログラミング講師をしている @ohataken です。以前は Ruby や JavaScript を使って Web アプリ開発をしていました。業務としての開発はしていませんが、学校運営の一環として Google Classroom や Slack の API を日常的に扱っています。

# 概要

Google Apps Script で以下のような `createCsv` 関数と `appendRow` 関数を作って、小さいドメイン固有言語 (DSL) だと思うことにして利用しています。Google Apps Script において Google スプレッドシートへの書き込みは頻出パターンなので、その書き方にルールを作ることで可読性、保守性が高まります。

```js
function createCsv(callback) {
  const csv = [];
  callback(csv);
  return csv;
}

function appendRow(csv, callback) {
  const row = [];
  callback(row);
  csv.push(row);
}
```

# 解説

Google Apps Script において、 Google スプレッドシートへの書き込みはかなりの頻出パターンだと思います。スプレッドシートに書き込むためのデータは2次元配列なので、この2次元配列を作ることもまた頻出パターンです。 `createCsv` 関数と `appendRow` 関数は、2次元配列をつくるためのものです。


```js
function createCsv(callback) {
  const csv = [];
  callback(csv);
  return csv;
}

function appendRow(csv, callback) {
  const row = [];
  callback(row);
  csv.push(row);
}
```

ここでは CSV は単に2次元配列のことを指しています。

# 使い方 (1) 

まずはリテラルで。

```js
const obj = createCsv((csv) => {
  appendRow(csv, (row) => {
    row.push("名前");
    row.push("年齢");
  });

  appendRow(csv, (row) => {
    row.push("アリス");
    row.push("16");
  });

  appendRow(csv, (row) => {
    row.push("ボブ");
    row.push("14");
  });

  appendRow(csv, (row) => {
    row.push("キャロル");
    row.push("11");
  });

  appendRow(csv, (row) => {
    row.push("デイヴ");
    row.push("19");
  });
});
```

コールバックを使って書くことで、 `const` や `let` などのローカル変数の宣言なしに書くことができてスッキリします。同じことですが、自然にスコープを狭く狭く持とうとする書き方になります。また、コールバック関数のインデントが2次元配列の「行があって、その中に列がある」という構造に対応していて、理解しやすいです。値をひとつ入れる度に1行使うようにするので、コードが横ではなく縦に伸びていくのも読みやすさに一役買っています。

# 使い方 (2)

例題として百マス計算でも。

```js
const obj = createCsv((csv) => {
  for (let i = 1; i < 10; ++i) {
    appendRow(csv, (row) => {
      for (let j = 1; j < 10; ++i) {
        row.push(i * j);
      }
    });
  }
});
```

この例はさほど読みやすいとも思いませんが、前の例と同じ方法で書くことができる、ということがわかってもらえれば。

# 使い方 (3)

これは実際のコードに近いパターンで、 Google ドライブの特定のフォルダ内のファイルを列挙するものです。

前述のとおり、スプレッドシートへの書き込みは Google Apps Script の頻出パターンと思われますが、もっと言い切ってしまうと、 `DriveApp.getFolderById` や `Folder.getFiles` などの **Google Apps Script にある API から得たデータを整形して2次元配列を作る** パターンこそ頻出だと思います。

```js
const folder = DriveApp.getFolderById("THIS_IS_ID_OF_A_GOOGLE_DRIVE_FOLDER");
const iter = folder.getFiles();

const csvObject = createCsv((csv) => {
  appendRow(csv, (row) => {
    row.push("ID");
    row.push("Name");
    row.push("URL");
  });

  while (iter.hasNext()) {
    const file = iter.next();

    appendRow(csv, (row) => {
      row.push(file.getId());
      row.push(file.getName());
      row.push(file.getUrl());      
    });
  }
});
```

こうすることで、データを取得するときと、2次元配列の形に整形するときを明確に区別することができ、数日後または数週間後の自分にもやさしい書き方になります。

# まとめ

頻出パターンである2次元配列の作成をイディオムにできました。本当にちょっとした関数なので、あたらしく Google Apps Script を書き始めるときは既存のプロジェクトからいつもコピーして使っていくことができます。

Google Apps Script は、技術的な興味や価値はともかく、業務上はとても価値があるツールなので、書き捨てのスクリプトのままにせず、動き続ける生きたものにするための工夫は、やはり重要だと思います。今回の方法はそれを実現するものになっていると思っています。
PCを起動すると内部で何が行われる？

#はじめに
PCの電源を入れてから画面が立ち上がるまで、PCの中でどんな処理が行われているのか、ずっと気になっていたのでどんな動きをしているのかまとめてみました。

#電源を入れてから画面が立ち上がるまで

画面が立ち上がるまでの処理の流れを大まかに示します。

①電源を入れたCPUがマザーボード上のBIOSを読み込む
②マウス、キーボードなどの周辺機器を初期化し、使用できるようにする
③BIOSプログラムを読み込みハードディスクにアクセスする
④OSをメモリに読み込んでプログラムを実行する
⑤パソコンが起動し、デスクトップ画面が表示される


PCの起動には最初にBIOSと呼ばれるプログラムが実行されて、処理が走るみたいです。

#BIOSとは

BIOSというのは、(Basic Input Output System=ベーシックインプットアウトプットシステム)のことです。

主にハードウェアを制御するプログラムで、PCのマザーボードに組み込まれていて、PCの電源を入れた時に最初に起動されるプログラムです。

ハードウェアを管理するのでマウスやキーボードの周辺機器も操作できるわけですね。

#BIOSはROMに搭載されている
ROMとは電源を切ってもデータが失われないメモリのことです。

BIOSはOSを起動するために必要なプログラムであり、データは必ず毎回読み込まれる必要があります。

なので、電源を切ってもデータがなくならないROMに入っています。

#終わりに
PC起動から画面表示までの処理の流れを把握できました。

もっと細かい流れがあるそうなのですが、ややこしくなるので今回はここまでにしておきます。

気が向いたら細かい処理についても調べようかな...
OpsRamp 仮想マシンをクローンするとエージェントはどうなるのか？

2021年OpsRampアドベントカレンダー12月7日分の投稿です。


# 概要

vSphere環境で仮想マシンに監視エージェントをインストールしている場合に、その仮想マシンをクローンすると自動的に監視対象としてOpsRampに登録されるのか確認してみました。


# クローン元の仮想マシンを確認

今回はOpsRamp監視エージェントをインストールしているLinux（ops-linux）でクローンを作成してみます。

![2021-1203-223312.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333529/99dc4076-8f4b-c65c-2026-4fd1fd8acf95.jpeg)


監視エージェントをインストールすると採番される、リソースIDを確認しておきます。

![2021-1203-223557.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333529/dda59d5e-faeb-6b72-7f89-611927c77553.jpeg)


クローン作成後にホスト名・IPアドレスが重複しないように変更。仮想ネットワークに接続すると、クローン元仮想マシンで監視エージェントが通信できなくなったというアイコンに変りました。

![2021-1203-230336.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333529/eeac8697-2d62-3c59-0a49-d36a94d6ead4.jpeg)


そして、5分ぐらい経過するとクローンした仮想マシンのホスト名・IPアドレスに切り替わりました。

![2021-1203-230624.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333529/9c785680-5cbe-59a7-7131-b118c6f8304f.jpeg)

アラート内容は残ったままです。

![2021-1203-230459.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333529/f78bc7a7-7b76-ee46-c201-ca1eea04c540.jpeg)

メトリクス情報も残ったままです。

![2021-1203-230647.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333529/c4e91021-7761-e3e3-5384-047e277a9168.jpeg)

その理由はリソースIDがクローン元と同一だからだと考えてます。クローン元、クローン先の仮想マシンの両方が有効になっていて、ポーリングのタイミングでコロコロ入れ替わっている状況でした。

![2021-1203-230539.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333529/78cfdcb7-5a30-be7d-a7df-6728f92da74c.jpeg)


# 元に戻す

クローンした仮想マシンをシャットダウンすると元に戻りました。エージェントのステータスも正常に戻ってます。

![2021-1203-230754.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333529/85f1bd39-db52-4013-fb9c-9fad015782aa.jpeg)


結果、OpsRampエージェントは仮想マシンのクローンには対応していないので、テンプレート仮想マシンにはインストールしない方が良いことが分かりました。


おわり。
SAMLってなんですか？

この記事は [カオナビ Advent Calendar 2021](https://qiita.com/advent-calendar/2021/kaonavi) 7日目です。

# はじめに

はじめまして！7日目を担当します、カオナビの新卒2年目の別府です。よろしくお願いします！！
今回はSAMLのタスクを担当した際に、自分が調べた「SAMLってそもそも何？」という概念的な部分を自分の備忘録的な形で記事にしようと思います。

# こんな方に読んでもらいたい

* SAMLってなんだ？という方
* 実装したことがあるが、SAMLとは何かを説明できない方

# SAMLって何ですか？

そもそもSAMLってなんですか？というところですが、略さないで書くと`Security Assertion Markup Language`です。
直訳すると**セキュリティーを断定するマークアップ言語**になります。私も勘違いしていたのですが、実はSAMLはマークアップ言語なのです。

ところが、色々なサイトをみてみると大体は**XMLをベースにした標準規格**と書かれていることが多いです。
**XMLをベースにしたマークアップ言語**だったらなるほどとなりますが**標準規格**ってなんやねん！となると思います。私もそう思いました。
ここがとてもややこしい点なのですが、SAMLはマークアップ言語と言いつつ実は通信プロトコルであるということです。
今回は深堀しませんが、Protocols, Bindings, Profiles, Metadataなどの色々な仕様が定義されています。

つまりSAMLとは

* 認証情報を安全にやり取りするための書式 + (通信する上でのお約束事) = SAML(実態はSAMLプロトコル)

ということになります。

# SAMLのバージョン？

歴史を見てみるとSAMLには

* SAML 1.0
* SAML 1.1
* SAML 2.0

の3バージョンがあります。

ちなみに、現在はSAMLという単語はほぼSAML 2.0を指しますので、今回のSAMLとは？というのもSAML2.0のお話になります。

実はSAMLはSAML1.0が2002年11月に発行され、最新版のSAML2.0は2005年3月に発行されているというかなりレガシーな規格です。

# IDaaSとIdPの違いは？
SAMLについて色々調べていたところ

> とあるサイト...
> 
> おすすめIDaaS！
> HENNGE ONE, One Login, Okta, ...
> 
> またまたとあるサイト...
> 
> おすすめIdP！
>  HENNGE ONE, One Login, Okta, ...

と書いてあり、IDaaSとIdPの違いってなんだろう？と思い調べてみました！  

まずは恒例の略さずに言い換えてみます

* IdP(Identity Provider)
* IDaaS(Identity as a Service)

ふむふむ、違いはアイデンティティ情報をProviderするかas a Serviceするかの違いだとわかりますね。  

この話をまとめると

* IDaaSはアイデンティティ情報をサービスとして提供するもの
* IdPはアイデンティティ情報を提供するもの

あれ？同じことを言ってますね。ということはIDaaS = IdPということでいいのでしょうか？

そう考えるのはちょっと待ってください、実はIDaaSはSAMLが非対応のアプリケーションにもSSOが可能という前提が実はあります。
そのため、具体的なサービスをあげるとCognito, Firebase Authentication, Auth0なども該当します。

なので私が導き出した答えは

* アイデンティティ情報をクラウド経由で提供するものの名称をSSO全体ではIDaaSと呼び、IdPはSAMLの時のみ使える限定的な用語  

です！

# まとめ
今回、特に私が混乱した「SAMLってマークアップ言語じゃないのかよ！」と「IDaaSとIdPの違いってなんだよ！」という部分を改めて文字に起こすことによってより深く調べることができSAMLマスターへの道を一歩前進することが出来ました。

SAML以外にも実装はできるけど概念は全然知らないというものがまだまだ沢山あるので、より知識を深堀して聞かれたときに堂々と答えられるエンジニアになれるよう精進していきます！

お読みいただきありがとうございました！！
内定者バイトをしてわかった学生時代やっててよかったこと

## はじめに
[QualiArts Advent Calendar 2021](https://qiita.com/advent-calendar/2021/qualiarts) 12/8の記事です。
先月より内定者バイトという形でQualiArtsで働いています。
これまでは学生として個人開発のみを行なっていたため、初めて企業でのコーディングをしています。
そこで、学生時代にやっていてよかったなと感じることが幾つかあったので書き起こします。

各項目「きっかけ」、「やったこと」、「会社でどう活きたか」に分けて書いていきます。
私自身がサーバサイドなので、内容が寄ってるかと思います。ご了承ください。

## スペック
 - 大学に入ってプログラミングを始める
 - 言語歴
   - Processing(5年)
   - JavaScript(4年)
     - Node.js(4年)
     - React/Next.js(3年)
   - Python(3年)
   - Go(2年)
 - 個人開発メイン
 - 企業での開発経験なし
 - サーバーサイドで内定


## 1. 慣れてきたところでリーダブルコードを読む
![リーダブルコード](https://images-na.ssl-images-amazon.com/images/I/51MgH8Jmr3L.jpg)
[リーダブルコード(Amazon)](https://www.amazon.co.jp/dp/4873115655)

### きっかけ
私自身はJavaScriptをそれなりに書くようになった頃に友達に勧められて読みました。
当時の状態としては以下の通りです。

- プログラミング歴としては2年
- ProcessingとJavaScriptの基本的文法を理解し、自由に開発ができる。
- JavaScriptの自由度ゆえに適切な書き方がわからなかった。
- 命名大事だよ等の周りの意見の理由がわからなかった。


### やったこと
- 読んだ。
- リーダブルコードの内容を意識してコード書いた。
- 周りにコードきれいと言われるくらいには書けるようになった。

### 会社でどう活きたか
プロジェクトのコードがきれいなので、コードを読みながら各ロジックの意図を簡単に理できました。
また、学生時代と同じようにコーディングすればいいので、脳内リソースがとられませんでした。
コードレビューしてもらうときにたぶん読みやすいと思います、たぶん。

学生時代にも、以前に書いたコードを使う時に読みやすいく、メンテしやすくめちゃめちゃ活きたこともありました。

## 2. コーディングスタイルに則って書く

### きっかけ
開発で使ってたライブラリからeslintの存在を知り、VSCodeの拡張を入れたこと。

### やったこと
- eslintの言う通りに書く。
- eslintの[airbnbのスタイルガイド](https://github.com/airbnb/javascript)を読んだ。
- Pythonの[pep8](https://pep8-ja.readthedocs.io/ja/latest/)を読んだ。
- スタイルを意識して書く。

### 会社でどう活きたか
(そんなに厳しくはないですが)ルールに従って書くことに慣れてて、書きやすいなと感じています。
あとは自分で書くときにミスが減りました。

## 3. アーキテクチャを設計してシステム作成

### きっかけ
1ファイルに数千行みたいな書き方をしていた中で、徐々にロジック分離をするようになった。
だんだん正解を知りたくなり、調べた。

### やったこと
- Goのレイヤードアーキテクチャの記事を読んだ。
 - たしかこの記事: [【Go】DDD + レイヤードアーキテクチャでREST APIを実装する](https://mintaku-blog.net/go-ddd/)
- 記事の通りの構成でとにかく書いた(理解はしてなかった)。

### 会社でどう活きたか
似たような構成でやっていたため、プロジェクトのアーキテクチャを素早く理解できました。
企業で働く上では、アーキテクチャという概念に少しでも触れていると役に立つのではないかなと思います。

(余談)
学生時代にシステムのデータベースをMongoDBからMySQLに変えるハメになりました。
このときレイヤードアーキテクチャを採用してたため、データベースのロジックのみ修正すればよく、めちゃめちゃ簡単に移行できました。


## 4. クライアントとサーバ両方触っておく

### きっかけ
最初にHTML/CSS/JavaScript勉強してクライアントサイドやってた。
JavaScriptでサーバが書けると聞きNode.jsをやった。

### やったこと
- Node.jsを勉強
- Reactを勉強
- Goを勉強
- これらを使って何回かシステム開発

### 会社でどう活きたか
バックエンド配属ながらも、管理ツール周りでクライアントをやることがありました。
Vueでしたが、大きくロジック変えるわけではなかったので、対応できたのはReactやっていたからだと思います。

## 最後に
自分が学生時代にやったことと、内定者バイトで活きたことを書き起こしました。
まだ企業で働いたことない学生や、プログラミングを最近始めた方の参考になればいいなと思います。
(Dockerfile) DSLコマンド入門！ 

##背景　
Dockerfileの書き方があまりよく分かってなかったので、復習として整理する。

##Dockerfileとは？
Dockerではcontainerを作るために、まずimageという材料を用意しなければならないのですが、そのimageの設計図がDockerfileです。

Dockerfileを書くときに使うコマンドは色々あるのですが、初心者のうちは

```
FROM,COPY,RUN,CMD,WORKDIR,ENV,USER
```
だけ覚えておけばいいそうです。なのでこの記事でも上記の７つのコマンドの意味を説明していきます。

##FROM
FROMコマンドとはどのimageを使うのかを指定するコマンドです。
一番最初にどのimageを使うかを指定してから他のコマンドをより詳細に付け足していきます。

##COPY
このコマンドはDockerのコンテナ内にローカルで作成したファイルやディレクトリをコピーしてくれます。

##RUN
Dockerコンテナに入ったら、RUNで指定されたコマンドを実行してくれます。

##CMD
Dockerを起動すると自動でコマンドを実行してくれます。

##WORKDIR
Dockerfileでコマンドを実行するときにどこのディレクトリを基準(スタート)にするかを設定できます。存在しないディレクトリを指定した時は自動的にディレクトリが作成され、何も設定しなければデフォルトでは/のディレクトリが設定されているので、既存のディレクトリを上書きしてしてしまう恐れがあります。

##ENV
環境変数を設定してくれるコマンドです。ちなみに環境変数とはOSが持っている変数のことです。

##USER
USERはimageを起動したときにどのユーザーがログインするかを指定することができます。デフォルトではrootユーザーが設定されているので、セキュリティのことを考えるとroot以外のユーザーを指定するのが推奨です。
Typescriptでassociatedtypeぽいことをする？

## はじめに

Swiftにあるassociatedtype的なやつがTypescriptでどうやるのか気になっていました。
<b>※associatedtypeにについては以下の記事が非常に分かりやすかったので、リンクさせていただきました</b>
https://qiita.com/akeome/items/78e650f27a4c53e1406a

例えば、以下のようにMyRequestのprotocolではResponseに対してMyResponseに準拠していることの制約だけかけて、準拠する側（GetUserRequestなど）で具体的な型を指定するやつです。

```swift
protocol MyResponse {}

protocol MyRequest {
    associatedtype Response: MyResponse
    func req() -> Response
}


// GetUser
class GetUserResponse: MyResponse {
    let userName: String = "UserName"
}
class GetUserRequest: MyRequest {
    typealias Response = GetUserResponse
    func req() -> GetUserResponse {
        return GetUserResponse()
    }
}

// GetProject
class GetProjectResponse: MyResponse {
    let projectName: String = "ProjectName"
}
class GetProjectRequest: MyRequest {
    typealias Response = GetProjectResponse
    func req() -> GetProjectResponse {
        return GetProjectResponse()
    }
}


class Client {
    func request<T : MyRequest>(request: T) -> T.Response {
        return request.req()
    }
}


let cli = Client()

let res = cli.request(request: GetUserRequest());
print(res.userName)

let res2 = cli.request(request: GetProjectRequest());
print(res2.projectName)

```

## やってみる

Typescriptには直接的にはassociatedtypeにあたるものはないようでした。
調べる中で「Indexed Access Types」と「ReturnType」という便利なやつを知り、この二つでそれっぽく出来ないか？と思いためしてみました。

### Indexed Access Types
オブジェクトなどから特定のプロパティの型を抽出するやつ

```typescript
type Person = { age: number; name: string; alive: boolean };
type Age = Person["age"];

> type Age = number
```

### ReturnType
関数などから戻り値の型を抽出するやつ

```typescript
type T0 = ReturnType<() => string>;
     
> type T0 = string
```

### 試す

```typescript
interface MyResponse {
}

interface MyRequest {
    req(): MyResponse
}

// GetUser
class GetUserResponse implements MyResponse {
    userName: string = "UserName";
}
class GetUserRequest implements MyRequest {
    req(): GetUserResponse {
        return new GetUserResponse();
    }
}

// GetProject
class GetProjectResponse implements MyResponse {
    projectName: string = "ProjectName";
}

class GetProjectRequest implements MyRequest {
    req(): GetProjectResponse {
        return new GetProjectResponse();
    }
}


class Client {
    request<T extends MyRequest, U extends ReturnType<T["req"]>>(req: T) : U {
        return req.req() as U;
    }
}


const cli = new Client();

const res = cli.request(new GetUserRequest());
console.log(res.userName)

const res2 = cli.request(new GetProjectRequest());
console.log(res2.projectName)
```

肝は以下のところだけでしょうか。

```typescript
   request<T extends MyRequest, U extends ReturnType<T["req"]>>(req: T) : U {
        return req.req() as U;
    }
```

ReturnTypeの対象にMyRequestを実装したTの「req」メソッドを指定して、具象クラスで指定したResponseの型を取り出しています。

一応それぽくなったような、なっていないような微妙な気はしつつ本日は以上にしたいと思います。

## さいごに

ZEROBILLBANKでは一緒に働く仲間を募集中です。
[ZEROBILLBANK JAPAN Inc.](https://zerobillbank.com/%e3%81%8a%e5%95%8f%e3%81%84%e5%90%88%e3%82%8f%e3%81%9b/)

Youtubeチャンネルもやっています
https://www.youtube.com/channel/UCe947G2stpPUv0xz7lN_MAg
# IICS Cloud Mass Ingestion Applicationsを使ってみる

# Cloud Mass Ingestion
Cloud Mass Ingestion (CMI)は、ファイル・データベース・ストリーミング・アプリケーションなどのデータをクラウドへ簡単に高速で一括で取り込むことができます。
例えば、オンプレミスのデータベースからクラウドデータウェアハウスへの移行や大量のファイルをクラウド・ストレージに一括で取り込むケースで活用できます。
今回は、アプリケーションからクラウドへデータを取り込むCMI Applicationsを紹介します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294379/d04a2631-9c6d-7581-834f-74e3262329c7.png)
# Cloud Mass Ingestion Applications
CMI ApplicationsはSaaSやオンプレミスのアプリケーションから大規模データを取り込み、クラウドベースのデータレイクやデータウェアハウスへ低レイテンシーでデータを転送することができます。
サポート対象のソースの詳細については、下記ドキュメントをご参照ください。
https://docs.informatica.com/integration-cloud/cloud-mass-ingestion/current-version/mass-ingestion/mass-ingestion-applications/supported-sources.html
##### サポート対象のソースとターゲット (2021年11月)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294379/efcc1a4a-a05e-137d-362e-fee4e2b13ff7.png)

# 実際に使ってみる
本記事ではSalesforceからRedshiftへ転送してみます。
######0.新規作成
CMIのホーム画面の[新規]から[アプリケーション取り込みタスク]を選択し、新規作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294379/77448e63-139a-87b2-d894-690c84090cba.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294379/b42e8a3e-2b1d-cf08-fdf7-884d96f3319d.png)
######1.定義
[名前]を入力し、[ランタイム環境]から使用するSecure Agentを選択し、[ロードタイプ]を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294379/13de76e8-e56f-59f6-6aa1-b95de3a62be2.png)
######2.ソース
[接続]でSalesforceへの接続を選択し、[Objcet Rules]の条件にここでは、opportunity*と指定して抽出対象のオブジェクトを設定しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294379/6730e075-3b0b-335c-5c98-6394c5e9b38c.png)
######3.ターゲット
[接続]でRedshiftへの接続を選択し、連携先の対象となる[スキーマ]、データオブジェクトを保存する[バケット]、ジョブの出力ファイルを保存する[ディレクトリ]を指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294379/b803ef62-7270-de3c-7a16-aa3486f46658.png)

######4.スケジュールおよびランタイムオプション
デフォルトの設定のまま[保存]します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294379/7ee9540e-986f-923c-5dd8-20c7ef2ff948.png)

######5.デプロイ
保存した後、設定した内容で[デプロイ]します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294379/a00f6646-0a56-0852-5233-66ed1255444b.png)
#まとめ
CMI Applicationsを使用してSaaSやオンプレミスのアプリケーション・データをデータレイクやデータウェアハウスへ統合することで、取得した最新データを高度なデータ分析に活用できたり、他のアプリケーションへ提供して処理を実行することができます。
HoneyBadgerでエラーが発生したjobの引数のリストをBQに送信する


paginationされているのでちょっとめんどかった。
https://docs.honeybadger.io/api/faults/#get-a-list-of-notices を参考にした。


```rb
$user_ids = []

# returns page of next url
def get_user_ids(url)
  connection = Faraday.new(url: url)
  connection.basic_auth("xxxxxxxxxxxxxxxx", "") # take this from https://app.honeybadger.io/users/edit
  res = JSON.parse(connection.get().env[:response_body])
  res["results"].each do |r|
    $user_ids << r["request"]["params"]["job"]["args"][0]["arguments"][3]["args"][0]
  end
  return res["links"]["next"]
end

url = "https://app.honeybadger.io/v2/projects/xxxxx/faults/yyyyyy/notices"
while !url.nil? do
  url = get_user_ids(url)
end

sql = <<~SQL
  INSERT `org.tmp.table_name`
  VALUES (#{user_ids.join("), (")})
SQL
BigQuery.client.query(sql)


# もし、user_idsが多すぎたら
# $user_ids.each do |uid|
#  sql = <<~SQL
#    INSERT `org.tmp.table_name`
#    VALUES (#{uid})
#  SQL
#  BigQuery.client.query(sql)
# end
```

> もし、user_idsが多すぎたら

以下のエラーがおこる。

```rb
Google::Cloud::InvalidArgumentError: resourcesExceeded: Resources exceeded during query execution: Not enough resources for query planning - too many subqueries or query is too complex.
from /app/vendor/bundle/ruby/3.0.0/gems/google-cloud-bigquery-1.34.0/lib/google/cloud/bigquery/service.rb:564:in `rescue in execute'
Caused by Google::Apis::ClientError: resourcesExceeded: Resources exceeded during query execution: Not enough resources for query planning - too many subqueries or query is too complex.
from /app/vendor/bundle/ruby/3.0.0/gems/google-apis-core-0.4.1/lib/google/apis/core/http_command.rb:228:in `check_status'
```
面接で出題されたフィボナッチ数列の問題が解けなかった話

##執筆者に関して

- 現在、未経験からエンジニアへのジョブチェンジを目指して、転職活動を実施しているkoheiです。

- 先日の企業様との面接で出題された、「フィボナッチ関数」が解けず悔しすぎる思いをしたので、自分と同じ過ちを犯さないでほしいという思いで記事を執筆することにしました:joy:

##フィボナッチ数列とは
まずフィボナッチ数列とは、「2つ前の項と1つ前の項を足し合わせていくことでできる数列」のことです。

n番目のフィボナッチ数Fnは

```
F0 = 0
F1 = 1
Fn+2 = Fn + Fn+1(n>1)
```
で定義される。

実際に `n = 0`から計算すると

```
F0 = 0
F1 = 1
F2 = 1 = 0+1
F3 = 2 = 1+1
F4 = 3 = 1+2
F5 = 5 = 2+3
F6 = 8 = 3+5
F7 = 13 = 5+8
...
```
となり、計算結果を並べた数列

```
0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,...
```
を**「フィボナッチ数列」** という

##問題(例)

自分の得意な言語で
`0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,...`
のようにn+2項が、n+1項とn項の和となるよう数列をプログラミングで書いてください。

##自分の回答

Rubyを使いました。

```ruby
def fib(n)
  if n == 0
    n = 1
  else
    n + n
  end
end

p fib(0)
p fib(1)
p fib(2)
p fib(3)

# 出力結果
1
2
4
6
```

自分なりに頭を捻って考えていたのですが、時間内で回答できず、、、:sob:

そもそも0から出力できていないし、、、Rubyのアルゴリズムへの理解の薄さを痛感しました。


##正しい解き方

```ruby
def fib(n)
  return 0 if n==0
  return 1 if n==1
  return fib(n - 2) + fib(n - 1)
end
```
**出力結果**

```ruby
p fiv(0)
p fiv(1)
p fiv(2)
p fiv(3)
p fiv(4)
p fiv(5)
p fiv(6)
p fiv(7)
p fiv(8)
p fiv(9)

>
0
1
1
2
3
5
8
13
21
34
```

正しく出力されました:thumbsup:


##感想

意外と短く書けるものなのですね！

面接は5社目だったんですけど、こういったコーディングのテストが出題されたのは初めてでした。

悔しい思いをしないためにも、面接前は、面接の練習や企業分析だけでなく、こういった言語の文法を復習するといったことも大切だなぁと感じました:joy:

まだまだ、転職活動は続きそうなので、Cherry本などを使って文法の復習も実施していこうと思います！！
Macbook Pro M1MaxにDocker + Jupyter環境を構築

# はじめに
２０２１年１１月中旬、予約していたMacbookPro　M1Maxが届きました。早速、いろんな記事を参考に環境構築しました。しかし、Docker＋Jupyterの環境だけは、いろんな記事を参考にしましたが、tokenエラーの画面から先に進めませんでした。

**何をやってもこの画面 :frowning2:**
![スクリーンショット 2021-12-06 18.11.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1037574/db01e345-4151-ebe8-be8d-bda4203c566e.png)

# Docker Desktop 4.3.0
Docker Desktop 4.3.0がアップされていたので、早速試してみました。

 [Docker Desktop for Mac リリースノート](https://matsuand.github.io/docs.docker.jp.onthefly/desktop/mac/release-notes/)

**早速、ダウンロード**
![スクリーンショット 2021-12-06 18.07.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1037574/b8acbc74-047e-5218-9d18-f3a707d1e713.png)

**無事にJupyter notebookが起動できました。**
![スクリーンショット 2021-12-06 18.21.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1037574/049d1bd7-6c2d-6205-25e8-abb92acb73e2.png)

よかった。
Lightning Sync for Office365

<h3>Lightning Sync for Office365を設定してカレンダーを同期する</h3>

Salesforceの行動とOffice365のカレンダーを同期して、
行動をOutlookカレンダーで把握できるよう設定しました。

<h4>手順</h4>
1.Lightning sync 基本設定
2.Sync登録
3.同期テスト

<h3>1.Lightning Syncの基本設定</h3>
1.1 設定に「outlook」と入力し、Outlookインテグレーションを有効にします。
![スクリーンショット 2021-12-01 17.36.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1520342/0578609a-15f7-58cd-24da-b4d72eae3c05.png)

1.2 画面を下にスクロールし、Lightning Syncを有効化します。
![スクリーンショット 2021-12-01 17.40.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1520342/15df9ae6-d875-5965-a8a7-e0a1ee544c88.png)

1.3 ここでログインボタンを押し、Sync設定を行うですが、↓のようなエラーが、、、
![スクリーンショット 2021-12-01 11.09.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1520342/ccda01a7-c7e7-cd0c-fcc8-b3745ef6d22d.png)
![スクリーンショット 2021-12-01 10.25.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1520342/4b031a88-3fce-9702-9ac0-ff1c138bf37b.png)

これは、私のドメインのリダイレクトポリシーをブロックすることで解消しました。
![スクリーンショット 2021-12-01 17.59.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1520342/9c75a054-e4c6-4bca-da60-f012f460f0b3.png)

1.4　ここでOffice365側で承諾すると、AzureADが設定されるので、OAuth2.0を有効化します。（　メールアドレスを入力することで、接続をテストすることができます）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1520342/3326eb76-7a93-9213-a8ef-16a926ba643b.png)

<h3>2.Sync設定</h3>
2.1 設定画面下部のSync設定の画面に移動します。
![スクリーンショット 2021-12-02 11.20.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1520342/0a069500-c1d4-30d0-f2c6-4ad9d3d4cb7e.png)


2.2 Syncを新規作成、保存します。（O365toSFDC/SFDCtoO365想定のため、双方向同期）
![スクリーンショット 2021-12-02 11.24.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1520342/35d70b13-4f90-0954-b017-a51b25b19da5.png)

<h3>3.同期テスト</h3>
3.1 Outlook/Salesforceで行動・予定を設定します。

3.2 Outlook/Salesforceのカレンダーで双方向同期されていることを確認します。
Outlookカレンダー
![スクリーンショット 2021-12-02 14.42.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1520342/54607d7c-1f22-d42f-a384-86971df52ffb.png)
Salesforceカレンダー
![スクリーンショット 2021-12-02 14.41.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1520342/e4891c4a-6208-9e49-7f2b-16854d436a6d.png)

以上となります。
配下のファイルを全部ひらくバッチ

## 配下のファイルを全部ひらくバッチ

```_all_open.bat
@echo off
set TARGET_DIR_FOR_ALL_OPEN=%~dp0
cd %TARGET_DIR_FOR_ALL_OPEN%
for %%a in (*.*) do (
 if not %%a == %~n0%~x0 (
  echo START:%%a
  start /max "" "%%a"
 )
)
```
自分以外のファイル(1階層)を全て開く。
自分(このバッチファイル)も開くと無限ループするので注意

いつも開くショトカとかをまとめたフォルダに入れておくだけで結構便利になるかも？