OmniAICreator/Qiita-1.07M huggingface dataset:
Rails6で画像のプレビュー機能を実装する方法

#はじめに

今回ご紹介するRails6で画像のプレビュー機能の実装は、私自身がオリジナルアプリを開発する際に、情報がほとんどなく(Rails5の情報はありましたが。）かなり苦労して実装したものになります。
なので、今後実装される方、もしくは今実装できずに苦労されている方の参考になれば幸いです。

#バージョン
**Rails６**
(rails5の場合は他の記事をご参考ください。）

#前提条件
Carrierwaveを使い、画像のアップロード機能は実装できているものとする。
実装できていない場合は私が以前に書いた記事 
[RailsでCarrierWaveとRMagickを使い、円形のプロフィール画像を実装する方法](https://qiita.com/jiiitaaa2/items/e48b4fe2a47494e8bb27) 
をご覧下さい。

#手順１・viewファイルの実装
今回は新規投稿ページを想定し、`views/posts/new.html.erb`にコードを書いていきます。

```erb:new.html.erb
<%= javascript_pack_tag 'posts' %>

　#中略

<div class="form-group">
  <%= f.label :image, class: "label" %>
  <%= f.file_field :image, accept: 'image/jpeg, image/gif, image/png', id: "image-select-btn" %>
</div>
<div class="post-image-prev">
  <% if @post.image? %>
    <%= image_tag @post.image.thumb.url, alt: "post-image", id: "img_prev", size: "150" %>
  <% else %>
    <%= image_tag "post-default.png", alt: "post-image", id: :img_prev, size: "150" %>
  <% end %>
</div>
```
一行目の`<%= javascript_pack_tag 'posts' %>`で次に書くjsファイルを読み込みます。

`post-default.png`はこのような画像です。
![post-default.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614783/63bda5c7-332f-cd7e-075a-365267fe1cf6.png)


`assets/images`の中に入れておいてください。


`image`タグのsizeの部分はご自身のデザインに応じてご変更下さい。

#手順２・jsファイルの実装
`javascript/packs/posts.js`にコードを書いていきます。

```posts.js

$(function () {
  function readURL(input) {
    if (input.files && input.files[0]) {
      var reader = new FileReader();
      reader.onload = function (e) {
        $("#img_prev").attr('src', e.target.result);
      }
      reader.readAsDataURL(input.files[0]);
    }
  }
  $("#image-select-btn").change(function () {
    readURL(this);
  });
});

```

以上です。

これで画像をアップロードをした際にプレビュー画像がデフォルトから切り替わります。

アップロードしたファイルを投稿前に確認できるので、とても便利な機能です。
Golangの'nil slice'と'non-nil slice'で地味に詰まった話



Golangでテストコードを書いていた際に、地味に詰まったことがあったので共有。

## サンプルコード
intのスライスを引数として受け取り、その中から正の整数だけを返す関数をサンプルとして用意しました。

```go:example.go
package example

// Example は、テスト用に作成した正の整数だけを返す関数
func Example(nums []int) (ret []int) {
	for _, num := range nums {
		if num > 0 {
			ret = append(ret, num)
		}
	}
	return
}
```

この関数に対して、下記の様なテストコードを書きます。
（本当はもっとテストケースを用意するべきだと思います。）

```go:example_test.go
package example

import (
	"testing"

	"github.com/stretchr/testify/assert"
)

func TestExample(t *testing.T) {

	tests := []struct {
		input    []int
		expected []int
	}{
		{
			input:    []int{1, -2, 3},
			expected: []int{1, 3},
		},
                {
			input:    []int{-1, -2, -3},
			expected: []int{},
		},
	}

	for _, test := range tests {
		result := Example(test.input)
		assert.Equal(t, result, test.expected)
	}
}

```

そして、このテストを実行してみると、下記のログが表示されテストは失敗します。


```
$ go test --run TestExample

--- FAIL: TestExample (0.00s)
    example_test.go:27: 
                Error Trace:    example_test.go:27
                Error:          Not equal: 
                                expected: []int(nil)
                                actual  : []int{}
                            
                                Diff:
                                --- Expected
                                +++ Actual
                                @@ -1,2 +1,3 @@
                                -([]int) <nil>
                                +([]int) {
                                +}
                                 
                Test:           TestExample
FAIL
exit status 1
```
どうやら、
期待している値(expected)が、`([]int) <nil>`になっているのに対して、
実際に返される値(result)は、`([]int) {}`となっているため、テストが失敗しているようです。


## nil sliceとnon-nil slice
このテスト失敗の理由を説明するためには、lengthとcapacityが共に0のスライスとして、
`nil slice`と`non-nil slice`というものが存在することを説明する必要があります。

この2つのスライスは、見た目上ほとんど同じ挙動なのですが、
その名の通りnilかnilでないかという違いがあります。

```go
package main

import "fmt"

func main() {
    // nil sliceになる
    var nSlice []int

    // non-nil sliceになる
    eSlice  := []int{}
    eSlice2 := make([]int, 0)

    fmt.Println(len(nSlice),  cap(nSlice),  nSlice  == nil)
    fmt.Println(len(eSlice),  cap(eSlice),  eSlice  == nil)
    fmt.Println(len(eSlice2), cap(eSlice2), eSlice2 == nil)
}
```

```:出力
0 0 true
0 0 false
0 0 false
```

## テストの失敗の原因

Goの名前付き戻り値にsliceを指定して、何も値を代入しないままreturnした場合、nil sliceを返します。

```go:サンプルコード
package main

import (
	"fmt"
)

func main() {
  slice := example()
  fmt.Println(len(slice),  cap(slice),  slice == nil)
}

func example () (slice []int) {
  return
}
```

最初にお見せしたテストでは、example関数は`nil slice`を返すにもかかわらず、
`non-nil slice`と比較するようなテストになってしまっていたため、テストが失敗してしまったのです。

シンプルなミスであるにもかかわらず、
nil sliceとnon-nil sliceのことを自分があまり意識していなかったために、
原因に気づくまでに少し時間がかかってしまいました。反省です。


## まとめ
- lengthとcapacityが共に0であるsliceには、nilとnon-nilの２種類がある。
- 名前付き戻り値で、sliceをそのままreturnすると、nil sliceになる。
GitLabのWikiのpage-slugとは

# page-slugとは
- 他のWikiページへのリンクを`[hoge](page-slug)`というフォーマットで簡単に貼り付け可能にする機能

# page-slugの場所
- URLの"Wikis"以降のパスがpage-slug
    - URLが`wikis/aaa`の場合：page-slugは`aaa`
    - URLが`wikis/aaa/bbb`の場合：page-slugは`aaa/bbb`
Android 11にアップデートしたらIPv6が繋がらない？

#Android 11にアップデートしたらIPv6のRDNSSが効かなくなりWi-Fiが接続できなくなった！
いよいよ Android OS Version 11のリリースが開始されましたが、 Android 11はベータ版の頃からずっと何故かIPv6の調子が悪く、自宅のルーター(Linuxを使った自家製)からRA(Router Advertisement)でIPv6アドレスが広報されているとWi-Fi APへの接続が上手くいかず接続が確立したかと思うとすぐに切断されてしまうの繰り返しになってしまいました。
いろいろと調べた結果、どうやらRAのオプションRADNSSのライフタイムが119より長いとこのような現象に陥るらしく、RAのデーモンradvdの設定ファイルradvd.confを修正してRDNSSのライフタイムを120より短くしてやることで解決できました。

Android 10までは大丈夫だった設定

```conf:/etc/radvd.conf
interface enp1s0
{
        AdvSendAdvert on;
        MinRtrAdvInterval 30;
        MaxRtrAdvInterval 100;
        AdvDefaultLifetime 120;
                AdvManagedFlag off;
                AdvOtherConfigFlag off;
        prefix xxxx:xxxx:xxxx:xxxx::/64
        {
                AdvOnLink on;
                AdvAutonomous on;
                AdvRouterAddr off;
        };
        RDNSS xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx
        {
                AdvRDNSSPreference 8;
                AdvRDNSSOpen off;
                AdvRDNSSLifetime 120;
        };
};
```

Android 11では`AdvRDNSSLifetime`を短くする必要があった！

```conf:/etc/radvd.conf
interface enp1s0
{
        AdvSendAdvert on;
        MinRtrAdvInterval 30;
        MaxRtrAdvInterval 100;
        AdvDefaultLifetime 120;
                AdvManagedFlag off;
                AdvOtherConfigFlag off;
        prefix xxxx:xxxx:xxxx:xxxx::/64
        {
                AdvOnLink on;
                AdvAutonomous on;
                AdvRouterAddr off;
        };
        RDNSS xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx
        {
                AdvRDNSSPreference 8;
                AdvRDNSSOpen off;
                AdvRDNSSLifetime 119;
        };
};
```

まだなぜそうなのか？までは調べてはいないのですが、とりあえず共有しておきます。
radvd.confのマニュアルではAdvRDNSSLifetimeはMaxRtrAdvIntervalの2倍より短くとしか書かれていないけど…
※我が家のLinuxサーバーのradvdではこれで解決しましたがCISCOのルーターではRDNSSのライフタイムを短くしても解決しなかったとのことなので、環境依存の可能性大かも。
最初にこの問題にぶつかったときには設定からRDNSSのセクションをすっぽりと取り去ってRDNSSの広告を行わないようにすれば大丈夫らしい？となったのですが、AndroidはDHCPv6でのアドレスやDNSの設定はサポートするつもりがないらしくRDNSSを使わないとDNSは手動で設定するほかなくなっちゃうし…
【React Native】TextInputでAndoirdのみ縦方向の中央寄せができない

# 前提
- React Native 0.62.2

# 問題
- TextInputコンポーネントでカスタムフォントを適用した際、Androidのみ入力したテキストの下方に謎のpaddingが出現する

↓左がiOS、右がAndroid
※わかりやすくするため、TextInputの背景をグレーにしている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224815/ba90d089-5777-a3d2-0fab-4f1410179294.png)


# 解決方法
- TextInputのstyleに `includeFontPadding: false` を追加する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224815/7397548a-f876-2add-4d3f-beef34835090.png)

- ちなみに、色々調べると、多かったのは以下のパターンのいずれかの組み合わせだが、いずれもうまくいかなかった。

```js
style = {
  padding:0,
  paddingVertical: 0,
  margin: 0,
  textAlignVertical: 'center',
}
```

# 参考文献
- https://codeburst.io/react-native-quirks-2fb1ae0bbf80
Jupyterで簡単な画像認識を出来るようにするまで

#初めに
ふとある画像判別のアプリが作りたくなったのでまずはWindow環境でjupyterをつかって
簡単に画像を判別するプログラムを動かすところまでを作ってみた。

開発環境
OS: Windows10 Home
GPU: Geforce GTX1660Ti
Anaconda: 4.8.2

#各種インストール
まずは以下のサイトからAnacondaをダウンロードしインストール
https://www.anaconda.com/products/individual

続いて画像認識に必要なライブラリであるTensorFlowを導入する。

そのまえに一応いま使用しているPCにGPUが入っているためせっかくなのでGPUを使って計算させたい。しかしNvidiaドライバとCUDAとcuDNNというものをインストールする必要があるらしく、しかもこれらのツールは最新ならよいというわけではなくバージョンに気を付けないとGPUが認識しないらしい...

ということで、まずはNvidiaドライバを以下のサイトから自分のGPUを検索してダウンロード・インストール
https://www.nvidia.co.jp/Download/index.aspx?lang=jp
ダウンロードタイプはよくわからないけどGame Readyドライバーのほうを選択。
自分がインストールした際はバージョン445.87だった。

先ほど書いたように各バージョンの対応に注意しながらインストールする必要があるのでこちらのサイトの対応表を見て
Nvidiaドライバのバージョン⇒対応するCUDAのインストール⇒さらに対応するcuDNNのダウンロードを行う
対応表が載ってるページ
https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html
https://www.tensorflow.org/install/source_windows
ダウンロードページ
CUDA: https://developer.nvidia.com/cuda-downloads
cuDNN: https://developer.nvidia.com/cudnn-download-survey
私の場合はCUDAのバージョンが10.0.130、cuDNNが7.4.2 for CUDA10.0となった。

インストール後下記をそれぞれ行う。
・ダウンロードしたcudnnのフォルダ内のデータをすべて
　C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.0内へコピー

・システム環境変数に
　変数名: CUDNN_PATH
　値: "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.0"
　を新規で追加

これでGPU側で必要なインストールが終わったので最後にTensorFlowのライブラリのインストールを行う。
まずはAnaconda上でTensorFlow用の環境を別で作る。

```
conda create -n tf37 python=3.7 anaconda
conda activate tf37
```

その環境の中で
tensorflowをインストール

```
conda install tensorflow-gpu==2.0.0
```

最後にpython上でコマンドを動かしてちゃんとGPUが認識されていることを確認。

```python
from tensorflow.python.client import device_lib
print(device_lib.list_local_devices())
```

![キャプチャ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259220/7bec478d-fcd3-19cc-ce36-f9a5d9c7d9d6.png)

これで各種インストールが終わりTensorFlowを使用できるようになった。

##以下少しつまずいたところ


最初他の記事を頼りにpipでインストールを行っていたがいざtensorflowを使うときに以下のようなエラーが出てしまった。
![キャプチャ3_2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259220/59c03cf1-3a5e-66db-4432-9035801b4433.png)
おそらくjupyterなどで使う際はcondaでインストールしないとだめっぽい。
Pythonの a += b と a = a + b は違う

いくつかのサイトで演算子 `a += b` が `a = a + b` と同じと書いてありますがミュータブルなオブジェクトでは厳密には異なります。
同じオブジェクトを指す変数がある場合は注意が必要です。（NumPy を使ってる人は特に！）


# 概要

一言でまとめると以下の違いがあります。
ミュータブルなオブジェクトでは、

- `a += b` では代入の前後で　`a` が指すオブジェクトは変化しない。
- `a = a + b` では代入の前後で `a` が指すオブジェクトは変化する。

ただし、イミュータブルなオブジェクトではどちらの場合も変化します（@shiracamusさんのコメントに例があります）。

# 実験
`[1, 2]` に `[3]` を追加して `[1, 2, 3]` を作成する実験をしてみます。
`y` は代入前の `x` のオブジェクトを指します。
組み込み関数 `id(x)` でオブジェクトのIDを取得できます。

## `a += b`

```python
>>> x = y = [1, 2]  # y は代入前の x と同じオブジェクト
>>>
>>> id(x)
4397797440
>>> id(y)
4397797440
>>>
>>> x += [3]
>>> 
>>> ｘ
[1, 2, 3]
>>> y  # y にも追加されている
[1, 2, 3]
>>>
>>> id(x)  # 代入前と同じオブジェクト
4397797440
>>> id(y)
4397797440
```

## `a = a + b`

```python
>>> x = y = [1, 2]  # y は代入前の x と同じオブジェクト
>>>
>>> id(x)
4397797440
>>> id(y)
4397797440
>>>
>>> x = x + [3]
>>> 
>>> ｘ
[1, 2, 3]
>>> y  # y には追加されていない
[1, 2]
>>>
>>> id(x)  # 代入前と異なるオブジェクトを指している
4395937472
>>> id(y)
4397797440
```
Vuetifyのv-data-tableで奇数行の背景色を変える

#やりたいこと
Vuetifyに用意されているテーブルコンポーネント[v-data-table]がデフォルトのままだといまいち見づらかったので、
よくある奇数行だけ色が変わっている一覧にしたい

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658979/dbba62fd-982a-7d21-ff5c-5818c6c16fe0.png)

#おなじみのCSSを設定してみる

普通にCSSで奇数行の色変わるように指定

```App.vue
<style scoped>
.v-data-table td {
	background: #f0f8ff;
}
.v-data-table tr:nth-child(odd) td {
	background: #fff;
}
</style>
```

変わらない。。。
あぁ、scopedがついてるから子コンポーネントには反映されんのか。。。

```App.vue
<style>
.v-data-table td {
	background: #f0f8ff;
}
.v-data-table tr:nth-child(odd) td {
	background: #fff;
}
</style>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658979/ee6402f3-98f2-8330-c048-14936151a9ac.png)
変わった！
・・・けど、マウスオーバーしてる行の背景色が変わらなくなった。。。

tableのstyle上書きしてしまったから？
しょうがないから自分で設定してやる。

```App.vue
<style>
.v-data-table td {
	background: #f0f8ff;
}
.v-data-table tr:nth-child(odd) td {
	background: #fff;
}
.v-data-table tr:hover td {
	background-color: #eee;
}
</style>
```
###完成！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658979/ca12f6c9-2ea8-3cf5-8080-06db556482d3.png)
【JavaScript】関数における、引数値を定数で定義することの利点

同じ変数を用いる複数の関数を実行したい場合、引数値を定数で定義すべき、という内容。

例）

```js
//関数１
function intro(name, food) {
  console.log(`私の名前は${name}です。好物は${food}です。`);
}

//関数2
function lunch(food) {
  console.log(`今日の昼ごはんは${food}を食べます。`);
}
```
どちらの関数も、仮引数`food`を使っている。

これらに対して、引数で定義し出力をする場合は、

```js
intro("田中","カレー"); //仮引数(name,food)に引数を与え、関数の実行。
lunch("カレー"); //上記と同様。
```

となる。
一方で、引数で定義するのではなく、定数で定義し出力する場合は、

```js
const name = "田中"; //定数nameに文字列"田中"を代入。
const food = "カレー"; //上記と同様。
intro(name,food); //仮引数(name,food)に定数(name,food)を与え、関数の実行。
lunch(food); //上記と同様。
```

となる。

一見、前者の方が記述が簡素で可読性に優れると思うが、メンテナンスの観点でいえば、後者の方が利便性に優れる。
仮に、`food = "ラーメン";`に修正したい場合、前者は修正箇所が２つ、後者は定数定義１つで済む。

同じ変数を用いる関数が増えれば増えるほど、後者の方がコード管理しやすいと考える。
[アプリ開発]DKImageViewControllerで写真共有アプリ作ってみた

![5568440d5934344ad6f605910ee9f3e1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679429/bb260802-cf93-1d92-fa30-5e030f525cf2.gif)
![464b0ad207bdce4da56f3c8461957761.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679429/afed0470-5448-a561-735c-e59b7cd8ab14.gif)

#作った経緯
初めて作ったファッションアプリが途中でできなかったので、なんかCollectionView使ってやりたいなーって思いましてインスタみたいな写真共有アプリ作ろうと決心して開発しました！
参考にしたアプリは`tabiori`さんです
>https://tabiori.com/

とりあえず作ってみた！
![スクリーンショット 2020-08-23 14.58.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679429/0417cc29-64cd-193d-c838-5d5c2f49af98.png)
こんな感じでやろうと思ったら、、、ア〜〜〜〜〜〜！！！！
![スクリーンショット 2020-09-09 20.34.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679429/59657b4a-c786-fa29-1d0b-241daaa2881e.png)
ViewControlller多くなりすぎて訳わからんくなった。。
初心者の僕はパンクしました
っていう感じで何回もプロジェクト作り直しました。

インスタの写真一枚だけならスクールの教材で出来るんですが、何せConllectionView使いたかったんでタイムラインの画像を複数表示出来るようにさせたかったんですよね
#問題
このアプリ開発するのめっちゃ時間かかりましたこれにスクールの大半の時間消費しましたねw
まずFirebaseですね
ライブラリの画像を選択→CollectionViewで表示→ボタン選択→Firebaseに保存したかったんですがうまくいかず諦めて、
日付とタイトル、画像を別の画面でやろうとするとすごくめんどくさくなったり、、、
いろいろうまくいきませんでした。
でライブラリから写真を複数選択しようとすると標準？のライブラリだとできないし

>DKImagePickerControllerの極意
http://cocoadocs.org/docsets/DKImagePickerController/3.8.1/

ライブラリから選択した画像を画面遷移先にデータを送るとかファイル形式違うものに渡しかたとか、、
どうやってやんの〜〜〜って感じです:joy_cat:

>CollectionViewとTableViewの組み合わせ極意
https://qiita.com/Erica_pon/items/f1c6a06e399723f32549

こちらを参考にタイムライン画面でcolleCtionViewとTableView使ってモデル作ってみたけど画像表示できず開発休止しました、、、

#結果
リリースはできてません！！
![picture_pc_fb4f1c662c0d1ac2606e5093ff74ddec.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679429/47c72894-ecf5-c70c-0e8b-e81cbf27cf18.png)
まだ未完成です
諦めませんねー
よかったらみてください！
>今回作ったリポジトリ
https://github.com/rentamaeda/Travel2

#感想
なんでもそうですが作る前の計画練るのって楽しいですよねー
なんか途中から気持ち折れてしまって何回も諦めかけましたよ

次もしollectioView使うならタスク管理アプリ作りたいなーって思いますw
#参考にしたサイト等
>taiori様HP
https://tabiori.com/

>DKImagePickerControllerの極意
http://cocoadocs.org/docsets/DKImagePickerController/3.8.1/


>CollectionViewとTableViewの組み合わせ極意
https://qiita.com/Erica_pon/items/f1c6a06e399723f32549
【VBA】リストボックスへ値を追加する＆選択した値をクリップボードにコピーする

##まずはリストボックスへ値を追加
コンボボックスのときとほぼ一緒ですね。[コンボボックスのリストに値を追加する](https://qiita.com/KaoTechBlog/items/eae37a0454983892ec64)
フォームに適当なリストボックスとボタンを作ります。
リストボックスの`MultiSelect`プロパティを
`2-fmMultiSelectExtended`（複数選択可）にしておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700414/f6e85b24-d0b3-5a67-a1dc-41ec9c6b829c.png)


今回はこのデータを追加しました。
（人の名前にしようかと思ってたんだけどなんかお腹すいててパンの名前になっちゃった…:yum:）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700414/b6ba469f-b496-646d-1f52-b08bdb5d2d37.png)

```VB
Private Sub UserForm_Initialize()
    lstName.Clear 'リストボックス内初期化
    Dim NameCol As Long
    NameCol = WorksheetFunction.Match("名前", Master.Rows(1), 0) '名前列数格納
    Dim LastRow As Long
    LastRow = Master.Cells(Rows.Count, NameCol).End(xlUp).Row '名前列最終行格納
    Dim i As Long
    For i = 2 To LastRow 'リストボックスに名前をすべて格納
        lstName.AddItem Master.Cells(i, NameCol)
    Next i
End Sub
```
##選択した値をクリップボードにコピーする
#####選択した値を変数に格納
リストボックスの値が選択されていたら変数に格納し、改行を入れます。
#####クリップボードにコピーする
以前、Win7(Office2010)を仕事で使っていたときに`New DataObject`を使った記憶があるのですが
今回やろうと思ったらうまく動作しませんでした:sweat:
調べると、`テキストボックス`を使った書き方が出てきて、
それを使ってみたら正常に動作しました。
「テキストボックスをフォームに作るってこと？？」って思ったんですが
__メモリ上に作成されたテキストボックスに文言を入れてそれをコピーする__ということらしいです！

```VB
Private Sub btnCopy_Click()
    '選択した項目をクリップボードにコピー
    Dim i As Long
    Dim ListDate As String 'リストボックスで選択した値を格納する変数
    
    For i = 0 To lstName.ListCount - 1 'リストボックスで選択した値を改行しながら変数に格納
        If (lstName.Selected(i)) Then
            ListDate = ListDate & lstName.List(i) & vbCrLf
        End If
    Next i
    
    'メモリ上のテキストボックスにListDateを格納する
    With CreateObject("Forms.TextBox.1")
      .MultiLine = True 'テキストボックスの複数行入力を許可
      .Text = ListDate '変数をテキストに格納
      .SelStart = 0 'テキストの0文字目以降
      .SelLength = .TextLength 'テキストすべてを
      .Copy 'クリップボードにコピーする
    End With
End Sub
```
【実行結果】
リストボックスに値が入って選択できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700414/7ad500d5-5cd0-8bc0-aad8-496c36631688.png)
コピーボタンを押すとクリップボードにコピーされ
セルやメモ帳などに貼り付けられました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700414/2aa7b5e6-4aa2-e58f-a424-c862e8c8917c.png)
##ワタシ流こだわり
リストボックスを複数選択可能にするとき、`MultiSelect`プロパティはいつも、
ctrlで複数選択できる`2-fmMultiSelectExtended`です。
`1-fmMultiSelectMulti`も複数選択可能ですが選択解除するとき選択したものをもう一度選択しなければなりませんので。
`1-fmMultiSelectMulti`を使うのってどんなときなんだろ？:rolling_eyes:
こういう時に使うといいよっていうのあったら教えて下さい:wink:

ちなみにワタシはパンよりお米が好きです:rice_ball:
Vue.jsでおみくじアプリを作ってみた

## はじめに
Vue.jsを学習中の初心者の私が理解を深めるためにおみくじアプリを作ったのでアウトプットの為に記事を書いておきます。
同じVue.js初心者の助けになれば嬉しいです。
## やろうと思うこと
おみくじは大吉、中吉...と○吉の文字を配列に入力しておきます。
ブラウザ上のボタンをクリックしたら配列数以下のランダムな数を取得し、それを使って同じ数の配列を取得してアラートを出します。
## コード
```omikuzi.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <title>Vue.js</title>
  </head>
  <body>
    <div id="app">
      <button @click="result">結果を見る</button>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="js/omikuzi.js"></script>
  </body>
</html>
```
```omikuzi.js
new Vue({
  el: '#app',
  data: {
    list: [
      '大吉',
      '中吉',
      '小吉',
      '末吉'
    ],
  },
  methods: {
    result: function() {
      const num = Math.floor(Math.random() * this.list.length)
      alert(this.list[num])
    }
  }
});
```

ではhtmlからコードの説明をしていきます。
まず```<div id="app">```はVue.jsの影響を及ぼす範囲のルートになります。
omikuzi.jsで```el: '#app'```と記載しているのでそれ以外の場所には影響を与えません。
[Vue.jsをシンプルに理解しよう その２](https://qiita.com/yusuke_ten/items/3c5ae79da459fb566fbd)
詳しくは上記記事をお読みください。

次に```<button @click="result">結果を見る</button>```ですが、
これはボタンをクリックした時にresultメソッドを呼び出すという意味になります。

最後に```<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>```と
```<script src="js/omikuzi.js"></script>```ですが、これはVue.js本体とresultメソッドを書いているomikuzi.jsを読み込むという意味になり、この読み込みが無い場合はVue.jsの機能である@clickやomikuzi.jsに書いてあるresultメソッドを呼び出せなくなるため正常に動作しません。

次にjavascriptファイルの説明をしていきます。
まず```new Vue```ですがこれはVueインスタンスを作成しています。
Vue.jsは```new Vue```で作成されたルートVueインスタンスの中にメソッドなどをツリー状にして保存しているので```new Vue```が無い限りVue.jsは動かないと思います。(Vue.js初心者の言うことだからもしかしたら違うかも？)
詳しくは[Vue.jsの公式ガイド](https://jp.vuejs.org/v2/guide/instance.html)をお読みください。

次に```data:```の中にある```list:```に配列で大吉などの○吉を入力しています。
これでlist[0]と書くことで大吉を呼び出すことができます。

次にメソッドの説明をしていきます。
```methods:```の中で```result: function()```と書くことでresultメソッドを作成しています。
resultメソッドに記載している```const num = Math.floor(Math.random() * this.list.length)```はnumという箱にランダムな数字を生成して入れるという意味です。
もっとわかりやすく書くと```Math.floor```は【小数点以下を切り捨てる】、```Math.random()```は【0以上1未満の数字をランダムで生成する】、```this.list.length```はlistの配列のデータの数を意味しています。

なので0以上1未満の数をランダムで生成してlistのデータの数だけ掛け算して、計算結果の小数点を切り捨ててnumに保存するという意味になります。

最後に```alert(this.list[num])```ですがalertは文字通りアラートを出します。
alertの()内にどのデータをアラートで表示するかを記載できるので```this.list[num]```でlistにある先ほど生成したランダムな数値を使って配列のデータを表示します。
## 最後に
一応私なりに頑張って書きましたが、かなり冗長になってしまいました。
ここが分かりづらいやこうするのがおすすめなどのご意見ありましたらコメントにお願いします。
A-Frame 開発者ツール開き方

#参照
https://aframe.io/docs/1.0.0/introduction/visual-inspector-and-dev-tools.html

#やり方
windows => ctrl + alt + i.
mac => ctrl + option + i.

#イメージ
<not 開発者ページ>
![スクリーンショット 2020-09-09 21.13.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631096/1fcb3f2a-9843-36d0-5148-9afbb06e3de4.png)
<開発者ページ>
![スクリーンショット 2020-09-09 21.13.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631096/769a4e15-8ecc-c422-527a-b1797a4ce834.png)
技術記事を書く時に意識していること

## 自分のために書く

「思考の整理 + 未来の自分のための資料作りが目的で、周りからの反応はおまけ」
というスタンスでいると雑な記事をバンバン書ける。自分は執筆時間が5分かかっていない記事の方が多いと思う。そして記事数に対してLGTM等は少ない。

## 自分の言葉で書く

普段自分が使う言い回しをした方が、後から振り返った時に理解しやすいです。カッコつけない方が良い。
文章は、きれいさや構造の正しさより、テンポを意識。

## [Qiigle](https://qiigle.com/)の検索に引っかかるようにする
将来検索に使いそうなワードは入れておく
https://qiigle.com/

## さっさと本題に入る

「記事の対象者」「この記事でわかること」「この記事で触れないこと」とかが必要なのは超長文記事か、反感を買いかねない踏み込んだ記事を書くときだけで良い。
あいさつとかギャグ的なものは技術記事には必要ない。

## その命名じゃないといけないのか、任意の名前で良いのかを明確にする

任意に名前をつけられる部分がアプリ名にちなんだ名前だったりすると、命名規則があるように見えてしまう。多少ダサくなってもわかりやすい方が良い。

## 参考記事を書く

モラル的な話だけじゃなくて、後から参照する時に執筆当時の状況を思い出しやすくなる。

## 記事投稿画面をブックマークバーにセット
1クリックで執筆開始できます。

## 伸ばしたい記事は拡散の努力をする

Qiitaではトレンドに入ると一気に伸びるので、サービス公開記事など伸ばしたい記事はTwitterやオンラインコミュニティ等でコメント付きで共有するなど、最大限拡散の努力をします。やりまくると嫌われるので、本当に伸ばしたい時だけ。

## 記事を伸ばすために学習するジャンルを変えない

経験上、Railsの記事を書くよりReact等の記事を書く方が全然伸びます。でもそれはそれなので、、
「記事が伸びる分野 = 自分が人柱になる確率が高い分野」で、今の自分は確実に技術力の土台を固めるフェーズなので、そこは履き違えないように注意してます。
Maxでランダムな高さの音がピコピコ鳴るものを作る

#前の記事
[Maxでピーでもパーでもプーでもいいから音を出したい](https://qiita.com/waokitsune/items/d53f7994c154494ce3bc)

#バージョン
Version 8.1.5（9359645）（64-bit windows）

#randomオブジェクトってなんぞや
音の波を出すオブジェクトがあるなら、ランダムな値を出すオブジェクトもあるはず！
そうあたりをつけてオブジェクトを作成して **rand** と入力してみたら…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/91bf9c67-60e2-9aee-8b30-4e414c7c6e65.png)
ほーらやっぱりいた。
と、まあ、randomオブジェクトを作ってはみたけど、これどうやって使うの…。(´・ω・`)

右クリックでリファレンスが見られることを発見。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/6e2f718a-6c28-9806-2182-de2134db6906.png)

「randomとは何ぞや」が書かれておるぅ。さらにOpen Helpを押せば…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/4ec9bb3a-e510-806f-89ac-2d6f9dae1d8a.png)
触って動かせるサンプルも出てきた～。ふむふむ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/62f5109e-777d-191d-bea9-b3489dbe95d9.png)

#とりあえず、0～1000の間でランダムな値発生器を
という訳でできあがったものがこちらになりま～す。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/28ad0383-0a2e-4080-3357-c07426b66907.png)
すっごいミニマムだなぁ…。いやいや、小さいことはいいことだ！大きければいいってもんじゃない！！小さい方が魅力的だよって言ってくれる人もいるし……。

うん、パーツの説明。まずは **button** 。こいつは「いつやるの？今でしょ！」な信号を出すやつ。これがいないと「いったい **いつ** ランダムな値を出力すればいいんだい？」って話になっちゃう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/0266ed1e-74dc-4a52-d329-5b6b8f30bfc7.png)
続いて **number** 。出てきたランダム値の確認用。デバッグって感じだね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/ca6c274d-3183-1689-e340-9477049b9017.png)
ボタンをポチポチクリックするたびに0～999のランダムな値が生成された！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/c90f3509-42eb-f61e-f44e-84acdc1e97f2.png)
って0～1000じゃないじゃん！そう、randomは0～第1引数 **未満** でランダムな値を発生してくれる。だから1000も出したいなら引数は1001にしないといけない。

#cycleの周波数にぶちこむ
という訳でできあがったものがこちらになりま～す。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/23f11b9e-513e-db13-67f0-2813c6e110b8.png)
そのままだとただ「ポーーーーーーー」みたいな一定の音程の音が出続けるだけだけど、ボタンを押すたびに音程が変わって「ぽぺぱぽぴぽぱぺ…」みたいになります！

#コメントパーツ
Maxにはコメントのパーツもあることが分かりましたん！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/47ab4e6a-e630-2a95-6722-0d499815e63f.png)

#りふぁれんす
ヘルプ ⇒ リファレンス でいろんなオブジェクトの説明や実際に動かせるサンプルが見られます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/26f5fb60-8435-abf1-4e69-746d4ac0e69c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/9ca0f3de-b0c6-e64d-cac8-e0e3a6f5fdc9.png)
チュートリアルには大抵Open Tutorialボタンがあって、押すと動かせるサンプルが開くぅ！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/8ae2f03b-8c0e-0516-c1af-c1d795fbe76b.png)

#次の記事
[Maxでメトロノームを使って腱鞘炎を華麗に回避](https://qiita.com/waokitsune/items/a09cc55f160f13ebfb9e)
デプロイしたら画像と音声が読み込まれない！！

###### ただデプロイするだけでは動的画面の画像は表示されないよって話

#### ローカル環境では表示されてる画像が本番環境では表示されない！！
結論をいうと、ローカル環境と本番環境では読み込まれるファイルが違うのでそれは当たり前なんです。

#### public ファイル
ではその解決策です。
今画像や音声は`app/assets/images or audios`のファイルに保存されていると思います。ローカル環境ではこのファイルから読み取り、表示をしています。

本番環境では public ファイルから読み取られるので、`public/assets/images or audios`となるように配置してあげます。

#### 解決！
とはなりません。ビューファイルの記述も変えないと何も変わらないです。
書き換える前は
`src="assets/画像 or　音声"`
`image_tag("画像")`
という記述だと思います。

例えば、ただ`src="public/assets/画像 or　音声"`としても本番環境ではうまく行ってもローカル環境でうまくいかない可能性があります。
そんな時に便利なのが asset_path です。

### asset_path
assetパイプラインから勝手に探して読み込んでくれます。
`src=<%= asset_path "画像 or　音声"%>`
`image_tag(asset_path("画像")`
こう記述することでローカル環境でも本番環境でも表示してくれます！

##### もし他の記述(form_with)で書いている方
`<%= f.submit %>`
送信ボタンを画像で作っている方は
`<%= form_with 省略, id: "search_form") do |form| %>
　<input type="image" name="submit" 
　src=<%= asset_path "画像"%>　form="search_form">`
という記述に書き換えてみてください。
訓練・検証・テストデータの違い

４月から人工知能について学び始め、８月にJDLA G検定に合格し、今は「ゼロから作るDeep Learning」でディープラーニングを勉強している者です。

今まで、訓練データ・検証データ・テストデータって、
「訓練データと検証データが学習時に使うもので、テストデータが汎化性能測るためのものやろ？」と理解していたのですが、ゼロつくを読んでいると厳密にはそうじゃないようなので、備忘録的に残しておきます。

以下、データセット＝訓練データ＋検証データ＋テストデータで話を進めます。

#訓練データ
訓練データは、パラメータ（重みやバイアス）の学習に利用する。


#検証データ(validation data)
ハイパーパラメータの性能を評価するために利用する。


#テストデータ
汎化性能をチェックするために、最後に（理想的には一度だけ）利用する。
”理想的には一度だけ”というところがポイントで、テストデータを何度もモデルに入力すると、今度はそのテストデータに対してモデルが最適化し始めて、テストデータに対して過学習を起こしかねないから。
この理由から、テストデータを用いてハイパーパラメータの性能を評価してはいけない。
『LeanとDevOpsの科学』を読んで

# 所感 

[LeanとDevOpsの科学](https://www.amazon.co.jp/Lean%E3%81%A8DevOps%E3%81%AE%E7%A7%91%E5%AD%A6-Accelerate-%E3%83%86%E3%82%AF%E3%83%8E%E3%83%AD%E3%82%B8%E3%83%BC%E3%81%AE%E6%88%A6%E7%95%A5%E7%9A%84%E6%B4%BB%E7%94%A8%E3%81%8C%E7%B5%84%E7%B9%94%E5%A4%89%E9%9D%A9%E3%82%92%E5%8A%A0%E9%80%9F%E3%81%99%E3%82%8B-impress-gear/dp/4295004901/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=2TO99L7CZA84D&dchild=1&keywords=lean%E3%81%A8devops%E3%81%AE%E7%A7%91%E5%AD%A6&qid=1599648696&sprefix=lean%E3%81%A8DEV%2Caps%2C261&sr=8-1)を読了しました。

私はアジャイルやDevOps礼賛本はやや苦手なのですが、本書は各種プラクティスの効果をエビデンスに基づいて検証しており、非常に科学的、かつ実践的な内容であると感じました。

# 印象に残った点

## パフォーマンスの計測尺度

### 本書で採用したのは下記の４つ
- デリバリのリードタイム
- デプロイの頻度
- サービス復旧の所要時間
- 変更失敗率

これらの尺度によって測定した「ソフトウェアデリバリのパフォーマンス」が「組織全体のパフォーマンス」に寄与することが調査により確認された

### 下記の尺度はパフォーマンスの計測尺度としてふさわしくない
####  ストーリーポイントを合算して記録した「ベロシティ」
- これは「キャパシティ計画の立案ツール」として使うべき
- ベロシティは絶対的ではなくチーム依存の相対的な尺度
- ベロシティを生産性の測定尺度にすれば、必然的にチームはベロシティを悪用するようになってしまう

#### リソースの利用率(エンジニアの稼働率)
- 利用率は一定レベルを超えてしまうと余力（余裕）がなくなって予想外の仕事や計画変更、改善作業を入れる隙がなくなる
- 「待ち行列の理論」で言えば、利用率が100%に近づくにつれて、リードタイムが無限大に近づく

## アーキテクチャのポイント

### システムのタイプとデリバリのパフォーマンス

システムのタイプがSoR（いわゆる勘定系システム）かどうか、組み込み系かどうか等により、デリバリのパフォーマンスに差が出ると予測していたが、実際には相関関係が見られなかった。差が見られたのは次の２つのタイプのみ

- 他社（外注先）が開発したカスタムソフトウェアかどうか
- メインフレームのシステムで作業を進めているかどうか

### アーキテクチャの特性のうち次の２つの事項がデリバリのパフォーマンスに大きな影響を及ぼしていた

- テストの大半を、統合環境を必要とせずに実施できる(テスト容易性)
- アプリケーションを、それが依存する他のアプリケーションやサービスから独立した形で、デプロイまたはリリースできる(デプロイ容易性)

### 継続的デリバリの最強の促進要因
『テストとデプロイの自動化』よりも次のケイパビリティをチームが備えているか否かが重要

- チーム外の人物の許可を得なくても、対象システムに大幅な変更を加えられる
- 対象システムの変更作業で他チームに頼ったり、他チームに相当量の作業を課したりすることなく、対象システムに大幅な影響を加えられる
- チーム外の人々とやり取りしたり協働したりすることなく作業を完遂できる
- ソフトウェア製品やサービスを、それが依存する他のサービスに関係なく、オンデマンドでデプロイ、リリースできる
- 統合テスト環境を必要とせずに、オンデマンドでテストの大半を実施できる
- デプロイメントを、無視できるほどわずかなダウンタイムのみで、通常の勤務時間内に完了できる

### 変更管理プロセス

1. 本番環境に対する変更については必ずチーム外の人や組織（管理者や変更詰問委員会）の承認を得なければならない
1. データベースの変更などハイリスクな変更関してのみ、承認を得なければならない
1. 変更の管理はピアレビューだけで済ませている
1. 変更承認プロセスはない

上記4つの方針とパフォーマンスの相関関係を調べたところ、1のパフォーマンスが低く、3と4のパフォーマンスが高かった。
1の方針は「リードタイム」「デプロイ頻度」「サービス復旧までの所要時間」との間に負の相関関係があり、「変更失敗率」とは相関がない。つまり、チーム外の人や組織の承認を得らなければならない場合、本番環境のシステムの安定性は向上せず、むしろ確実に作業の遅れを招いてしまう。

本書が推奨するのは「ペアプログラミングやチーム内でのコードレビューなど、負荷の軽い変更承認プロセスとともに、望ましくない変更を探知・排除するためのデプロイメントパイプラインと併用する」
形態素解析して頻出単語を出す

このコードで行うこと
・txtデータを読み込む
・形態素解析を行い、名詞だけを取り出してリスト化
・リストの平坦化、記号の削除できれいな状態にする
・単語の頻出数を出す

とりあえずコード


```python:qiita.py

import MeCab
import itertools
import collections
import string

#データ全体を名詞群として扱う,リスト化して収納
with open("deta.txt","r",encoding='utf-8') as f:
        a = f.read().splitlines()

#形態素解析2パターン目<-いろいろやり方がある

def split_text_only_noun(text):
    tokenizer = MeCab.Tagger()
    node = tokenizer.parseToNode(text)
    keywords = []
    while node:
        if node.feature.split(",")[0] == u"名詞":
            keywords.append(node.surface)
            print(keywords)
        node = node.next
    return ','.join(keywords)

#１つ1つのリストaの要素を形態素解析して名詞抽出
r_aa = []

for aa in a:
     r_a = ''.join(split_text_only_noun(aa)).split(',')
     r_aa.append(r_a)

#形態素解析、リストの平坦化、記号の削除
r_aa = list(itertools.chain.from_iterable(r_aa))
kigo = string.punctuation
table = str.maketrans( '', '',kigo)

word_list = []
for bb in r_aa:
    word_list.append(bb.translate(table))

#空白を削除
count = 0
words_list = []
while count < len(word_list):
    if word_list[count] != '':
        words_list.append(word_list[count])
    count += 1

#単語の頻出数
count_num = 0
c = collections.Counter(words_list)

#テキストに書き込み
with open('結果.txt',mode='w') as f:
    for word,count in c.most_common():
        if  count > 50:
            f.writelines(str(f"{word}:{count}"))
            f.writelines("\n")

```


これでいい感じに出る。これがTF-IDFを出すためのTFを出すのに使えそう。

以下、今チャレンジしている(挫折中の)collections.Counterを使用せずにソートしようとしたコード


```python:zasetu.py

result = []

for num_1 in range(len(words_list)):
    ct = 0
    for num_2 in range(len(words_list)):
        if words_list[num_1] == words_list[num_2]:
            ct +=1
            continue
    if ct > 50:
        result.append(words_list[num_1])
        result.append(ct)
        
print(result)

```

これだと頻出単語が出る度に個数を数えちゃうから、この結果を使ってソートしたりしないといけない気がする。

結論：collections.Counter(class)使え。

続き
Markdown: [続・tf-idf関数を使わずに重みづけ](https://qiita.com/aramesaya/items/3976b6343fe0c7aeaf49)
Webpack関連

Vue.jsで開発でWebpack関連でつまずくことが多かったので得た情報をまとめていく
# Webpack4、CopyWebpackPluginのwebpack.config.js
Webpackはバージョンアップごとに設定ファフィルの記述方式が変わるらしい
↓見出し環境下での基本的な設定方法↓

```js:webpack.config.js
const CopyPlugin = require("copy-webpack-plugin");

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: "**/*.html",
          to: "./sample",
          context: ".src/sample",
        },
      ],
    }),
  ],
};
```

正直よくわかってない

### 参照ページ
https://tadtadya.com/webpack4-error-of-version-up-of-copywebpackplugin/

# ValidationError: Invalid options object.
Vue.jsで`npm run dev`実行時に発生したエラー

```bash
ValidationError: Invalid options object. Copy Plugin has been initialized using an options object that does not match the API schema.
 - options[0] misses the property 'patterns'. Should be:
   [non-empty string | object { from, to?, context?, globOptions?, filter?, toType?, force?, flatten?, transform?, cacheTransform?, t
ransformPath?, noErrorOnMissing? }, ...] (should not have fewer than 1 item)
```

`トップディレクトリ/build/webpack.dev.conf.js`内の`new CopyWebpackPlugin`部分を以下のように書き換え

```js:webpack.dev.conf.js
new CopyWebpackPlugin({
      patterns: [
        { from: 'source', to: 'dest' },
        { from: 'other', to: 'public' },
      ],
    }),
```

### 参照ページ
https://webpack.js.org/plugins/copy-webpack-plugin/
エンジニアだったらターミナルの見た目にはこだわった方がいいんじゃない？

# Mac デフォルトの「ターミナル」はダサい

未セットアップの iMac を触る機会があった。

私「最初から入ってるデフォルトの端末って何だっけ？」
弊社エンジニア「『ターミナル』っすね」
私「そっか、そのまんまやな（ﾎﾟﾁｯ」
![スクリーンショット 2020-09-06 13.48.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667942/fdd29922-1ead-c6ff-0ecb-b1d8d85594ca.png)
**なんやこれは…**

確かにシェルは問題なく動かせる。
端末エミュレータとしては機能的になんの問題もない。

…とはいえ、Windows のメモ帳を彷彿とさせる外観がダサい。ダサすぎる。
見るたびに血圧が上がってテンションは下がる。やめてくれよ、頼むから。

# iTerm2 と Dracula Color を入れる

iTerm2 を入れて Dracula Color に設定した。
ウィンドウ単位のスクリーンショットだと写らないけど、背景は半透明でデスクトップが見えてます。
![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667942/3f75f40d-a771-6eb9-ce41-41e0cb0025da.png)
iTerm2：https://iterm2.com/
Dracula：https://draculatheme.com/iterm/

設定は、iTerm2 のメニューから
Preferences -> Profiles -> Colors -> Color Presets... -> Import...
を選んで、Dracula のカラーセットを unzip したファルダから import するだけ。
![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667942/e9bcf8c4-0195-3be6-f0e6-956634357e6c.png)
ちなみに、[Iceberg](https://github.com/Arc0re/Iceberg-iTerm2) というテーマも結構カッコいい。

見た目は個人の好き嫌いでしかないので、各自好きなようにすればいいと思うんだけど、ソフトウェアエンジニアであれば１日に何度も見る画面なので、こだわりを持って使い込む方がいいんじゃないかなと思います。
Cannot fit requested classes in a single dex file (# methods: 115337 > 65536)

メソッド数が65536を超えた場合のビルドエラー

https://minpro.net/android-64k-problems

要求されたクラスを単一のdexファイルに収めることはできません

#解決法
最初から複数のdexファイルが使えるように設定。

```xml:build.gradle(app)
    defaultConfig {
        ...
        multiDexEnabled true
    }
    dependencies {
    implementation 'com.android.support:multidex:1.0.3'
}
```
XcodeでOpenCVの実行時に code signature not valid エラーが出たら

XcodeのDisable Library Validationにチェックすると、解消します。

![Screen Shot 2020-09-09 at 19.45.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47942/cdcdb1b1-e5e5-dafc-be73-fc80d15d518e.png)

## エラー
```
dyld: Library not loaded: /usr/local/opt/opencv/lib/libopencv_features2d.4.4.dylib
  Referenced from: /Users/oosuyuuki/Library/Developer/Xcode/DerivedData/RectangleDetection-akoxhwvgxqqsyydewscmnhcsbdzy/Build/Products/Debug/RectangleDetection
  Reason: no suitable image found.  Did find:
	/usr/local/opt/opencv/lib/libopencv_features2d.4.4.dylib: code signature in (/usr/local/opt/opencv/lib/libopencv_features2d.4.4.dylib) not valid for use in process using Library Validation: mapped file has no cdhash, completely unsigned? Code has to be at least ad-hoc signed.
	/usr/local/lib/libopencv_features2d.4.4.dylib: code signature in (/usr/local/lib/libopencv_features2d.4.4.dylib) not valid for use in process using Library Validation: mapped file has no cdhash, completely unsigned? Code has to be at least ad-hoc signed.
	/usr/local/Cellar/opencv/4.4.0_1/lib/libopencv_features2d.4.4.0.dylib: code signature in (/usr/local/Cellar/opencv/4.4.0_1/lib/libopencv_features2d.4.4.0.dylib) not valid for use in process using Library Validation: mapped file has no cdhash, completely unsigned? Code has to be at least ad-hoc signed.
(lldb) 
```

## 原因
GatekeeperとSoftware notarizedによる制限のようです。下記の記事が参考になります。
https://qiita.com/Arime/items/e1df2a8c3d4c2ce75069

## 参考
XcodeでOpenCVを使う手順については、下記の記事が参考になります。
https://qiita.com/KakeruMasuda/items/49d369ab49fac5ea3eab
Rubyアルゴリズム（inject,メソッド定義）

#はじめに
Rubyアルゴリズムを学習する際に作成したコードを解説します。
#学んだ事
次の技術に挑戦しました。

* injectメソッド
* メソッド定義

#挑戦したこと
１０個ずつ数字を並べた二つの配列を使用します。
それぞれの配列の、1番目・1番目から2番目の和・3番目までの和…を比較し、
どちらが大きいか表示するコードを作成します。

#内容

まずはなんでもいいので、配列を二つ用意します。

```ruby
a = [1,2,3,4,5,6,7,8,9,10]
b = [10,2,2,2,2,2,2,2,2,2]
```

次に
配列の和を求めるメソッドを作ります。
色々方法はありますが、ここではinjectメソッドを使用します。

```ruby
def sum(array,n)
  sum = array[0,n].inject(:+)
  return sum
end
```

`array[0,n].inject(:+)`の部分では、引数として代入した配列の1番目からn+1番目の和を計算します。

最後に、上記の処理を配列の全ての要素に対して実行し、その度に大小を判定するようにします。

```ruby

(1..10).each{|i|
  if sum(a,i) > sum(b,i)
    puts "#{i}：aが大きい"
  elsif sum(a,i) < sum(b,i)
    puts "#{i}：bが大きい"
  else
    puts "#{i}：等しい"
  end
}
```

全てを合わせると下記の通りになります。

```ruby
a = [1,2,3,4,5,6,7,8,9,10]
b = [10,2,2,2,2,2,2,2,2,2]

def sum(array,n)
  ans = array[0,n].inject(:+)
  return ans
end

(1..10).each{|i|
  if sum(a,i) > sum(b,i)
    puts "#{i}：aが大きい"
  elsif sum(a,i) < sum(b,i)
    puts "#{i}：bが大きい"
  else
    puts "#{i}：等しい"
  end
}
```

以上です。

#おわりに
今回のコードで新しくinjectメソッドの使い方を知ったほか、
メソッド返り値同士でも大小比較ができるという気付きが得られました。
今後も、新しい知識を得ていくと共に、既に知っている知識の新しい使い方を追求したいと思います。
【MySQL】dockerで構築したデータベースサーバが日本語対応していないかも、、、

#環境

```shell:
$ docker -v
Docker version 19.03.12

$ rails -v
Rails 6.0.3.2

$ mysql --version
mysql  Ver 14.14 Distrib 5.7.29, for osx10.15 (x86_64) using  EditLine wrapper
```


#データベースに日本語でユーザー名を登録しようとすると、、、、

```:エラー内容
ActiveRecord::StatementInvalid (Mysql2::Error: Incorrect string value: '\xE3\x83\x8F\xE3\x83\xAA...' for column 'name' at row 1):
```

あらら、日本語として認識されてない模様
ここは、データベースのcharasetでも見て設定確認しますか。

```shell:
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
f51c4b953b05        feeder-in_back      "rails server -b 0.0…"   About an hour ago   Up About an hour    0.0.0.0:3000->3000/tcp              back
925b28f3b58d        mysql:5.7           "docker-entrypoint.s…"   About an hour ago   Up About an hour    33060/tcp, 0.0.0.0:3308->3306/tcp   database
ab6efeba59a1        feeder-in_web       "docker-entrypoint.s…"   About an hour ago   Up About an hour    0.0.0.0:8080->3000/tcp              web
```

```
$ docker exec -it 925b28f3b58d mysql -u root -p

mysql> show variables like "chara%";
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | latin1                     |
| character_set_connection | latin1                     |
| character_set_database   | latin1                     |
| character_set_filesystem | binary                     |
| character_set_results    | latin1                     |
| character_set_server     | latin1                     |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.03 sec)
```

`character_set_database   | latin1`
これを見る限り、MySQLのデフォルトのcharasetになっており、日本語対応になっていない。



#MySQLデータベースサーバを日本語対応にする

```docker:docker-compose.yml
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
```

```shell:
$ docker-compose down

$ docker-compose up -d --build
```

#データベースの再構築

```database.yml
default: &default
  charset: utf8mb4   #追記
  encoding: utf8mb4  
```

```shell:
$ docker-compose exec back sh
> rake db:drop

> rake db:create
> rails db:migrate
```


これで日本語対応のデータベースになった！
keepalivedの通知をSlackへ流す

Keepalivedの通知ではメールが設定できるが，Slackの方が便利なのでSlack通知を設定する．

# 手順

ここでは，HAProxyの起動状態をチェック基準にする．

```c:keepalived.conf
! Configuration File for keepalived
vrrp_script chk_haproxy {
    script "systemctl is-active haproxy"
}

vrrp_instance VI_1 {
    state BACKUP
    priority 50
    interface ens160
    garp_master_delay 10
    virtual_router_id 31
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass XXXXXXXX
    }
    virtual_ipaddress {
        192.168.100.10
    }
    track_script {
        chk_haproxy
    }
    notify /etc/keepalived/notify.sh
}
```

新たに以下のSlack通知のスクリプトを作成した．

```bash:notify.sh
#!/bin/bash

TYPE=$1
NAME=$2
STATE=$3

URL='https://hooks.slack.com/services/XXXXXX'
CHANNEL=${CHANNEL:-'#_alert'}
BOTNAME=${BOTNAME:-'keepalived-notice'}
HOSTNAME=`hostname`
MESSAGE="\`${TYPE:-'type'}\` on \`${HOSTNAME:-'host'}\` :: ${STATE:-'state'}"

payload="payload={
    \"channel\": \"${CHANNEL}\",TYPE=$1
    \"username\": \"${BOTNAME}\",
    \"text\": \"${MESSAGE}\"
}"
curl -s -S -X POST --data-urlencode "${payload}" ${URL} > /dev/null
```

実際にSlack通知された例を以下に示す．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103672/58c6b288-820d-82c9-4441-ccddb46b3cbe.png)

# 参考資料

- [Keepalived Check and Notify Scripts](https://tobru.ch/keepalived-check-and-notify-scripts/)
Rでアクセス(.accdb)にODBC接続


windows
社内データを掘り出していたら珍しいファイル形式の分析依頼をされたので接続方法について備忘録を残しておく。
Accessからcsvにエクスポートしてもいいけど、定形の処理にしたい場合に再現できなくなることがあるので、
なるべくデータソースには直接つないでおきたい。

#接続

[サンプルデータ](https://github.com/amazongodman/open_folder/blob/master/iris_data.accdb)を作っておいたのでここからDL


```r
#import library
library(RODBC)

setwd("C:\\Users\\user\\Desktop")

#conect odbc to access
#read data

con<-odbcConnectAccess2007("iris_data.accdb")

#各テーブルのデータはRDBのようにSQLで取得する

PetalLength <- sqlQuery(con, "select * from PetalLength")
PetalWidth <- sqlQuery(con, "select * from PetalWidth")
SepalLength <- sqlQuery(con, "select * from SepalLength")
SepalWidth <- sqlQuery(con, "select * from SepalWidth")

odbcClose(con)
```



ドライバが問題なら以下からインストールしておく。

https://www.microsoft.com/ja-jp/download/details.aspx?id=13255


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/7211f0f7-d10f-b1b3-4ec6-fb2c12b2276d.png)




#以上
ETHoverを使ってみたら動かなかった（対処法あり〼）

[ConsenSys](https://consensys.net/)がEthereum開発用に新しいツールをリリースしました。

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">We recently released a new VSCode extension called ETHover for interacting with some pretty juicy features.<br><br>1. Right click on a ETH address to pull the verified source into a new pane: <a href="https://t.co/s9lrMSQVFf">pic.twitter.com/s9lrMSQVFf</a></p>&mdash; ConsenSys Diligence (@ConsenSysAudits) <a href="https://twitter.com/ConsenSysAudits/status/1303338999751340035?ref_src=twsrc%5Etfw">September 8, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


その名は[ETHover](https://marketplace.visualstudio.com/items?itemName=tintinweb.vscode-ethover)。

VSCodeの拡張機能で、ETHアドレス上にマウスオーバーすれば、残高を調べたり色々できる便利そうなやつです。

早速つかってみよう！
とおもったら入れても動かなかったのでメモです。

## 対処法
こっちを入れれば動きます。
[Solidity Visual Developer](https://marketplace.visualstudio.com/items?itemName=tintinweb.solidity-visual-auditor)

ETHアドレス上にマウスオーバーしてポップアップすれば成功です。
![スクリーンショット 2020-09-09 19.01.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280104/49bef50d-cb18-383f-dcd2-8355c2157cfb.png)

[Solidity Visual Developer](https://marketplace.visualstudio.com/items?itemName=tintinweb.solidity-visual-auditor)は、ETHoverを含む４つのエクステンションがパッケージになっています。こっちを使いましょう。
![スクリーンショット 2020-09-09 19.23.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280104/130eff69-55d0-9fdc-7056-4e4113a64d51.png)
Anaconda,Python学習に参考になったサイトまとめ

##実行環境
・Windows10 Laptop&Desktop
・Anaconda 4.8.4
・VScode 1.49.0
・Python 3.8.5

##参考
####基本,環境構築
・[【超入門コース】Python｜プログラミング初心者向け講座 キノコード](https://www.youtube.com/watch?v=3jymAyMJjR8&list=PLavQwENTsEBUHi7XZHGfKjTQQdOvnYPmB)
・[Windows環境でのAnacondaのアップデート](https://qiita.com/kerobot/items/917dc7027e15f5ff75ac)
・[Anacondaのcondaとpipのinstallコマンドを使い分ける方法（管理上の方針）](https://code-graffiti.com/how-to-use-conda-and-pip-install-command-properly/)
・[Anaconda Prompt の作業フォルダを変更](http://izmmr.blog.jp/archives/10188841.html)

####GUI
・[AnacondaでKivyをインストールする](https://qiita.com/GRGSIBERIA/items/4eeddea88dba031216de)
・[Python GUI kivyで電卓を作ってみる](https://medium.com/@hokan_dev/python-gui-kivy%E3%81%A7%E9%9B%BB%E5%8D%93%E3%82%92%E4%BD%9C%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%8B-c32d64de1a99)
・[Kivy + PythonでイケてるGUIアプリを作ってみる](https://musaprg.hatenablog.com/entry/2018/05/01/213355)
・[Pythonでデスクトップアプリ作成入門 - Tkinterで肥満判定ツールを作ろう](https://news.mynavi.jp/article/zeropython-46/)
・[Tkinterを使うのであればPySimpleGUIを使ってみたらという話](https://qiita.com/dario_okazaki/items/656de21cab5c81cabe59)

####スクレイピング
・[【完全版】PythonとSeleniumでブラウザを自動操作(クローリング／スクレイピング)するチートシート](https://tanuhack.com/selenium/)
・[Pythonでブラウザ操作を自動化するSelenium WebDriverの使い方](https://valmore.work/how-to-use-selenium-webdriver/)
・[python+seleniumでChromeとEdgeを操作する/インストールと環境設定と動作確認](https://arakan-pgm-ai.hatenablog.com/entry/2018/01/10/080000)
・[【Anaconda】condaコマンドで仮想環境を構築する方法](https://code-graffiti.com/how-to-build-a-virtual-environment-with-conda/)
・[WebページのスクレイピングとYouTube Data APIで動画情報取得（ホロライブの動画配信予定を収集）](https://qiita.com/kerobot/items/6009cb0db643bceaf4e9)
・[Python + Selenium で Chrome の自動操作を一通り](https://qiita.com/memakura/items/20a02161fa7e18d8a693)
・[テストオートメーションに WebDriver (Chromium) を使用する](https://docs.microsoft.com/ja-jp/microsoft-edge/webdriver-chromium?tabs=python)
・[Webアプリケーションを自動で操作してみよう](https://qiita.com/mima_ita/items/4149a4cdb9a33084258b#python%E3%81%AE%E5%A0%B4%E5%90%88)
・[Pythonでseleniumを試してみる(InternetExploer)](https://qiita.com/__init__/items/1a90bfbbd2b1015bb90d)
・[Selenium webdriverよく使う操作メソッドまとめ](https://qiita.com/mochio/items/dc9935ee607895420186)

####Youtube
・[YouTubeから動画をダウンロードしてくるGUIツール(Python)](https://qiita.com/KMim/items/5583da12d33e913f1c10)
・[PythonでYouTubeの動画を取得する方法](https://www.sejuku.net/blog/70173)
・[Youtube Data APIを使ってPythonでYoutubeデータを取得する](https://qiita.com/g-k/items/7c98efe21257afac70e9)
・[【Python】youtube-dlを使ってYoutubeの動画をダウンロード（mp4, mp3）（Pytube不使用）](https://shizenkarasuzon.hatenablog.com/entry/2019/02/03/123545)

####Unity
・[IronPythonを使ってUnity上でPythonのコードを実行する](https://blog.negativemind.com/2015/05/27/ironpython-on-unity/)
・[C#からPythonを実行する方法【Unity】](https://tofgame.hatenablog.com/entry/2019/04/30/011221)

####その他
・[Pythonプログラム用のショートカットをつくる（Windows10）](https://qiita.com/odanny/items/4e3a320b70df5136c622)
・[コマンドプロンプト非表示でPythonスクリプトを実行する方法](https://fraxinus.at.webry.info/201107/article_2.html)
yamlファイルのコメントアウトをエディタのショートカットで解除してエラーが出るときに確認すること

### おことわり
Railsで遭遇したエラーではありますが、Rails以外でも起こりうるのでタイトルからRailsを外しています。

### 問題が起こった状況
Railsの設定ファイルの一つに、`storage.yml`という、ストレージ周りの設定をするyamlファイルがあるのですが、
その中に、デフォルトではコメントアウトされているAWSのS3に関する設定があります。

今回、S3を設定する必要があったので、それを意気揚々とIDEのショートカットでコメントアウトを解除したときに問題が発生しました。

```:storage.yml
test:
  service: Disk
  root: <%= Rails.root.join("tmp/storage") %>

local:
  service: Disk
  root: <%= Rails.root.join("storage") %>

# Use rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key)
# amazon:
#   service: S3
#   access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
#   secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
#   region: us-east-1
#   bucket: your_own_bucket
```

### どうなったか

下記エラーが発生しました

```
RuntimeError: YAML syntax error occurred while parsing /project_dir/config/storage.yml. Please note that YAML must be consistently indented using spaces. Tabs are not allowed. Error: (<unknown>): did not find expected key while parsing a block mapping at line 1 column 1
```

### どこが間違っていたか

```:storage.yml
test:
  service: Disk
  root: <%= Rails.root.join("tmp/storage") %>

local:
  service: Disk
  root: <%= Rails.root.join("storage") %>

# Use rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key)
 amazon:
   service: S3
   access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
   secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
   region: us-east-1
       bucket: your_own_bucket
```

この見た目ではわかりにくいですが、`amazon`というキーの行以降が半角スペース1つ分右にずれています。

そのため、yamlの解釈エラーが出てしまっていたということになります。

### 対処法
ずれている分の半角スペースを削除する

### 結論
エディタのコメントイン機能を使う際はインデントに注意してください。
【Salesforce】 開発を始める際にしてること

- 私がSalesforceで開発を始める際にやることをまとめました

## 開発ツールのインストール

### Salesforce Logins
- https://chrome.google.com/webstore/detail/salesforce-logins-by-syne/mhpbcjokcjoldhjcapkcmfkkkgepapgm
- Google Chrome拡張
- Salesforceアカウントを複数管理＆自動ログインできます
- 類似拡張にForce.com LOGINSがありますが、こっちのほうがおすすめです

### Visual Studio Code
- Salesforce Extension Packプラグインを入れます
    - https://marketplace.visualstudio.com/items?itemName=salesforce.salesforcedx-vscode

### Salesforce CLI
- https://developer.salesforce.com/docs/atlas.ja-jp.sfdx_setup.meta/sfdx_setup/sfdx_setup_install_cli.htm
- 次のコマンドでインストールされたことを確認します

```
sfdx plugins --core
```


## 開発環境の作成（Salesforce）

### 開発用Sandboxの作成
- 本番環境にログインします
- [設定] > [環境 - Sandbox]を選択します
- [新規 Sandbox]ボタンをクリックします
- 名前と説明を入力します（作成元は本番のまま）
- Developerを選択して「次へ」
- Sandboxが作成されるのを待ちます（丸一日くらい）
- Sandboxには次の本番環境のユーザーコピーが作成されるので、それを使ってSandboxにログインできます
    - ユーザ名：(本番環境のユーザ名).(Sandbox名)
    - パスワード：(本番環境のパスワード)
    - メールアドレス：(本番環境のメールアドレス).invalid

## 開発環境の作成（ローカル）
- Salesforce標準機能で補えないようなページが必要になった場合、Apexを用いて独自にページを作成する必要があります
- Apexの開発はSalesforce内のエディタでも行えますが、VS Codeで行ったほうが色々捗るので、ローカルに開発環境を構築しておきましょう

### Salesforceプロジェクトを作成（初回のみ）
- VS Codeのコマンドパレッを開き「SFDX: プロジェクトを作成（Create Project）」を選択します
- 「標準（Standard）」を選択します
- プロジェクト名を入力します（適当に分かりやすい名前で）
- プロジェクトが作成されます

### Salesforce認証（タイムアウトする度に行う）
- コマンドパレットから「SFDX: 組織を認証（Authorize an Org)」を選択します
- 組織の名称を入力します（適当でOK）
- 「Sandbox」を選択します
- ブラウザが開き、Salesforceのログイン画面が表示されるので、Sandbox環境のアカウントを入力します
- 初回のみアクセス許可を求める画面が出るので「許可」をクリックします

### Salesforceメタデータの取得
- 認証が完了すると、VS Codeの左ペインに雲マーク(☁)が出現するのでクリックします
- Salesforce上のデータが表示されるので、使うデータを適宜ダウンロードします
- 開発でよく使うのは以下
    - Apex Classes
        - Apexクラス
        - ローカルプロジェクトのforce-app/main/default/classesに同期されます
    - Aura Component
        - Lightningページ
        - ローカルプロジェクトのforce-app/main/default/auraに同期されます
    - Visualforce Pages
        - VisualForceページ
        - ローカルプロジェクトのforce-app/main/default/pagesに同期されます

### ローカルデータのアップロード方法
- VS Code上で編集したファイルを右クリックします
- 「組織へソースをデプロイ」を選択します
- Salesforceへデータがアップロードされます

### 注意事項
- コンフリ検出等は一切行われず、後勝ちでアップロードされるので、複数人で編集する際は気をつけましょう（編集する前に最新ソースをダウンロードする）


# おまけ

## Community Cloudを使う場合

### Communityの有効化
- Sandbox環境にログインします
- [設定] > [機能設定 - コミュニティ - コミュニティ設定]を選択します
- [コミュニティの有効化]をクリックします
- ドメイン名を入力して有効化します（会社名を入れるのが一般的）

### Communityの作成
- Sandbox環境にログインします
- [設定] > [機能設定 - コミュニティ - すべてのコミュニティ]を選択します
- [新規コミュニティ]をクリックします
- Build Your Ownを選択します
- [使用を開始する]をクリックします
- コミュニティ名を入力して保存します（コミュニティ名は後から変更可能です）

## Einstein Analyticsを使う場合

### Analyticsの有効化
- Sandbox環境にログインします
- [設定] > [機能設定 - 分析 - Analytics - 始めましょう]を選択します
- [Einstein Analyticsを有効化]をクリックします

### Analytics管理権限の付与
- Sandbox環境にログインします
- [設定] > [ユーザ - ユーザ]を選択します
- Analytics管理権限を付与したいユーザをクリックします
- [権限セットの割り当て] > [割り当ての編集]を選択します
- Einstein Analytics Plus システム管理者を追加します
- 保存します