OmniAICreator/Qiita-1.07M huggingface dataset:
高校数学で考える感染症

# 拝啓
2020年の出来事を知らない未来の読者へ
2020年初頭、COVID19というウイルスが世界に蔓延しました。
初めは中国で発見され、日本をはじめとするアジアで感染が広がり、日本人が海外旅行すると「ウイルス」と呼ばれて差別されることもありました。しかしあれよあれよという間に世界中に感染が拡大し、アメリカでは数万人規模で死者が出ました。
2020年半ばごろ、日本では感染者が下火になって経済活動も再開しましたが、再び感染者が増加し始めました。

この時代どうやって検査したかというと、PCR検査という方法を用いました。
PCR検査がどういうものかは詳しくないのでさておいておきます。インフルエンザの検査と似たようなものだと思います。

敬具

# 感染症検査の精度
インフルエンザでもなんでもそうですが、検査には間違いが必ず存在します。
間違いというのは、感染者にもかかわらず検査で陰性が出る、あるいは、非感染者なのに検査で陽性が出るということです。感染再拡大中と言われる今、なぜだかわかりませんが「PCR検査をもっとやれ」の世論を煽るような報道が増えた気がします。
しかし、発見から1年も経っていないCOVID19のPCR検査がどれほど信頼できるのでしょうか。どれくらいの精度になれば全体検査を行ってもいいのかという目安が知りたいと思ったので、高校レベルの数学で考えてみます。

タグにMATLABがあるのは、この計算にMATLABを使ったからです。完全にオーバースペック。

# まず分類
とりあえず人々を2種類に分類しましょう。それは「実際の感染者」と「実際の非感染者」です。「実際の」というのは、本当にウイルスを保有しているという意味です。未症状というのがありえるのでこの分け方にしています。あくまで発症者ではありません。
グループに名前をつけましょう。以下のようにします。

| グループ名 | 名前 |
|:-:|:-:|
| 全体 | $A$ |
| 実際の感染者 | $G_x$ |
| 実際の非感染者 | $G_y$ |

感染症を押さえ込むためには当然$G_x$を把握したいのですが、実際には不可能なのでPCR検査など何かしらの検査を用います。
しかし、検査というものには2つの確率がつきものです。それが以下の確率。

- 偽陽性 | 実際には非感染者だが、検査で陽性が出る確率
- 偽陰性 | 実際には感染者だが、検査で陰性が出る確率

COVID19が見つかって1年も経たない今現在では、この2つがどれくらいの値なのかはっきりしていません。というより調べていません！
そこで、偽陽性率を$P_a$、偽陰性率を$P_b$として、無作為なPCR検査にどれくらいの効果があるのか計算します。

# やることは簡単
やることは簡単で、全体集合$A$に対して無作為にPCR検査を行った場合

1. その人が本当に感染者である確率$Q_x$
2. その人が本当に非感染者である確率$Q_y$
3. 感染してないのに検査で陽性が出る確率$Q_a$
4. 感染してるのに検査で陰性が出る確率$Q_b$

の4つの確率を求めます。
すごく簡単なので以下に示しちゃいます。まず1と2は

```math
Q_x = \cfrac{G_x}{A}\\
Q_y = \cfrac{G_y}{A}
```

です。続いて3、4ですが、偽陽性率$P_a$は「非感染者のうち検査で陽性が出る確率」、偽陰性率$P_b$は「感染者のうち検査で陰性が出る確率」と、全体集合が$A$ではありませんのでそこに注意します。

```math
Q_a = P_a\cfrac{G_y}{A}\\
Q_b = P_b\cfrac{G_x}{A}
```

これで無作為検査した場合の4つの確率がもとまりました。

# 具体的な数字を入れてみよう
数式では実感沸かないので、数字を入れてみます。
なんとなくCOVID19の感染者数を多めに見積もって以下のようにします。

| 集合 | 数(人) |
|:-:|:-:|
| 全体$A$ | 120,000,000 |
| 感染者$G_x$ | 10,000 |
| 非感染者$G_y$ | $n(A)-n(G_x)$ |

偽陽性率、偽陰性率は0〜1%としておきます。
この時、$Q_x$と$Q_a$を比べてみます。

![偽陽性率.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530192/8ede6ee3-7411-2d76-e321-d39e7e13a2e2.png)

下のほうにへばりついてる黒線が$Q_x$です。偽陽性率1%、いやいや0.1%でも偽陽性者>本当の感染者になるじゃないですか。。。よーく見ると偽陽性率0.008%くらいでやっと偽陽性者=本当の感染者になります。
逆に$Q_y$と$Q_b$を比べてみましたが、雲泥の差($Q_y>>Q_b$)なので図は省きます。

適当に調べたら、インフルエンザの偽陽性率は3%ほどあるようです。
[朝日新聞DIGITAL 『インフルエンザ、陽性と陰性は絶対か　検査の限界を知る』](https://www.asahi.com/articles/ASM4D4T7HM4DULBJ00H.html)

どうみても全数検査に求められそうな0.01%以下という偽陽性率は、実態の把握に対しては現実的な数字ではありません。

# じゃあどうすればいいのさ
実際の感染者数を把握したいという目的の下であれば、以下のような対処法があるのかなと思います。ただし専門家ではないので網羅はできていないと思います。

1. 複数の検査法を組み合わせて確度を上げる。
2. 全体集合を絞る

1において、他の検査法としてあげられるのが「抗体検査」なのかなと思います。体内に抗体があるかどうかを調べるので、「体内に抗体が作られるほど症状が進行した人」しか反応しません。(当然偽陽性とかはあります)
しかし、抗体検査の反応対象が狭いため、大量に検査できないですね。。。

2の考え方は、「初めから$Q_a, Q_b$に当たると思われる人を検査しない」というものです。ここまでの考察で$Q_a$がめちゃくちゃ邪魔だとわかります。そこで全体集合$A$に対して、「疑わしい症状がある人」もしくは「濃厚接触者」など、感染者は引っ掛かるが非感染者は引っかからないようなフィルタをかけ、全体集合から偽陽性になりうる成分を省くことで確度を上げることができそうです。

# まとめ
昨今、検査対象のフィルタが緩くなっている気がします。実際に検査数も第一次感染拡大期に比べて爆増しています。フィルタは適切にかけるから所望の結果が出るのであって、本来なら何かしらのフィードバック制御をするべきと思うのは私だけでしょうか。
例えば「未症状かつ検査陽性の人から、通常の生活を送り続ける人を一定確率で選出し、その人の濃厚接触者の検査陽性率を調べる」などしていけば(適当な発言です)、最適なフィルタリングに近づくのではないかと思います。
「陽性のうち95%が未症状」と報道されている現在ですが、この人たちは本当に感染してるんですかね。
tmux と Mac のクリップボードの双方向コピペ

## 要件

- コピーモードで emacs キーバインドである
- tmux でコピーして GUI アプリ(ブラウザや GUI emacs)　へペーストできる
- GUI アプリ(ブラウザや GUI emacs)でコピーして tmux にペーストできる

## 環境

- tmux v3.0α

## 設定

```
set -g mode-keys emacs
bind-key -T copy-mode C-w send-keys -X copy-pipe-and-cancel "pbcopy"
bind-key C-y paste-buffer
bind C-m run "pbpaste | tmux load-buffer - && tmux paste-buffer"
```

## 課題

- ２種類のペーストを交互に実行すると片方が上書きされる

## 資料

- https://man7.org/linux/man-pages/man1/tmux.1.html
- http://mirror.informatimago.com/next/developer.apple.com/documentation/Darwin/Reference/ManPages/man1/pbcopy.1.html
- http://mirror.informatimago.com/next/developer.apple.com/documentation/Darwin/Reference/ManPages/man1/pbpaste.1.html
高卒工場勤務が未経験から転職するまで(Prologue)

#自己紹介
はじめまして！高校卒業後→地元の工場へ就職→現在転職のため学習中
はい。こんな感じで何にも学歴も良いわけでもなく何も取り柄がないわけですが、
転職を考えております。技術で勝負するしかないのです。
#Qiitaになぜ投稿し始めたか。
これは単純にアウトプットする場所が欲しかったからです。
これから少しづつアウトプットしていきます。
##とりあえず触ってみた技術、言語
HTML,CSS,JavaScript,Python,Django,Vue.js
とざっくりこのあたりを触りましたが、エラーを吐かれすぎて挫折仕掛けていました。
##これからどうしていくのか
エラーを吐かれて解決できずに止まることがモチベーションが下がり気味
スクールに通うか迷いましたが、闇が深すぎて断念
様々な人に聞いたところMENTAを使ってみてはどうかということで、
メンターさんについてもらうことにしました。
これからはもう少し効率的に進めていけたらと思います。
【GAS初心者】スプレッドシートの中にあるシート数を取得する(GAS)


シートがたくさんあって、何があるかわからない.........

そんなことはないでしょうか。

カウントの仕方は簡単。

結論
--------
```javascript:結論
.getNumSheets();
```

具体例
--------
```javascript:シート数を取得
function sample() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet();
  var sheet_num = sheet.getNumSheets();
  Logger.log('シート数は：'+ sheet_num);
}
Heroku Redisアドオンのデータを消去する

# はじめに
MacのターミナルからHeroku Redisアドオンのデータを削除する方法です。
Herokuコンソールに接続し削除するのが一般的のようですが、今回はredis-cliを使用して削除してみました。

## やりたいこと
- HerokuのRedisデータを消去したい

# 作業内容
## MacにRedisをインストール
```
$ brew install redis
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 1 tap (homebrew/core).
==> New Formulae
chart-testing              jinx                       oci-cli
jimtcl                     ngs                        reg
==> Updated Formulae
Updated 194 formulae.

==> Downloading https://homebrew.bintray.com/bottles/redis-6.0.6.catalina.bottle
######################################################################## 100.0%
==> Pouring redis-6.0.6.catalina.bottle.tar.gz
==> Caveats
To have launchd start redis now and restart at login:
  brew services start redis
Or, if you don't want/need a background service you can just run:
  redis-server /usr/local/etc/redis.conf
==> Summary
🍺  /usr/local/Cellar/redis/6.0.6: 13 files, 3.8MB
```

## Redisのデータ消去
### Heroku環境変数 REDIS_URLの値を元にコマンドを実行
REDIS_URL： `redis://h:<パスワード>@<ホスト名>:<ポート>`

```
$ redis-cli -h <ホスト名> -p <ポート> -a <パスワード> flushall
OK
```
discord.pyを使ってbotを作ったときの知見


プリコネのクラバト管理botを作ったのでそのへんで気づいたことです
https://github.com/izmktr/yukarisan


#on_readyでのイベント

on_readyはdiscordに接続したときに呼び出されます
また、不定期にdiscordから切断されるようで、
自動的に再接続したときにも呼び出されます。

ここでは内部的に持っている情報とdiscord.pyのデータを結びつけると良さそうです。

```Python
import discord
from discord.ext import tasks
from typing import List, Dict, Optional

#guild_idと内部的なクラスとの紐付け
guildhash: Optional[Dict[int, GuildData]] = None

@client.event
def on_ready():
global guildhash

if guildhash is None:
# ロード処理
    guildhash = {}

for g in client.guilds:
    gdata = guildhash.get(g.id)
    if gdata is None:
        gdata = GuildData()
        guildhash[g.id] = gdata
    gdata.guild = g

```

#メッセージに付随する処理

リアクションを付ける/外すときに発生する、
on_reaction_add,on_reaction_remove ですが、呼び出されないことがあります。
大体、投稿されて15分程度経った後のメッセージでは反応しないことがあります。
(サーバの活発度によるのではないかと考えています)
おそらく、こうなるとon_message_deleteも飛んでこない気がします。

max_messagesが1000なので大きくすれば回避できるかと思いましたが、
こんな感じで100000を入れてみても回避できませんでした。
(この辺の知見求む)

```Python
# 意味がない？
client = discord.Client(max_messages = 100000)
```

on_raw_reaction_add,on_raw_reaction_remove を使えば、確実に飛んできます。
on_messageでmessageの情報を保存しておき、on_raw_reaction_～を使って
処理を解決するのがいいでしょう。

なお、on_raw_reaction_add → on_reaction_addの順で呼び出されます。
on_reaction_add が飛んできたらこちらで、飛んでこないならon_raw_reaction_addと考えてましたが、
順序が逆なのでこの処理は面倒そうです。

#プライベートチャット

botにメッセージを送ることでbotとプライベートチャットができます。
開発用のコマンドを使う場合はプライベートチャットを使えば、
周りにログが見られない形で作業が行なえます。

```Python
@client.event
async def on_message(message):
    # メッセージ送信者がBotだった場合は無視する
    if message.author.bot:
        return

    # 通常のメッセージ
    if message.channel.type == discord.ChannelType.text:
        return

    # 1:1のメッセージ
    if message.channel.type == discord.ChannelType.private:
        return

```

問題は、通常のメッセージとmessageの型が違います
ですから、なくなっているクラス変数やクラス関数があります。

また、プライベートメッセージではギルドがありませんので、
プライベートメッセージ内でギルドを指定する必要があります。

この差異を吸収するような設計にして各種コマンドの処理を作っておくと
便利だっただろう、という反省点です。
Arduino UNO : USB2UARTの最大通信速度を探る(1)


##Arduino UNOのUSB2UART最高速度は115200bps ??
各場所を調べてもArduinoのUART最高速度は115200で、それ以上は保証しないと書かれています。
しかし、私が試している限りでは921600bpsを設定しても普通に通信ができています。
下記サイトを見ると、500000bpsで通信速度自体は頭打ちとのオシロ上での測定結果もあります。
https://arduino.stackexchange.com/questions/296/how-high-of-a-baud-rate-can-i-go-without-errors
Arduino UNO USB2UARTで実際にはどれくらいのスピードで通信できるか測定してみます。

###Arduino UNO部品レベルの限界値
ここでArduinoは Arduino UNO R3(Revision3)前提となります。
外付けOSCとATmega328P、USB2UART ICの設定を見てみます。
回路図は下記よりダウンロードできます。
https://www.arduino.cc/en/uploads/Main/Arduino_Uno_Rev3-schematic.pdf

ATmega328Pがメインマイコンとなります。
メインクロックは16MHzの水晶が搭載されています。
この関係から、ATmega328Pに接続されるUARTは Max 2Mbpsまで可能だと思われます。
FTDIのUSB2UARTチップを外付けで使えばこのスピードで通信が可能となります。

Arduinoの場合USB通信(Virtual Com Port)用に ATmega16U2が搭載されています。
このマイコンがUART⇔USB変換と、FW書き込みを担っていると思われます。
メインクロックは16MHzの水晶が搭載されています。
こちらのUART通信最高速度は2Mbpsです。ATmega328PとATmega16U2がUART接続されているため、
システム全体では2Mbpsが最高速度となっていると思われます。


###通信時間確認プログラムを作る
この通信速度を計測するプログラムを作成してみます。
1byteを相互に通信しあうプログラム
それぞれに対して100kbyte送信するまでの時間を測定します。

100kbyte * 2(送受信) * 8(bit) / 秒数 =  ??? bps

Arduino側送受信

```C:SpeedText.ino
#include <Wire.h>
#define BAUDRATE 500000

char buffer[0x10];

void setup() {
  Wire.begin();
  Serial.begin(BAUDRATE);
}

void loop() {
  if (Serial.available() > 0) {
    buffer[0] = Serial.read();
    Serial.write('!');
  }
}
```

PC側送受信 (Python)

```Python:SpeedText.py
import sys
import serial
import time

from StopWatch import *

datasize = 1024*100

if __name__ == "__main__":

    print("Arduino USB Speed Test")
    sw1 = StopWatch("No1")
    ser = serial.Serial()
    ser.baudrate = 500000
    com_str = 'COM3'
    ser.port = com_str
    ser.open()
    time.sleep(2)
    print("start")

    sw1.start()
    for i in range(datasize):
        ser.write(str.encode("!"))
        data = ser.read(1)
    print(sw1.name + ":" + str(sw1.stop()))
    print("finesh")
```

測定結果 
209.718秒
計算してみると、1024*100 * 2 * 8 / 209.718 = 7812bps
50000bpsを設定しているのになかなかの遅さです。

他のボーレートでも通信速度確認してみる。
115200bpsを設定してみても、計測結果は209.7144秒とほぼ一緒。
57600bpsを設定すると、419.4265秒とほぼ倍。　約3906bps
という事で、Web情報通りにArduinoは115200bpsがUSB-UART接続を使った場合の最大速度だと思われます。

Virtual COM Port Driverは2Mbps設定可能で、実際通信ができます。
ただ、どこかの通信経路がボトルネックとなるか、別途調べてみたいと思います。
初心者によるプログラミング学習ログ 384日目

#100日チャレンジの384日目
twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。
100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。
384日目は、
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>昨日の作業⇩<br><br>●就寝前筋トレ5分、キンドル読書 10分<br>●ブログ1記事作成<br>●プログラミング学習384日目 2h<br>・メンターの課題<br><br>モヤモヤしながらだったから捗らず・・・<a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E3%81%A4%E3%81%AA%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアとつながりたい</a><a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a><a href="https://twitter.com/hashtag/%E6%97%A9%E8%B5%B7%E3%81%8D%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8?src=hash&amp;ref_src=twsrc%5Etfw">#早起きチャレンジ</a></p>&mdash; ぱぺまぺ@社畜✕投資✕ブロガー (@ppmp65) <a href="https://twitter.com/ppmp65/status/1287844424895012864?ref_src=twsrc%5Etfw">July 27, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
メールの疎通確認するときに役に立ったことまとめ



メール系の確認方法が乗っているサイトが古くて見つけられなくなりそうなので備忘としてメモ

## シンプルなメールの確認方法

mailxなどをサーバーにインストールして確認する。

`$ yum install mailx`

以下コピペして確認


`$ echo “test” | mail -s $Subject -S $SMTP_Server -r $From_Address $To_Address`


## telnetから直接アクセスして確認する場合

telnetコマンドでipまたはドメインと25番ポートを指定してアクセスする。

```
$ telnet xxx.xxx.xxx.xxx 25

Resolving host xxx.xxx.xxx.xxx  . . . done.
Connecting to xxx.xxx.xxx.xxx  . . . connected.
220 mail.example.com ESMTP Postfix
>>> HELO test.example.com
250 mail.example.com
>>> MAIL FROM:<from@example.com>
250 2.1.0 Ok
>>> RCPT TO:<to@example.com>
250 2.1.5 Ok
>>> DATA
354 End data with <CR><LF>.<CR><LF>
>>> .
250 2.0.0 Ok: queued as E44xxxxxxx
>>> QUIT
221 2.0.0 Bye
```

## 参考URL
[mailコマンドでSMTPサーバを指定してメール送信する方法 | ぴぐろぐ](https://pig-log.com/mail-smtp-linux/)
[Telnet を使用して SMTP 通信をテストする: Exchange 2013 のヘルプ | Microsoft Docs](https://docs.microsoft.com/ja-jp/exchange/use-telnet-to-test-smtp-communication-exchange-2013-help)
僕たちが『webpack』を使うワケとは？

#そもそもwebpackとは？
Node.jsをサーバーサイドで動かすモジュールバンドラーの事。
複数のモジュールをまとめる役割があります。

分かりやすく言いますと、

**JS、sass、画像ファイルを一つのJSファイルにまとめてくれます。**

まとめることが出来るのはわかりましたが、そのことにどんなメリットがあるのでしょうか？

#webpackでモジュールをまとめるメリットは？
開発者側だけではなく、ユーザー側にもメリットがあります。

・可読性の向上
・コードの再利用
→モジュールで分けたコードを他案件で使える
・JS以外に、CSSや画像もバンドル可能
・読み込み速度向上（ユーザー側）

#npmやyarnとの違いは？
npmやyarn：フレームワークの管理
webpack：ファイルの生成。コーディングの手助け。

#参考
[Webpackってどんなもの？](https://qiita.com/kamykn/items/45fb4690ace32216ca25)

[webpackとは？使い方と導入するメリットをわかりやすく解説](https://goworkship.com/magazine/how-to-webpack/)
Goでの構造体埋め込みと、埋め込んだ構造体に構造体を代入する

構造体の埋め込みについてはよく書いてあるのだけど
埋め込んだ構造体に、埋め込んだ元の構造体を代入する方法があまりなかったのでメモ

### 埋め込み
```
	type A struct {
		A string
	}
	type B struct {
		B string
	}

	type C struct {
		*A
		*B
	}
```

### 代入
```
	a := new(A)
	b := new(B)
	c := new(C)

	a.A = "hoge"
	b.B = "hage"

	c = &C{B: b} // CにBを代入
```

### 代入済みのCにAを追加
        
```
	c = &C{
		A: a,
		B: c.B,
	}
```
『開発チーム　組織と人の成長戦略』より「人事管理の導入」についてまとめ

#開発チーム　組織と人の成長戦略

https://www.amazon.co.jp/dp/B0894PYT15/

この記事では、４章２節「人事管理の導入」について記載されていることをまとめました。
（一部４章１節、３節の内容にも踏み込んでいます）

**太字部分は私個人が特に印象的に感じた点、**<font color="Red">赤字の部分は私個人の所感・注釈です</font>

#フォーマルな人事管理の必要性
* 人事管理は、次の３つの領域のマネジメントとは明確に異なる。
    * テクニカルマネジメント
        * チームが技術的な意思決定を適性に下すよう計らう仕事
    * プロジェクトマネジメント
        * プロジェクトが計画通りに進行、完遂されるよう管理する仕事
    * プロダクトマネジメント
        *  顧客の望む製品が構築されるよう管理する仕事
     
* 「共通の目標を達成するための骨格と筋肉をチームに与えてくれるのが、適正な人事管理なのだ」by ジョー・ゼイビアー 
* 創業フェーズではフォーマルな管理者を設置せず、創業者が直接エンジニアを束ねるケースが多い（アドホックな人事管理）
* アドホックな管理手法の効果は、チームが成長拡大するにつれて薄れてくる
* フォーマルな管理体制への移行が必要なフェーズに来ているのに、恐れや惰性で先延ばしにしているケースが多々ある
    * 人事管理にまつわる過去の不快な経験に基づいた先延ばし
        * **過去にひどい管理者の下で悲惨な経験をしたことのある幹部が「管理者なんて百害あって一利なしだ」と感じている**
    * 文化的な抵抗感による先延ばし
        * **一般社員であるチームメンバーの職位を上げたほうがよい、との考えが根底にあったりする**
        * スタートアップの間では**「フラットな組織構造」の良さをほめそやす傾向**があるが、その実「優れた管理者の真価に対する無理解」や」「ひどい管理者を雇ってしまった場合のダメージへの恐れ」「管理者の優劣を見分ける能力に対する自身のなさ」といった素因が隠れていることもある

<font color="Red">私を含めてですが**フラットな組織信仰**を持っているエンジニアは意外と多いと思われます。ただ現実問題としてフラットな組織体制のまま成長を続けられる企業はほとんど存在しないので、やはりどこかのタイミングで管理体制の整備に舵をとるべきでしょう。</font> 

#自社の希望や目標を把握し、チームの態勢固めを

* 自分たちがどういった人事管理の文化を臨んでいるのかを把握しておく
    * 管理者に対してどのようなことを期待するのか
    * **それがテックリードやプロダクトマネージャーなど既存の関連職位に対するものとどう異なるのか**
    * 人事管理者は主としてどの領域に焦点を当てるべきなのか

<font color="Red">マネージャーの職務・職権がどこからどこまでなのかを定義することはどの組織でも難航しそうですね。テックリードやPMに権限委譲しすぎるとマネージャーの職務がスカスカになりますし、そんな綺麗に分業できるほど人材が豊富な組織は少ないと思われるので。</font> 
* キャリアパスの規定は草創期から必要
    * **「エンジニアはいわば二流の市民。管理職に『格上げ』してやらなければキャリアアップは望めない」との誤った認識を正す**
    * 人事管理者のポストは、技術職とはまるで違う資質を要求される、まったく異なる職位
    * 「並外れた技術力」を「管理者としての可能性」と混同してはならない
    * 「コーディングの腕前がピカイチのエンジニアを管理者に抜擢したいという誘惑に負けてはならない。（中略）管理はコードではなく人を扱う仕事だ」by ティム・ハウズ

<font color="Red">後続の節でも同様の話題が出てきますが、**”優秀なエンジニアがマネージャーにされちゃう問題”**は海外でも頻出している模様ですね。エンジニアリングチームのマネージャーは、優秀なエンジニアが務めるべきか、平凡なエンジニアが務めるべきか、はたまた外部から引っ張ってきた赤の他人が務めるべきか、難しい問題です。</font> 
    
#変更計画の公表と実施

* 管理体制を当たらに導入するのは気を使う大変な仕事
* 管理体制変更の理由と意図は極力明確に説明するべき
* 好ましくない公表のしかた

```CEO: はい、皆さん、聞いてください。本日付で大きな変更を実施します。人事管理社が必要だとの経営判断に従い、管理者にB氏を任命しました。今日からB氏の直属となるのは次の方々です。Cさん、Dさん、Eさん、・・・
みんな: えぇーっ！
```
* 過去にひどい管理者の下で苦労させられた覚えがあり、管理者の存在を煙たがる者は多い
* 人事管理のポストを創設することで得られると期待される価値や、管理者の勤務成績の評価方法の案を、十分に時間を割いてきちんと説明する必要がある

<font color="Red">日本人お得意の**ネマワシ**です！！この辺りの進め方の丁寧さは古典的な日本企業に一日の長があることは間違いないと思います。全くの余談ですが、[Wikipediaの英語ページにNemawashiの項目](https://en.wikipedia.org/wiki/Nemawashi)がありましたw</font> 

#新任管理者の紹介はあくまで地味にひっそりと
* エンジニアの管理者への鞍替えは、「職責の大きな変化」であり「昇進」ではない
* あなたが新任管理者に対してどれほど深く感謝の念を抱いているとしても、皆に紹介する場でほめそやしたい気持ちは抑えなければならない
    * **「実力を認めたければ管理職になるのが一番」「昇進する上での最良の方法は管理職への転身」との誤った認識を招く恐れがある**
    * 管理の職務を引き受けたメンバーが、その職務に不適であったり興味を失った場合、元のポジションに戻りにくくなる恐れがある

<font color="Red">残念ながら「実力を認めたければ管理職になるのが一番」「昇進する上での最良の方法は管理職への転身」はほとんどの組織で当てはまってしまっていると思われます。エンジニア、管理職の給与を比較した比較的新しいデータが[こちら](https://www.technoproholdings.com/news/detail.php?id=7026)にあります。</font>
Appleに開発者登録をしたときに、まずすること・してはいけないこと

　Appleは最近セキュリティーに厳しく、開発者登録を行い、公証を受けたアプリケーションでないとこのアプリケーションは悪意を持つソフトの可能性がある旨のメッセージが出るようになりました。

　そこで開発者登録し、公証を受けた野良アプリを作る際に最初にやるべき事、やってはいけない事を自分の失敗から、同じ失敗をしないように、この記事を読んで下さった方のために纏めたいと思います。

## 開発者アカウントをXcodeに追加する

　証明書の作成はdeveloper.apple.comのサインイン後のページからもできますが、
Xcodeのアカウント環境設定から行うのが確実で良いかと思います。

　まずは、環境設定の`Accounts`タブへ移動し、画面一番したの`+`ボタンで開発者登録したメールアドレスを追加します。
<img width="802" alt="Account.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20251/53f794db-a2b7-c31f-e7ba-31937fa7b324.png">

## 開発者証明を作成する

　`AppStore`のアカウント作成は色々資料があると思うので割愛します。
今回の目的は、公証を受けた野良アプリ（自サイトで配布するアプリケーション）なので、作成する証明書は、`Developper ID Application`になります。
![Certificate.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20251/979ad478-d0aa-755b-e883-b249debacfbd.png)
　これを`Xcode`から作成するには、追加したアカウントの右側のペインの右下にある`Manage Certificate`ボタンを押します。
すると表示されるのが下の様なウィンドウになると思います。
僕の場合は、すでにアカウントを作成しているので黒文字・グレイ文字の行がいくつかありますが最初は行が一つも存在しないかと思います。

ここで、画面左下の`+ ∨`ボタンを押して、`Developper ID Application`を選んで下さい。

## 作成した開発者証明書を保存する

　上の作業で、`Developer ID Application`に黒文字で証明書が一つ追加されたと思います。
ここで、まず最初にこの証明書をエクスポートして保存しておきます。
　証明書の保存方法は黒地の`Developer ID Application`を右クリックして、`Export Certificate...`を選びます。
保存場所は自分がわかる場所ならどこでも構いません。パスワードも人に渡すものでもないのでそう難しいパスワードで無くても良いと思います。
<img width="599" alt="SaveCertificate.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20251/13df2467-c669-bef7-f3e9-219220b36724.png">
パスワードと、チェック用にもう一度同じパスワードを入力したら、`Save`ボタンを押すと`付けた名前.p12`というファイルが作成されます。これがプライベートキー付き証明書になります

## エクスポートした証明書から証明を復旧する

　作成された`.p12`ファイルをダブルクリックすると、`KeyChain`に証明書が追加されます。
確認は、`KeyChain Access`アプリケーションの`ログイン`→`証明書`で右側のペインに読み込んだ証明書が表示されます。
![KeyChain.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20251/2f633041-6bfd-7394-4ab3-ea3befe0de13.png)

## 余談かつ戒め

　注意すべきはこの開発者証明書、取り消しが出来なくて、しかも作成できる上限が5つと少し少なめです。
そのため、マシンをクリーンインストールした・買い換えたなどで証明書を発行しまくると、あっという間にパンクしてしまいます。
それを防ぐためにも証明書はこの、プライベートキーがある状態で保存しておき、特別な理由がない限りそれを再インポートして使うべきです。

　なぜ、[Appleの開発者ページ](developer.apple.com)で証明書を作成し、ダウンロードしたものをダブルクリックでキーチェーンに追加しないか？というと、**ダウンロードされた証明書にはプライベートキーが含まれていない**ため、ダウンロードした証明書をバックアップして安心してしまうのが危険だからです。

 そこで、Xcodeでプライベートキー付きの証明書をダウンロードして、余計なファイルを作らず、それをエクスポートした「プライベートキー付き証明書」(=`.p12`ファイルで`.cer`ファイルではないことに注意)を管理することを強くお勧めします。

　証明書の復旧が必用なときはこのファイルをダブルクリックして`KeyChain`に追加して下さい。
そして、このファイルはマシンが不慮の事態でクラッシュしたときに影響を受けないように、物理的に別なディスクやUSBメモリーカードなどにコピーを作っておくのが良いと思います。

## お付き合い下さりありがとうございました
Smart CAML ツールについて 

# はじめに  

SharePoint等で使われるCAML(Collaborative Application Markup Language)はSharePointをカスタムするうえで知っておいて損はないマークアップ言語なのですが、いかんせんMicrosoftの提供している資料もわかりづらく、エディタもなかなかない。
そんな中で、少し便利なツールを最近見つけましたので紹介します。

※参考　Microsoft　DocsのCAML概要
　https://docs.microsoft.com/ja-jp/sharepoint/dev/schema/collaborative-application-markup-language-caml-schemas

## SmartCAML
プルダウン方式でクエリーを組み立ててゆくツールです。
以下から入手することができます。

https://www.microsoft.com/ja-jp/p/smartcaml/9nn8gjpnxvfg
※Windowsストアアプリです。

システム要件はWindows10以上。標準的なマシンならインストールはできると思います。

【ストアの画面】

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147937/4410d544-db37-78ba-757f-55dad2e82c07.png)

インストールして起動するとサイトを入力する画面が出てくるので、サイト名とアカウント情報を入力

![無題９９.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147937/594f6bea-ee4b-0d0a-2ef6-222cfb3c9330.png)

こんな画面が起動します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147937/1f7e9b51-7756-3bf2-2b4f-57166648263f.png)

左ペインにリストやらライブラリーやらが並びます。システムのリストが見えてしまっているので注意してください

対象となるリストを選択し「New Query」ボタンを押すと、クエリービルダーが起動します
![無題98.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147937/620032d5-d01b-8e21-9f05-e5c23df6c14e.png)

ビルダ画面で項目名やAnd or　をいじって「Run Query」ボタンを押すと、実行結果が下ペインに表示されます
![無題97.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147937/1b1e73b1-85fb-85c8-3f9c-f951c8066718.png)

結果が問題なければ、「XML」タブを開いてみてください。
CAMLクエリーが生成されています。
![無題96.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147937/209c3fed-628e-2a4d-bb76-070cf90927ce.png)

これをペタペタ張り付ければ、完成です。

# 最後に
はじめてQittaに投稿しました。
CAMLはもう使うこともないと思っていたんですが、モダンのWebパーツでちらほらと出てきています。
書式JSONも大事ですが、こんな旧技術も生きていますといういうことで
[Rails][Turbolinks] inline Javascript が実行されない 解決法



Javascript周り の取り扱いが難しい `Turbolinks`。


# 起こったこと
ページ毎に任意の`Javascript` を実行したいが
普通に書いたら以下エラー。

ページ遷移でも同様。

``` js:ChromeDeveloperConsole
Refused to execute inline script because it violates the following Content Security Policy directive: 
"script-src 'self' https: 'unsafe-inline' 'nonce-UiVx2CiP0HHN9jOOSEG43g=='". 
Note that 'unsafe-inline' is ignored if either a hash or nonce value is present in the source list.
```


`Content-Security-Policy (CSP)` (Cross Site Scripting (XSS) や data injection 攻撃を防ぐための HTTP の仕様)のために
ブラウザでの Javascript 実行が制限されている。

https://qiita.com/tearoom6/items/30e3aacaa432860d4b36

# 解決法

Rails 側で nonce を発行し、Javascript を認証する。
(HTTPヘッダに追加)


``` views/layouts/head.html.slim
= csp_meta_tag
```


``` config/initializers/content_security_policy.rb
Rails.application.config.content_security_policy_nonce_generator = -> (request) do
  # use the same csp nonce for turbolinks requests
  if request.env['HTTP_TURBOLINKS_REFERRER'].present?
    request.env['HTTP_X_TURBOLINKS_NONCE']
  else
    SecureRandom.base64(16)
  end
```

script タグに nonce をつける

``` some_page.html.slim
= javascript_tag, nonce: true
 | console.log('JS here');
```


Turbolinks の`Event` に合わせて、nonce を入れ替える。

``` application.js
document.addEventListener('turbolinks:request-start', function(event) {
  var nonceTag = document.querySelector("meta[name='csp-nonce']");
  if (nonceTag) event.data.xhr.setRequestHeader('X-Turbolinks-Nonce', nonceTag.content);
});
document.addEventListener('turbolinks:before-cache', function() {
  Array.prototype.forEach.call(document.querySelectorAll('script[nonce]'), function(element) {
    if (element.nonce) element.setAttribute('nonce', element.nonce);
  });
});
```




# Turbolinks Event list

https://github.com/turbolinks/turbolinks#full-list-of-events


# 参考

https://github.com/turbolinks/turbolinks/issues/430

https://discuss.rubyonrails.org/t/turbolinks-broken-by-default-with-a-secure-csp/74790

https://github.com/thredded/thredded/pull/797/commits/beac77f9c7ac0c880afac3302f752157f2945afe


https://stackoverflow.com/questions/57044770/what-is-csp-meta-tag-in-rails-5-2-3-and-how-does-it-work

https://y-yagi.hatenablog.com/entry/2018/02/24/070139

https://site-builder.wiki/posts/1050
Custom Laravel7 Flash Message Examples Tutorial

This tutorial is designed to give you Laravel 7 Flash Message example, mutually we will learn to how to integrate and use flash message in laravel 7. We would shed light on flash message example in laravel after login. Possibly, this is required in almost every application, be it built with laravel or any other language or framework.


click here to read more:
https://www.positronx.io/custom-laravel-flesh-message-examples-tutorial/
Laravel7 Notification Tutorial – Create Notification in Laravel

Today is our lucky day, and We will know how to send a notification in laravel 7. Laravel mechanism is getting stronger day by day, and we all know it. The laravel notification system not just supports mail but it also goes smooth with the database, broadcasting, sms, slack, markdown etc.

click here to read more:
https://www.positronx.io/laravel-notification-example-create-notification-in-laravel/
Angular 10 Popup Notification with  Example

This tutorial explains to you how to show an alert or popup notification in Angular 10 with SweetAlert2 npm package. We will learn how to use sweetalert2 in angular altogether, and learn how to display the alert boxes with user-centric information.

click here to read more:
https://www.positronx.io/angular-popup-notification-with-sweetalert2-example/
form_withがUndefinedエラーになったので、railsのバージョンをあげたらrails sが立ち上がらなくなった話 

railsで入力フォームを作ろうをしたら

undefined method `form_with' for #<#<Class:0x00007fdef2555c48>:0x00007fdef1211178>
Did you mean?  form_tag

とエラー。

どうやらform_withはrails5.1以降の機能だったらしい。


なのでrailsのバージョンをあげることに

```Gemfile:Gemfile
gem 'rails', '5.2.1'
```

そして  bundle install

無事にバージョンアップに成功！

しかし　rails s したところ

undefined method `halt_callback_chains_on_return_false=' for ActiveSupport:Module (NoMethodError)

と言われる。
どうやらhalt_callback_chains_on_return_falseはRails 4との後方互換のためのメソッドで、定義されていないメソッドだと言われる。
なのでターミナルにて

```tex:ターミナル
vi config/initializers/new_framework_defaults.rb
```

```ruby:config/initializers/new_framework_defaults.rb
ActiveSupport.halt_callback_chains_on_return_false = false
```

をコメントアウトでok!

無事にrails s 立ち上がりました！
JavaScript で wait

# 何をしたいの

JavaScript で wait をしたい。段階的に何かを表示するとかの演出に使うかもしれない。
setTimeout の入れ子とか、再帰的に書くのとかを回避するとか、Exponential Backoff したかったりする場合とかにも使える。

# どう書くの

```JavaScript
const wait = (msec)=>{
  return new Promise((resolve)=>{
    setTimeout(()=>{resolve(msec)}, msec);
  });
};
```

# どう使うの

素直に Promise を利用して次のように記述できる。

```javascript
const waitBehavior1 = () => {
  const before = Number(new Date());
  wait(1250).then((waitLength) => {
    const after = Number(new Date());
    console.log(after - before);
  });
};
```

ループで回したりするのには不便。

```javascript
const LOOP_REQUEST_COUNT = 3;
const waitBehavior2 = (loopCount) => {
  if(loopCount) {
    wait(1250).then((waitLength) => {
      console.log(`${LOOP_REQUEST_COUNT  - loopCount + 1}週目`);
      waitBehavior2(loopCount - 1);
    });
  } else {
    console.log('おしまい');
  }
};
waitBehavior2(LOOP_REQUEST_COUNT);
```

# 入れ子にしないで使う

本題。async と await に頼るといい感じに書ける。

```javascript
const waitBehavior3 = async () => { // async を入れないとだめ
  const before = Number(new Date());
  await wait(1250); // ここも await を入れないとだめ
  const after = Number(new Date());
  console.log(after - before);
};

waitBehavior3();
```

これならループも簡単

```javascript
const waitBehavior5 = async () => { // async を入れないとだめ
  const before = Number(new Date());
  for(let i = 0; i < 3; i++) {
    await wait(1250); // ここも await を入れないとだめ
  }
  const after = Number(new Date());
  console.log(after - before);
};

waitBehavior5();
```

ただ、以下のような使い方はできないので注意。

```javascript
// ほぼ同時に ぱんだ、うさぎ、こあらが console.log される
waitBehavior6 = () => {
  ['ぱんだ', 'うさぎ', 'こあら'].forEach(async (animal)=>{
    await wait(1250);
    console.log(`${animal} ${Number(new Date())}`);
  });
};
```
PHPでアクセスされているURLを取得

現在のURLを取得する方法です。
必要なのは【プロトコル】【ホスト】【パス】の3つで、それぞれを組み合わせてURLを表示させます。






##【プロトコル】 (HTTP or HTTPS)の判定
HTTPでのアクセスか、HTTPSでのアクセスなのかを判定。

```php

echo $_SERVER['HTTPS'];
```
<b>実行結果</b>

```
'on'
```
HTTPSでのアクセスの場合は'on'
HTTPでのアクセスの場合はNULLとなります。

##アクセスされているページの【プロトコル】を取得
httpやhttpsなどのプロトコルを取得します。
HTTPSではなかったら、$_SERVERのHTTPSは空になりhttpを表示、そうではなかったらhttpsを表示。

```php
echo (empty($_SERVER['HTTPS']) ? 'http://' : 'https://')
```
<b>実行結果</b>

```
'https://'
```


##アクセスされているページの【ホスト】を取得
ホスト名（ドメイン部分）を取得します。

```php
echo $_SERVER['HTTP_HOST'];
```
<b>実行結果</b>

```
'localhost'
```


##アクセスされているページの【パス】を取得
httpやhttpsなどのプロトコル名やサーバーのドメイン名(ホスト名)を除いた、ページURLを取得します。

```php
echo $_SERVER['REQUEST_URI'];
```
<b>実行結果</b>

```
'/index.php'
```



#実際に現在のURLを取得する！
上記で書いた【プロトコル】【ホスト】【パス】がの組み合わせが現在のURLになるため、下記のように書くことで、URLを取得することができます。

```php
echo (empty($_SERVER['HTTPS']) ? 'http://' : 'https://') . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
```
<b>実行結果</b>

```
'http://localhost/index.php'
```

##まとめ
複数ページのSNSシェア設定部分のテンプレ化をしたくてURLの取得をしてみました。
画像サイズについて

＜Navigation Drawerに表示するヘッダの画像サイズについて＞
Navigation Drawerの幅は240〜320dpにすべき
https://qiita.com/nein37/items/6c57fe5ec94a7914872c

＜画像サイズについて＞
Androidにおいて、一般的なスマートフォンの横幅は320-384dp
xxxhdpi  640dpi以下で作成
xxhdpi   480dpi以下で作成
xhdpi   320dpi以下で作成
hdpi  240dpi以下で作成
mdpi    160dpi以下で作成

iOSにおいて、320pxはiPhone 3GS非Retinaの画面幅いっぱいのサイズ
->Retinaはそこから倍数だったが、途中から中途半端になってきた
（iPhone 4 ~ 5sまでは Retinaで = 640)
https://qiita.com/Yuta/items/98b9ea2739718b9184de
https://backapp.co.jp/blog/11573/#Android_dp_iOS_Retina
https://www.webtech.co.jp/blog/optpix_labs/6915/


＜例：320dpの画像を作成依頼するとき＞
幅320dpで指定。高さはお好み

1dp=
mdpi:1px
hdpi:1.5px
xhdpi:2px
xxhdpi:3px
xxxhdpi:4px

なので、横幅320dpの画像が欲しい場合は以下で作成する

320px x 高さ任意
->【Android】mdpiで使用【iOS】非Retina端末で使用
480px x 高さ任意
->【Android】hdpiで使用
640px x 高さ任意
->【Android】xhdpiで使用【iOS】@2xで使用
960px x 高さ任意
->【Android】xxhdpiで使用【iOS】@3xで使用
1280px x 高さ任意
->【Android】xxxhdpiで使用

＜背景を透明にし、不要な背景部分をカットし、画像サイズを変える＞

背景を透過にする->pngに変換される
https://qiita.com/na1412/items/90a9641d9644e1bfbb49

トリミング（不要な背景を削除）
http://www.mac-beginner.com/77.html

画像サイズを変える(解像度も変えられる)
https://www.fusenhonpo.com/submit/popup_mac.html
->@x2と@x3が必要なので、@x3の「幅」を3/2の長さで指定してやれば良い

反転はプレビュー.appで行う。
【Windows】ドメインユーザーのリモートデスクトップ許可設定

ドメインユーザーのRDP許可設定の話。

ActiveDirectoryに参加しているコンピューター`Windows01`と`Windows02`があって、ドメインユーザー`User01`と`User02`があったとします。

`RemoteDesktopUsers`グループにUser01,User02を追加した状態で、コンピューターWindows01,Windows02それぞれRemoteDesktopUsersグループにリモートログイン権限をつけると、User01,User02はWindows01,Windows02両方にRDPできますが、
たとえばチームごとに踏み台を分けるとかで、Windows01はUser01だけ、Windows02はUser02だけRDPさせる時は以下のように設定します。

# 1.RemoteDesktopUsersグループにユーザーを追加する

`[コントロールパネル]→[システム]→[リモートの設定]から、
「このコンピューターへのリモート接続を許可する」にチェックを入れて、
[ユーザーの選択]`から追加します。

![20200712141054.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/673840/430fa287-4946-1ad5-9c2c-cc0fc9564359.png)
`[コンピューターの管理]→[ローカルユーザーとグループ]と移動して、リモートデスクトップを許可したいユーザープロパティの[所属するグループ]タブよりRemoteDesktopUsersグループを追加する`ことでも設定できます。※上記と同じウィンドウが開きます。
ちなみに、AdministratorsグループはデフォルトでRDPできるようになっています。

ここで注意なのが、ドメインユーザーなので、RemoteDesktopUsersグループに追加すると、RemoteDesktopUsersにRDP権限があるコンピューターすべてにRDPできてしまいます。
ということで、コンピューターのRDP権限をいじりましょう。

# 2.コンピューターごとにリモートログイン権限を割り当てる
グループポリシーエディター(gpedit.msc)を開いて、
`[コンピューターの構成]→[Windowsの設定]→[セキュリティの設定]→
[ローカルポリシー]→[ユーザー権利の割り当て]から、
「リモートデスクトップサービスを使ったログオンを拒否」`を確認します。
![20200712143315.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/673840/055af3fc-e696-ea26-620c-48fa7e1bf070.png)
許可には`[Administrators]`と`[RemoteDesktopUsers]`が入っているため、拒否の方で
<font color="Blue">RDPを拒否するユーザーを指定する</font>ことでリモートログインできるユーザーを絞ることができます。
<br>
# 3.確認
RDPで繋いだ時にそもそもウィンドウが開かない場合はリモートセッション自体ができていない＝**"RemoteDesktopUsersに入っていない"** ため、上記1.の方法を確認します。

2.の項目で拒否できている場合は、リモートセッションはできていますが以下のような画面が出てRDPできません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/673840/abc91994-bccf-955b-b9f3-9fccad2c75d8.png)

上記以外でも、
例えばRemoteDesktopUsersグループを追加で作成したり、そもそもOUで分けたりと方法は色々ありますので、
運用ポリシーに従って設定しましょう。

以上。
Chromium版 Edge で、指定したプロファイルで起動するためのコマンド

# Edge Chromium は複数プロファイルを作成できます

Microsoft Edge でサインインして複数のプロファイルを作成する
- https://support.microsoft.com/ja-jp/office/microsoft-edge-%E3%81%A7%E3%82%B5%E3%82%A4%E3%83%B3%E3%82%A4%E3%83%B3%E3%81%97%E3%81%A6%E8%A4%87%E6%95%B0%E3%81%AE%E3%83%97%E3%83%AD%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B-df94e622-2061-49ae-ad1d-6f0e43ce6435

# 起動コマンドラインはこちら

"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --profile-directory="プロファイルディレクトリ"

## プロファイルディレクトリを調べるには？

以下に作られています。
 %%AppData%%\Local\Microsoft\Edge\User Data\

### 標準プロファイルで起動する

"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --profile-directory="Default"

### 追加したプロファイル（Profile 1）で起動する

"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --profile-directory="Profile 1"
Couldn't find ModelName with 'id'=batch_action

Rails 4.2.0
activeadmin (1.0.0.pre1)

active_adminで
タイトルのようなエラーが出ました。
# 解決方法

```ruby:app/admin/model_name.rb
ActiveAdmin.register ModelName do
  #これをかく
  config.batch_actions = false
end
```
Nuxt.js【Unexpected token 'export'】エラーの対処法


Nuxt.jsで、下記エラーが出た時に対処した方法です。　

```
Unexpected token 'export'
```

## プラグインをnuxt.config.jsで読み込む際に【Unexpected token 'export'】が発生

```nuxt.config.js
export default {
  plugins: [{ src: '~/plugins/vee-validate.js' }],
}

```
フォーム検証用のライブラリであるVeeValidateをプラグインに設定しようとした時に発生しました。

## transpileの設定を追加することで解決

```nuxt.config.js
export default {
  plugins: [{ src: '~/plugins/vee-validate.js' }],
  build: {
    transpile: ['vee-validate'], // 追加
    extend(config, ctx) {}
  }
}

```
nuxt.config.jsにtranspileの設定をすることで解決することができました。
Slackアプリのインストール種別

Slack botなどのアプリの開発をする上で、開発したアプリをインストールする方法は4種類ほどある。
最初よくわからず手戻りが発生して面倒だったのでまとめた。

こちらのURLからアプリを管理できる。
https://api.slack.com/apps/

# インストール種別

## 所属ワークスペースへのインストール(直接)

- **インストール先**
アプリには所属するワークスペースというものがあり、アプリ作成時の初期設定で決まる。
今のところ、あとから変更できないので慎重に決める。
この方法では所属ワークスペースにしかインストールできない。

- **インストール方法**
インストール作業自体は一番簡単で、アプリ管理画面で Install App ボタンを押すだけでインストールできる。

- **botトークン**
botトークンはアプリ管理画面から取得できる。

## 所属ワークスペースへのインストール(OAuthフロー)

- **インストール先**
この方法でも所属ワークスペースにしかインストールできない。
他のワークスペースにインストールしようとすると `invalid_team_for_non_distributed_app` エラーがでてインストールに失敗する。

- **インストール方法**
OAuthフローは普通のSlackアプリをインストールする時のフローなので見たことがあるはず。
このアプリはこういう権限を要求してるがインストールしてよいか？とインストール承認画面で聞いてくるやつ。
違いはワークスペースの選択ができないこと。
事前にアプリ管理画面でRedirectURLを設定する必要がある。RedirectURLについては後述。

- **botトークン**
認可後にRedirectURLに認可コード付きで戻ってくるので、それを使ってbotトークンを取得できる。
OAuthフローでのインストール課程でbotトークンが手に入るので、トークンをDBに保存しておく必要がある。
自作のbotでは、チームIDとenvをキーにインストール情報を丸ごとDynamoDBに保存した。

## 他のワークスペースへのインストール

- **インストール先**
どのワークスペースでもインストールできるようにするには、アプリを公開する必要がある。公開することと、Slack App Directoryに登録することは別。
公開自体はアプリ管理画面で Activate Public Distribution ボタンを押すだけで完了する。
公開するとインストール承認画面の右上からワークスペースを選択できるようになる。逆にインストールURLが分かれば誰でもインストールできるようになる。

- **インストール方法**
所属ワークスペースへのインストールと同じ。

- **botトークン**
所属ワークスペースへのインストールと同じ。

## Slack App Directoryへの登録

- **インストール先**
他のワークスペースへのインストールと同じ。

- **インストール方法**
公開した上で更にチェックリストをクリアするとSlack App Directoryに登録できる。
Slack App Directoryに登録すると https://slack.com/apps からインストールできるようになる。

- **botトークン**
所属ワークスペースへのインストールと同じ。

# 追加開発や必要な設定

## OAuth認可コード発行後のリダイレクトURLの設定

bot側でOAuthフローを実装した上で OAuth & Permissions から Redirect URLs の設定を行う。
`@slack/bolt` や `@slack/oauth` のデフォルト設定では `/slack/oauth_redirect` のパスに対応しているので、そのまま設定すればよい。
設定値は `https://bot.example.com/slack/oauth_redirect` のようになる。

## アンインストール/トークン無効化時の対応

アンインストールやトークンの無効化をされた時にインストール情報をDBから削除するため `tokens_revoked` イベントを受け取るようbot設定を変更する必要がある。
`app_uninstalled` イベントも用意されているが、アンインストール時には `tokens_revoked` イベントも発火するのでトークンの削除が目的であれば `tokens_revoked` イベントを設定すればよいと思う。
設定はアプリ管理画面の Event Subscriptions から行う。

## トークン管理処理

所属ワークスペースへのインストール(直接)の場合、アプリ管理画面からbotトークンを取得できる。
ただコピーしてくるだけなので、bot起動時にトークンをアプリに直接渡すことになる(環境変数など)。
他ワークスペースにインストールできるようにする場合には追加開発が必要になる。
fadeIn()を使うには先に非表示を

#jQuery fadeIn()を使えない？

動的に追加した要素をフェードインさせたい。
fadeIn()は要素が非表示になっている状態でないと使えない。
これを忘れててフェードインできないできない、と悩みました。

解決策は2パターン。

* パターン1
CSSで対象要素を非表示display:none;にしておく。

* パターン2
hide()で一度非表示にする。


今回は動的に要素を追加するためパターン2を採用。

```js
$('body').append(`<div><img src="${src}"></div>`);
$('div').hide().fadeIn();
```
MacOSでHHKBがうまくBluetooth接続できなくなったときの対処法

# 概要
HHKB HYBRID などの Bluetooth 接続の HHKB を使っているとき、たまに接続がうまくいかないことがあります。
そのときの対処法をいつも忘れてマニュアルを探しにいく羽目になるのでまとめておく。

# 検証環境
macOS Mojave 10.14.6
HHKB HYBRID 英語配列

# 対処法
## HHKB の電源を入れ直す
一番簡単な対処法で、まれにこの方法で直ります。
接続にやや時間がかかることがあり、電源を入れ直してから少し長めに待つと接続されることがあります。

## MacOS 自体の Bluetooth を一度 OFF にする
2番目に簡単な対処法で、私は大抵の場合これで直ります。

## [本題] それでも直らないときは
上記の方法で直らない場合は **ペアリング情報の削除** を行います。
今のところこれで直らなかったケースには出会っていませんが、手順が長くて面倒くさいのが難点です。

1. MacOS の設定から Bluetooth の設定画面を開く
<img width="670" alt="システム環境設定_と_案件管理___スポットコンサル_ビザスク_.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114828/2d9d1120-4d09-4ee2-60e0-86d5028723c7.png">

2. デバイス一覧にある HHKB を削除する
<img width="669" alt="Bluetooth_と_案件管理___スポットコンサル_ビザスク_1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114828/e6bbf938-47d3-6452-6ea2-b8e3b4e1d6bb.png">

3. HHKB の電源が ON の状態で [Fn] キーを押しながら [Q] キー を押してペアリング待機モードにする
ペアリング待機モードになると LED インジケーターが緑色で点滅する

4. ペアリング情報の削除操作
    1. すべてのペアリング情報を削除する場合  
    [Fn] キーを押しながら [Z] キーと [Delete] キーを押す（LED インジケーターが橙色に点灯し、完了後に消灯する）  
※ HHKB Professional BT も同様の操作でペアリング情報の削除ができる  
※ SW3 スイッチで [Delete] キーに Backspace を割り当てている場合は、 [Delete] キーの替わりに [ ` ] （バッククォート） キーを押す

    2. 個別にペアリング情報を削除する場合  
    [Fn] キーを押しながら [Ctrl] キーと [Delete] キーを押し、そのままさらにペアリング情報を登録している 1~4 のいずれかのキーを押す

5. Bluetooth 設定画面に表示された HHKB の [接続] ボタンを押す
<img width="669" alt="Bluetooth_と_案件管理___スポットコンサル_ビザスク_.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114828/bd3291d6-58cd-f3c8-11f2-a67bf0bb9e6a.png">

6. 接続要求が表示されるので表示されている数字キーを押して [return] キーを押してから [接続] ボタンを押す
<img width="508" alt="接続要求元__HHKB-Hybrid_1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114828/c51043a4-ba94-1442-b3de-36b8a338da1e.png">

7. 完了！

# 参考
[HHKB HYBRID マニュアル](https://origin.pfultd.com/downloads/hhkb/manual/P3PC-6641-01.pdf)
[HHKB Professional BT マニュアル](https://www.pfu.fujitsu.com/hhkeyboard/manual/P3PC-5931-01.pdf)
指定文字数の文字列出力　絶対値の出力

アウトプットの簡単な備忘録です。

絶対値
---------------------------------------

```
n = gets.to_i

puts n.abs 
```

入力値　-15

出力結果　15


文字列表示
---------------------------------------
```ruby:qiita.rb
n = gets.to_i - 1
s = gets.chomp


puts  s.slice(0..n)
```

入力値　4
      aiueo
出力結果　aiue






２個目のスタートはどうしても０から取り出すっぽいので
入力した値-1が必要にななってしまいました。（文字数を０個出力って入力することは恐らくありませんから）
もっと良い取り出し方ないのだろうか
baserCMS、Chromeでログインできなくなる

baserCMSのデモサイトが、いつの間にかChromeで管理画面にログインできなくなっていた。

SafariでもFirefoxでも問題ない。なんだこれ。

調査したところ、どうやらCSRFチェック用のトークンがセッションに保存できていない。

あれや。Chromeのアップデート、Cookie周りの変更の影響や。

SSLを導入したらなおりました＾＾
【Python】AttributeError: 'list' object has no attribute 'replace'

Pythonのスクレイピングを勉強中、値の加工をしていたら`AttributeError: 'list' object has no attribute 'replace'`が出たので、メモで対策を残します

## エラーが出た原因
以下のように、 **list** （list型）から特定の文字列 **a** を削除するロジックを書きました。

```py3
list = ['aaabbb','article']

>>> list_replace = list.replace('a', '')
AttributeError: 'list' object has no attribute 'replace'
```

しかし、このエラー

```py3
AttributeError: 'list' object has no attribute 'replace'
```


## 対策

配列を一旦単独の文字列に変換してから、replace()で置換、のちに配列に戻すという処理をすればいいらしいです。

```py3
list = ['aaabbb','article']

>>> list_replace = [item.replace('a', '') for item in list]
>>> list_replace
['bbb', 'rticle']
```


参考
https://spcx8.hatenablog.com/entry/2017/07/05/204423
新規ファイル作成【BashとPowerShellの比較】

[BashとPowerShellのコマンド対応表に戻る](https://qiita.com/karakuri-t910/items/c3b9a314afe18f6d0e7c)

# コマンドの比較

| <font color="Magenta">シェル</font> | <font color="Magenta">コマンド</font> | <font color="Magenta">コマンドの短縮形</font> |
| --- | --- | --- |
| **Bash** | `touch` | - |
| **PowerShell** | `New-Item` | `ni` |


# Bash

## コマンド形式

```bash
$ touch 新規ファイル名
```

### 使用例

例えば `sample_bash.txt` というファイルを作るには、下のようにします。

```bash
$ touch sample_bash.txt
```

# PowerShell

## コマンド形式

```powershell
> New-Item -Type File 新規ファイル名
```

または

```powershell
> ni -Type File 新規ファイル名
```

### 使用例

例えば `sample_powershell.txt` というファイルを作るには、下のようにします。

```powershell
> New-Item -Type File sample_powershell.txt
```

または

```powershell
> ni -Type File sample_powershell.txt
```
現場ではGit Hub Desktopは殆ど使われていないって本当？

某プログラミングスクールを卒業したものでまだ、実際に働いた事がないので確証は得られませんが、先日現場で働いている方にGit Hub Desktopを使っていると言ったら笑われました、、、
なのでそれをネタに記事を書いてみる事にしました。

# Git Hub Desktopを使ってる理由
単純明快でスクールで勧められたからだけです笑
カリキュラムではgitコマンドは習いましたが次のカリキュラムでは直ぐにDesktopの方を勧めてきてあれよあれよの内に今後の学習では全てDesktopを使う事になり最後の方になるとスクール生の大半はgitコマンドなんてほぼ忘れていたに違い有りません（自分も例外ではない）
プログラミング初心者からしたらGUIで操作出来るDesktopは居心地が良いですし直感的に操作も出来ますのでかなーーり楽出来ますから使わない理由がないでしょうし、スクール内ではそれで困る事は無かったです。

# gitコマンドの方が良い理由
私が話したエンジニアの方曰く操作出来る範囲がDesktopでは出来ない事もコマンドでは出来るとの事、具体的に何が出来ないのかはその時聞いていないので分かりませんので気になる方はご自身で調べてください。

# スクール生はDesktopを使い続けるべきか？
今スクールに通っている最中は別に使い続けてもいいのかなとは思います。同期の方はDesktopを使っているでしょうし今すぐに変えるべきとは思いません。卒業してからポートフォリオ制作の時からでも遅くはないでしょう。
私は指摘されてからは直ぐにDesktopを使う事は辞めてコマンドでする事にしました。一応習ったとは言え殆ど使ってこなかったのでgithubフローですら最初はコマンドを確認しながらゆっくりやりました。早く慣れたい笑

# 最後に
もし最後まで読んで下さった現場で働いてるエンジニアの方がいれば実際に使ってるかやDesktopは使わない方がいいかなど教えて下さると幸いです。
画像が読み込まれたか監視するjavascriptをnpmに公開しました

#　やりたかったこと
「シンプルjavascriptで画像の読み込みを監視し、
読み込み終わったらイベントを発火する」
という画像読み込みの監視クラス

# 使い方
npm 
https://www.npmjs.com/package/load-image.js

```
$ npm install load-image.js
```

```javascript
import loadImage from 'load-image.js';
 
const PATH_IMG = "/assets/img/";
let callbackEvent = () => {
    // fadein event
}
new loadImage({
    targetImageUrl : [
        PATH_IMG + `mv/background.jpg`,
        PATH_IMG + `mv/title.png`,
        PATH_IMG + `mv/image.png`,
    ],
    callback: callbackEvent
});
```

# 中身
var img = new Image();
で画像要素を作り、そこにロードイベントを追加して、
カウンターを回すだけのシンプルな作り。
念の為エラー吐いたときもカウンター回して、全部ロード完了orエラー吐いた状態で
コールバックが発生するようにした。

```javascript
loadimage(target_img) {
  var img = new Image();
  img.addEventListener("load", () => {
    this.counter();
  }, false);
  img.addEventListener("error", () => {
    this.counter();
  }, false);
  img.src = target_img;
}
```
Laravel 論理削除の実装方法と論理削除されているデータを取得しない

##概要　
Laravelで論理削除の実装方法です。


$table->softDeletes();を追加すれば論理削除を実装できる

```
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateTasksTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('tasks', function (Blueprint $table) {
            $table->id();
            $table->integer('user_id')->unsigned();
            $table->text('task');
            $table->timestamps();

            $table->softDeletes();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('tasks');
    }
}
```

deleted_atが追加されたことを確認

```
+------------+---------------------+------+-----+---------+----------------+
| Field      | Type                | Null | Key | Default | Extra          |
+------------+---------------------+------+-----+---------+----------------+
| id         | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
| user_id    | int(10) unsigned    | NO   |     | NULL    |                |
| task       | text                | NO   |     | NULL    |                |
| created_at | timestamp           | YES  |     | NULL    |                |
| updated_at | timestamp           | YES  |     | NULL    |                |
| deleted_at | timestamp           | YES  |     | NULL    |                |
+------------+---------------------+------+-----+---------+----------------+
```

modelの設定

```
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Task extends Model
{
    use SoftDeletes;

    protected $dates = ['deleted_at'];

    protected $fillable = [
        'task',
    ];
}

```

モデルの削除

```
$task = Task::find(1);
$task->delete();
```

以下のようにuser_idとjoin結合をすると論理削除済みのデータも取得してしまう。

```
$tasks = User::join('tasks', 'users.id', '=', 'tasks.user_id')->get();
```

以下のようにwhere句でdeleted_atカラムがnullのものを指定すれば、論理削除済みのデータ以外を取得できます。

```
$tasks = User::join('tasks', 'users.id', '=', 'tasks.user_id')->where('deleted_at', null)->get();
```
Linux（Bash）とWindows（PowerShell）のコマンド対応表

とりあえずメモ。
私が必要に応じて変更します。




# BashとPowerShellのコマンド対応表 (50音順)

| <font color="Magenta">したいこと<br>(リンク先は使い方の説明)</font> | <font color="Magenta">Bashコマンド</font> | <font color="Magenta">PowerShellコマンド</font> |
| --- | --- | --- |
| **インストール** | Debian系：`apt` または `apt-get`<br>RedHat系：`dnf`(旧：`yum`) | `choco`<br><font color="red">環境構築</font>：<b>[こちら](https://qiita.com/konta220/items/95b40b4647a737cb51aa)</b> |
| **URLからファイルのダウンロード** | `wget` | `Invoke-WebRequest`<br>エイリアス：`wget` |
| **エイリアスの作成** | `alias` | `Set-Alias`<br>エイリアス：`sal` |
| **[エイリアスの作成（引数が複数ある場合）](https://qiita.com/karakuri-t910/items/d751987065d4c52b3af4)** | `alias` | 存在しない（自作関数を作成する） |
| **エイリアスの詳細の表示** | `alias` | `Get-Alias`<br>エイリアス：`gal` |
| **[コマンドの場所を表示](https://qiita.com/karakuri-t910/items/84da4378fdab7c86fe6f)** | `which` | `Get-Command`<br>エイリアス：`gcm` |
| **コマンドのマニュアルの表示** | `man` | `Get-Help`<br>エイリアス：`man` |
| **再起動** | `shutdown` または `reboot` | `Restart-Computer` |
| **シャットダウン** | `shutdown` | `Stop-Computer` |
| **ストレージ容量の確認** | `df` | `Get-PSDrive`<br>エイリアス：`gdr` |
| **設定の反映** | `source` または `.` | `.` |
| **疎通確認** | `ping` | `Test-Connection` |
| **疎通確認（ポート指定可）** | `？？？` | `Test-NetConnection` |
| **ファイル権限の変更** | `chmod` | `icacls` |
| **ファイルの削除** | `rm` | `Remove-Item`<br>エイリアス：`rm` |
| **ファイルの中身を出力** | `cat` | `Get-Content`<br>エイリアス1：`gc`<br>エイリアス2：`cat` |
| **ファイル所有者の変更** | `chown` | `takeown` |
| **[ファイル新規作成](https://qiita.com/karakuri-t910/items/d06bbc562a7e0b679bc8)** | `touch` | `New-Item`<br>エイリアス：`ni` |
| **[ファイル内の文字列検索](https://qiita.com/karakuri-t910/items/acef6ad60d1b1f9e1e43)** | `grep` | `Select-String`<br>エイリアス：`sls` |
| **ファイル名検索** | `find` | `Get-ChildItem`<br>エイリアス1：`dir`<br>エイリアス2：`ls` |
| **プロセスの起動（アプリの起動）** | `xdg-open` または `./` | `Start-Process`<br>エイリアス1：`start`<br>エイリアス2：`./` |
| **プロセスの表示** | `ps` | `Get-Process` |
| <font color="red">**何かあったら、追加していきます**</font> | `` | `` |
macでsvnを使う

このご時世にSVNを使うことになった。
windowsのときは、TortoiseSVNを使用していたが、macにはない...
また、ろくなSVNクライアントもなさそう。

git-svnなるものがあったのでこちらを使用することにした。

Mac 最強の git/Mercurial クライアントである SourceTree では、git-svn した Subversion リポジトリもほとんどシームレス い扱うことができるようです。


### git svn clone　する

```
git svn clone https://<パス>

```

-s　オプションをつけると、最後が /trunkとなる。（例：＜パス>/trunk　をclone使用とする。 trunkフォルダをcloneするつもりが無いならつけないほうがよい）

### ファイルをコミットしたい

以下の手順でファイルをコミットできることを確認。
ファイル編集するごとに何故か git add が必要だったのはなぞ。

```
git add <追加したいファイル>
git commit -m "コメント"
git svn dcomit
```

### 最新ファイルを入手する
これでupdateされる

```
git svn rebase
```
MindSphereで得た知見について

MindSphereを案件で使用するにあたり、勘所や得た知見などを残しておきます。

随時更新予定。



## Vue/Nuxt/SPA使用時のルーティングについて

NuxtはVueのフレームワークです。

MindSphere上でNuxtをSSRで使うこともできるでしょうが、今回は静的サイトジェネレータ(最新版v.2.4では`yarn generate`)で出力してからCF pushでデプロイしていました。

ただ静的ファイルとして出力する際に問題があるのがURL周りです。一般にSPAではHistory APIを使った「クリーンな」URL(http://localhost/users のようなもの)と、Hash(フラグメント識別子)を使ったURL(http://localhost/#users )の二通りがあります。多くの場合は「クリーンな」URLが好まれますが、サーバー側の設定をする必要があるため、サーバーの設定ファイルをいじれない場合は使用できません。

MindSphereが利用する静的サイト用のビルドパックもデフォルトではこの設定がされておらず、少なくとも自分ではいい方法が見つかりませんでした。

もしもHashモードでもいいのであれば、Nuxtの場合はnuxt.config.jsを以下のように書き換えます。

[mode](https://ja.nuxtjs.org/api/configuration-router/#mode)

```JavaScript
export default {
  router: {
    mode: 'hash'
  }
}
```

これで動きはします。

ただ、細かい点ではHashとHistoryでは性能差はありますが見栄え的な理由からHistoryのほうが望ましいので、できればHisoryで実行できるよう試行錯誤しました。

当初はCFのbuild_packのオプションなどをいじっていましたが、どうもうまく行かず。

最終的にはNodejsのビルドパックである`nodejs_buildpack`と、express.js(と`connect-history-api-fallback`)を利用して、静的ファイルをexpress.js経由で出力する方法に切り替えました。



仮にNuxtの静的出力ディレクトリを`nuxt-dist/dist`とすると、以下のような構成にします。

```
nuxt-app
├ assets
├ components
├ pages
├ (その他Nuxtディレクトリ)
└ nuxt-dist
　 ├ .dist
　 ├ server.js
　 └ package.json
```

インストールするパッケージは２つだけです。ローカルで使用する場合は以下のコマンドでインストールします。

```
yarn add express connect-history-api-fallback
```

最後に、expressjsで実行されるserver.jsは以下のようになります。

```JavaScript
const path = require('path')
const express = require('express')
const history = require('connect-history-api-fallback')
const app = express()
const root = path.join(__dirname, '/dist') // Nuxt出力ディレクトリ

app.use(history())
app.use(express.static(root))

app.listen(process.env.PORT || 3000)
```

以上でOKです。

あとはmanifest.ymlを例えば以下のように指定をします。

```yaml:manifest.yml
applications:
  - name: app-name
    memory: 100M
    instances: 1
    path: ./nuxt-dist # server.js、package.json、distが入ってるDir
    host: app-host
    buildpack: nodejs_buildpack
```

正直Nuxtのディレクトリ関係を把握しないと混乱するかもしれません。Nuxt開発時とexpressによって実行されるファイルの区別がつくようによく考えて構成しないと混乱を生むと思います。



## MindSpheres取り込み制限

MindSphereにはデータ取り込みレート(Data ingest rate)という制限があります。これは場合によっては作成するMindSphereアプリの制限になりえるので最初に計算しておくといいと思います。

この制限はプランによって異なりますが、たとえばSプランの場合はデータ取り込みレートは3KB/sです。

3KB/sというのは、たとえばアセットは(Sプラン最大の)20個として、30個の変数(variables=アスペクトで設定できるもの)があるとして、その変数がそれぞれ50バイトのデータ(オーバーヘッド込)とすると、10秒に一回データを送信できる、という意味です

　データサイズ/秒 = (20*30*50)/10

もしも10秒に一度データを送信する場合、理論上最大で一度に30KB送信できます。

これを超えるとさすがに問題になると思うので予め設計しておく必要があります。

## アプリケーションクレデンシャル

Developer cockpitで、アプリごとに発行され、そのアプリに割り当てられているロールをToken Management Service経由で使用することができるクレデンシャルです。一つのアプリに一つのアプリケーション・クレデンシャルが発行されます。

基本的にアプリケーション・クレデンシャルは他人に知られないよう隠す努力が必要です。
このアプリケーション・クレデンシャルを例えばサブテナントに渡してしまうのもよくないパターンです。仮にこのクレデンシャルの使用者がサブテナントのユーザーであっても、アプリケーションのロール(権限)で使用されることになります。つまり通常はそのサブテナントは自分が割り当てられたサブテナントアセットにしかアクセスできませんが、、アプリケーションのロールでアセットマネージャーAPIの使用が割り当てられている際は、他のサブテナントにもアクセスできてしまうことになります。
そのため、基本的にはアプリケーション・クレデンシャルは他人に知られないように運用しなければいけません。

またアプリケーション・クレデンシャルは365日ごとの交換が必要になりますので、交換の際にダウン・タイムが発生しますのでこのあたりも運用時の考慮に必要です。

また自分はDeveloperプランなので使用したことはありませんが、Operatorプランの場合は自動的にアプリケーション・クレデンシャルを更新できるようです。

[Rotating app credentials](https://documentation.mindsphere.io/resources/html/operator-cockpit/en-US/130790411147.html)
Linux で Jupyter で起動するブラウザを指定する(JSON)

Ubuntu 18.04, jupyter-lab を想定します.

`jupyter-lab` と打ったときに自動で開くブラウザを変えたい.

調べると, `.py` を生成する方法がありますが, json でもいけました.

`~/.jupyter/jupyter_notebook_config.json` を編集します(ファイルがなければ作成すればいけるはず)


```
{
  "NotebookApp": {
    "nbserver_extensions": {
      "jupyter_nbextensions_configurator": true
    }
  }
}
```

のようになっているはずです.

以下のように `browser` で起動したいブラウザを指定します.

```
{
  "NotebookApp": {
    "browser": "google-chrome",
    "nbserver_extensions": {
      "jupyter_nbextensions_configurator": true
    }
  }
}
```

これでいけるはずです!