OmniAICreator/Qiita-1.07M huggingface dataset:
Gitコマンドの省略

私は,gitのコマンドでよく使うものを省略して使用しています.

今回は,以下３行を省略して使用する方法を記載します.

```
git add .
git commit -m "aaaaを修正"
git push origin master
```

~.bashrc内に以下を追加し,`source ~/.bashrc`で設定を適用させます.

```bash:~/.bashrc
function gp () {
  git add .
  git commit -m "$@"
  git push origin master
}
```

すると,最初の3行のコマンドは以下のように省略できます.

```
gp aaaaを修正
```

以上,ご参考になれば幸いです.
物理的安全性について考えた

## 心理的安全性

https://www.hrpro.co.jp/series_detail.php?t_no=2122

> 「心理的安全性」とは、**他者からの反応に怯えたり、羞恥心を感じたりすることなく、自然体の自分をさらけ出すことができる状態** を意味する。2015年に米グーグル社が、「心理的安全性は成功するチームの構築に最も重要なものである」と発表した

とあります。グーグル社の色々は以下から読めます。

https://rework.withgoogle.com/guides/understanding-team-effectiveness/steps/foster-psychological-safety/

以来、[心理的安全性のつくりかた | 石井 遼介 |本 | 通販 | Amazon](https://www.amazon.co.jp/dp/4820728245) 

https://qiita.com/akiraak/items/40c79199a90c59022be2

読みやすい解説本等が手に入るようになりすっかり我々の業界で浸透したワードに思えます。

## 「心理的安全性は達成し得るのか？」

以上を前置きとして、自分の周りの社内Slackチャンネルで非常に面白い話題があったので考えてみた、という内容です。

**1. 人としてマイナスに捉えられないという安心感**
**2. 人事考課において一切のダメージを受けないという安心感**

1.は先に定義されているいわゆる「心理的安全性」であるとして、2 は果たして達成し得るのか。達成を目指すべきなのか？

### 会社はあくまで相対評価？

会社は相対評価の世界。会社において 1 がいくら達成されようともそれだけでは「リスクを取ったチャレンジをして失敗しよう」とまでは、人間は思えないのでは、2 までの保証、安心を結局求めるのでは、という疑問。

会社は 2 のように「チャレンジしろ！失敗も許す！」と都合よく言っているように見えることがある。しかしその結果、「カモ」が生まれる現象がある。「カモ」とは粛々とやろうとしてしまうタイプ、社内にアピールしないタイプと定義する。いわゆる「47歳さん」は「カモ」だったとしてみると伝わりやすいだろうか。

https://twitter.com/tome_ura/status/1419566405389746176?s=20

現実は、47歳さんの結末のように 2 が会社において達成できることなどありえないのでは。しかし、**それは「心理的安全性」が達成されたと言えるのだろうか？**

## 以上、問い

以上、ここまでの内容を「問い」だと考えて、2 の「安全性」は果たして達成可能なのかどうか考えてみてほしい、というのがこの記事のテーマです。チームで話してみても面白そう。この記事にも「結論は、ありません」。が、このテーマを話すこと自体が、チームなどに有意義なのでは？とおもい書きました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/39fba5fc-af96-3e21-d62b-0ba4fd6c80b0.png)

## 以下、仮説

ここからは筆者のただの意見、仮説です。こういうことを言うチームメンバーが居たら面倒くさいな、などと思いながら読んでください。笑。

さて47歳さんはいわば果敢なチャレンジャーだったのかというと結局は所詮「カモ」だったと筆者は考えます。2 の達成も「できない」が正解。

- チャレンジャブルにやって成果が出たら最高評価。 <-- これは疑いないとして
- 要領よくギリギリ問題を回避したら及第点。 <-- 現実のベストはここ
- 愚直にギリギリアウト気味に問題を回避して、ボーナスカット <-- これが47歳さんであり「カモ」

47歳さんを救う事はできるのでしょうか？
筆者は究極、この世の中でガチャが無いことなどないので無理だと思いました。

「アピール下手」は残念ながら、その人が結局力量不足だと思います。言っても伝わらないものが言わないで伝わるわけがないのです。嫌なら食われないように頭を使うしかありません。

参考: [エンジニアはどこまで好かれればよいのか - 嫌われる勇気と円満退職の極意 - Qiita](https://qiita.com/e99h2121/items/a25f0485f8281d793d3c)

とはいえ筆者も堂々宣言するなら、カモタイプです。もちろんおそらく47歳さんはそこそこ貢献した人であるのですから、47歳さんのような人を救済できる策を会社は頑張って考えていただきたいものだとは思います。会社に対して上から目線ですね。笑。でも我々開発者側も、そのくらいの気持ちで所詮理不尽な会社に対峙するのが、自分の心に対して健全だと考えています。もちろん嫌なら辞めて正解。


## 「物理的安全性」の達成は不可能

物理的安全性という言葉をここまで来て思いついたのですが、その達成は人類の夢かもしれないが不可能、と考えました。

2 は心理的安全性とは別、2 は心理ではなく「物理的安全性」で、物とは本来取り合うもの。分け合う以上、安全など元からないのです。人事考課はカネ = 物の分配を決めるために必要です。「評価もカネも下がるけど、お前のせいじゃないよ、次頑張ろうぜ」って心の底の本音から慰めてくれる仲間（実際はもう少し優しい言葉で、かつその上司も評価もカネも下がってるとかね）がいれば、それでまあギリ諦めが付けば良いじゃないでしょうか、そしてそれが心理的安全性の達成なのかななどと考えました。

おカネはほしいけど。以上、「問い」を楽しんでいただけたらさいわいです。
Flutterの設定に詰まったところまとめ

<h2>参考ページと所要時間

<p>Flutterの勉強が必要になったのでテキパキ環境構築する。参考にしたのは以下のページ

[MacでFlutterの開発環境を構築する手順](https://qiita.com/oekazuma/items/92e9bae4268fea107efa)
[Android sdkmanager tool not found.の解決法](https://qiita.com/masa-321/items/0e0643b9b848f146ef3d)
[FlutterをMacにインストールしてPATHを通す(外部サイト)](https://dtpscriptin.com/flutter-install/)

<p>Flutterの設定に掛かった時間は大体２時間程度。Macの環境構築を行いました。


<h2>詰まったところ

<h3>Android Studioで新しいFlutterプロジェクトが作れない

<p>理由は定かではないですが、キャメルケースでプロジェクト名を入力したのが原因だと思っています。スネークケースでプロジェクト名を入力した場合も、別の理由で弾かれてファイルを作成できませんでした。設定時はuntitledのままで進みましょう。

<h3>Android sdkmanager not found.が表示される

<p>これは参考にした記事の通りです。が、Preference　→ system　setting → Android SDK →　SDK tools この順番で目的の場所に着きます。が、その中のAndoroid SDK build-toolsだけ新しくダウンロードしただけでは、うまく操作できません。Android SDKと書かれたものを全てダウンロードし、有効にしましょう。



<h2>まとめ

<p>気になったらとりあえず、flutter doctorを使って確認しよう。環境設定なので、基本的にデフォルトの状態で先に進み、他はいじらない。
JavaScriptで配列内オブジェクトの文字列ソート

# 概要
JavaScriptの文字列ソートで少しハマったので記事にします。

## やりたいこと

```JavaScript
//before
var array2 = [
  {label:'apple'},
  {label:'かきくけこ'},
  {label:'computer'},
  {label:'あいうえお'},
  {label:'book'}
];
//after
/*
[
  {label:'apple'},
  {label:'book'},
  {label:'computer'},
  {label:'あいうえお'},
  {label:'かきくけこ'}
];
*/
```

## 単純な配列ならうまくいく

```JavaScript
var array1 = ['apple','かきくけこ','computer','あいうえお','book'];
array1.sort();
//result
/*
['apple', 'book', 'computer', 'あいうえお', 'かきくけこ']
*/
```

## 連想配列のソートどうやるんだっけ？？
この辺の記事を見つけてコピペしてみる
https://kinocolog.com/javascript_sort/

```JavaScript
//before
var array2 = [
  {label:'apple'},
  {label:'かきくけこ'},
  {label:'computer'},
  {label:'あいうえお'},
  {label:'book'}
];
array2.sort(function(a, b){ return b.label - a.label});
//result
/*
[
  {label:'apple'},
  {label:'かきくけこ'},
  {label:'computer'},
  {label:'あいうえお'},
  {label:'book'}
];
*/
```

並び変わらない！？！？
なぜ？？
結論：上記のかきかたは、数値比較にしか使えない。

比較演算子にすればうまくいく。

```JavaScript
//before
var array2 = [
  {label:'apple'},
  {label:'かきくけこ'},
  {label:'computer'},
  {label:'あいうえお'},
  {label:'book'}
];
array2.sort(function(a,b){
  if(a.label > b.label){
    return 1;
  }else{
    return -1;
  }
});
//result
/*
[
  {label:'apple'},
  {label:'book'},
  {label:'computer'},
  {label:'あいうえお'},
  {label:'かきくけこ'}
];
*/
```

仕様を正しく理解してればわかるのですが、ハマったので、メモまで。
Manjaro Linux(btrfs + grub btrfs + timeshift)

Manjaro Linuxのインストール時の標準設定では、btrfsで@、@homeのフォルダ構成で、これはtimeshiftでバックアップをとるのに適しています。またgrub btrfsとの連携でスナップショットからのブートも可能ということで、安心できるシステム構成といえます。
この組み合わせが、容易にセットアップできるので、Archでいろいろと自分で設定するよりは、かなり敷居が低くなっています。
設定コストが低くて済みます。
Manjaroがおすすめです。
Gentooベースでバイナリパッケージが用意されたディストリビューションがあったら、良いのですが、誰も作っていないですね。
gcc、Rustなども含めたコンパイラを自分でビルドするのは、時間がかかるので、主なパッケージがバイナリパッケージで用意されて、ソースからのビルドも可能な仕組みは残しつつ、簡単にデスクトップ環境を構築できる、そんなリリースがあるといいなぁ。
言い出しっぺの法則で、やりたいところだけど、難しいな。
ManjaroがArchからGentooベースに移行してくれないかな？という淡い願望を持ちつつ。
十分、便利で使いやすいディストリビューションをメンテナンスしてくださっていることに感謝しております。
NuxtのlayoutってCSSを出し分けしてくれないらしい

## 前提
既存で運用しているサイトで所々vueを使用している箇所があり、この度Nuxt化しようとなった
HTMLはpug、CSSはscssで書かれている


## 課題
共通のCSS（例えばボタンとかリストとかutilityとか）を読み込んでいるページと、読み込んでいないページが少数存在
なので、この共通CSSを読み込んでいるlayout（default.vue）と読み込んでいないlayout(init.vue)を作成
おのおのページでレイアウト設定したところ、共通CSSを読み込んでいないlayout(init.vue)で設定しているのに共通CSS読み込まれいていた…

```
★ おおよそこんなイメージ ★
assets
 L common.scss ← 共通のstyle
 L index.scss  ← ページごとのstyle
pages
 L index.vue   ← init.vueのレイアウトを使用。index.scssをimport(not scoped)
layouts
 L default.vue ← common.scssをimport(not scoped)
 L init.vue    ← common.scssは読み込んでいない
```
[Nuxt - Layout](https://ja.nuxtjs.org/docs/2.x/directory-structure/layouts)

## 原因
Nuxtのlayouts配下で読み込まれているCSSはレイアウトごとに分ける設定にデフォルトではなっていないらしい。
つまり、layouts配下のvueで読み込まれているCSSはなんであれ一つにまとめてられてしまう。

えーーー！？！？なんためのレイアウトなのーーー？？？
見た目をバッチリ分けたいからこの機能あるんじゃないのーーーー！？！？
と思ってしまいました…

## 解決案
nuxt.config.jsのbuildに以下を設定するとレイアウトごとにファイルを分けて出してくれる

```
    splitChunks: {
      layouts: true, ←デフォルトではここがfalse
      commons: true,
      pages: true
    },
```

[https://ja.nuxtjs.org/docs/2.x/configuration-glossary/configuration-build#splitchunks](https://ja.nuxtjs.org/docs/2.x/configuration-glossary/configuration-build#splitchunks)

scoped属性をつけてしまうと、ボタンとかリストとか共通のモジュールのstyleが当たらなくなってしまうし……ここは後者で対応。
よっしゃー！これで行けるゼッと思ったところ新たな問題が発生

## 問題点
上記の設定をしたあと、再度表示を確認したところ各ページごとのCSSより共通のCSSが優先されている…！？ことが発覚

**＜極端な例＞**
default.vueで読み込んでいるdefault.css（=common.scss）ではbodyは赤だけど、TOPだけはbodyをピンクにしたい！
→index.scssでbodyをピンクに設定
結果：bodyは赤色になっている
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365109/d6858b79-7c13-2379-9747-5b8521146926.png)

なぜ。。。。。？？？？？？？

## 原因
よく見ると、閉じbodyの直前にCSSの読み込みが記述されいてる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365109/a8d187f9-aaa8-0531-e308-c85262120298.png)
ビルドされたhmtlファイルにはこの読み込みは存在していなかった、ので！動的に追加されているらしい。。
しかも順番が、ページ用のCSSの後にdefaultのCSS。。。
なんで！？！？！？
そういう仕様なのねッ！？！？！？

## 考えた対応策
### 1.layoutは分けず、CSS読み込み用のコンポーネントを作ってコンポーネントの読み分けをする
BaseStyle.vueみたいなコンポーネントを作成して共通cssをimport
中身はslotのみにして、layout機能のようなものを作成
このコンポーネントをdefault.vueで読み込んで、分岐したらいける？？

```
<tempate lang="pug">
 div(v-if="判定するためのフラグがtrueだったら")
　　　BaseStyle
　　　　　Nuxt
　　div(v-else)
 　　Nuxt
</tempate>
```

##### 結果
意味なし！
コンポーネントが表示されてるされてないに関わらず、default.vueで読み込まれてると全ページに共通CSSがきいてしまうらしい。。。

### 2.各ページで共通CSSをimportする
##### 結果
まぁ、うまくいくけど面倒だよな


### ３.ページごとのSCSSのimportをscopedつける
##### 結果
うまく行くページと行かないページが…

### ４.共通SCSSを別でビルドして動的にCSSの読み込みを追加する
##### 結果
いやいや、共通SCSS別ビルドするの…？それはなくね…？

## 結論
チームで話し合った結果、今回は共通CSSを読み込んでいないページでも読み込むことによる表示崩れはほとんど発生しないから読み込んでしまおうということになりました。

共通モジュールのstyleを、ファイルの読み込み順によって上書きしよ。っていう発想はやめよ

以上
Proxy環境下でKinD（Kubernetes-in-Docker）を利用する


# はじめに

**背景**
[kind (Kubernetes-in-Docker)](https://kind.sigs.k8s.io/)を利用すると簡単にマルチノードのKubernetesクラスタを作成できます。
プロキシ環境下でkindクラスタを作成し、クラスタのノードからインターネットに接続する際は各ノードにプロキシの設定を行う必要があります。
Kubernetesクラスタがコンテナイメージをpullするためにも、プロキシの設定は必要になります。
プロキシの設定を入れる方法を調べてもすぐには分からなかったので備忘としてここに記載します。


**目標**

- Proxy環境下でkindを利用できるようになる
（k8sクラスタのノードからプロキシを利用する）

# kindクラスタのノードに環境変数をセットする方法

通常、コンテナからプロキシを利用する場合は、
コンテナに`http_proxy`や`https_proxy`の環境変数を設定します。
kindで作成したKubernetesクラスタのノードについても同様です。
kind公式サイトにも下記の通り記載があります。

> If you are running kind in an environment that requires a proxy, you may need to configure kind to use it.
> You can configure kind to use a proxy using one or more of the following environment variables (uppercase takes precedence):
>
> ・HTTP_PROXY or http_proxy
> ・HTTPS_PROXY or https_proxy
> ・NO_PROXY or no_proxy
>
> https://kind.sigs.k8s.io/docs/user/quick-start/#configure-kind-to-use-a-proxy

これに関してはまあ当然の話なのですが、1つだけ疑問が生じます。

「どうやって環境変数を設定すんの？」

kindではyamlファイルにクラスタの設定を記載し、
`kind create`とコマンドを打つと自動でKubernetesのノード用コンテナが起動します。

yamlファイルでクラスタの設定を行うということは、
通常のKubernetesのマニフェストと同様に`env`などの項目をyaml内に設定すると良さそうです。
しかし、どうやらその方法ではできない様子。

まさか、各ノード1つ1つに環境変数を設定するのか？
いや、そんなわけないな.....。

こんな調子で数時間悶々としていました。
調べても全く情報は得られず、あきらめて再度公式ドキュメントを読み直しました。
すると下記の注意書きに気が付きました。

> NOTE: If you set a proxy it would be passed along to everything in the kind nodes.
> 
> https://kind.sigs.k8s.io/docs/user/quick-start/#configure-kind-to-use-a-proxy

一瞬何を言ってるか理解できませんが、
どうやら`kind create cluster`コマンドを実行するマシンに環境変数を設定しておけば
自動的にkindクラスタのノード(コンテナ)にも環境変数を設定してくれるみたいです。
（予想外の方法でした.......）

Windowsで利用する場合は、例えば以下のようにします。

```powershell
C:\Users\user\kind> set HTTP_PROXY=http://<ProxyID>:<ProxyPW>@<ProxyHost>:<ProxyPort>
C:\Users\user\kind> set HTTPS_PROXY=http://<ProxyID>:<ProxyPW>@<ProxyHost>:<ProxyPort>
C:\Users\user\kind> kind create cluster --config=sample-cluster.yaml
```

上記方法により、全てのノードにプロキシの設定が入っていることを確認できました。


# (参考)プロキシを使わずコンテナイメージをクラスタへ追加する方法

kindにはオフライン環境でもコンテナイメージをクラスタへ追加できる機能があります。
[Loading an Image Into Your Cluster](https://kind.sigs.k8s.io/docs/user/quick-start/#loading-an-image-into-your-cluster)に記載がある通り
下記のようなコマンドでイメージを追加できます。

オフライン環境だけでなく、kubernetesクラスタ内からイメージをpullする必要が無いときやCICDのパイプライン等でもこちらの方法も使えそうです。

```powershell
C:\Users\user\kind> kind load docker-image [ <コンテナイメージ名>... ] --name <kindクラスタ名>
```
【Salesforce】Lightning コミュニティのファビコン作成

Lightning コミュニティのファビコン作成の詳細方法について、下記の公式ヘルプに書かれてます。
[-- Salesforce Help --](https://help.salesforce.com/s/articleView?id=000317947&type=1)
下記二つの方法でLightning コミュニティのファビコンを作成してみます。
###①静的リソースの使用でファビコンの作成
　次の手順に従ってファビコンをコミュニティに追加します。
　１．ファビコン (公開キャッシュコントロール) を静的リソースとして組織に追加します。
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618831/0be02bef-0c47-4ff3-e1b3-8d70b44d8cdc.png)
　　※静的リソースの名前はこの後のステップで特に使用されません。

　２．[エクスペリエンスワークスペース] | [管理] | [ページ] | Force.com に移動します。
　３．[編集] をクリックしてファビコン静的リソースを [サイトのお気に入りアイコン] に追加して保存します。
　４．コミュニティビルダーで、[設定] | [詳細] | [ヘッドマークアップを編集] に移動します。
　５．次のコードを追加します: `<link rel="shortcut icon" href="<SITE>/favicon.ico?v=2"/>`
　　`<SITE>`はコミュニティの URL です。たとえば、[設定] | [すべてのコミュニティ] で設定されている URL 値です。
　　<font color="Red">【注意】：「favicon.ico?v=2」そのまま使ってください。（変更しないこと）</font>
　　      　これで自動的に静的リソースのファビコン画像を参照できるようになります。
　６．保存します。
　７．Community Builder でコミュニティを公開します。
###②コミュニティのアセットの使用でファビコンの作成
　１．下記通り、Site.com Studioを開いて、ファビコン画像をコミュニティのアセットフォルダに追加します。
　　・[エクスペリエンスワークスペース] | [管理] | [ページ] | Site.com Studio
　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618831/fd1f5e3c-e165-0f92-233c-41db7b2b4822.png)
　・[アセット] | インポートでファビコン画像をインポートします。
　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618831/9ea813d1-abf8-0883-1f27-6f066125df5a.png)
　　・ファビコンファイルパスをメモして、「変更を公開..」ボタンで変更公開します。
　　　<font color="Red">【注意】： ファビコンファイルパスは後ろのステップで使用されます。</font>
　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618831/c22a24f8-bcc4-680a-c43f-d3d461e47dd0.png)
　２．コミュニティビルダーで、[設定] | [詳細] | [ヘッドマークアップを編集] に移動します。
　３．次のコードを追加します:
　　```<link rel="shortcut icon" href="/mycommunity/s/myfavicon.ico"/>```
　　【注意】： 上記hrefに相対パス「/ + `<community path>` + /s + 前のファビコンファイルパス」を設定します（/s/を忘れず）。
　４．保存します。
　５．Community Builder でコミュニティを公開します。
Nuxtの環境構築【Windows】

#Nuxtの環境構築
Nuxt の環境構築を行います。また Nuxt での開発がしやすくなる環境も構築します。
Nuxt の開発環境を構築するには、JavaScript 系のパッケージマネージャーが必要です。パッケージマネージャーとは、さまざまなソフトウェアのインストールやアンイストールが容易にできるツールとなります。

JavaScript 系のパッケージマネージャーには、npm もしくは Yarn がありますが、公式が推奨している Yarn を使用します。 → [NuxtJS](https://ja.nuxtjs.org/guide/upgrading/)

Yarn は Node.js で動作します。Node.js とはサーバーで動く JavaScript の実行環境です。そのため Node.js もインストールします。

#目次
・YarnとNode.jsのインストール
・Nuxtの新規プロジェクトの作成

##YarnとNode.jsのインストール
###Node.jsのインストール
[Node.jsの公式サイト](https://nodejs.org/ja/)
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2034987/50d3fdef-d1e2-36b8-315e-b40503619ae5.png)

Git Bash を開き、以下のコマンドを実行してください。Node.js のバージョンが表示されれば成功です。
もし Node.js のバージョンが表示されない場合は、一度 Git Bash を再起動して、コマンドを実行しましょう。
####▼Node.jsのバージョン確認
```
node -v
>v16.0.0など
```
###Yarnのインストール
続いて Yarn をインストールします。[Yarn の公式サイト](https://classic.yarnpkg.com/lang/en/docs/install/#windows-stable) を開いて、インストーラーをダウンロードしましょう。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2034987/ce2e329d-a474-0c40-bcce-6a708fdaab3f.png)
Git Bash を開き、以下のコマンドを実行してください。Yarn のバージョンが表示されれば成功です。

####▼Yarn のバージョン確認
```
yarn -v
> 1.22.0 など
```
もし Yarn のバージョンが表示されない場合は、一度 Git Bash を再起動して、コマンドを実行しましょう。
##Nuxtの新規プロジェクトの作成
ターミナルで Nuxt の新規プロジェクトを作成します。まずはカレントディレクトリをデスクトップに移動します。
```
cd Desktop
```
次にデスクトップ配下で、nuxt_hello_world という プロジェクトをターミナルで作成します。

▼ ~/Desktop
```
yarn create nuxt-app プロジェクト名
```
質問されるので、解答していきます。基本的に Enter を押せば OK です。
```
? Project nuxt_hello_world => 何もせず Enter
? Programming language  => Javascript
? Choose the package manager => Yarn
? Choose UI framework => None
? Choose Nuxt.js modules (Press <space> to select, <a> to toggle all, <i> to inv
ert selection) => 何もせず Enter
? Linting tools: (Press <space> to select, <a> to toggle all, <i> to invert sele
ction) => ESLint と Prettier をスペースキーで押して、Enter
? Testing framework: 何もせず Enter
? Rendering mode: Universal (SSR / SSG)
? Deployment target: Server (Node.js hosting)
? Development tools: 何もせず Enter
? Version control system: Git
```
以下のような画面が出ると、新規プロジェクトの作成が完了です。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2034987/4e141cc0-e247-e9f3-15ba-55cdcb959bb5.png)
続いてVS Codeに作成したフォルダをドラッグ＆ドロップします。
スピルのすすめ(ユーザー定義関数との組み合わせ

##前書き

Excel2020くらいからの新機能のスピルですが、まだまだ知名度は低いです。
しかしながらユーザー定義関数と組み合わせることで今までと少し違ったユニークな機能を実現できそうです。
二つの具体例で説明を進めます。


##例① ～Summaryの出力～
エクセル上の特定のデータを処理して複数の値をまとめて出力する。
同時にラベリングも可能。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237248/5db86392-7ec3-a2c8-4bcb-f8a54f4a2992.png)


```VB
Public Function 統計値出力(ByRef argRange As Range) As Variant
    Dim i As Long, j As Long
    
    Dim average As Double, sigma As Double, max As Double, min As Double
    
    average = Application.WorksheetFunction.average(argRange)
    sigma = Application.WorksheetFunction.StDev(argRange)
    max = Application.WorksheetFunction.max(argRange)
    min = Application.WorksheetFunction.min(argRange)
    
    Dim label As Variant, value As Variant
    
    label = Array("平均", "標準偏差", "最大値", "最小値")
    value = Array(average, sigma, max, min)
    
    Dim myReturn As Variant
    ReDim myReturn(0 To 1, 0 To UBound(value))
    
    For i = 0 To UBound(label)
        myReturn(0, i) = label(i)
        myReturn(1, i) = value(i)
    Next i
    
    統計値出力 = myReturn
End Function

```

スピルとは新しくエクセルに導入されたいくつかの関数が持っている機能です。
スクリーンショットのrandarray()のようにスピルによって結果を複数セルに展開することが可能になっています。

これはユーザー定義関数でも同様です。（ユーザー定義関数とはプログラミングによって関数を作れる機能です。ここでは詳しくは説明しません。）
新しく作成した「統計値出力」関数で簡単にサマリを作成できます。

##例② ～データを間引く～
データを間引く関数を作成します。
引数を変えることで３行スキップの４行ごとのデータ出力、
５０行スキップの５１行ごとの出力を得ることが出来ます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237248/ddece31b-a400-22b2-9605-6d942d9aff72.png)


```vb
Public Function データを間引く関数( _
        ByRef argRange As Range, _
        Optional ByVal skipRow As Long = 0, _
        Optional ByVal skipColumn As Long = 0 _
    ) As Variant
    
    Dim i As Long, j As Long
    
    Dim argRow As Long, argColumn As Long
    argRow = argRange.Rows.Count
    argColumn = argRange.Columns.Count
    
    'アルゴリズムの都合上 newRow := 新しい行数から1引いた数になっていたり少しわかりずらい。
    Dim newRow As Long, newColumn As Long
    newRow = (argRow - 1) \ (skipRow + 1)
    newColumn = (argColumn - 1) \ (skipColumn + 1)
    
    Dim myReturn As Variant
    ReDim myReturn(0 To newRow, 0 To newColumn)
    'ここもアルゴリズム優先
    '行数・列数の時は1 to RowNumberにしたほうが5行3列目のデータがmyReturn(5,3)に入りわかりやすい。
    '関数経由でエクセルから得たargRangeも(1 to 列数,1 to 行数）となっており統一感がでる
    
    Dim row As Long, column As Long
    For row = 0 To newRow
        For column = 0 To newColumn
            myReturn(row, column) = argRange(row * (skipRow + 1) + 1, column * (skipColumn + 1) + 1)
        Next column
    Next row
    
    データを間引く関数 = myReturn
    
End Function
```

###おわりに
いかがだったでしょうか？（一度言ってみたかった）
スピル×ユーザー定義関数のメリットとしては以下の2点を挙げることができると思います。

- リッチな出力を簡易に実現できる。
- 引数による動作の制御可能

複数人で使いまわすことがなかなか難く一人分の削減できる時間＞作成コストの見込みが強いため、自分は実際に活用するところまではいけていません。
しかしスピルと組み合わせた機能はユニークであり、レガシーが多く嫌われがちなExcelの長所を伸ばせる可能性を感じます。

引数を受け取り、処理をし、出力するといったフォーマットは今回の例で提示できていると思うので、何か面白い使い道を思いついたら作って見て下さい。
[競プロ] 配列AにおけるA[i1]-A[i2]+A[i3]-A[i4]+... (i1<i2<i3<i4...)の最大値の求め方

## 問題
配列AにおけるA[i1]-A[i2]+A[i3]+A[i4]+... (i1<i2<i3<i4...)の最大値を求めよ

## 回答 (総当たり)

インデクス(i1,i2,i3...)の組合わせを全て試す

インデクスが２つの場合は下記のイメージ
選択するインデクス数が増えるとforの数が増えていく。

```c++
int n = A.size();
int ans = -1e9;
for (int i=0; i<n; i++) {
    for (int j=i+1; j<n; j++) {
        ans = max(ans, A[i]-A[j]);
    }
}
cout << ans << endl;
```

## 回答（DP）

dpを下記のように定義する

```
dp[i][j] := 0..i-1の範囲でj個のインデクスを選択した場合の最大値
```

dp[i+1][j+1]の値はiの値を選択するかどうかで場合分けができるので次の２つの最大値となる。

1. iの値を選択すると、0..i-1の範囲からj個のインデクスを選択した場合の最大値とA[i]の和
2. iの値を選択しないと、0..i-1の範囲からj+1個のインデクスを選択した場合の最大値

よってdp遷移は下記になる

```
dp[i+1][j+1] = max( dp[i][j+1], dp[i][j] + A[i] ) if jが偶数 && i >= j
dp[i+1][j+1] = max( dp[i][j+1], dp[i][j] - A[i] ) if jが奇数 && i >= j
```

```c++
int n = A.size();
int m = 5; // 選択するインデクス数
vector<vector<int>> dp(n+1, vector<int>(m+1, -1e9));
for (int i=0; i<=n; i++) dp[i][0] = 0;
for (int i=0; i<n; i++) {
    for (int j=0; j<4; j++) {
        if (i<j) continue;
        if (j % 2 == 0) dp[i+1][j+1] = max(dp[i][j+1], dp[i][j] + array[i]);
        if (j % 2 == 1) dp[i+1][j+1] = max(dp[i][j+1], dp[i][j] - array[i]);
    }
}
	
cout << dp[n][m] << endl;
```
CSV.parse で空のフィールドを必ず空文字に変換する

## バージョン情報

```rb
RUBY_VERSION #=> "3.0.1"
CSV::VERSION #=> "3.1.9"
```

## 内容

CSV.parse で CSV 文字列をパースした場合、空のフィールドは場合によって nil を返したり空文字を返したりする。

```rb
require 'csv'

CSV.parse(%(🐱,,🐶\n,"🐰",""))
#=> [["🐱", nil, "🐶"], [nil, "🐰", ""]]
```

空のフィールドを空文字に統一したい場合は `nil_value` オプションを使用するとよい。

```rb
require 'csv'

CSV.parse(%(🐱,,🐶\n,"🐰",""), nil_value: '')
#=> [["🐱", "", "🐶"], ["", "🐰", ""]]

# もちろん nil_value オプションに空文字以外の値を指定することもできる。
CSV.parse(%(🐱,,🐶\n,"🐰",""), nil_value: '🈳')
#=> [["🐱", "🈳", "🐶"], ["🈳", "🐰", ""]]
```

## 参考

- [Feature #12839: CSV - Give not nil but empty strings for empty fields - Ruby master - Ruby Issue Tracking System](https://bugs.ruby-lang.org/issues/12839)
- [csv/nil_value.rdoc at v3.2.1 · ruby/csv](https://github.com/ruby/csv/blob/v3.2.1/doc/csv/options/parsing/nil_value.rdoc)
【Golang】相関係数の算出

## 概要
Goで相関係数を求める

## 数理パッケージ
gonumはちょっと用途に合わなかったので、[montanaflynn/stats](https://github.com/montanaflynn/stats)のCorrelation関数を使う

## 使い方

```go
package main

import "github.com/montanaflynn/stats"

func main() {
	cor, _ := stats.Correlation([]float64{1, 2, 3, 4, 5}, []float64{1, 2, 3, 5, 6})
	fmt.Println(cor)
	// Output: 0.9912407071619302
}
```
【Salesforce】experiencebundleでコミュニティサイトの開発と移行

Summer ’19 リリース以前 (API バージョン 45.0 以前) は、Network、CustomSite、SiteDotCom メタデータ型を組み合わせてコミュニティサイトを定義していました。ただし、SiteDotCom のメタファイルが人間の判読できないバイナリファイルなので、多人数開発（資源のマージが必要）またはサイト移行の際に、ほとんど使えないとの問題があり、その後ExperienceBundleの登場でこの問題が解消されました。

ExperienceBundleとはサイト資源を人間判読可能なメタデータファイル（普通のメタデータファイルに似てる）として管理しサイトの開発と移行に便利です。

参考：[Salesforce Developers](https://developer.salesforce.com/docs/atlas.ja-jp.234.0.communities_dev.meta/communities_dev/communities_dev_migrate_expbundle.htm)
##①メタデータ API でサイト資源（ExperienceBundle）の取得方法
　１．「設定」からExperienceBundleを有効化します。
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618831/3e7574f7-b8e7-3d30-bbdd-51bf63662cbc.png)

　２．VSCodeで対象資源定義のpackage.xmlファイルを作成します。
　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618831/ef77df8d-24d0-aa8b-8977-cb178bd99ccf.png)
　　※CustomSite、NetworkとExperienceBundleの三つが必要ですが、必要に応じてその他資源（上記例のNavigationMenu）追加の場合もあります。
　　<font color="Red">【注意】：SiteDotComを使用しないこと</font>

　３．資源を取得します。
　　package.xmlファイルを右クリックし、「SFDX:マニフェストファイルのソースを組織から取得」でサイト資源一式が取得できます。
　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618831/7c4a4473-8617-5022-0d5c-825978190460.png)
　　<font color="Red">【注意】：うまく取得できない場合、上記図の通り、手動でexperiences（force-app\main\default\experiences）フォルダを作成してから再度試してください。</font>

　４．取得した資源を確認します。
　　下記とおり、資源(ExperienceBundle)が取得できました。
　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618831/7b10e206-b4bb-1c3c-fa47-b4df133e27e8.png)

##②Salesforce DXでスクラッチ開発方式を使用したExperienceBundleの取得方法
スクラッチ開発方式の場合、手順が下記になります。
　　１．スクラッチ組織定義ファイル（project-scratch-def.json）に下記を追加します。
　　```"features": ["COMMUNITIES"],
　　"settings": {
　　　　"experienceBundleSettings": {
　　　　　　"enableExperienceBundleMetadata": true
　　　　},
　　　　"communitiesSettings": {
　　　　　　"enableNetworksEnabled": true
　　　　}
　　}```
　　　　これでスクラッチ組織を作成するとExperienceBundleが自動的に有効になります。

　　２．sfdxコマンド(force:source:push,force:source:pull)でサイト資源のデプロイと取得ができます。
　　　　※force:source:pushで資源をデプロイするとサイトの作成と有効化が自動的に行われます。

##③ExperienceBundleでサイトデプロイと移行の注意点
* メタデータ API でデプロイの際、package.xmlにCustomSite、NetworkとExperienceBundleの三つを設定しておけば、コミュニティサイトの作成と有効化が自動的に行われるので手動で行う必要がありません。
*  2回目以降のデプロイではサイトの再作成が必要ないので、package.xmlに必要な資源だけ（例：ExperienceBundleだけ）を定義すればOKです。
Python + Beautiful Soupスクレイピング

#Requestsインストール

`requests`はWebサイトの情報取得や画像の収集など、スクレイピングに役立つHTTP通信用のPythonのライブラリです。
後述する`Beautiful Soup`と併用することで、Webサイトを解析し、必要な情報だけを抜き出すことができます。

https://docs.python-requests.org/en/latest/

▼インストール

```plaintext:
pip install requests
```

#Beautiful Soupインストール

`Beautiful Soup`はHTMLやXMLからデータを抽出するためのライブラリです。
タグを指定し、ピンポイントでのデータ抽出も可能です。

https://www.crummy.com/software/BeautifulSoup/bs4/doc/

▼インストール

```plaintext:
pip install beautifulsoup4
```

#ソースコード

ここでは基本構文のみ。
実際に何か作った際は、使い方の詳細を書きます。

▼基本的な使い方

```python:get.py
# resuestsモジュールをインポート
import requests

# BeautifulSoupクラスをインポート
from bs4 import BeautifulSoup

# スクレイピング対象URLのHTMLを取得
html = requests.get("https://www.yahoo.co.jp/")

# レスポンスのHTMLをもとにBeautifulSoupのオブジェクトを生成
soup = BeautifulSoup(html.content, "html.parser")

# HTMLのタイトルタグを取得
print(soup.title)
```

# 実行結果

```plaintext:
D:\prj_python>python get.py
<title>Yahoo! JAPAN</title>
```
Unity カメラを追従させる方法

##0.0 はじめに
プレイヤーなどにカメラを追従させる方法です。
色々な方法があると思いますが、今回はスクリプトから追従させる簡単な方法を紹介します。



##1.0 普通に追従
カメラ（Main Camera）に下記スクリプトを添付する。2Dゲーム上でプレイヤーをカメラが追っかける例です。カメラのz座標は-10fとしています。


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

public class Camera1 : MonoBehaviour {

    [SerializeField] Transform playerTr; // プレイヤーのTransformをInspectorから入れる

    private void Update() {
        // カメラをプレイヤーの場所へ
        transform.position = new Vector3(playerTr.position.x, playerTr.position.y, -10f);
    }
}
```

##2.0 カメラの追従を制限する
カメラ移動の限界を設けることにより見せたくないエリアまでカメラを移動しない方法です。
下記スクリプトではMathf.Clampを使用して右上限界点(5,5)、左下限界点(-5,-5)を越えないようにしています。


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

public class Camera2 : MonoBehaviour {
    [SerializeField] Transform playerTr; // プレイヤーのTransform
    [SerializeField] Vector2 camaraMaxPos = new Vector2(5, 5); // カメラの右上限界点
    [SerializeField] Vector2 camaraMinPos = new Vector2(-5, -5); // カメラの左下限界点

    private void Update() {       
        transform.position = new Vector3(
            Mathf.Clamp(playerTr.position.x, camaraMinPos.x, camaraMaxPos.x), // カメラの左右を制限
            Mathf.Clamp(playerTr.position.y, camaraMinPos.y, camaraMaxPos.y), // カメラの上下を制限
            -10f); // カメラz座標は-10f
    }
}
```


##3.0 ゆっくり追従
Mathf.Lerpを使うと少し遅れてカメラが追従します。画面の移動が滑らかな動きになります。

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

public class Camera3 : MonoBehaviour {
    [SerializeField] Transform playerTr; // プレイヤーのTransform

    private void Update() {
        transform.position = Vector3.Lerp(
            transform.position, 
            playerTr.position + new Vector3(0, 0, -10), // カメラzの位置
            2.0f * Time.deltaTime);       
    }
}
```

##4.0 まとめ
まとめると下記のような感じになります。
Update()はどの順番で呼ばれるかがランダムなため、処理の呼ばれるタイミングがばらばらでカメラの動きががカクつくときがあります。フレームの最後に呼ばれることが決まっているLateUpdate()を使うことで問題が改善されます。


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

public class Camera4 : MonoBehaviour {
    [SerializeField] Transform playerTr; // プレイヤーのTransform
    [SerializeField] Vector3 cameraOrgPos = new Vector3(0, 0 ,-10f); // カメラの初期位置位置 
    [SerializeField] Vector2 camaraMaxPos = new Vector2(5, 5); // カメラの右上限界座標
    [SerializeField] Vector2 camaraMinPos = new Vector2(-5, -5); // カメラの左下限界座標

    void LateUpdate() {

        Vector3 playerPos = playerTr.position; // プレイヤーの位置
        Vector3 camPos = transform.position; // カメラの位置
        
        // 滑らかにプレイヤーの場所に追従
        camPos = Vector3.Lerp(transform.position, playerPos + cameraOrgPos, 3.0f * Time.deltaTime);
        
        // カメラの位置を制限
        camPos.x = Mathf.Clamp(camPos.x, camaraMinPos.x, camaraMaxPos.x);
        camPos.y = Mathf.Clamp(camPos.y, camaraMinPos.y, camaraMaxPos.y);
        camPos.z = -10f;
        transform.position = camPos;

    }
}
```
UIStepper 復習

#今回の内容

* UIStepperについての復習です。

<img width="150" alt="C488BC55-FE52-4DDB-A808-AEE9A0BA7E5A_4_5005_c.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1466343/937a1f01-370e-d4b4-2f9c-fc778218ee36.jpeg">

#コードと簡単解説



```Swift:
    @IBOutlet weak var stepper: UIStepper!
```

```Swift:
    override func viewDidLoad() {
        super.viewDidLoad()
        
        stepper.stepValue = 0.5
        stepper.minimumValue = -50
        stepper.maximumValue = 50
    }
```

* `.stepValue`には、`+`または`-`を押したときに増減する値を設定します。
* `.minimumValue`には、扱える値の最小値を設定します。
* `.maximumValue`には、扱える値の最大値を設定します。

```Swift:
    @IBAction func changeValue(_ sender: UIStepper) {
        
        print(sender.value)
        
    }
```
* `UIStepper`の値を利用する時は`.value`を利用して値にアクセスします。

# 終わり
ご指摘、ご質問などありましたら、コメントまでお願い致します。
HTMLでスマホの画面サイズにする方法

#HTMLでスマホ画面サイズにする方法

##HTML
```index.html
<head>
 <meta name="viewport" content="width=device-width,initial-scale=1.0">
</head>
```


- ブラウザや、検索ロボットにホームページの情報を知らせるタグ。
- 横幅はデバイスのサイズで表示し、1.0倍率で表示させる。

#CSSの設定

```style.css
@media screen and (max-width:768px){
 /* ここにスマホサイズで表示するコードを書く */
}
```
【vyos on VMware Playerでネットワークのお勉強】(001)ご挨拶

## はじめに
セキュリティスペシャリストを2015年、ネットワークスペシャリストを2017年に取得し、ある程度知識に自信を持っていた筆者ですが、現場では実機操作が無いと厳しいという現実に直面しました。
GNSに手を出そうと思っていたのですが、下手に新しいものに手を出すよりも、昔触ったことがあるvyatta(現vyOS)の方が扱いやすいやと思って、古い知識を温め直すことにしました。

## 環境説明 
| # | 使用環境 |
|:-:|:------------|
| 1 | VMware(R) Workstation 16 Player |
| 2 | vyos-1.4 |

なお、vyosは下記のページからダウンロードすることができます。
[vyOSのダウンロードページ](https://vyos.net/get/nightly-builds/)

## 本記事のゴール
vyosの基本設定から、複数セグメントに配置したサーバのログを、Elastic Searchに取り込むところまでをまとめようと思っています。
途中でタイトル変更(主体がvyOSから変更したときにタイトル変更を行う予定です)いますが、できる限り最後まで書き上げようと思っていますのでよろしくお願いいたします。
【備忘録】swift UI テキストサイズ、カラー等の変更とボタンの追加

#テキストサイズ、カラー等の変更

①：対象の文字を「コマンド」+クリックをしポップアップを表示

②：「show swiftUI inspector...」を選択

③：表示されたFontのcolorやsize,weightを任意のものへ変更


#ボタンの追加

①：画面右上の「＋」をクリックし、ライブラリーウィンドウを表示

②：「button」を選択し、任意の場所へドラックアンドドロップ

##新出単語
**Vstack**.....要素を縦並びに表示する。
以下の例の場合テキストとボタンが縦並びに表示される。

        VStack {
            Text("Hello, world!")
                .font(.largeTitle)
            .padding()
            Button(action: {}{
             Text:"button"
            }
        }
Railsチュートリアル2週目を終えて

#概要
Railsチュートリアル2週目を終えたので、感想を書こうと思います。

##かかった期間
10/10 ~ 10/27 (24~26を除く、約2週間)
合計：約63時間

1週目では約48時間かかったので、2週合計で110時間ほど費やしました。


##開発環境
1週目からクラウドIDEではなくローカル環境で開発に挑戦しました。

- Macbook Pro(13-inch, M1, 2020)
- Mac OS Big Sur 11.6
- VSCode (Visual Studio Code - Insiders 1.62.0)
- Ruby 3.0.2p107
- Rails 6.1.4.1

##1週目と2週目の間にやったこと
1週目を終えた時点で「Rubyのコードが読めない」「なにが書きたいのかわからない」と気づきました。恥ずかしながら。Rubyの基礎力がかなり不足していたのです…。Rubyの力を養うために、「たのしいRuby」で文法をメインに勉強しました。

# 2週目で心がけたこと
1週目では上記の通りコードを読めないことに加え、**コードに対するコメント**を全然書いていませんでした。「いま勉強している内容がこうだから…このコードはこうかな？」となんとなく理解できたコードも、2~3日経てば

**なんということでしょう～、なんのためのコードか全くわからないではありませんかぁ〜!!**

ということで、2週目は過剰なぐらいコードにコメントを書きました。例えば、

```:routes.rb
  resources :password_resets, only: [:new, :create, :edit, :update]
  # GET     /password_resets/new
  # new     new_password_reset_path
  
  # POST    /password_resets
  # create  password_resets_path

  # GET     /password_resets/トークン/edit
  # edit    edit_password_reset_url(token)
  
  # PATCH   /password_resets/トークン
  # update  password_reset_url(token)
```

このように、チュートリアル内の説明をコピペしたり、

```:static_pages_controller_test.rb
class StaticPagesControllerTest < ActionDispatch::IntegrationTest
  # 各テストが実行される直前で実行
  def setup
    @base_title = "Ruby on Rails Tutorial Sample App"
  end

  test "should get home" do
    # GETリクエストをhomeアクションに対して発行
    get root_path
    # リクエストに対するレスポンスは［成功］になるはず
    assert_response :success
    # titleタグの内容を検証する、homeは基本タイトルのみ表示
    assert_select "title", "#{@base_title}"
  end
  
  test "should get help" do
    # GETリクエストをhelpアクションに対して発行
    get help_path
    # リクエストに対するレスポンスは［成功］になるはず
    assert_response :success
    # titleタグの内容を検証する
    assert_select "title", "Help | #{@base_title}"
  end
```
テストの1行ごとに対して内容を書いてました。おかげさまで後々見返したときの理解が捗ります。コメントを書くだけで学習のスピードが1.7倍ぐらいになった気分でした。

## コメントってすごい
コメントを書くようにすることで、以下のことを感じました。

- コードの内容を思い出しやすくなる
- わかりやすいコメントを書くためにコードについて調べるようになる
- 見返したときに読みにくいコメントを見つけて、コメントの書き方にも気をくばるようになる

なによりも1つ目の「思い出しやすくなる」のメリットはすごいです。**新しいことを勉強している最中に、過去に書いたコードについて思い出す**のってかなり労力がかかると思います。

自分本位ではありますが、「コードを書いている今、すこし一手間加えただけで未来の自分が楽になれる…ならばやらない手はない」と思いました。

これって、複数人で開発するときでも当てはまりそう！誰かに自分のコードを読んでもらうときに、わかりやすいコメントがあったら相手に労力をかけさせないで済むかもしれませんね…


## コメント以外に心がけたこと
1週目にやった演習や、AWS(S3)への保存などはできる限り飛ばすようにしました。理由としては「もうすでにできることにかける時間がもったいない」のと「AWSはそのうち勉強するはず。いまチュートリアルにそってやっても身につかなさそうだし、手間とメリットが釣り合わない」と感じたからです。

その代わり、1週目でできなかった演習には時間を割きました。2週目でクリアできたときには成長できていると感じ嬉しかったです。


#これから取り組む方に向けて
コメントをいっぱい書きましょう。コードで書く処理を言語化することで、コードの意図を少しでも把握できるようになります。

私自身の理解力の無さが原因だとは思いますが、2週してもチュートリアルの半分を理解できたとは感じません。個人的には**「全部理解してやる！」**と意気込むよりは**「理解できなくても、一度は全部やりきってみる」**ぐらいの気持ちで挑戦するのをおすすめします。

---

1週目の感想はこちら　→　「[Railsチュートリアルを1週してみた感想](https://qiita.com/NIssyi/items/3a9804fa9bc0dbc655ab)」
【AWS】boto3を使ってS3でフォルダを作成する方法


boto3を使ってS3でフォルダを作成する方法です。（備忘録として）

```python
import boto3　#boto3インポート

dir = 'hoge/fuga/'　　#ディレクトリパス
bucket_name='your_buket_name' #S３のバケット名
s3 = boto3.client('s3')
result = s3.list_objects(Bucket=bucket_name, Prefix=dir)　#ディレクトリを変数に

if not "Contents" in result:　# ディレクトリがない場合はContents というキーが存在しない。これを使えば存在判定ができる。
  s3.put_object(Bucket=bucket_name, Key=dir)  #ディレクトリ作成 
```

#　参考にした記事

https://intellipaat.com/community/41744/using-boto3-how-can-i-create-a-folder-inside-s3


https://qiita.com/rareshana/items/ea72a7b226d7bf2c16f9
AIを活用する会社紹介 vol.1【​株式会社レボーン】

![会社紹介_001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1667780/4f9c2a1a-1701-61ea-7d57-2bdb198220fd.jpeg)

こんにちは！キカガクで機械学習・AIプログラミングを学習中のカワイです。今回はAIを活用されている魅力的な企業をご紹介します。今後ますます活用の場が広がっていくAI。その技術を、どうビジネスに活用しているのかを探っていきます。いつまで続けるか未定ですが、シリーズにしようと思っています。

記念すべき1社目は"香り × AI × IoT"というコピーが興味をそそる、「株式会社レボーン」さんです。のっけから斬新なビジネスを展開している雰囲気がプンプンします。AIやディープラーニングと聞くと、画像分類や言語処理が思い浮かびますが、"嗅覚"にアプローチしているところが実にユニークです。どんなビジネスを展開されているのか探っていきましょう。

# ポテンシャルはあるが、科学的な理解が難しい "におい" への挑戦
同社はにおいの特徴を以下のように述べています。

- 人間の感情にじかに働きかけ、生活の質に大きな影響を与えるといわれている
- 嗅覚へ働きかける商品やサービスは限定的で、新しい視点で市場に展開されていない
- 嗅覚のメカニズムで未解明な部分が多い
- 人がにおいから受ける影響は多様
- 無意識ににおいによる影響を受けている
- においは、センサとしての感じ方においても個人で違いが生じる
- 脳の情動に作用する部分にダイレクトに働きかけ、人の心を動かしたりそれがにおいの評価につながったりすることもある
- 未だに科学的な理解が難しい部分が数多く存在している
- においビジネスにおける市場ポテンシャルへの注目はかねてよりあった
- 新興ビジネスの展開がほとんど望めていない状況が続く

"におい"についてここまで考えたことはなかったです。脳に直接影響するので、あまり意識する機会がないからでしょうか。興味深いです。

# レボーンのアプローチ
同社はAIを活用し、収集したにおいデータの識別を行うことで人の嗅覚の再現を目指していると述べています。においを科学するためには、嗅覚のメカニズムを再現する必要がありますが、一般的な嗅覚センサで測定できるのは、におい分子の種類の判別に限られているのが現状だそうです。

# レボーンが生み出す「香り × AI × IoT」の可能性
実際に同社が"におい"ビジネスを展開している分野を8つ紹介します。

### 01. Culture（文化）
香りをブランディングの要素として活用します。においは一番記憶に残ると聞いたことがありますが、これをコントロールできると確かにブランディングに大きく貢献しそうです。

### 02. Parameters（​評価）
香りをデータで見える化し、香り高さを測ります。コーヒーやワインなど、香りで評価することがありますが、ここに数字が入り込んでくると今まで見えてこなかった細かい違いが分かりそうですね。

### 03. Behavior（​行動）
「香りが変わると、人の行動が変わる」という一文にドキっとしました。これはマーケティングに活用できそうな印象を受けました。まだ3つ目ですが、ここまででも十分"におい"の重要性を認識することができた気がします。

### 04. Living Environment（​空間）
これは一番身近な例ではないでしょうか。アロマをたいてリラックスしたり、お香に癒されたり。ここにAIやIotを絡めると、用途や場所によって最適な香りの提案ができそうです。

### 05. Healthcare（​医療）
においで体調や病気の兆候が分かるそうです。自分の体調を他人に理解してもらうのは難しいですが、においを数値化できれば客観的にその人の状態が分かるのでしょうか。昨今、加齢臭はストレス臭と呼ばれるようになりましたが、ストレス度数なんてのも測れるようになるかもしれません。

### 06. Quality（​品質）
「05. Healthcare（​医療）」が人に対する活用事例だとすると、こちらは商品に対しての活用事例だと認識できます。視覚的には判断できない品質も、"におい"で測れると、今後の品質管理のあり方も変わってきそうです。賞味期限切れの食品を食べても大丈夫かどうかを判定してくれるアプリがあったら重宝しそうです。

### 07. Society（​社会）
国内では100頭以上の麻薬探知犬が活躍しているそうですが、"におい×AI×Iot"の活用で彼らの助けがなくても異常検知が可能になるそうです。今年開催されたオリンピックのような世界的なイベントがある際にも大いに活躍しそうです。

### 08. Lifestyle（​ライフスタイル）
本当に自分が好みの香りをAIが提案してくれます。私は香水をつけたり、部屋に香りをまくといったことはしないのですが、自分にはどんな香りが適しているのかが分かるのなら、一度判定してもらいたいです。

# さいごに
「においの“なんとなく”をなくす」というミッションを掲げるレボーン。同社が「重要性があるのは分かりつつ未開拓な部分が多い"におい"」に挑戦する理由が分かりました。正直、"におい"がここまで可能性を秘めているものだとは思いませんでした。AI活用企業の紹介でしたが、あまりにも"においビジネス"のインパクトがあり、そちらがメインの内容になってしまいました w 　しかし、未開拓分野にこそAI技術が生きてくることも感じることができました。メディアでもたびたび紹介されているレボーン。今後も目が離せません。


【株式会社レボーン】
https://www.revorn.co.jp/
Query 関数のクエリに他セルの内容を埋め込む

## 要点
& とか CONCATENATE 関数とかを使って文字列を組み立てる

## 例

Google スプレッドシートの話．
例えば以下のような表があったとして，

| | A | B |
|---| :-- | --: |
|1|2021/08/30|-100|
|2|2021/08/31|-300|
|3|2021/09/01|500|

（Aは文字列，Bは数値）  

月ごとの合計を Query 関数で求めたいとする．
このとき，

||C|
|---| :-- |
|1|2021/08|

があったとして，

```
=QUERY(A:B, "SELECT SUM(B) WHERE A LIKE '" & C1 & "%' LABEL SUM(B) ''")
```

などとして， & を使ってクエリを組み立ててやれば，結果が得られる．
（このセルを下にコピーして増やすことも可能！）

||D|
|---| --: |
|1|-400|

## これ安全？
アプリ開発などにおいて，クエリを自分で組み立てるのはご法度
> -> SQL インジェクション

場合によっては，この方法は危険かもしれない
自分だけが使うスプレッドシートなら，これでいいんじゃないかなぁという認識...
Query 関数の仕様をよく知らないが， もし SELECT 以外のことができるなら，うっかりミスでも事故る可能性があるかもしれないので，考えもの
開発者が自分による不具合やデグレードにコンサルに謝罪するべきか？

開発者が開発した新機能や不具合修正により新たなデグレードを起こした。
そのデグレードで現場に立っているコンサルや実際のお客様に迷惑をかけ、多大な工数をかかってしまいました。

こんなことを私が体験しました。


結果、自分が頭を下げて謝罪しました。

しかし、これで本当にいいのかをまた疑問を持ち始めました。

もちろん、
自分の修正によるデグレードは承知しているけど、
自分が悪いことをしたくてデグレードを起こすようなコードをわざと書いたわけではありません。

自分が書いたコードを自分でテストし、
またチームメンバーもテストし、
QAチームも動作確認し、
上長もわざわざMTGを開催し、この修正を出していいと判定しました。

なぜ私だけを責めるのか？
**あ、デグレード発生後に、自分が「申し訳ない」という感情を表してないからです。**

しかし、デグレード発生後、積極的に取り込んで原因究明や修正方針を決めるのも私でした。
つまり、問題解決以外に、
コンサルやお客様に「申し訳ない」という気持ちを示す必要があります。

もしこれがビジネスマナーであれば、確かに守る必要があります。

積極的に問題解決する姿が「申し訳ない」を示す最高の証ではないでしょうか？
単に「申し訳ない」を口にするだけでは何の役にもないと思うだけです。

私は少し迷いました。

開発者の皆様はどういうご意見があるでしょう？

自分が読んだ記事。
（なかなか関連記事がないようです。稀事かもです

- https://blog.danslimmon.com/2019/08/02/stop-apologizing-for-bugs/
- https://workplace.stackexchange.com/questions/174503/should-i-send-out-an-apology-email-or-im-after-introducing-a-production-bug
備忘録~XSS対策~

##XSS(クロスサイトスクリプティング）攻撃のセキュリティリスク

###これは超々基本的なセキュリティ対策。

ユーザーが入力フォーム(SNSの投稿欄など)にコードを記入することで、そのコードが実行されてしまい、Cookieが攻撃者に取得され、不正ログインなどにつながる！

###対策

特殊文字（<,>など）をエスケープする。
エスケープとは、文字参照に置き換えるという意味。
例えば、"<"と単純な文字として認識させる。

###方法
#####htmlspecialchars($string, $flags, $encoding)を用いる！

＄string:変換する文字列
＄flags:処理の仕方を指定するフラグ
例）ENT_QUOTESなら、シングルクォーテーションかダブルクォーテーションに囲まれている文字列を指定する。
＄encoding:文字を変換するときに使用するエンコーディング


```
htmlspecialchars('<script>...</script>',ENT_QUOTES,'UTF-8')
```
'＜script＞...＜/script＞'が文字列になる。

下のように関数化してしまえば楽。

```
function escape($string)
{return htmlspecialchars($string, ENT_QUOTES, 'UTF-8');}

echo escape($review);
```
####・おまけ
nl2br()について

```
nl2br(escape($review['summary']));　
```
フォーム入力で改行された部分のHTMLに自動的に</br>を差し込む。
テキストに入力された通りに改行したものを表示できる。

:::note warn
escape(nl2br($review['summary']));
escapeを先に書いてしまうと改行タグ</br>も文字列として表示してしまうので注意！
:::
Windows環境のPowerShellからaws-cli v2を使う時にいい感じに入力補完する

PowerShellからAWSのリソースを操作するために、`AWS Tools for PowerShell`モジュールが提供されていますが。

上記モジュールを利用せずに、`aws-cli v2`を利用することも多いかと思います。
本記事は、`PowerShell`コンソールから`aws-cli v2`を利用する際にいい感じに利用する方法の紹介となります。

## aws_completer.exeで入力補完をする

Windows環境に`aws-cli v2`をインストールすると、入力補完を提供する`aws_completer.exe`がインストールされます。

試しに、`aws_completer.exe`で`aws ec2 describe`の入力補完の提案を確認してみます。

```PowerShell:aws_completer.exe
#環境変数  COMP_LINE、COMP_POINT を入力してから　aws_completer.exe　を実行すると入力補完の一覧を取得できる
$Env:COMP_LINE = "aws ec2 describe"
$Env:COMP_POINT = 17
aws_completer.exe
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/e5a17b6a-3402-366e-2013-4bd791919f6c.png)

上記、画像ように入力補完の一覧が取得できます。
AWSドキュメントに記載もある通り、aws-cli v2ではPowerShellで入力補完を提供する`Register-ArgumentCompleter`コマンドレットと`aws_completer.exe`を組み合わせる事によりPowerShell上で入力補完を使うことができるようになります。

この設定方法については下記ドキュメントがありますので、こちらに記載されている通り。

PowerShellの起動プロファイルに設定を追加すると、PowerShellコンソール上でaws-cliの入力補完が使えるようになります。

[Windows でのコマンド補完の設定](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-completion.html#cli-command-completion-windows)



```PowerShell:起動プロファイルにaws-cli用の入力補完を追加
Register-ArgumentCompleter -Native -CommandName aws -ScriptBlock {
    param($commandName, $wordToComplete, $cursorPosition)
        $env:COMP_LINE=$wordToComplete
        $env:COMP_POINT=$cursorPosition
        aws_completer.exe | ForEach-Object {
            [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
        }
        Remove-Item Env:\COMP_LINE     
        Remove-Item Env:\COMP_POINT  
}
```

`aws s3`とまで入力して`CTRL-SPACE`を入力すると画像の用にコマンド入力の補完を確認できるかと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/e336d6d9-5b65-0c0e-f7aa-f061c74e7b11.png)

## cli-auto-promptパラメータを利用して入力補完を利用する

aws-cli v2には`cli-auto-prompt`というパラメータが用意されており、このパラメータを付けて`aws`コマンドを実行すると自動プロンプトモードが有効になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/3f4d9d3c-f332-8223-bb87-dc2881e11646.png)

こちらを利用することによっても、自動プロンプトモードで入力補完を利用することができます。

F3キーを入力するとドキュメント表示のパネルも付いていたりかなりリッチな入力補完となります。

毎回、`cli-auto-prompt`パラメータを入力するのが大変なので。
aws-cli用の設定ファイルである、`~/.aws/config`に下記の登録をしておけば、不完全なawsコマンドを実行時に自動プロンプトモードが起動する用になります。

[](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-files.html#cli-configure-files-settings)

```text:~/.aws/config
# on-partialで不完全なawsコマンド実行時に自動プロンプトモードが起動する
[default]
cli_auto_prompt = on-partial
```

`config`ファイルを設定し、`aws s3`まで入力して`ENTER`を実行すると自動プロンプトモードになる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/18b919d4-4c96-6d33-a588-50d74abaacde.png)

## 総評

`aws_completer.exe`を利用していて不便は感じていませんでしたが。
ある時、`cli_auto_prompt`の自動プロンプトの存在に気が付き、さわってみたら想像以上にリッチなプロンプトだったため割と驚きました。

この2つを併用することにより、`Windows` + `PowerShell` な環境での `aws-cli v2` 利用がだいぶ快適になるような気はします。
「ゼロからのOS自作入門」day02 Hello Worldまで

# 概要
前回、環境構築を終わらせた。今回は、実際にOSを動かして、Hello Worldを表示させるまでをやる。

# 環境の変更点
作業中、X11のライブラリとX11のextensionがなければビルドができないという問題が発生した。よって、下記をDockerfileに付け加えた。

```Dockerfile
RUN sudo apt update
RUN sudo apt install libx11-dev
RUN sudo apt install libxext-dev
```
自分の[github](https://github.com/O-Jun-S/my-mikanos)から持ってきてもらっても構わない。

# ソースコードを持ってくる
まず、[mikanosリポジトリ](https://github.com/uchan-nos/mikanos)をフォークする。そして、それをローカルに持ってくる。

```
git clone https://github.com/(自分のユーザー名)/mikanos
```

以下のコマンドで、二日目のタグに移動する。

```
git checkout osbook_day02a
```

本のタイトルは「ゼロからのOS自作入門」であるため、自分が実装する用のブランチを作る。

```
git checkout -b my-changes
```

ブランチの切り方は[この記事](https://qiita.com/bolte/items/ab5d0ddcbb9cb907ad40)を参考にした。

以上の操作を終えた後、my-changesブランチはosbook_day02aの状態のはずである。一応自作OSなので、申し訳程度にMikanOSから好きな名前にしてもモチベーションに繋がるだろう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/608348/4b301381-1077-30f2-e846-3435e92469f8.png)

# ビルド
さて、いよいよOSのビルドをしていく。ここからはターミナルをスプリットした方がやりやすいだろう。
edk2を用いてOSをビルドする準備をする。

まず、edk2があるディレクトリに移動し、シンボリックリンクを作る。

```
cd ~/edk2
ln -s /path/to/MikanLoaderPkg ./
[*] MikanLoaderPkgのところは、各自のLoaderの名前でよい。デフォルトはMikanLoaderPkgである。
[*] 私の場合、Loaderへのパスは/workspaces/my-mikanos/mikanos/OjunLoaderPkgであるが、これも人によって異なる。
```

そして、edk2でビルドする準備をするため、以下のコマンドを実行する。

```
source edksetup.sh
```

以下のコマンドにより、Conf/target.txtが作成される。
target.txtの内容を、本書に従って設定する。
その後、以下のコマンドによってビルドができる。

```
build
[*] これが使えるのはsource edksetup.shをしたからである。
```

ビルドが成功したら、本書を参考にしてOSを起動してみよう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/608348/8ddd3faf-858e-f0f2-39f6-317748916c33.png)
railsチュートリアル第１０章 サンプルのユーザー ページネーション

###サンプルのユーザー
ユーザーを一気に作成

fakerは実際にいそうなユーザー名を作成するgemです

####GemfileにFaker gemを追加する
Gemfile

```
source 'https://rubygems.org'

gem 'rails',                   '6.0.3'
gem 'bcrypt',                  '3.1.13'
gem 'faker',                   '2.1.2'
gem 'will_paginate',           '3.1.8'
gem 'bootstrap-will_paginate', '1.0.0'
.
.
.
```
サンプルユーザーを生成するRubyスクリプトを追加
####データベース上にサンプルユーザーを生成するRailsタスク
db/seeds.rb

```rb
# メインのサンプルユーザーを1人作成する
User.create!(name:  "Example User",
             email: "example@railstutorial.org",
             password:              "foobar",
             password_confirmation: "foobar")
# create!は基本的にcreateメソッドと同じものですが、
#   ユーザーが無効な場合にfalseを返すのではなく例外を発生させる

# 追加のユーザーをまとめて生成する
# メイン以外のユーザー99人を作成
99.times do |n|
  name  = Faker::Name.name
  email = "example-#{n+1}@railstutorial.org"
  # 数ごとにメアドが変更される
  password = "password"
  # パスワードは変わらない
  User.create!(name:  name,
               email: email,
               password:              password,
               password_confirmation: password)
  
end
```

#####データベースをリセット
```
$ rails db:migrate:reset
$ rails db:seed
```

####演習
1.
試しに他人の編集ページにアクセスしてみて、10.2.2で実装したようにリダイレクトされるかどうかを確かめてみましょう。

確認

###ページネーション
####Gemfileにwill_paginateを追加する
Gemfile

```
source 'https://rubygems.org'

gem 'rails',                   '6.0.3'
gem 'bcrypt',                  '3.1.13'
gem 'faker',                   '2.1.2'
gem 'will_paginate',           '3.1.8'
gem 'bootstrap-will_paginate', '1.0.0'
.
.
.
```
####indexページでpaginationを使う
app/views/users/index.html.erb

```rb
<% provide(:title, 'All users') %>
<h1>All users</h1>

<%= will_paginate %>

<ul class="users">
  <% @users.each do |user| %>
    <li>
      <%= gravatar_for user, size: 50 %>
      <%= link_to user.name, user %>
    </li>
  <% end %>
</ul>

<%= will_paginate %>
```
これではページネートされない。

#####ページネートの実験
```rb
$ rails console
>> User.paginate(page: 1)
  User Load (1.5ms)  SELECT "users".* FROM "users" LIMIT 11 OFFSET 0
   (1.7ms)  SELECT COUNT(*) FROM "users"
=> #<ActiveRecord::Relation [#<User id: 1,...
>> User.paginate(page: 1).length
  User Load (3.0ms)  SELECT "users".* FROM "users" LIMIT ? OFFSET ?  [["LIMIT", 30],
  ["OFFSET", 0]]
=> 30
```
コンソールの様にしたい。

####indexアクションでUsersをページネートする
app/controllers/users_controller.rb

```rb
class UsersController < ApplicationController
  before_action :logged_in_user, only: [:index, :edit, :update]
  before_action :correct_user,   only: [:edit, :update]
  # before_actionメソッドを使って何らかの処理が実行される直前に
  # 特定のメソッドを実行する仕組み
  # ログインをさせる
  # :editと:updateアクションだけ
  
  def index
    @users = User.paginate(page: params[:page])
    # allをpaginateメソッドに置き換えます
    # :pageパラメーターにはparams[:page]が使われていますが
    #   、これはwill_paginateによって自動的に生成されます
  end
.
.
.
end
```

###演習
1.
Railsコンソールを開き、pageオプションにnilをセットして実行すると、１ページ目のユーザーが取得できることを確認してみましょう。

確認
2.
先ほどの演習課題で取得したpaginationオブジェクトは、何クラスでしょうか? また、User.allのクラスとどこが違うでしょうか? 比較してみてください。

```
>> User.paginate(page: 1).class
=> User::ActiveRecord_Relation
>> User.all.class
=> User::ActiveRecord_Relation
```
同じ
Arduino Unoでバイナリ出力する

#概要

テスト用にArduino Unoからバイナリデータを出力させる必要があったので実装した。
1000回ごとにダミーデータとして`0xFF 0xFF`を出力するようにしている。
出力データは1000回のカウンタをそのまま使っている。

#環境

- Arduino Uno
- Platform IO

#ソースコード

```c++
#include <Arduino.h>

void setup() {
  Serial.begin(9600);

  Serial.println( "Hello, world!");
}

void loop() {
  int cnt=0;

  typedef union {
    int val;
    byte binary[2];
  } u;
  
  u u1;

  while(cnt<1000){
    u1.val = cnt;
    Serial.write(u1.binary, 2);
    cnt++;
  }
  u1.val = 65535;
  Serial.write(u1.binary, 2);
}
```

#参考
[Arduino の Serial.write とうまく付き合う方法 (BLESerial2 編)](https://hawksnowlog.blogspot.com/2016/11/sending-multibytes-with-serialwrite.html)
共用体unionで書くのはスマートでわかりやすかった。
[Tera termで16進数表示](https://shuzo-kino.hateblo.jp/entry/20111027/1319682490)
デバッグはTeraTermのデバッグモードを利用。
Watson OpenScaleの全体像

# はじめに
MLOps（機械学習/AIモデルを継続的に運用していく仕組み） を実現するサービスの一つとして、IBM Cloud 上でWatson OpenScaleというサービスがあります。
Watson OpenScale は、モデルやデータのモニタリング機能を提供しています。
Watson Studio でモデルを作成し、Watson Machine Learning にデプロイしたモデルを Watson OpenScale でモニタリングすることができます。
Watson OpenScale の一つ一つの機能や使い方などは様々な資料で説明されていますが、全体がつかみにくいので、この記事ではWatson OpenScaleの全体像について解説していきたいと思います。
![WOの位置づけ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305774/e915855b-dab0-d8e3-c634-2255df4c9567.png)

----
# Watson OpenScaleとは
全体像の解説に入る前に、Watson OpenScaleの主要な機能について振り返りたいと思います。
主要な機能は、以下の4つです。

- **正確性（Accuracy）**
    - 本番ランタイムでの性能劣化の検知します。
- **公平性（Fairness）**
    - 本番ランタイムでの公平さの問題（バイアス）の検知します。
- **ドリフト（Drift）**
    - 学習時とデータやモデルの傾向に違いがないかチェックします。
        - モデル・ドリフト：実行時のモデルの正確度の低下を推定します。
        - データ・ドリフト：訓練時のデータの特性と比較した、実行時のデータの整合性の低下を推定します。
- **説明性（Explainability）**
    - AIの予測・判定結果の根拠・道筋の提示します。
    - トランザクション単位の入力項目別寄与度を調べることが可能です。


Watson OpenScaleについての説明は、[こちらの記事](https://qiita.com/ishida330/items/ced6e5233ca61ae0af9d)がわかりやすくまとまっていますので、ご参照ください。

----
# Watson OpenScale の全体像
各コンポーネントとの関連を1枚の絵で表現すると以下のようになります。
![WO全体像.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305774/c3b79f27-bd3d-7cfc-c356-662d342af46d.png)



----
# Watson OpenScale の重要なデータ
Watson OpenScale はモニタリングで使用するデータを格納するためのDBを保持していて、このDBを「データマート」と呼びます。
このデータマートに保持されるデータのうち、重要なデータが2つあります。ペイロード・データとフィードバック・データです。

- **ペイロード・データ**（Payload Data）
    - 入力データと推論結果をセットとするデータ。(未来の予測データ)
    - 公正性、ドリフト、説明性のモニタリングに使用します。
    - ペイロード・データをデータマートに取り込む機能のことを**ペイロード・ロギング（Payload Logging）**と言います。
- **フィードバック・データ**（Feedback Data）
    - 正解ラベル付きのデータ。(過去の実績データ)
    - 正確性のモニタリングに使用します。
    - フィードバック・データをデータマートに取り込む機能のことを**フィードバック・ロギング（Feedback Logging）**と言います。

もう一つ重要なデータとして、トレーニング・データがあります。

- **モデル学習時のトレーニング・データ**（Training Data）
    - 「モデルを作った時のトレーニング・データ」もモニター定義の際に必要です。保管先は、ICOS または Db2 のみサポートしています。
    - トレーニング・データはモニター定義の際に設定し、データマートには統計情報とメタデータが保管されます。
    - 主にデータ・ドリフトのモニタリングに使用します。

----
# モニタリングの流れ
Watson OpenScale 利用の流れとしては、以下の通りです。
#### 事前準備

1. Watson Studio でモデルを作成して、プロモートします。
2. Watson Machine Learning でモデルをデプロイして公開します。
3. Watson OpenScale で上記でデプロイしたモデルをモニタリングするように構成します。

#### 本番自動運用
1. アプリケーションからデプロイされたモデルに対して API Callして「推論」を行います。
2. Watson Machine Learning からアプリケーションにモデルの予測結果を返します。
3. 同時に、Watson OpenScale のデータマートにペイロード・データを自動的に取り込みます。

#### 本番随時運用
1. Watson OpenScale にフィードバック・データを取り込みます。

----
# 参考リンク
MLOpsでのモデルやデータのモニタリング要件を考える
https://qiita.com/ttsuzuku/items/7d871598b20e6dad4a9f
Watson OpenScaleを触る前に知っておきたかったこと（技術Tipsなど)
https://qiita.com/ishida330/items/2c9b049966a988850b06