OmniAICreator/Qiita-1.07M huggingface dataset:
リンク元のページのURL取得方法(リファラってなんやねん!!)

#リンク元のページのURL取得方法(リファラってなんやねん!!)
wordpressでリンク元のページのURLを取得する方法で少しつまった書きます！！
##リファラとは
リファラとは、あるWebページのリンクをクリックして別のページに移動したときの、リンク元のページのこと。 Webサーバのアクセスログに記録される項目の一つ。
##結論
```
wp_get_referer()
```
これで取り出せる
##もうちょっと具体的に
遷移前のpageが
http://localhost:8888/contact
であれば、

```php
$referer = wp_get_referer();
<p><?php echo $_SERVER['HTTP_REFERER']; ?></p>
```

![スクリーンショット 2020-11-05 15.30.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590181/71649c6f-d49f-58ad-d588-031729b54ee7.png)

上記のように表示される(お問い合わせは関係ない)

##ちなみに(その他の実装)
```
$_SERVER['HTTP_REFERER']
```
phpでは上記で実装できる。具体的には以下

```
<p><?php echo $_SERVER['HTTP_REFERER']; ?></p>
```

どちらでも実装できるが、wordpressの場合はwordpress指定のものを使うべきである。はず、、

##最後に
もっと良い実装方法や誤り等あれば、ご指摘いただければ幸いです。
Raspberry Pi3をインターネットに公開する

#はじめに
ラズベリーパイ３はハードディスク起動ができます。WEBサーバーとしての実力を試したくてインターネットに公開してみました。

#前提
筆者はBroad WiMAXの回線をつかっています。

#グローバルIPアドレス
なんと月額96円（税抜）でグローバルIPアドレスが払い出されます。しかもルーターで接続先設定(APN)をするだけ！
https://faq.wimax-broad.jp/faq/show/165?back=front%2Fcategory%3Asearch&category_id=12&commit=&keyword=%E3%82%B0%E3%83%AD%E3%83%BC%E3%83%90%E3%83%AB&page=1&site_domain=customer&site_id=2&sort=sort_keyword&sort_order=desc&utf8=%E2%9C%93

グローバルIPアドレスが取得できたらラズベリーパイ３をDMZに設定します。

#DDNS
Broad WiMAXのグローバルIPアドレスは都度変更されるためDDNSに登録します。MyDNS.JPを利用する事にしました。
http://www.mydns.jp/

```
# cat /etc/cron.hourly/mydns
#!/bin/sh
wget -O - 'https://mydnsXXXXXX:PASSWORD@www.mydns.jp/login.html'
```

#SSLサーバ証明書
Let's Encryptを利用する事にしました。

```
# apt install certbot python-certbot-apache
# certbot certonly --webroot -w /var/www/html/ -d rp3.mydns.jp
```

以下を記載してapache2を再起動します。

```/etc/apache2/sites-enabled/000-default.conf
SSLCertificateFile /etc/letsencrypt/live/rp3.mydns.jp/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/rp3.mydns.jp/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/rp3.mydns.jp/chain.pem
```

#最後に
わかりずらい部分がありましたら追記いたします。
【Ruby】インスタンスとは何か

#インスタンスとは

結論：<strong>クラス（設計図）</strong>から作られた<strong>オブジェクト（完成品）</strong>のこと

もう少し具体的に掘り下げていきます。

##そもそもクラスとは？？
「クラス」と調べるとよく「設計図」に例えられています。
もう少し噛み砕くと、自分が行いたい処理を保管しておく箱のような存在です。
つまり、クラスという箱に処理を保管しておけば、いつでも簡単にその処理を呼び出すことができるのです。

クラスは下記のように定義できます。

```ruby:
class クラス名（一文字目は大文字）
end
```

そして、一般的にクラス内では`initialize`というメソッドを定義し、初期化します。

```ruby:
def initialize()
　初期化処理
end
```


では、実際にコードを書いてみます。下記に例を記載します。
今回はUserというクラスを作ってみましょう。

```ruby:
class User
  def initialize(name)
    @name = name
  end

  def introduction
    p "私の名前は#{@name}です。"
  end
end

user1 = User.new("mataro")　#newでインスタンス化し、引数（"mataro"）を渡す。
user2 = User.new("taro")　　#newでインスタンス化し、引数（"taro"）を渡す。
user1.introduction　#出力結果：”私の名前はmataroです”
user2.introduction　#出力結果：”私の名前はtaroです”
```

このように`class`で処理を定義し、`new`でインスタンス化を行うことで、クラスから完成品（インスタンス）を生み出すことができるようになるのです。
Railsで開発したアプリをGithubにPushする方法

#Railsで開発したアプリをGithubにプッシュする方法

ruby 2.6.6
rails 6.0.3.4
mac os

プッシュしたいローカルディレクトリに移動

```
 ＄　cd sample_app
```
プッシュの準備（？）

```
＄ git init
$ git add .
```

Githubのプッシュ先のレポジトリを指定
＜URL＞= レポジトリのHTTP
![スクリーンショット 2020-11-07 午後2.50.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763647/50de8162-b633-6b77-5e29-e4ae7ca04f8f.png)


```
$ git remote add origin <URL>
```

GitHubにプッシュする
 "" = プッシュの内容

```
$ git commit -m "first commit"
$ git push origin master
```
Push完了
UIフローのガバナンスをCoE(センター・オブ・エクセレンス）で高度化


皆さんこんにちは、マイクロソフトの川端です。
Microsoft Power Automateの有用な情報を発信していきます。

#1. はじめに
Power PlatformにおけるガバナンスはCoE(Center of Excellence)という形で様々なベストプラクティスが提供されています。
このCoEによって、アプリ、フロー、チャットボットの作成、利用状況が一覧で可視化され、組織内での効率的、かつセキュアな形での管理が可能になります。

今回のアップデート(2020年11月時点）により、CoEの機能向上がなされ、UIフロー内のPower Automate Desktopの利用状況を管理者が把握し易くなりました。

#2. Power Automate Desktopで作成されたフロー、利用状況が一目瞭然！
Power Automate DesktopはPower Automteクラウドサービス内の"環境"で管理されています（RPAにおけるOrchestrator機能が標準で具備）。
今回のアップデートにより、Power Automate Desktopで作成されたフロー、実行されたフローの数や実行状況、エラー状況も含め、一元的に可視化され、参照することができるようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/808554/d7b66705-48be-699d-ff79-891c0c83b416.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/808554/8382d634-4ea8-944f-a918-e515801d7a68.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/808554/3f9d865b-5420-e441-def1-2507b579bc18.png)

(引用元）
https://docs.microsoft.com/ja-jp/power-platform/guidance/coe/power-bi-monitor#ui-flows

#3. まとめ
Power Automate Desktopを含むUIフローのガバナンス機能の強化について、2020年11月時点のアップデート内容をお伝えしましたが、CoEではPower Apps, Power Virtual Agents, 利用コネクタの使用状況などが、[CoE Starter Kit(センター・オブ・エクセレンス・スターターキット）]という形でテンプレート化され[GitHubから一般提供されています]。

こちらはPower Platformの導入が進み、運用の過渡期で必要なガバナンス機能をテンプレート化して提供しているもので、お持ちのPower Platform有償ライセンス内で構成可能となっています。

ぜひ導入をご検討してみてください！

[CoE Starter Kit(センター・オブ・エクセレンス・スターターキット）]:https://docs.microsoft.com/ja-jp/power-platform/guidance/coe/starter-kit

[GitHubから一般提供されています]:https://github.com/microsoft/powerapps-tools/tree/master/Administration/CoEStarterKit
機械学習の評価指標（Accuracy, Recall, Precision）インフォグラフィック

Accuracy, Recall, Precision, Specificityの関係を説明するためにインフォグラフィックを作りました。
Specificityはあまり使われないので薄く描いています。

![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704329/eb8f6f5f-5a88-4000-9cb1-b87c12277616.png)
Golang で Word の内容を取得してみる

#  はじめに

普段よく Golang でちょっとした社内ツールを開発しています
先日、後輩からこんな相談を受けました
「毎週、Word で書かれたドキュメントを Excel に貼り付けてまとめるだけの作業があるんです...」

**「しかも、`.docx` と `.doc` が混在しているんです...」**

Oh...

調べてみたところ、良さげなパッケージを見つけたため使ってみました


## [code.sajari.com/docconv](code.sajari.com/docconv)

Word のファイルをただ読み込んでコンソールに出力するだけのプログラム

```go
package main

import (
	"fmt"
	"log"
	"os"
	"path/filepath"
	"strings"

	"code.sajari.com/docconv"
)

// WordContent Word のファイルから取得した内容を保持
type WordContent struct {
	body string
}

// String fmt.Println() で出力する時に呼ばれる
func (wc *WordContent) String() string {
	return strings.TrimSpace(wc.body)
}

// FileRead filename で指定されたパスのファイル読み込み、そのコンテンツを返す
func FileRead(filename string) (*WordContent, error) {
	f, err := os.Open(filename)
	if err != nil {
		return nil, fmt.Errorf("fail to open file: %v", err)
	}
	defer f.Close()

	switch filepath.Ext(filename) {
	case ".docx":
		content, _, err := docconv.ConvertDocx(f)
		wc := WordContent{content}
		return &wc, err
	case ".doc":
		content, _, err := docconv.ConvertDoc(f)
		wc := WordContent{content}
		return &wc, err
	}
	return nil, nil
}

func main() {
	filename1 := "samples/sample.docx"
	wc, err := FileRead(filename1)
	if err != nil {
		log.Fatalln(err)
	}
	fmt.Println(wc)

	fmt.Println("----------------")

	filename2 := "samples/sample.doc"
	wc, err = FileRead(filename2)
	if err != nil {
		log.Fatalln(err)
	}
	fmt.Println(wc)
}
```



ポイントは、拡張子によってファイルを読み込むメソッドが違うという点くらい

- `.docx` -> `docconv.ConvertDocx()`
- `.doc` -> `docconv.ConvertDoc()`

うまくいくといいね
英語テキストに対して品詞タグ付けがしたい．RNNTagger編

公式の解説
https://www.cis.uni-muenchen.de/~schmid/tools/RNNTagger/

#導入
ダウンロード

```
!wget 'https://www.cis.uni-muenchen.de/~schmid/tools/RNNTagger/data/RNNTagger-1.2.zip'
!unzip 'RNNTagger-1.2.zip'
```


#テスト

```
%cd RNNTagger
!echo "This is a test." > test.txt
!cmd/rnn-tagger-english.sh test.txt
```


```
#結果
This	DT	this
is	VBZ	be
a	DT	a
test	NN	test
.	.	.
```
Scrum Fest Sapporo Day 2 参加レポート「アジャイルな組織を創っていくには？地銀で取り組むアジャイルな組織創り」

# Scrum Fest Sapporo Day 2 「アジャイルな組織を創っていくには？地銀で取り組むアジャイルな組織創り」
 
2020/11/07に開催されたScrum Fest Sapporoの発表です。
https://confengine.com/scrum-fest-sapporo-2020/proposal/14062
 
# チーム参加してきました
 
[aslead Agile](https://aslead.nri.co.jp/solution/aslead_agile.html) のチーム「[オキザリス](https://speakerdeck.com/viva_tweet_x/huesudeyong-qi-wode-taxin-gui-timugashi-yan-wozao-rifan-sitejin-nizhi-rumadefalsewu-yu?slide=3)」にて参加してきました。
チーム7人中、1人で参加して、その場で実況しつつ、記事も作っています。


# 発表について
RSGT2020を圧縮＋その後のこと＋その後の観点を盛り込んで発表する。
また、エピソードを紹介し、そこから得た知見・考えを発表する。

# 自己紹介
- 福岡の地銀で2018年からアジャイル開発に携わる
- 現在スクラムマスター 

# RSGTの振り返り
アジャイル組織を作っていくためには自分自身や自チームからやっていかないといけない。
以前は無駄な時間、コストがとても多かった。
また、WEBサービス開発するのに経験者がまったくいない状態からのスタートということでプレッシャーもあった。

### エピソード１・期待の新戦力
経験者が入ってくるという話があり期待していたが実際は未経験者だった。
素人集団にさらに素人が入ってくるということで絶句。
育成が必要だが、自分たちも育成段階だったため、ペアプロをやってみた。

**実際やってみたら**
作業量は大して変わらないのに知識の共有ができ、２人で実装することにより不安も減った。

**ポイント**
ダメだったら辞めればよいという考え。
気軽にやって、試してみることが大事。
また、それを振り返ることも大事

**その後**
人数が増えてきたのでモブプロにも挑戦。
現在ではソロ・ペア・モブなど使い分けを行っている。

### エピソード２・プッシュ戦争
他チームからプッシュされるという情報がありチームがざわつく。
プッシュされたものがコンフリクトした場合には遭遇したチームが直すことになり、しかもボリュームが多いため。
プッシュされたものが動くかどうかの保証がない状態で引き渡されるため、結果責任が持てないし、チームとしての活動ができていない状態になってしまう。
→　**CI（Continuous Delivery）を導入**

**導入前は**
・問題が起きたら誰かが解決するはず
・コミュニケーションが希薄

**実際やってみたら**
問題に全員で対応するようになり、コミュニケーションも増加した

**ポイント**
問題が自分ごとになってから、どうするか考える
SMが問題を解決しすぎるのではなく、どう解決していくかをみんなで考えるのが大事

**その後**
TDDに挑戦→ATDDにも挑戦→フロント、バック分けずに挑戦し、現在はインフラにも挑戦


### エピソード３・兼任するってよ
兼任問題。開発しながらスクラムマスターを兼務してほしいと言われ、やってみた。
スクラムマスターとしてよりも、開発に集中してしまう。
また、ちょこちょこ抜けるので開発メンバーも気を遣う状態に。
そんな状況にも関わらず、本人は出来ていると考えている。
結果、入っていたコンサルなどから戦力外通告されてしまう。

**スクラムマスターは専任しよう！**
CSMの取得。
スクラムマスターを専任でやることで、兼任スクラムマスターを作らない風潮ができた。


### エピソード４・チーム崩壊
なんだか楽しくなさそうだよね、と周囲から言われるようになった。
「ならもっと楽しくやってやるぜ」という雰囲気となる。
その結果、
「楽しくやろう」から「面白ければいい」という雰囲気になり、真剣さ、規律が欠如してしまった。
また、それを指摘すると「雰囲気悪くなるからやめてください」と言われてしまう始末。

**ポイント**
・チームの意見を尊重することとチームに配慮することは違う。
・自律的なチームと自立的なチームは違う。
・リーダーシップの使い分けも必要。
　サーバントなだけではなく、いろいろなリーダーシップを使い分けよう。

これらを正しく理解しながらチーム活動することが大事。


# その後のチーム
入っていたコンサルから卒業して、自分たちだけで活動中。
銀行の文化はコンサルが入ってるのが普通だが、そこから卒業できたのはチームとしての１つの大きな成果。

# さらに追加の話
（ここで時間が来てしまったので３分延長し、重要な点を説明いただいた）
### エピソード６・板挟み
他チームを巻き込むうえでの重要なポイント。
ある程度他チームを巻き込んで進められているときに、チームメンバーからプロダクトチームと組織から求められていることにギャップがあるのではないか指摘があった。

**ポイント**
ボトムアップで成し遂げるだけでなく、トップも巻き込もう！
上司が協力してくれたり、組織の理解を得ることが大事。
そこをケアして進めていくことで、求められていることの乖離というものがなくなっていく。

# 感想
（チーム全員の感想です）

- 地銀というアジャイルを取り入れるというチャレンジングな取り組みにまず驚きました。おそらくアジャイルを組織で始めるまでにも様々な苦労があったのだろうと思うと脱帽です。ぜひエピソード０としてお聞きしてみたいです。
- チームが成長する過程で挙げられた様々な課題は我々が遭遇しそうなことばかりで、業界は関係ないのだと感じます。「XXの業界はアジャイルやるには難しい」と頭から決めつけるのではなく、どう我々の業務にフィットさせていくのかを考えることが大事だなと感じました。
チームでイベント参加して学びを最大化してきた話

# チームでイベント参加して学びを最大化してきた話

こんにちは
島田です。

私が所属しているチームで一緒に共通のイベント（Scrum Fest Sapporo）に参加してきました。
チームでイベントに参加するにあたって、学びを最大化するためにどのように参加してきたかを共有したいと思います。

チームでのイベント参加は、メンバーで共通言語を持ち学びを深められる良い方法だと思うので、参考になれば幸いです。
[aslead Agile](https://aslead.nri.co.jp/solution/aslead_agile.html) のチーム「[オキザリス](https://speakerdeck.com/viva_tweet_x/huesudeyong-qi-wode-taxin-gui-timugashi-yan-wozao-rifan-sitejin-nizhi-rumadefalsewu-yu?slide=3)」にて参加してきました。

# はじめに
この記事では、個々のセッションの内容には触れません。
参加セッションごとの記事は別途公開しているのでそちらをご覧ください。

[Scrum Fest Sapporo Day 1 参加レポート「アジャイルに向かう組織に聴いてほしいアジャイルへの第一歩」](https://qiita.com/viva_tweet_x/items/095daeed7a185a44c1f6)
[Scrum Fest Sapporo Day 1 参加レポート「日本にJoy,Incを創る！どん底からスタートしたぼくらのジョイインクジャーニー7年間の軌跡　Scrum Fest Sapporo特別編」](https://qiita.com/r2-oishi/items/5240f6adf99a87fc3bd2)
[Scrum Fest Sapporo Day 1 参加レポート「ゼロからつくったリモートスクラムチームはスクラムに挫折し解散しました」](https://qiita.com/shima-d/items/95ad35e88f82cad3097f)
[Scrum Fest Sapporo Day 1 参加レポート「もりあがるスプリントレビューをしよう」](https://qiita.com/shiasa/items/1ed4e3b69d44f85593bc)
[Scrum Fest Sapporo Day 1 参加レポート「これまでと違うやり方に取り組む時にうまくいくかもしれない方法とその落とし穴」](https://qiita.com/kimagre_human/items/20691dab69e0883ca984)
[]()
[]()


# イベント参加前〜準備編〜
効果的にイベントの参加できるように、私達のチームではイベント参加前に以下のような準備をしていました。

- 参加セッションを事前に決めておく
- 参加時のメモを取る準備をしておく

## 参加セッションを事前に決めておく
参加セッションを事前にチームで決めておくことでスムーズな参加が可能です。
Scrum Fest Sapporo2020はオンラインで実施されたため、オフラインでチームメンバーとの会話しながらの参加が難しいです。
そのため、事前に参加セッションを表明しておくことで、誰がなんの話を聞いているかが把握でき、あとから話を聞きやすくなります。

## 参加時のメモを取る準備をしておく
参加セッションがはじまってからメモ環境を整えているようでは大事な内容を聞き逃してしまいます。
メモなど記録する準備は事前に済ませておきましょう。
私達のチームでは日々の業務でConfluence（いわゆるWikiツール）を使用しており、事前準備としてイベント参加メモ用のConfluenceのページを作成しておきました。


# イベント参加中〜激闘編〜
いよいよイベント参加当日です。
イベント参加時は”チーム”としての学びを最大化するための以下の点を意識しながら参加しました。

- 発表内容を聞きながら思ったこと／感じたことをチームで共有する／チームで発表メモを取る
- アウトプット前提で参加する

それぞれ意識した点について、具体的にどのような方法で実践したかをご紹介していきます。

## 発表内容を聞きながら思ったこと／感じたことをチームで共有する／チームで発表メモを取る
すでに書いたように、私達のチームでは日々の業務でConfluecneを利用しています。
Confluenceには共同編集機能があり、イベント参加時はこの機能が真価を発揮します。

私達のチームで実際にどのようにConfluenceを使っていたかをご紹介します。

### 全員で同一セッションに参加
全員で同一セッションに参加する場合はページを

- 実況用（思ったこと、感じたこと、メモを自由に書いていく）
- Qiita用（記事として発信するよう）

に左右２分割し、交代でどんどん書いていきます。
![スクリーンショット 2020-11-07 14.29.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/754254/fb74f3f7-9591-e5e5-9b89-9621ca73b20e.png)

発表内容を聞きながら書いていくため、話すことができません。
交代の合図はテキストベースで「疲れた交代して」「次書いてくねー」といった形で意思表示をします。
常日頃モブワークをしているため、私達のチームではシームレスに交代することができます。



### メンバーが２セッションに分かれて参加
それぞれのメンバーが参加したいセッションに参加するため、ときには参加セッションが分かれることもあります。
そんなときは画面を３分割し左から

- セッション１ Qiita用
- 実況用
    - 実況用のエリアに２列の表を用意し、セッションごとに同じ列にどんどん書いていきます。
- セッション２　Qiita用

を書いていきました。
![スクリーンショット 2020-11-07 14.30.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/754254/ef206a2c-38ff-0fbb-c68d-bc1fc06a68f5.png)



あとは２分割同様に、適宜交代しながら思ったことなどをどんどん書いていくだけです。


## アウトプット前提で参加する
インプットで終わらせず最大限理解を深めるために、アウトプット前提でイベントに参加します。
すでに書いたように実況しながら参加するのも１つのアウトプットであり、この記事を書いていることも１つのアウトプットです。
参加後に参加セッションについて会話することもアウトプットになるかと思います。

# イベント参加後〜追いつき学習編〜
イベント参加後は、参加できなかったメンバー含め感想戦をしていきます。
イベント参加後の記事についてはまたの機会に。


# まとめ

チームでイベントに参加することで、雑談をしながら理解を深めたり、重複して参加できなかったセッションの話を聞くことができます。
チームビルディングの１つの方法としてよいのではないでしょうか。
RspecでCapybara js: true を入れるとCould not find Firefox binary (os=macosx)というエラーが出る

#エラー内容
```
Could not find Firefox binary (os=macosx). Make sure Firefox is installed or set the path manually with Selenium::WebDriver::Firefox::Binary.path=
```

Firefoxがダウンロードされていないよというエラーが出ます。
#解決法
仮想環境でアプリケーションを作成してない人はMacOSだと

```
brew cask install --appdir="/Applications" firefox
```
でfireboxをダウンロードすればOKです。

#ここからが自分が詰まったところ
自分の場合Vagrant環境でアプリケーション作成していたので上記のコードを実行しても
VagrantにはMacOSを使用して構築してないため
`command not found`がでる。
それに気付くのに20分程かかりました😭
自分のVagrant環境はCentOSであった為CentOSのやり方でfireboxダウンロード
ダウンロードの仕方は下記参考
https://qiita.com/snow_rain000/items/551e35e76b92df06f7ea

#エラー解決と思ったら
fireboxをダウンロードして`bundle exec rspec`を実行すると

```
selenium::webdriver::error::unknownerror: process unexpectedly closed with status 1
```
というエラーが出ました。
エラー内容の原因としてはselenium::webdriverが正しく動いてないようでしたので

```ruby:rails_helper
Capybara.register_driver :selenium do |app|
  options = Selenium::WebDriver::Chrome::Options.new

  options.add_argument('--no-sandbox')
  options.add_argument('--headless')
  options.add_argument('--disable-gpu')
  options.add_argument('--disable-dev-shm-usage')
  options.add_argument('--window-size=1680,1050')

  Capybara::Selenium::Driver.new(app, browser: :chrome, options: options)
end
```
をrails_helperに記載すると、テストが通りました！！！
他にも`gem 'capybara'` `gem 'selenium-webdriver'` `gem 'webdrivers'`を最新版に`bundle update`して、chromeをダウンロードしたり色々やったので上記で失敗した場合は試してみてください。

#最後に
一時間くらいかかりました😭
本当に解決できてよかったです。
他の人がエラー出た際にこの記事で解決できるように祈っています。
hooksのuseStateの使い方メモ

※hooks は React 16.8以降で追加された機能

```
import React, { useState } from 'react';  // useStateをインポート

export default function App() {
  const [outputText, setOutputText] = useState('初期値');  　
  //useStateの引数はstateの初期値　定数outputTextに格納される
　//setOutputText('変更後の値')でstateを変更できる

  return (
    <View style={styles.container}>
      <Text>{outputText}</Text>
      <Button title="Change Text" onPress={() =>  setOutputText('The text changed!') } />
    </View>
  );
}
```

### TextInputを使う場合

```
const GoalInput = props => {

  const [enteredGoal, setEnteredGoal] = useState('');

  const goalInputHandler = (enteredText) => {
    setEnteredGoal(enteredText);
  };

  return(
    <TextInput 
      onChangeText={goalInputHandler}
      value={enteredGoal}
    />
  )
}
```
引数enteredTextに暗黙的にtextへの入力値が渡されているようだ。

###コールバック関数を引数にした場合
ButtonタグのonPressメソッドでaddGoalHandlerが発火するようなシチュエーション。

setCourseGoalsの引数にコールバック関数を入れた場合、
引数currentGoalsにはcourseGoalsの値が渡っているようだ。（goalTitleはinputTextからの値）

```
  const [courseGoals, setCourseGoals] = useState([]);
  const addGoalHandler = goalTitle => {
    setCourseGoals(currentGoals => [
      ...currentGoals, 
      { id: Math.random().toString(), value: goalTitle }
    ]);
    setIsAddMode(false);
  };
```
AWSのストレージサービスを学ぶ前に知っておきたい用語

AWSのストレージサービスを学ぶに当たり最低限、理解しておきたい用語をまとめました。

# HDD(Hard Disk Drive)

- データやプログラムを記録したり、読み出したりする**補助記憶装置**。
    - 補助記憶装置とは、記憶装置の一つ。
    - CPUが直接アクセスする**主記憶装置**以外の記憶装置を指す。
    - 主記憶装置の容量不足を補う。
    - データやプログラムを長期間保存する。
    - ストレージとも呼ばれる。
- 機会的な駆動部分が多く、構造的に衝撃に弱い。
- 消費電力が大きい。

# SSD(Solid State Drive)

- HDDと同様、補助記憶装置。
- フラッシュメモリを記憶媒体として内臓する。
- 機械的な駆動部分が少なく、構造的に衝撃に強い。
- 消費電力が小さい。
- 読み書きが高速。
- HDDに比べてビットあたりの単価が高い。

# ファイルストレージ

- ディレクトリ形式で階層的にデータを保存するストレージ形式。
- ファイルレベルまたはファイルベース・ストレージとも呼ばれる。
- 一意のパスを用いて階層を辿る形で、データへアクセスする。
- 大規模なデータ利用や構造化できないデータの管理には不向き。
- データ容量の増加に伴い、ハードウェアマシンへのリソース要求が大きくなる。
- ファイル名、作成日、サイズ、データの種類など最低限のメタデータしか付与することができない。

# ブロックストレージ

- 記録領域をボリュームという単位で分割して、その内部を固定長のブロックに切り出してデータを保存するストレージ形式。
- 各ブロックには一意のIDが付与される。
- 保存するデータがブロックのサイズを越える際には複数のブロックにまたがってデータが保存される。(ブロックが連続する必要はない)
- 読み込むデータへのパスの複数指定が可能であり、階層構造を必要としないため高速なアクセスを行うことができる。
- 価格が高価で、メタデータを付与することができない。

# オブジェクトストレージ

- データをフラットなアドレス空間にオブジェクトとして保存するストレージ形式。
- オブジェクトベース・ストレージとも呼ばれる。
- カスタマイズ可能なメタデータをもとにしたデータのグループ分けが可能。
- インデックスの作成が容易に行える。
- 仮想化の技術を用いて物理的に離れた複数のサーバーを並列化して、一つのストレージプールとする分散ファイルストレージ形式での構成が可能。
- オブジェクトの更新ができない。
- オブジェクトストレージAPIを使用する必要がある。

# 参考

[ファイルストレージ、ブロックストレージ、オブジェクトストレージの比較](https://www.redhat.com/ja/topics/data-storage/file-block-object-storage)
[オブジェクトストレージ、ファイルストレージ、ブロックストレージの違いとは？｜用語集｜SBクラウド株式会社 - SBクラウド株式会社](https://www.sbcloud.co.jp/entry/difference-between-object-storage-file-storage-block-storage)
Alpine docker image上で、golangのタイムゾーン変換を行うと、JSTが+0000 +0000と変換されてしまう問題調査

## はじめに
ちょっとマニアックなバグを引いたので、これはOSSに貢献できるかな？と思い、調査記録をまとめます

## 事象

- alpineのdocker image上で動作するgolangの時刻を変換する処理で、 `2020-11-08 00:04:05 +0900 JST` のようにJSTのタイムゾーンで変換されるはずの時刻が `2020-11-07 15:04:05 +0000 +0000`となる
    - golang: 1.12.4でbuild
    - alpine: latest (2020年10月末時点)→3.20?
    - tzdata: latest (2020年10月末時点)→tzdata2020d-r0?

そのほかの事実として以下が挙げられます

- 10月半ば頃までは動作していた
- zoneinfoを差し替えるとうまく動作する
- ちょうど10月25日にalpineのtzdataがアップデートされていた ([alpine tzdata](https://pkgs.alpinelinux.org/package/edge/main/x86/tzdata), [commit](https://git.alpinelinux.org/aports/commit/?id=fbc0b7dac48b9df9d3b9a04e514b6445b75f2e52)より)

## 検証

検証時点でtzdata2020dが使えなかったのでtzdata2020c-r0での検証となりましたが、結論は以下です。

- **golang1.12でビルドしたバイナリで、alpine && tzdata2020c-r0, tzdata2020d-r0を使うとJSTの変換ができない** という結果になりました。

調査用のリポジトリ([alpine_tzdata_investigation](https://github.com/developer-kikikaikai/alpine_tzdata_investigation)を使って、Dockerを使っていくつかのversionの組み合わせを確認。(Dockerfileでversion指定しなかったものは、notesに確認方法を記載しています。)

|go version|docker image|tzdata|result|note|
|:----|:-----|:----|:----|:---|
|go 1.12|alpine 3.12.1|tzdata 2020c-r0|failure|versionは[dockerhub](https://hub.docker.com/_/alpine)および[alpine package](https://pkgs.alpinelinux.org/packages?name=tzdata&branch=v3.12)で確認|
|go 1.12|alpine 3.10.3|tzdata 2020c-r0|failure||
|go 1.12|alpine edge|tzdata 2020d-r0|failure||
|go 1.12|alpine 3.8|tzdata 2020a-r0|success|2020aを使用しているのがalpine 8までだったため|
|golang 1.12|ubuntu 20.04|tzdata 2020d-0ubuntu0.20.04|success|versionは[dockerhub](https://hub.docker.com/_/ubuntu)および[Ubuntu packages](https://packages.ubuntu.com/focal/tzdata)で確認|
|golang 1.15.4(alpine)|alpha 3.12.1|tzdata 2020c-r0|success|golang versionは[golang dockerhub]で確認|
|golang 1.13|alpine 3.12.1|tzdata 2020c-r0|success||

結果、
- go 1.12でもubuntuやalpine && tzdata2020aなら通る
- alpine && tzdata2020c-r0, tzdata2020d-r0でもgolang 1.13以降なら通る

ことがわかります。

## 対処
1. goもしくはalpineのversionを変える
2. どうしても両者を変えたくない場合は、tzdataを差し替える([sample](https://github.com/developer-kikikaikai/alpine_tzdata_investigation/blob/master/Dockerfile.success.usetzdata-2020a))
【Java】static修飾子の使い方(static final, static importとは)

#プログラミング勉強日記
2020年11月7日
Javaのstatic finalやstatic importを理解していなかったので、static修飾子についてまとめる。

#static修飾子とは
　クラスをインスタンス化せずに直接メソッドや変数にアクセスするために使用する。staticを付けたメソッドを静的メソッド、変数を静的変数という。

#static classの使い方
　Javaではstatic classはクラスの中にクラスを定義する内部クラス(インナークラス)で使用する。内部クラスからは外部クラスの変数などのメンバーにアクセスできる。内部クラスにstatic修飾子を付けると、外部クラスのstaticなメンバーにのみアクセスできるようになる。

　※他の言語ではclassにstatic修飾子を付けることで、インスタンスを生成できない静的クラスを作れるが、Javaだとコンパイルエラーになるので注意する。

#staticメソッドとstatic変数の使い方
　staticメソッドはメソッドにstatic修飾子を付けることで、newを使ってインスタンスを生成することなく呼び出すことができるメソッドのことで、メソッドを呼び出すときに毎回インスタンスを生成する必要がなくなるのでコードを短く書ける。

　static変数は変数にstatic修飾子を付けることで、その変数が含まれるクラスをインスタンス化せずに変数にアクセスできるようになる。static変数はそのクラスから生成されたすべてのインスタンスで共有される値なので、グローバル変数のように使える。

#static finalとstatic importの使い方
　static finalは変数の値を変更されたくない場合に使用し、<b>値の変更ができない定数</b>にすることができる。staticイニシャライザを使って複数の定数を初期化する方法やListやMapを定数で使用する方法などがある。

　static importは外部クラスのstaticメンバの参照を簡略化するための機能。メソッドや定数の呼び出しが簡略化されて、簡潔なコードで処理を記述できるようになる。

#参考文献
[【Java入門】static修飾子の使い方総まとめ](https://www.sejuku.net/blog/24797)
nem catapult バイト列構造置き場 0.10.0.x編

Alpaca
https://qiita.com/planethouki/items/e1c153f9ea395ce0e8e6
Bison
https://qiita.com/planethouki/items/d22da901e5f71a366302
Cow
https://qiita.com/planethouki/items/bd21182f06b69df1ce35
Dragon
https://qiita.com/planethouki/items/75dc1d685438218a72cd
0.10.0.x
https://qiita.com/planethouki/items/c926905e9fde4c6ef68b

# Transfer Transaction


| 項目 | サイズ | 意味 |
|:----:|:------|:------|
| サイズ | 4byte(LE) | トランザクションのバイト数 |
| 予約 | 4byte | 未使用 |
| 署名 | 64byte | トランザクションへの署名 |
| 公開鍵 | 32byte | 署名者の公開鍵 |
| 予約 | 4byte | 未使用 |
| バージョン | 2byte(LE) | バージョンID＋ネットワークID |
| タイプ | 2byte(LE) | `5441` |
| 手数料 | 8byte(LE) | 手数料 |
| 期限 | 8byte(LE) | 期限 |
| 受取人 | 24byte | 受取人アドレス |
| msg size | 2byte(LE) | メッセージバイト数＋１ |
| num mosaics | 1byte | モザイクの種類数 |
| 予約 | 4byte | 未使用 |
| 予約 | 1byte | 未使用 |
| mosaics | - | 下表が`num mosaics`分続く |
| msg type | 1byte | メッセージタイプ |
| msg payload | 可変 | メッセージ本文 |


| 項目 | サイズ | 意味 |
|:----:|:------|:------| 
| mosaic id | 8byte(LE) | モザイクID |
| amount | 8byte(LE) | 量 |

```text:sample
// size
BD000000
// reserve
00000000
// sig
E9E8CEC7F4BC3836A692A293AB617134F2E787138769F63993CCA32FD413B3737A999F785B7E3FE92EAA5C676DB7ADB5355D867D449333BF9976730494B2ED04
// pub
5E89AED43BAC01105952EC4A1EC7F722EE087A0E092E32FB4E45E937A391CF56
// reserve
00000000
// version + network
0198
// type
5441
// fee
204E000000000000
// deadline
F07CCB4907000000
// recipient
983E8C8EDC36E3CEE6F4A2083A9A6DE9480454520E2D44B3
// msg size + 1
0D00
// num mosaics
01
// reserve
00000000
// reserve
00
// mosaic id or namespace id
EEAFF441BA994BE7
// amount
E00947F80D000000
// message
0074657374206D657373616765
```

参考
https://github.com/nemtech/catbuffer/blob/45478ad9c50af59b8bc91eec2e57af5bf321c3bc/schemas/transfer/transfer.cats
RubyMineを導入後に設定すべきこと

最近RubyMineを導入したので自分が設定したことを列挙してこうと思います。
随時更新していく予定です。

# 日本語化プラグインを導入する
メニューバーのPreferences→Pluginsを開き、「Japanese Language Pack EAP」というプラグインを導入する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403521/5cd3527b-37dd-2cc2-371b-65e78f52dafe.png)

(まだアーリーアクセスなので英語のとこもちょいちょいあるが、普通に使っている分には問題なく使える。)

# RubyMineの設定変更

### 開いているファイルを常にプロジェクトビューで表示する
左側のプロジェクトタブを開き、上部の三点リーダーみたいなメニューを開いて以下のチェックを入れる

![スクリーンショット 2020-11-07 14.23.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403521/1c81fac4-aa21-62b9-6a6e-2c3fa5fbde1c.png)

### 

# テーマの設定
自分にあったテーマを導入する。
もちろん自分でカラースキーマを1から設定するのも良いと思うが、いろんなテーマが公開されているので、まずは自分の好みのテーマがないかどうかを調べてみた方が良いと思います。
以下はおすすめのテーマ、アイコン設定プラグインです。

- https://plugins.jetbrains.com/plugin/8006-material-theme-ui
    - マテリアルカラーのテーマ。アイコンも設定されるらしいが自分が導入したときは反映されなかったので別途以下のプラグインを入れた。
- https://plugins.jetbrains.com/plugin/10044-atom-material-icons
    - マテリアルアイコンのプラグイン。Railsのアイコンが紫なのが気に食わないがそれ以外は神。


自分で設定する場合
ファイル名の色はPreferences→Version Control→File Status Colorsで変えられる。
https://intellij-support.jetbrains.com/hc/en-us/community/posts/206694189-Where-can-you-change-the-color-of-the-filename-text-on-a-tab-that-is-opened-

# インタプリタの設定
以下のリンクを参考に自分の環境にあったインタプリタの設定をする。
そうしないとgemのメソッドなどを見つけてくれないので必須。

- https://www.jetbrains.com/help/ruby/2020.2/configuring-language-interpreter.html?utm_source=product&utm_medium=link&utm_campaign=RM&utm_content=2020.2#add_local_ruby_interpreter
【GAS】GAS⇒HTML変数の受け渡しをする方法

Google Apps Scriptで変数の受け渡しをする方法がとうとう分かった！
`HtmlService.createTemplateFromFile()`を使う。

```コード.gs
function doGet() {
  var template = HtmlService.createTemplateFromFile('index');
  template.text = '変数の受け渡しが成功しました！';
  return template.evaluate();
}
```
```index.html
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <h1><?=text?></h1>
  </body>
</html>
```
そしてウェブアプリケーションとして導入すると...
変数の受け渡しができていて「変数の受け渡しが成功しました！」が表示されている:thumbsup:
ClapackをVisual Studio で使う

lapackを授業の課題で用いることになった。コマンドプロンプトがよくわかってないので何とかしてVisual Studioでやってみた。

#始めにやったこと
Clapackをダウンロード (Netlibから)
(http://icl.cs.utk.edu/lapack-for-windows/clapack/)
Visual Studio 2017ではバージョン的に不可能なので(_imp_iob_func?が未解決のシンボルらしい　詳しいことはわからないので教えてください。)
Visual studio 2013 express desktopをダウンロード。

# ライブラリの導入
Clapackのinclude,libディレクトリを設定する。
(includeには~.hが入っているディレクトリを配置、libには~.libが入っているディレクトリを配置する。）
(includeはプロパティ→c/c++/一般から)
(libはプロパティ→リンカーから)
libの追加ライブラリは blas.lib libf2c.lib lapack.lib

私はここを参考にしました。より詳しい内容が書かれている素晴らしい記事です。
[Corgi.Lab] 
(https://corgi-lab.com/windows/vs-external-library/)



#注意
コードを書くときは, f2c.h　→clapack.hの順で書く。　逆で書くとなぜかエラー


#出来ました~

ソースコード（写しただけなのであんまり意味ないですが)

```
#include<stdio.h>
#include "f2c.h"
#include "clapack.h"

	/* 3x3 matrix A
	* 76 25 11
	* 27 89 51
	* 18 60 32
	*/
	doublereal A[9] = { 76, 27, 18, 25, 89, 60, 11, 51, 32 };
	doublereal b[3] = { 10, 7, 43 };

	integer N = 3;
	integer nrhs = 1;
	integer lda = 3;
	integer ipiv[3];
	integer ldb = 3;
	integer info;

	dgesv_(&N, &nrhs, A, &lda, ipiv, b, &ldb, &info);
	if (info == 0) /* succeed */
		printf("The solution is %lf %lf %lf\n", b[0], b[1], b[2]);
	else
		fprintf(stderr, "dgesv_ fails %d\n", info);
	return info;

	/*ctrl+f5でデバッグ*/

```
kintone Advent Calendar リンク集

過去の kintone Advent Calendar のリンク集です。

# 2023

https://qiita.com/advent-calendar/2023/kintone

# 2022

https://qiita.com/advent-calendar/2022/kintone

# 2021

https://qiita.com/advent-calendar/2021/kintone

# 2020

https://qiita.com/advent-calendar/2020/kintone

https://qiita.com/advent-calendar/2020/kintone2

# 2019

https://qiita.com/advent-calendar/2019/kintone

https://qiita.com/advent-calendar/2019/kintone2

# 2018

https://qiita.com/advent-calendar/2018/kintone

# 2017

https://qiita.com/advent-calendar/2017/kintone

# 2016

https://qiita.com/advent-calendar/2016/kintone

# 2015

https://qiita.com/advent-calendar/2015/kintone
【Rails】ActiveModel::Serializersでネストを明示したりしなかったり

# なにこれ
RailsのActiveModel::Serializersを使っている時に、
2つのjsonオブジェクトをrenderしたい時、片方だけにネストさせたり、あえてネストさせない方法を
自分への備忘録として書く記事です。

# この記事で得られること
Railsのメソッド内で下記みたいなコードを書く時に、ネストさせたいオブジェクトを
好きなようにいじくる方法を知れます。

```users_controller.rb
render json: { hoge: hoge, fuga: fuga }, include: :piyo
```

# 答え
Railsの`as_jsonメソッド`を使えば解決する！

# 環境
Ruby 2.6
Rails 6.0
active_model_serializers 0.10.10

# 前提
下記4つのモデルがあります。
- user.rb
- facility.rb
- product.rb

userとfacilityは1:N、
productモデルとuserモデルはアソシエーション組んでません。
今回はカラムは必要ないので省略。

```user.rb
class User < ApplicationRecord
  belongs_to :facility
end
```

```facility.rb
class Facility < ApplicationRecord
  has_many :users
end
```

```product.rb
class Product < ApplicationRecord
  # アソシエーションなし
end
```

# 状況
users#showアクションを呼び出した時に、
userとproductsオブジェクトの2つをrenderする必要があり、
userのネストしたオブジェクトも取り出す必要がある。

# 実際に遭遇したエラー

```users_controller.rb
  def show
    user = User.find(params[:id])
    products = Product.all
    render json: { user: user, products: products }, include: ['facility']
  end
```





上記のコードで書いてレスポンスを受け取る時、下記のエラーが発生します！

```
NoMethodError (undefined method `facility' for #<Product:0x00007fed8d885518>):
```
renderするjsonオブジェクトにincludeすることを明示しました。
でも、上記の書き方だと
userオブジェクトとproductsオブジェクトの両方にfacilityがネストされてしまう。
productsモデルとfacilityモデルはアソシエーションを組んでいないので、
当然そんなメソッド（モデル？）はないので、
Railsは「facility？そんなメソッド知らないよ！」と言ってしまう。

# じゃあどうするか
## 結論

変数を代入するタイミングでas_jsonメソッドを使ってjson整形して、
includeでfacilityモデルをネストすることを明示する。

```users_controller.rb
  def show
    user = User.find(params[:id]).as_json(include: 'facility')
    products = Product.all
    render json: {user: user, products: products}, status: :ok
  end
```
こうすることで、変数userだけにfacilityモデルをネストすることができます。

# 応用編
もし、「facilityモデルが不要なので、facilityモデルをネストさせないでデータを取得したい！」って時は、こうする。

```users_controller.rb
  def show
    user = User.find(params[:id]).as_json
    products = Product.all
    render json: {user: user, products: products}, status: :ok
  end
```

記述方法は分かったけど、正直なぜネストされないでjsonが整形されるかは分からないです。
勝手にネストされるときとネストされない時がある？
ここは要検証

おまけ：as_jsonのオプションは[ActiveModel as_json のオプション一覧](https://qiita.com/tmak_tsukamoto/items/b45cdc3ad6a0607534cb)という記事で詳しく解説してくれています。ありがたや〜

Railsのas_jsonメソッドの公式ドキュメントはこちら：https://railsdoc.com/page/as_json
rails g model 全体の流れ


環境構築がある程度完成して、アプリ開発に映ったらまずmodelとテーブルを作成。
モデルの作成の基本を簡単にまとめます。


## 基本の流れ
#### ①modelの作成
`rails g model [model名] column1:data型, column2:data型, ...`
※ model名はテーブル単数系
※ modelとテーブルは1対1
※ references型を指定すると、アソシエーションを設定できる
 ex. `rails g model [model名] [参照先]:*references*`
※ `rails g model`コマンドを実行すると、以下4つのファイルが自動生成される。うち、1と2は今回登場するのでよくおさえておく
```
1. モデルのクラスファイル(/app/models/[モデル名].rb)
2. マイグレーションファイル(/db/migrate/yyyyMMddxxxx_create_[テーブル名])
3. モデルの自動テスト
4. モデルの自動テストで使うfictureファイル
```
#### ②テーブルを作成/更新
`rails db:migrate`コマンドを実行

#### ③テーブルを参照し、問題なく作成できているか確認する

##上記の流れの主な留意点
#### ①外部キー制約について

###### `rails g model`コマンド実行時に外部キーのカラムにreferences型を設定していた場合
以下のような記述があるので、修正する(追記する)

```text:/db/migrate/yyyyMMddxxxx_create_[テーブル名]
t.references :[自身のテーブル名単数形]`
```

↓

```text:/db/migrate/yyyyMMddxxxx_create_[テーブル名]
`t.references :[自身のテーブル名単数形], foreign_key:true`
```

テーブルを作成/更新

###### 後で外部キーをカラムごと追加して設定したい場合
`rails g migration [クラス名] [参照先クラス名]:references, ...`コマンドを実行
※ [クラス名]はAddXXXRefsToYYYの形にする。XXX:参照先クラス YYY:参照元クラス
※ ちなみにデータ型にstringなどを指定すれば通常のカラムを追加することができる

テーブルを作成/更新
自分用にまとめたDocker実行メモ

### 記事にする理由
Windows HomeでDockerを入れたはいいもののやってから触らずに1か月いたら、いろいろ忘れてしまったのでメモとして記事にします。 
勉強した内容は何回もアウトプットしないと忘れてしまいます。 

### 環境など
- Windows10 Home
- Docker ToolBox
- .Net Core 3.1

### 参考ドキュメント  
- [**MSDN チュートリアル: NET Core アプリのコンテナー化**](https://docs.microsoft.com/ja-jp/dotnet/core/docker/build-container?tabs=windows)  
このMSDNにDockerファイルの作成からimage、containerの実行についてすべて書いてあります。  
初歩的なことで迷ったらこの記事を見てください。 
- [**MSDN Azure Learn**](https://docs.microsoft.com/ja-jp/learn/modules/deploy-run-container-app-service/)  
順序だててContainerへのデプロイが書いてあり、すべてAzurePortalで行う内容になります。 
- [**Qiita よく使うDockerコマンド**](https://qiita.com/tera_shin/items/8a43e904bd15990d3129)  
次のローカルでの使い方で書いたコマンドについて簡潔にまとめてあります。

### ローカルでのDockerの使い方 
1. Docker Quickstart Terminalの実行
2. `docker images` で保存済みのimageの確認
3. `docker run {image name or id}` で指定したimageのコンテナ作成と起動  
runコマンドはcreateとstartを行ってくれるコマンド。
4. `docker stop {container name or id}` で停止
5. 参考ドキュメントで作ったカウンターアプリを実行した場合、`docker attach {container name or id}`で現在のカウントを確認できます。
6. `docker rm {container id or name}`で指定したコンテナの削除
7. `docker ps -a`で登録されているコンテナの一覧が確認できます。（-aオプションがないと起動中のもののみ表示）
OpenMPによる並列化

[ONNX Runtimeでプロファイルを取ってみる](https://qiita.com/project_raizin/items/659b99396e63e0378f78)の続きです。

前回、全処理の中でConvolution処理が大半を占めていることがわかりました。
今回から、この処理の高速化にとりかかります。

まず、てっとりばやく速くする方法として、**OpenMP**というものがあります。
これは、コードにディレクティブを挿入してコンパイル時に`-fopenmp`というコンパイルオプションをつけるだけで処理が並列化されるものです。

```c++
#pragma omp parallel for
for (int i = 0; i < num; ++i) {
  target_function(i);
}
```
例えばこのように、並列化したいfor文の上に`#pragma omp parallel for`をつけると、そのfor文が並列化されます。

今回高速化するConvolution処理の使われ方をより詳細に見たところ、floatの2次元データを対象とした処理が主に使用されていたので、まずはそのケースで実行される演算処理を抜き出します。抜き出した処理のうち`Depthwise畳み込み処理`の部分はfor文での繰り返し回数が多く、並列化が有効と考えられます。

実際に`#pragma omp parallel for`をDepthwise畳み込み処理のfor文の前につけて並列化させたところ、これだけでも推論にかかる時間は**30%**高速化しました。

次回は更なる高速化のために、SIMD(single instruction, multiple data)を使って演算処理をより細かく並列化していきます。
Scrum Fest Sapporo Day 2 参加レポート OST「ふりかえりの悩みを集めよう」

# Scrum Fest Sapporo Day 3 OST 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221788/601ffe30-31c7-9c84-87ad-1fdaa88b1a6f.png)

2020/11/07に開催されたScrum Fest Sapporo 2020 Day 2にて、OST(Open Space Technology)が開催されました。
OSTは、話すテーマを自由に挙げて、話したい人・聞きたい人同士で集まって場を作っていくという議論の方法です。
1回20分×3のセッションが行われました。私は、1セッション目「ふりかえりの悩みを集めよう」のテーマを作って、悩みを集めてきました。

OSTについては、以下の資料を読むとイメージがしやすいと思います。
https://takaking22.com/2019/ost-introduction/

# ふりかえりに関する悩み

ふりかえりに関する悩みを集めました。悩みへの解消はしない場でしたが、他の人もこんな悩みを持っているんだ、と気づくことは非常に有用です。
悩みを列挙していきます。

## Q. ふりかえりが上司の機嫌取りになってしまっている

上司が参加すると、忖度が発生してしまって、「カイゼンされています」「問題ないです」という風に言ってしまう。
1週間のスパンしか見ていなくて、長期的にみると変わってないよなーという風に思ってしまう。
ご機嫌取りのために付箋の内容を書いてしまう

## Q. ふりかえりを言い訳の場にしてしまう人がいます

## Q. KPTでやっているとうまくネタが出てこない、停滞感が出てしまう

## Q. 自虐的になるだけで、カイゼンに繋がらない

「やったことに対してうまくできなくて…」とぼそぼそと言って、自分のモチベーションが下がることだけを言ってしまう。
こういう風にカイゼンしていこうね、という話にはならずに、場が冷え切ってしまう。ポジティブな方向に持っていけない。

## Q. 「ふりかえり＝問題点探し、ダメ出しの場」と思ってしまう

## Q. 定量情報とふりかえりをどう連動させたらいいか？

コードの作成数とか、TODO消化数など、メトリクスをどのようにふりかえりで活用すればいいか？

# その他のコメント

TIPS的な情報もあったので、こちらに記載します。

## みんなに知見を与えたプロブレムとして「ベストプロブレム賞」を決める
[Swift5]TableViewCellにTextViewを配置したときにCellのタップができなくなる問題

TableViewCellの上にTextViewを設置している状態で、TextViewをタップすると、セルのdidSelectRowAtが発火しません。

TextViewに以下の設定を追加すると、セルのタップができるようになります。

```Swift
textView.isUserInteractionEnabled = false
```
バッチファイルで湯婆婆を実装してみる

#はじめに
バッチファイルで書いてみました。

元ネタ：[Javaで湯婆婆を実装してみる](https://qiita.com/Nemesis/items/c7192a7c510788d2cba2)

#コード
バッチファイルは文字コードを Shift_JIS にして保存してください。

```bat:湯.bat（湯婆っち）
@echo off

setlocal enabledelayedexpansion
  :BOL
    echo.
    echo 湯婆っち：契約書だよ。そこに名前を書きな。
    
    set /p A=
    if "%A%" == "" call :die
    
    call :Q "湯婆っち：フン。「%A%」というのかい？" || goto :BOL
  
  call :length "%A%"
  set l=%ERRORLEVEL%
  set /a i="%RANDOM% %% %l% - 1"
  set s=!A:~%i%,1!
  
  echo.
  echo 湯婆っち：贅沢な名だねぇ。今からおまえの名前は「%s%」だ。いいかい、「%s%」だよ。分かったら返事をするんだ、「%s%」！
endlocal
goto :EOF

:die
setlocal
  call %~0
endlocal
goto :EOF

:length
setlocal
  set s=%~1
  
  if "%s%" == "" (
    exit /b 0
  )
  
  set i=0
  :BOL_length
    call set c=%%s:~%i%,1%%
    if "%c%" == "" goto EOL_length
    set /a i+=1
    goto BOL_length
  :EOL_length
  
  exit /b %i%
endlocal
goto :EOF

:Q
setlocal
  :BOL_Q
    echo.
    set /p A=%~1 ^(Y/n^) 
    if /i "%A%" == "Y" exit /b 0
    if /i "%A%" == "N" exit /b 1
  goto :BOL_Q
endlocal
goto :EOF
```

#実行結果
念のため再入力とエラーも実装しています。

![2020-11-07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29814/2b54bd64-ae3b-a7a5-3428-4f8d82dd8ddc.png)

#おわりに
むかし夢中になった「どう書く.org」というウェブサイトを思いだしました。

いつになっても自分の好きな言語で書くのはたのしいものですね。
Firebase で無料で作るハイスコアDB(3) : 書き込み他

## 前回までの砂漠のひつじ

無料プログラム学習用ピコピコゲーム[砂漠のひつじ](https://kaku3.github.io/the-sheep-in-the-desert/)を作成しつつ、その過程を記事にしている。
２日程前(執筆 11/7、実装 11/5深夜)にハイスコア処理実装を終えたが、誰も登録がなく悶ている最中となる。

Firebase編記事：

* [【超簡単】Firebase で無料で作るハイスコアDB : APIキー制限設定忘れずに！！](https://qiita.com/kaku3/items/ce3a84424026cb46b226)
* [Firebase で無料で作るハイスコアDB(2) : 課金・認証を考える](https://qiita.com/kaku3/items/b104ca08eeb69f803c3b)

## 認証処理について

前回の記事で`firebase.auth.AuthUI()`でログイン処理の挙動を確認した。
匿名ログインを使うとブラウザをリロードする度にログアウトされる挙動を取るようだった。

## APIキー制限について

IPアドレスによる制限をかけられるが、なぜかアクセス権がないエラーが出ることがあった。
※原因不明ママ

![ip制限.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136165/090567d4-b83e-b6db-cb18-9d58a2359531.png)


## DB書き込みについて

書き込み処理は以下の通り。
簡単過ぎて記事にするのが申し訳ないレベルである。

``` game.js
  var db = firebase.firestore()
  // scores テーブルに、レコード登録。
  // 登録データはjson形式で指定
  // id は指定しなければ自動で生成される
  db.collection('scores').add({
    name: name,
    score: this.score
  }).then((r) => {
    $('#register-container').hide() // 重複登録させないよう、登録ボタンを消す。
    Game.buildHiScores(true)        // ハイスコアを再取得/再表示
  })
```

## おわりに

元々i-mode用のゲームをブラウザゲームとして移植してなんちゃってレスポンシブ対応を入れることでスマホでも動作するゲームとしたが、**ひつじにはりついたツノを見て楽しむ**ゲームだったがスマホだと**指が邪魔で一切見えない**という大変残念なUXとなっていたが学習用ということで最後まで作成した。

アクセス量や読み書き量をウォッチしたいので、適当に遊んでスコア登録してもらえると幸いです。学習用ソースのためSNSログインも対応したが匿名ログイン推奨です。

ソースコードは githubにて公開していますのでご自由にご利用ください。

[砂漠のひつじ:ソースコード](https://github.com/kaku3/the-sheep-in-the-desert/)
[砂漠のひつじ:ゲームページ](https://kaku3.github.io/the-sheep-in-the-desert/)
Micronaut + KotlinでHelloWorld

## Micronaut

[Micronaut](https://micronaut.io/)とは

* JVMベースのフルスタックフレームワーク。
* Java, Kotlin, Groovyが使える。
* SpringBootと比較して起動が早くメモリ消費も抑えられるらしい。

今回は環境構築とHelloWorldを返すAPIの作成まで行います。
Kotlinに触れてみたかったので言語はKotlinを使用します。

# 環境作成

Micronautをインストールします。
SDKMANを使用します。

### SDKMANのインストール

```shell
$ curl -s "https://get.sdkman.io" | bash
```

### Micronautのインストール

```shell
$ sdk install micronaut
$ mn --version
```

# プロジェクトの作成
`mn create-app`コマンドを使用する事でプロジェクトを作成します。
今回は`helloworld`プロジェクトを作成します。

```shell
$ mn create-app example.helloworld --lang=kotlin
| Application created at hogehoge/helloworld
```

オプションとして`--lang=kotlin`を指定する事でkotlinでプロジェクトが作成されます。
作成したプロジェクトの中身はこちら。

```shell
$ tree helloworld
helloworld
├── README.md
├── build.gradle
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── micronaut-cli.yml
├── settings.gradle
└── src
    ├── main
    │   ├── kotlin
    │   │   └── example
    │   │       └── Application.kt
    │   └── resources
    │       ├── application.yml
    │       └── logback.xml
    └── test
        └── kotlin
            └── example
                └── HelloworldTest.kt
```

# HelloWorldを返すAPIを作成

`src/main/kotlin/example/controller/HelloController.kt`を作成します。
ちなみに配置は`controller`以下でなくとも大丈夫です。

```kotlin:HelloController.kt
package example.controller

import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Get

@Controller()
class HelloController {

    @Get("/")
    fun index(): String {
        return "HelloWorld"
    }
}
```

Graldeの`run`コマンドで実行します。

```shell
$ ./gradlew run

> Task :kaptKotlin
注意:Creating bean classes for 1 type elements
> Task :run
13:43:38.802 [main] INFO  io.micronaut.runtime.Micronaut - Startup completed in 1980ms. Server Running: http://localhost:8080
```

`localhost:8080`にアクセスしてみます。

```shell
$ curl -X GET  http://localhost:8080/
HelloWorld
```
`HelloWorld`が返却されました。

# テスト
せっかくなので`Controller`のテストも用意します。
`test/kotlin/example/controller/HelloController.kt`を用意します。

```kotlin:HelloControllerSpec.kt
package example.controller
import io.micronaut.context.annotation.Property
import io.micronaut.http.client.HttpClient
import io.micronaut.http.client.annotation.Client
import io.micronaut.runtime.server.EmbeddedServer
import io.micronaut.test.annotation.MicronautTest
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import javax.inject.Inject

@MicronautTest
class HelloControllerSpec {

    @Inject
    lateinit var server: EmbeddedServer

    @Inject
    @field:Client("/")
    lateinit var client: HttpClient

    @Test
    fun testHelloWorldResponse() {
        val rsp: String = client.toBlocking()
                .retrieve("/")
        assertEquals("HelloWorld", rsp)
    }
}
```

テストを実行します。

```shell
./gradlew test
```

# 次にやりたいこと

DB接続してみました。
[Micronaut + Kotlin のプロジェクトにてMyBatisを使ってデータベースからデータ取得してみる](https://qiita.com/h-ueno2/items/9b70e55b341e4a3dd355)

# 参考
[公式ドキュメント](https://docs.micronaut.io/latest/guide/index.html)
ExcelからSnowflakeのデータを取得する方法


# 概要

ExcelからSnowflakeに接続し、データが取得する方法を調べてみたので整理してみました。

# Snowflake接続設定
### ODBCドライバのダウンロード
以下のＵＲＬからODBCドライバをダウンロードします。
（今回検証したのはWindows環境ですが、Mac版のODBCドライバもあるみたい）

https://docs.snowflake.com/en/user-guide/odbc-download.html

ダウンロードした.msiファイルをダブルクリックすると以下の様な画面が立ち上がるので、Nextをクリックしインストールを完了させます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77722/e9b20e75-5cff-4a5b-fb3b-4dda755f1608.png)


### ODBCデータソースの設定
（多くの場合は画面左下の）windowsアイコンをクリックし``odbc``と入力し、ODBCデータソース(64ビット）をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77722/e5ab3d03-89df-62e9-66b4-e1b9c3216bab.png)

以下のウインドウが表示されるので、追加ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77722/71bca6fb-167c-f822-f323-4082a4ed0f43.png)

SnowflakeDSIIDriverを選択し、完了をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77722/4fb69859-db1f-e698-f897-7350f6fdefc4.png)

### Snowflake Configration Dialogの設定
各入力項目にSnowflakeのログイン時に必要な情報を入力します。
Server欄には先頭http://などを入れない点に注意してください。（このような文字が入っていると接続失敗します）
Authenticator,Proxyなどは入力しなくてもよいです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77722/d660130d-a6cf-839c-09f6-d9b11e74d74e.png)

ここまでで、ODBCの設定は完了です。

# Excelでデータを取得してみる
それでは、実際に設定したODBCを使ってSnowflakeからデータを取得してみましょう。

### Excelのデータインポート設定
まず、Excelを起動して新規でファイルを開き、以下の手順でODBCからのデータ取得を設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77722/3941e709-bce7-c6a5-3af5-1acf0f4f8fce.png)

先ほど設定したODBC名が一覧に表示されるはずですので、選択をしてOKをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77722/b669c2e8-c15d-0438-da9a-45a24de49999.png)

接続が成功すると、Snowflakeに登録されているデータベースとテーブルの一覧が表示されますので、インポートしたいデータを選択し、下の読み込みボタンをクリックします。
（サンプルはSnowflakeがサンプルデータとして公開しているデータです）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77722/8a00399e-5e75-8641-4aa7-656d1a67bb55.png)

### 取得データ確認
Snowflakeに登録されているデータをExcelに読み込むことができました！
データサイズが大きい場合は読み込みに時間がかかりますが、150万件のデータの取得も可能です。
読み込んだデータはPowerQueryというツールを使って集計などの加工をしてからExcelに取り込むといったこともできるようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77722/bfca4593-994e-f20e-31a0-76bffc535d9d.png)



# まとめ
簡単な設定を行うだけで、Snowflakeに登録されているデータを取得することができました。
Datashareringと組み合わせることで蓄積したデータを（社内の）多くの人で活用することができるようになりそうです。
Angular Materialのmat-form-fieldの外観の既定値を設定

元記事：[genkitech.net](https://genkitech.net/angular-material-mat-form-field-options-default)

Angular Materialのフォームフィールドmat-form-fieldは、HTMLタグの属性でスタイルを変更できるようになっています。

しかし、サイト内のコントロールの外観は固定であることが多いため、全てのコントロールタグに属性を付けていくのは大変であり、やっぱり変えたいとなった場合はさらに大変です。

それで今回は個人的に規定値から変更することの多い、外観設定「appearance」と、キャプション表示方法「floatLabel」の既定値を設定してみます。

##appearanceとfloatLabelの挙動を確認

とりあえず以下のコードを編集し、結果がどのように変わるか試してみてください。

[画像をクリックして編集できます<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/834797/2d1401e5-8701-ce47-8d5b-d42b18ac7b60.png">](https://stackblitz.com/edit/angular-material-field-options)

##appearanceとfloatLabelの既定値を設定

appearanceやfloatLabelはHTMLタグで指定されるため、CSSで一括指定ができません。それで例えば、appearanceの既定値をoutline、floatLabelの既定値をalways（タイトルを常に上に表示）に変えたい場合、各種モジュールをインポートしている箇所（上の例だとmain.ts）に、以下のコードを追加します。

```Javascript
@NgModule({
  ...
  providers: [
    { provide: MAT_FORM_FIELD_DEFAULT_OPTIONS, useValue: {
      appearance: 'outline',
      floatLabel: 'always', } },
  ]
  ...
})
```

すると以下のように、スタイル未指定フィールドの既定の動作を変更できます。

[画像をクリックして編集できます<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/834797/6a11b667-1297-3d50-8dc3-60918d8dfee6.png">](https://stackblitz.com/edit/angular-material-field-options-default)
Cで湯婆婆を実装してみる

# 元ネタ

↓が流行っているらしいので便乗してみました。
@Nemesisさんの[Javaで湯婆婆を実装してみる](https://qiita.com/Nemesis/items/c7192a7c510788d2cba2)

# コード
Cの場合環境依存性が高いので、[paiza.io](https://paiza.io/ja)でやってみました。

2020/11/8編集：
　未入力と空白一文字だけの場合は再入力するようにしてみました。
　原作リスペクトを考えると落ちたほうが良いのか・・・？

```C:yubaba.c
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void){
    char name[65];/*4byte×16+'\0'*/
    int first_char_len=0;

    setlocale(LC_ALL, "");
    memset((void*)name,0,sizeof(name));

    printf("契約書だよ。そこに名前を書きな。\n");
    while(1){
        scanf("%64s%*[^\n]", name);
        if((name[0]!='\0') && (strcmp(name," ")!=0) && (strcmp(name,"　")!=0)){
            break;
        }
        printf("[あなた]> あの、名前ってここですか？\n\n"   
               "そうだよもぅぐずぐずしないでさっさと書きな！\n"
               "まったく……つまらない誓いをたてちまったもんだよ。働きたい者には仕事をやるだなんて……\n"
               "書いたかい？\n\n");    
    }
    printf("フン。%sというのかい。贅沢な名だねぇ。\n",name);

    first_char_len = mblen(name, sizeof(name));
    name[first_char_len] = '\0';

    printf("今からお前の名前は%sだ。いいかい、%sだよ。分かったら返事をするんだ、%s!!",name,name,name);
}
```

# 参考サイト
setlocale
http://www.c-lang.org/detail/function/setlocale.html

【C言語】scanf関数で安全に文字列を読み込む方法
https://marycore.jp/prog/c-lang/scanf-string-safely/

mblen
http://www.c-lang.org/detail/function/mblen.html
Active Storage 初期設定マニュアル

# はじめに

## やりたいこと
- 簡単に画像を登録したい

## Active Storage でできること
- モデルに簡単に画像を紐付けできる
- Amazon S3、GCPなどクラウドストレージへのアップデートも可能　=> たしかAWSでデプロイするときもActive Storageまわりはいじらなくてよかったはず。。。

## やってみて
毎度お世話になってますが初期設定のやり方を毎回忘れるので備忘しておきます。

※Active Storage はGem？
>Active Storage はファイルアップロード用の**Gem**だそうです。
もともとは外部からインストールが必要なGemでしたがRailsに統合されたため、Active Storage 自体のbundle installは不要です。

## 参考URL
[Rails ガイド > Active Storage の概要](https://railsguides.jp/active_storage_overview.html)

  
# 手順

- 画像加工ツールの導入
- Active Storage のインストールとマイグレーション
- アソシエーション
- ストロングパラメーターに含める
- 保存した画像を表示する

## 画像加工ツールの導入

### ImageMagicのインストール

ImageMagick とは
> 画像処理ライブラリのひとつ。Gemではなくソフトウェアなので、Homebrewからインストールします。よって一度構築すれば次回以降この作業は不要です。

```:ターミナル
% brew install imagemagick
```

### 必要なGemのインストール

MiniMagick
> ImageMagickをRubyで扱うためのGem

ImageProcessing
> 画像サイズ調整用のGem

```ruby:Gemfile
gem 'mini_magick'
gem 'image_processing', '~> 1.2'
```
```ruby:ターミナル
% bundle install
```
&サーバー再起動

## Active Storage のインストールとマイグレーション
Active StorageはあくまでGemなのでインストールを行います。

```:ターミナル
% rails active_storage:install
```
インストールが完了するとActive Storage関連のマイグレーションが作成されるので、そのままmigrateします。

```:ターミナル
% rails db:migrate
```

## アソシエーション

画像を扱わせたいモデルにアソシエーションを記述します。

```ruby:models/profile.rb
class Profile < ApplicationRecord
  has_one_attached :image
end
```
この際、対象のテーブルにimageカラムを設ける必要はありません。

## ストロングパラメーターの設定

最後にimageをストロングパラメーターに含めます。

```ruby:profiles_controller.rb
class ProfilesController < ApplicationController

  〜中略〜

  private
  def profile_params
    params.require(:profile).permit(:image)
  end
end
```
以上で、画像データが保存できるようになりました。

## 保存した画像を表示する

image_tagメソッドを使用して表示します。

```ruby:example
image_tag モデル.カラム名
image_tag profile.image
```

### 画像の有無で条件分岐する

画像ファイルのある／なしで表示を変える場合、attached?メソッドを使います。

```ruby:example
image_tag profile.image, class: 'profile-image'  if profile.image.attached?
```

***※画像の大きさ調整の記事を書く！***
 
# おわりに
Qiita、2回目の投稿です。
できる限り毎日、ネタが尽きるまで更新していこうと思います。

最後まで読んでいただきありがとうございました！！

✔︎
バッチファイルでボリュームをマウントした Docker コンテナを起動する方法

# これは何?

docker コンテナを起動する際、バッチファイルの配置場所を volume としてマウントする方法です。
適当な場所で bash を使いたいときに便利です。

# 確認環境

Windows 10 (1909)
Docker version 19.03.13

# 結論

下記バッチファイルを作成し、好きな場所に置く。ダブルクリックで起動する。コンテナに引数を渡したいときは、バッチファイルに D&D する。

```bat:launch.bat
@setlocal
@rem container image
@set IMAGE=buildpack-deps:buster
@rem working directry in container
@set WORK=/workspace
@rem ###########################
@cd /d %~dp0
docker run -it --rm -v "%CD%:%WORK%" -w "%WORK%" %IMAGE% %*
@if errorlevel 1 (
  pause
  exit /b %errorlevel%
)
@exit /b 0
```

`IMAGE` に起動する docker image 名を設定しています。好きなイメージに書き換えてください。
`WORK` に mount 先を指定します。コンテナ無いの適当なマウントポイントに書き換えてください。
Minicondaで作成した仮想環境をJupyter notebookに反映させる

#1.背景
自宅のPCが故障したのを機にPCを新調し、今度は何かと物議をかもしているAnacondaではなくMinicondaを新しくインストールした。

久々にQiitaに記事を投稿するための仮想環境を作成。
miniconda経由で作成した仮想環境をjupyterに適応させ検証したかったが、意外とハマってしまい・・

Anacondaの仮想環境をjupyterに反映させる記事は多数あったが、Minicondaを使用しているからなのか私の場合はそれだけではどれも解決には至らなかったので記録として残しておく。（結論からいうとMinicondaは関係なかったですが、、）

* 動作環境
 * OS : Windows10 pro
 * Python : 3.8.3 // Miniconda 4.9.1

#2.まずは参考記事を元に試してみる

###2-1.仮想環境作成
```Python:
#sample_envという仮想環境をpython3.8.3で作成(pythonのバージョンは何でもいいと思う)
conda create -n sample_env python=3.8.3

#base環境から作成したsample_env仮想環境に切り替える
conda activate sample_env
```

###2-2.その他の作業、確認
jupyter_environment_kernelsの導入

```Python:
#jupyter_environment_kernelsのインストール
pip install environment_kernels
```
jupyter_notebook_config.pyを作成

```Python:
#~/.jupyter/jupyter_notebook_config.pyに設定ファイルが作成される
jupyter notebook --generate-config
```

作成したjupyter_notebook_config.pyの最後行を以下のように追記して保存※Miniconda

```Python:
c.NotebookApp.kernel_spec_manager_class = 'environment_kernels.EnvironmentKernelSpecManager'
c.EnvironmentKernelSpecManager.env_dirs=['/Users/username/miniconda3/envs/']
```

動作確認をするが・・・うまくいかず。
(↓のようなものは選択できるようになったが、これはbase環境)
<img width="400" alt="追加されたkernel" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373060/38279c8e-a5e7-c7a8-9946-8c4d0ac920a9.png">


#3.解決策と確認

仮想環境に切り替えた状態でipykernelをインストールで解決した。

```Python:
#base環境から作成したsample_env仮想環境に切り替える
conda activate sample_env

#ipykernelをインストール ※jupyterをインストールでもOK
conda install notebook ipykernel
```

この状態からjupyterを再起動して、まず現在の環境を確認。
<img width="400" alt="追加されたkernel" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373060/c948dfcd-768e-57b3-9fc7-54d5ec0431ee.png">
***
次に、Kernel>>Change Kernelでsample_envに仮想環境を切り替える
<img width="200" alt="追加されたkernel" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373060/597e9e94-5f0b-6de2-f6de-62f3f411fb9a.png">
***
最後にもう一度環境を確認し、環境が切り替わっていることを確認できた。
<img width="400" alt="追加されたkernel" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373060/ab89ad62-5af8-3d0e-6955-836855b18c98.png">


#4.最後に
ミソなのが、作成した仮想環境にipykernelを導入するというところだった。
ipykernelを導入しなくても「!conda info -e」で作成した環境の存在自体は確認できたが、ipykernelを導入しないと、作成した仮想環境が「Change kernel」に出現しなかった。
意外とこういうので時間を使ってしまうんだよなぁ・・


**(追記)**
参考記事にも
「作る仮想環境の方にも必ずjupyterをインストールする必要があります。」と記載がありましたね。。これを見落としていただけでしたが、同じところで躓く人もいると思うので一応記事は残しておきます。(Minicondaの記事はググってもでないですし)

<br>

参考記事：
[Condaで作ってる仮想環境の切り替えをJupyter上で簡単に行う方法](https://qiita.com/yoppe/items/38005f415a5b8b884c7d)

https://gdcoder.com/how-to-create-and-add-a-conda-environment-as-jupyter-kernel/