OmniAICreator/Qiita-1.07M huggingface dataset:
CloudFrontとElasticBeanstalkを使った際のHTTPS化

CloudFrontとElasticBeanstalkを併用する構成の場合にどうやって通信をHTTPS化するを解説します。

# ざっくり概要
- CloudFrontだけじゃなく、ElasticBeanstalkの方にもドメイン名を指定しておくと便利です。
- ユーザーとCloudFront間の通信だけではなく、CloudFrontのオリジンとなるとElasticBeanstalk間の通信もHTTPS化します。
- ElasticBeanstalkはCloudFrontを経由しないアクセスを制限するために別途設定を追加します。

![Untitled Diagram.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47882/51d4d2cd-7058-e7b0-c6ce-f6977668f050.jpeg)


# ドメイン設定
CloudFrontの方をexample.com、ElasticBeanstalkの方をserver.example.comと設定することにします。

# CloudFrontのHTTPS化
CloudFrontのHTTPS化はCertificateManagerから証明書を発行し、それをCloudFrontで利用します。

<img width="1404" alt="スクリーンショット_2020-03-13_9_32_53.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47882/c3738a91-928a-11a9-0905-12395f2524f3.jpeg">

このときに気をつけることはただ一つだけです。CloudFrontで使う証明書は__バージニア北部リージョン__で作らなくてはいけません。東京リージョンで作ったものは使えませんのでご注意ください。

# ElasticBeanstalkのHTTPS化
<img width="1404" alt="スクリーンショット_2020-03-13_9_37_14.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47882/c70a0209-cc6b-533b-cbac-0db3ee1e01ac.jpeg">

証明書をElasticBeanstalkの設定画面で設定します。このときの証明書は東京リージョンのElasticBeastalkを使っているのであれば東京リージョンのCertificateManagerで設定した証明書を使います。つまりCertificateManagerとElasticBeanstalkで使う証明書は全く別物になります。

# ElasticBeanstalkでリダイレクト設定
リダイレクトの方法は複数考えられると思いますが、今回はApacheのmod_rewriteでリダイレクト設定します。

```yaml:.ebextensions/force_host_redirect.config
files:
  # ALBを通しているのにHOST名がAPP_URLと一致していなかったらリダイレクト
  # healthcheckのためにALBを通していないアクセスはリダイレクトしない
  "/tmp/force_host_redirect.sh":
    mode: "000755"
    owner: root
    group: root
    content: |
      #!/bin/bash
      {
        echo "RewriteEngine On"
        echo "RewriteCond %{HTTP:X-Forwarded-Proto} !^$"
        echo "RewriteCond https://%{HTTP_HOST} !=https://example.com"
        echo "RewriteRule (.*) https://example.com%{REQUEST_URI} [R=301,L]"
      } > /etc/httpd/conf.d/force_host_redirect.conf

container_commands:
  set_up:
    command: /tmp/force_host_redirect.sh

```

HOSTが期待したものと違ったらリダイレクトする、というだけの設定ですが、ElasticBeanstalkのhealthcheckが通るように工夫しています。

# まとめ
最初、CloudFrontとElasticBeanstalkで同じ証明書を使わないといけないんじゃないかと思って、だいぶハマってしまいましたが、ElasticBeanstalkに対してCloudFrontがクライアントのように働きHTTPS通信してくれるので、問題なく設定出来るということが分かりました。CloudFrontからElasticBeanstalkへの通信がグローバルなインターネット経由であるという認識がなかったですが、理解したら早かったです。
Elasticsearch7.6.1とKibana7.6.1のDocker作成

Elasticsearch7.6.1とKibana7.6.1のDockerの作成を行いました。

環境
\- Debian 10.3
\- docker-compose 1.25.4
\- Docker 19.03.7
\- Elasticsearch 7.6.1
\- Kibana 7.6.1

docker-composeとDockerのインストールは下記参照
[docker-compose](https://docs.docker.com/compose/install/)
[Docker](https://docs.docker.com/install/linux/docker-ce/debian/)

docker-composeを使用して起動するために下記のようにファイルを作成します。

```yml:docker-compose.yml

version: "3.3"

services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.6.1
    environment:
      - discovery.type=single-node
      - cluster.name=docker-cluster
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    ports:
      - 9200:9200
    volumes:
      - es-data:/usr/share/elasticsearch/data
  kibana:
    image: docker.elastic.co/kibana/kibana:7.6.1
    ports:
      - 5601:5601

volumes:
  es-data:
    driver: local
```

コマンドを実行して起動します。

```
$ docker-compose up
```


ブラウザにて、
http://<サーバーアドレス>:5601/
にアクセスするとkibanaの画面が表示されます。

![kibana.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189046/b9f04a1e-5698-e5fe-bdf0-21324af4ccfd.png)
Node.js: ランダムな文字列を生成する1行の関数

Node.jsでランダムな文字列を生成する関数です。

## 36文字種

* `length`で与えた長さの文字列を生成する。
* 生成される文字列は`/[0-9a-z]*/`。
* このアルゴリズムにはバイアスがあり、0〜4が多めに出現するので、厳密なランダムではない。
    * [Secure random values (in Node.js)](https://gist.github.com/joepie91/7105003c3b26e65efcea63f3db82dfba#bias)

```javascript
const {randomBytes} = require('crypto')

function generateRandomString(length) {
  return randomBytes(length).reduce((p, i) => p + (i % 36).toString(36), '')
}
```

## 32文字種

* `length`で与えた長さの文字列を生成する。
* 生成される文字列は`/[0-9a-v]*/`。
* ランダムな0-256を32でモジュロ演算しているので、一応文字ごとの確率は均等なはず。

```javascript
const {randomBytes} = require('crypto')

function generateRandomString(length) {
  return randomBytes(length).reduce((p, i) => p + (i % 32).toString(32), '')
}
```

## Base32風の文字種

* `length`で与えた長さの文字列を生成する。
* 生成される文字種は32種類。
    * すべて大文字。
    * OやIと見た目が似てる0や1がない。
    * `/[2-7A-Z]*/`
* ランダムな0-256を32でモジュロ演算しているので、一応文字ごとの確率は均等なはず。

```javascript
const {randomBytes} = require('crypto')

const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'.split('')

function generateRandomString(length) {
  return randomBytes(length).reduce((p, i) => p + chars[(i % 32)], '')
}
```
iOSで等幅フォントを指定する

# 等幅フォントを指定する方法

XCodeでiOSアプリを開発する際、UILabelのフォントとしてシステムフォントを指定すると、San Franciscoが適用されます。これは特に何も指定しなければプロポーショナルフォントとなりますが、数値や時間表記においては等幅フォントを使用したいケースがあります。

システムフォント(San Francisco)を等幅とするには、以下のように `monospacedDigitSystemFont` を使用します。

```swift
@IBOutlet weak var label: UILabel!

override func viewDidLoad() {
    label.font = UIFont.monospacedDigitSystemFont(ofSize: 20, weight: .medium)
}
```

# 参考
- [Proportional vs. Monospaced Numbers: When to use which one in order to avoid “Wiggling Labels”](https://blog.usejournal.com/proportional-vs-monospaced-numbers-when-to-use-which-one-in-order-to-avoid-wiggling-labels-e31b1c83e4d0)
- [monospacedDigitSystemFont(ofSize:weight:)](https://developer.apple.com/documentation/uikit/uifont/1619022-monospaceddigitsystemfont)
コマンドでサブディレクトリ含む指定ファイルを全部削除する

苦手な黒い画面での操作

こんな構成

```
a
 1.txt
 b-1
   1.txt
   2.txt
 b-2
   1.txt
   c-1
     1.txt
   c-2
     1.txt
     2.txt
```

該当ファイルを一応確認

```
$ find ./ -name "1.txt"
```

一気に消す

```
$ find ./ -name "1.txt" -delete
```

消したらこうなる

```
a
 b-1
   2.txt
 b-2
   c-1
   c-2
     2.txt
```
初心者から始めるJava、データ隠蔽

追記：2020/3/13　今回の内容は、「カプセル化」というより「データ隠蔽」の内容になっていたことをコメントで指摘していただいたので、修正。
タイトルもカプセル化からデータ隠蔽へ変更。

#はじめに
この記事は備忘録である。
参考書レベルの内容だが、本記事に掲載するコードについては、
~~**間違えた**ものが中心となる。これは実際にコーディング中に間違えた部分を掲載し、自分で反省するために投稿するという目的によるもの。~~
また、後日にJavaSilver試験問題の勉強を兼ねて復習するため、深い部分の話はここでは触れない。

##環境
言語：Java11、JDK13.0.2
動作環境：Windows10

#メンバへのアクセス制限
`new`で生成したインスタンスが、クラスから引き継いだメンバ（フィールドとメソッド）を独自の形で保有していることは確認した。だが、前回の`Cat`クラスで言えば

`Cat myCat = new Cat;`
`mycat.weight = -20;`

と、`Cat`クラスを作ったときには想定していなかった値を、`main`メソッド内から勝手に格納することが出来てしまう。
`main`メソッド内から直接、`Cat`クラスで設定された**フィールド(今回は`double weight`)**にアクセスを許していると問題を起こしかねない。

##private
そこで、「クラス処理の外部からは扱うことが出来ないメンバ（フィールド・メソッド）を持たせたい」場合に、メンバ（フィールド・メソッド）へつける修飾子が**`private`**である。

今回はString型のcolorから、double型のheight(身長)へ変更して、Catクラスを扱ってみたい。

```Java:classCat再挑戦
class Cat
{
  private double weight;
  private double height;
  //クラス

  public void setWeightHeight(double w,double h)
  {
    if(w > 0 && w <= 50){
    weight = w;
    System.out.println("この猫の体重を" + weight + "kgにしました。");
    } else{
        System.out.println("ちょっとこの体重はないんじゃないですかねぇ……");
      }
   
    if(h > 0 && h <= 200){
    height = h;
    System.out.println("この猫の身長を" + height + "cmにしました。");
    } else{
    System.out.println("流石にそんな身長の猫は聞いたことはない……");
      }
  }

  double getWeight()
  {
    System.out.println("猫の体重を更新します。");
    return weight;
  }

  double getHeight()
  {
    System.out.println("猫の身長を更新します。");
    return height;
  }

  void introduce()
  {
    System.out.println("この猫の体重は" + weight + "kgです。");
    System.out.println("この猫の身長は" + height + "cmです。");
  }
}
```
Catクラスの`weight　height`はいずれも`private`になったので、勝手に値をいじられる心配は無くなった。

##public
だが本当に値を変更できないのであれば、新しく`new`したい`myCat`インスタンスの値も変えることが出来ない。
しかし、`Cat`クラスで言えば

`public void setWeightHeight(double w,double h)`

に注目してもらいたい。これはCatクラスに定義したメソッドだが、その修飾子は**`public`**に設定されている。これは「クラスの外側からのアクセスを許す」修飾子であり、処理の中に

`weight = w;`
`height = h;`

と、**`private`に設定したフィールドにアクセスしている**。
メソッドのうち、同じクラスの中に入っているメソッドからであれば`private`へのアクセスが可能であることを利用し、**メソッド内処理経由で`private`に設定した値への格納は許されている**。

`public void setWeightHeight(double w,double h)`
はその内部にif文を抱えており、条件に合わない値の代入を阻止できるようになっている。これでとんでもない値を格納される心配はなくなった。

#終わりに
今回見た、「メソッドを使って`private`フィールドへ値を格納する」という処理について。参考書の[やさしいJava 第7版](http://mana.on.coocan.jp/yasaj.html)から引用すると、

>クラスの中にデータ（フィールド）と機能（メソッド）をひとまとめにし、保護したいメンバにprivateをつけて勝手にアクセスできなくする機能

である。この機能設計を
**~~カプセル化(encapsulation)~~データ隠蔽**
と呼んでいる。
これは**オブジェクト指向設計の基本的な原則のひとつ**であり、このためにクラスを作るのである。他の原則はまた扱うがどれも大切な原則なので、しっかり把握しておきたい。

#参考
出来るだけ自分で変数や式を書いてコンパイルしているので、完全に引用する場合はその旨記述する。

[やさしいJava 第7版](http://mana.on.coocan.jp/yasaj.html)
[Java SE11 Silver 問題集](https://book.impress.co.jp/books/1118101186)（通称黒本）
Androidインストゥルメントテストをコマンドラインから実行する

# 概要

AndroidのインストゥルメントテストはAndroid Studioから実行できますが、事情があってコマンドラインから実行したかったので調べてみました。

# 実行方法

以下のコマンドですべてのテストが実行されます。

```
$ ./gradlew connectedAndroidTest
```

結果はHTMLで、appモジュールの場合は app/build/reports/androidTests/connected/index.html に出力されます。

# 特定のテストだけ実行したい場合

実行するテストを指定する場合は次のようにします。

```
$ ./gradlew connectedAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=com.example.HogeTest
```
Google Cloud Platform (GCP)サービスの正式名称・略称・読み方まとめ#10(ハイブリッド クラウドとマルチクラウド)

Google Cloud Platform (GCP)のサービスで正式名称や略称はともかく、読み方がわからずに困ることがよくあるのでまとめてみました。


クラウド コンピューティング サービス  |  Google Cloud
https://cloud.google.com/?hl=ja


## まとめルール

まとめルールについては下記を参考ください。

Google Cloud Platform (GCP)サービスの正式名称・略称・読み方まとめ#1(AI と機械学習/AI ビルディング ブロック) - Qiita
https://qiita.com/kai_kou/items/fa930eef23470c2f8f0b


## Amazon Web Services (AWS)のまとめはこちら！

Amazon Web Services (AWS)サービスの正式名称・略称・読み方チートシート - Qiita
https://qiita.com/kai_kou/items/cb29d261c8acc49fd22a

Amazon Web Services (AWS)サービスの正式名称・略称・読み方まとめ #1 (コンピューティング) - Qiita
https://qiita.com/kai_kou/items/a6795dbab7e707b0d1a6


## 概要について

サービス一覧ベージの概要を引用しています。

プロダクトとサービス  |  Google Cloud
https://cloud.google.com/products?hl=ja#product-launch-stages


間違いや、こんな呼び方あるよーなどありましたらコメントお願いします！


## Hybrid and Multi-cloud - ハイブリッド クラウドとマルチクラウド

### Anthos

既存のアプリをモダナイズし、ハイブリッド環境とマルチクラウド環境で新しいアプリを迅速に構築します。

- 正式名称: Anthos
- https://cloud.google.com/anthos
- 読み方: アンソス
    - 参考: [ASCII\.jp：Googleは「Anthos」でどのようにマルチクラウドを実現し、普及させるのか](https://ascii.jp/elem/000/001/847/1847485/)
- 略称: なし
- 俗称: なし


### Anthos GKE

ハイブリッドなマルチクラウド環境に対応したコンテナ化アプリケーションを効率的かつ安全な方法で確実に実行できます。

- 正式名称: Anthos GKE
- https://cloud.google.com/anthos/gke
- 読み方: アンソス ジーケーイー
- 略称: なし
- 俗称: なし


### Anthos Config Management

ハイブリッドの Kubernetes デプロイにおける大規模なポリシー運用とセキュリティ対策を自動化できます。

- 正式名称: Anthos Config Management
- https://cloud.google.com/anthos/config-management
- 読み方: アンソス コンフィグ マネジメント
- 略称: なし
- 俗称: なし


### Anthos Service Mesh (beta)

複雑なマイクロサービス アーキテクチャ向けのフルマネージド サービス メッシュ。

- 正式名称: Anthos Service Mesh
- https://cloud.google.com/anthos/service-mesh
- 読み方: アンソス サービス メッシュ
- 略称: なし
- 俗称: なし


### Cloud Run for Anthos

Kubernetes とサーバーレスの両方のメリットを簡単に生かすことができます。

- 正式名称: Cloud Run for Anthos
- https://cloud.google.com/anthos/run
- 読み方: クラウド ラン フォー アンソス
- 略称: なし
- 俗称: なし


### Kubernetes applications

事前に構築されたデプロイメント テンプレートと統合請求を採用した、コンテナ化されたアプリケーション。

- 正式名称: Kubernetes applications
- https://cloud.google.com/kubernetes-applications
- 読み方: クーべネティス アプリケーション
- 略称: なし
- 俗称: なし


### Migrate for Anthos

オンプレミスまたは他のクラウドにある VM を GKE のコンテナに直接移行します。

- 正式名称:Migrate for Anthos
- https://cloud.google.com/migrate/anthos
- 読み方: マイグレート フォー アンソス
- 略称: なし
- 俗称: なし


### Operations

サービス、コンテナ、アプリケーション、インフラストラクチャのモニタリングと管理。

- 正式名称: Operations
- https://cloud.google.com/products/operations
- 読み方: オペレーション
- 略称: なし
- 俗称: なし


### Cloud Build

継続的なビルド、テスト、デプロイを行います。

- 正式名称: Cloud Build
- https://cloud.google.com/cloud-build
- 読み方: クラウド ビルド
- 略称: なし
- 俗称: なし


### Traffic Director

エンタープライズに対応したオープン サービス メッシュ用トラフィック管理。

- 正式名称: Traffic Director
- https://cloud.google.com/traffic-director
- 読み方: トラフィック ディレクタ
- 略称: なし
- 俗称: なし


### Apigee API Management

あらゆる場所から API を開発、保護、デプロイ、モニタリングします。

- 正式名称: Apigee API Management
- https://cloud.google.com/apigee
- 読み方: アピジー エーピーアイ マネジメント
- 略称: なし
- 俗称: なし
Macのスクリーンショット保存先を変更する方法


* デフォルト設定だと、デスクトップにスクリーンショットがポコポコ吐き出されて鬱陶しい。
* なので、ユーザーディレクトリ配下に「ScreenShot」というディレクトリを作ってそこに吐き出すように変更したい。
* 自己責任でお願いします。
* `2021.11.23追記`
    * 「スクリーンショットの保存先を変更する。」の方法として、コマンド叩かなくても画面操作で実現する方法があったので修正しました。

# 新たなスクリーンショット保存先ディレクトリを作成する。（必要なら。）

```
mkdir ~/ScreenShot
```

# スクリーンショットの保存先を変更する。
* `Command` + `Shift` + `5`を押して、下方に表示されるメニューから`オプション`を選択。
* `保存先`の`その他の場所...`から、保存先ディレクトリを指定する。

## （以前に掲載していた方法）
```
defaults write com.apple.screencapture location ~/ScreenShot/
killall SystemUIServer
```
コロナウイルス検査数のグラフを作成

[東洋経済オンライン](https://toyokeizai.net/sp/visual/tko/covid19/)の記事を参考にしました。

次のようなグラフを作成します。
![corona_mar13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/25ec0032-3ed8-7a0f-47f5-7ef393d76a55.png)

データソースは
[新型コロナウイルス国内感染の状況](https://toyokeizai.net/sp/visual/tko/covid19/)
[厚生労働省の報道発表資料](https://www.mhlw.go.jp/stf/seisakunitsuite/bunya/0000121431_00086.html)

フォルダー構造

```text
$ tree
.
├── data.json
├── index.html -> inspect.html
├── inspect.html
└── inspect.js
```

```html:inspect.html
<!DOCTYPE html>
<html lang="ja">
<head>
<title>PCR検査数</title>
<meta charset="UTF-8">
<script src="/js/jquery-3.4.1.min.js"></script>
<script src="/js/Chart.min.js"></script>
<script src="inspect.js"></script>
</head>
<body>
<h1>日本全国　PCR検査数</h1>
<canvas id="chart" height="200" width="400"></canvas>
<p />
データソース<br />
<blockquote>
	<a href="https://toyokeizai.net/sp/visual/tko/covid19/">新型コロナウイルス国内感染の状況</a><p />
	<a href="https://www.mhlw.go.jp/stf/seisakunitsuite/bunya/0000121431_00086.html">厚生労働省の報道発表資料</a><p />
</blockquote>
<hr />
<div id="outarea_aa">outarea_aa</div>
<div id="outarea_bb">outarea_bb</div>
<div id="outarea_cc">outarea_cc</div>
<div id="outarea_dd">outarea_dd</div>
<div id="outarea_ee">outarea_ee</div>
<div id="outarea_ff">outarea_ff</div>
<div id="outarea_gg">outarea_gg</div>
<div id="outarea_hh">outarea_hh</div>
<hr />
Mar/12/2020<p />
</body>
</html>
```

```js:inspect.js
// ----------------------------------------------------------------------
//	inspect.js
//
//					Mar/13/2020
// ----------------------------------------------------------------------
const file_json = "data.json"

jQuery.getJSON(file_json,function (data)
	{
	jQuery("#outarea_aa").text ("*** start ***")
	const graph_data = convert01(data)
	jQuery("#outarea_cc").text (graph_data.labels.toString())
	jQuery("#outarea_dd").text (graph_data.datasets[0].data.toString())
	prog01 (graph_data)
	jQuery("#outarea_hh").text ("*** end ***")
	})


// ----------------------------------------------------------------------
function convert01(data)
{
	var count = 0
	var labels = []
	var numbers = []
	var number_before = 0
	for (it in data.transition)
		{
		if (0 < it)
			{
			number_before = data.transition[it-1][3]
			}

		unit = data.transition[it]
		if ((2 < unit[0]) && (4 < unit[1]))
			{
			const label = String(unit[0]) + "-" + String(unit[1])
			labels.push(label)
			const number = unit[3] - number_before
			numbers.push(number)
			count += 1
			}
		}

	graph_data = {}

	graph_data['labels'] = labels
	graph_data['datasets'] = []

	const unit_aa =		{
		label: "Inspect",
		lineTension: 0,
		data : numbers
		}

	graph_data['datasets'].push(unit_aa)

	jQuery("#outarea_bb").text ("count = " + count)

	return graph_data
}

// ----------------------------------------------------------------------
function prog01 (graph_data)
{
	const config = {
		type: 'line',
		data: graph_data
		}

	const context = jQuery("#chart")
	const chart = new Chart(context,config)
}

// ----------------------------------------------------------------------
```

data.json の取得方法

```bash
wget https://toyokeizai.net/sp/visual/tko/covid19/data/data.json
```
Action Cable 本番使用時のNginxとCable.ymlの設定

##はじめに

Action CableはWebSocket通信技術を用い、リアルタイムなチャットなどの機能を実装できる機能です。
AWS本番環境でのNginxとCable.ymlの設定に関して詰まった箇所を共有します。

![chat.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481058/2bae78db-49d1-fe42-804d-252e0ba769f5.gif)

##前提
 - Rails 5.2.3
 - Puma
 - Nginx
 - AWSでデプロイ
 - **Https通信**

ローカルではWebsocket通信が正常に動いていることが前提です。

##Nginxの設定追加
**最後の一行ですが、Httpsの場合はこれがないとコンソール内に403エラーになるので注意してください。**

proxy_set_header X-Forwarded-Proto https;

```nginx:/etc/nginx/conf.d/app_name.conf
location /cable {
        proxy_pass http://puma;
        proxy_http_version 1.1;
        proxy_set_header Upgrade websocket;
        proxy_set_header Connection Upgrade;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
        }
```


##Cable.ymlの設定

ドキュメントにも記載されている通り、**Production環境ではアダプターに"async"を使用するのは非推奨です。**
同時に多数のアクセスがあると捌き切れなくなるようです。
>8.1.1.1 Async Adapter
The async adapter is intended for development/testing and should not be used in production.

Heroku にも丁寧な解説があります。
本番環境にはRedisまたはPostgreSQL(DBとして使用しているなら)が必要です。
[Real-Time Rails: Implementing WebSockets in Rails 5 with Action Cable](https://blog.heroku.com/real_time_rails_implementing_websockets_in_rails_5_with_action_cable)
>
Lastly, Action Cable uses Redis as a data store for transient data, syncing content across instances of your application.
>
![1473343848-1462551406-rails-rack.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481058/3b9039f3-fae3-5c3f-0f1d-e427a086df44.png)

私は一度AWSでRedisを契約し、そのエンドポイントURLを下記productionのアダプターに設定していましたが、たまたまPostgreSQLを使用していたのでこれでいけました。
Redisお金かかるのでpostgresでよかった、、、

```ruby:/config/cable.yml
development:
  adapter: async

test:
  adapter: async

production:
  adapter: postgresql
```

##Production.rb
自分ドメインからのリクエストを許可します。

```ruby:/config/environments/production.rb

  config.action_cable.url = 'wss://app_name.com/cable'
  config.action_cable.allowed_request_origins = [ 'https://app_name.com', /https:\/\/app_name.*/ ]
  ActionCable.server.config.disable_request_forgery_protection = true

```

##終わりに
特にNginxの設定と、Redisなどアダプターの設定に大変ハマりました、、
ActionCableはRails5から追加された比較的新しい機能のためか、日本語記事ではHttpsやRedisについての言及が少なく、英語記事を参考にしました。
ご参考になれば幸いです。
Rails6 のちょい足しな新機能を試す 123（Gemfile 編)

# はじめに

Rails 6 に追加された新機能を試す第123段。 今回は、`Gemfile` 編です。
Rails 6 では、 `rails new` するときに `--skip-test` などのオプションつきで、実行したときに、空行が2行にならないように修正されています。

Ruby 2.6.5, Rails 6.0.2.1, Rails 5.2.4.1 で確認しました。 (Rails 6.0.0 でこの修正が入っています。)

```shell
$ rails --version
Rails 6.0.2.1
```

今回は、 `rails new --skip-test` でGemfileを作成して中身を確認します。

# Rails プロジェクトを作る

Rails プロジェクトを新たに作成します。

```shell
$ rails new --skip-test rails_sandbox
$ cd rails_sandbox
```

# Gemfile を確認する

Gemfile を確認すると、 `:development` group の次の1行だけが空行になっています。

```ruby:Gemfile
group :development do
  # Access an interactive console on exception pages or by calling 'console' anywhere in the code.
  gem 'web-console', '>= 3.3.0'
  gem 'listen', '>= 3.0.5', '< 3.2'
  # Spring speeds up development by keeping your application running in the background. Read more: https:
  gem 'spring'
  gem 'spring-watcher-listen', '~> 2.0.0'
end

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
```

# Rails 5では、

Rails 5.2.4.1 では、以下のように2行空いてます。

```ruby:Gemfile
group :development do
  # Access an interactive console on exception pages or by calling 'console' anywhere in the code.
  gem 'web-console', '>= 3.3.0'
  gem 'listen', '>= 3.0.5', '< 3.2'
  # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
  gem 'spring'
  gem 'spring-watcher-listen', '~> 2.0.0'
end


# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
```

本当に「ちょい足し」の中の「ちょい足し」ですが、こういった些細なところも放置しないで、修正されていくことが、Rails のコードの品質を良くし、Railsが「生き続ける」ための重要な要素だと思いました。

# 参考情報

* [Remove redundant empty line when we don't use system test](https://github.com/rails/rails/pull/36798)
AutoLISP シンボル処理関数の使い方

[シンボル処理関数リファレンス（公式ヘルプ）](https://help.autodesk.com/view/OARX/2020/JPN/?guid=GUID-796EFF94-E904-4F5B-B120-C6D2DCD8646A)

### 指定された項目がアトムかどうかを調べる atom
```scheme
(atom 1)
;; -> T
(atom "a")
;; -> T
(atom 'a)
;; -> T
(atom "abc")
;; -> T
(atom '(1 2 3 4 5))
;; -> nil
(atom '("a" "b" "c" "d" "e"))
;; -> nil
```

### 現在定義されているシンボルのリストを返す　atoms-family
```scheme
(atoms-family 0)
;; -> (acToolbarDockBottom acet-var-setvar ･･･ C:SAVEALL)
(atoms-family 1)
;; -> ("ACTOOLBARDOCKBOTTOM" "ACET-VAR-SETVAR" ･･･ "C:SAVEALL")
(atoms-family 0 '("+" "-" "setq" "aaa" "princ"))
;; -> (+ - SETQ nil PRINC)
(atoms-family 1 '("+" "-" "setq" "aaa" "princ"))
;; -> ("+" "-" "SETQ" nil "PRINC")
```

### シンボルに値が代入されているかどうかを調べる　boundp
```scheme
(setq val 1)
(boundp 'val)
;; -> T
(setq val nil)
(boundp 'val)
;; -> nil
(setq val 1)
(boundp val)
;; -> nil
```

### 指定された項目の評価が nil になるかどうかを調べる　not
```scheme
(not nil)
;; -> T
(not (< 1 2))
;; -> nil
(not (> 1 2))
;; -> T
```

### 指定された項目の内容が nil かどうかを調べる　null
```scheme
(null nil)
;; -> T
(null (< 1 2))
;; -> nil
(null (> 1 2))
;; -> T
```

### 指定された項目が実数または整数かどうかを調べる　numberp
```scheme
(numberp 1)
;; -> T
(numberp 1.5)
;; -> T
(numberp "a")
;; -> nil
(setq val 2.5)
(numberp val)
;; -> T
(numberp pi)
;; -> T
```

### 評価せずに式を返す　quote
```scheme
(quote a)
;; -> A
(quote +)
;; -> +
```

### シングル クォーテーション付きのシンボル名の値に式を代入する　set
```scheme
(set 'a 123) ;;(setq a 123) と同じ
;; -> 123
```

### シンボル(1 つまたは複数)に式の値を代入する　setq
```scheme
(setq a "aaa")
;; -> "aaa"
(setq b 123)
;; -> 123
;; まとめて代入
(setq c 123 d "aaa" e '("a" "b" "c"))
;; -> ("a" "b" "c")
```

### 指定された項目のタイプを返す　type
```scheme
(type 1)
;; -> INT
(type 1.0)
;; -> REAL
(type "abc")
;; -> STR
(type 'abc)
;; -> SYN
(type '+)
;; -> SYM
(type +)
;; -> SUBR
(type '(1 2 3 4 5))
;; -> LIST
```

### シンボルの名前を含む文字列を返す　vl-symbol-name
```scheme
(vl-symbol-name 'a)
;; -> "A"
(vl-symbol-name 'abc)
;; -> "ABC"
```

### シンボルに代入されている現在の値を返す　vl-symbol-value
```scheme
(setq val 1)
(vl-symbol-value 'val)
;; -> 1
(setq val "abc")
(vl-symbol-value 'val)
;; -> "abc"
```

### 指定されたオブジェクトがシンボルかどうかを調べる　vl-symbolp
```scheme
(vl-symbolp 'a)
;; -> T
(vl-symbolp 1)
;; -> nil
(vl-symbolp "a")
;; -> nil
(vl-symbolp +)
;; -> nil
(vl-symbolp '+)
;; -> T
```
PytorchのエラーがVSCodeから消えない（Pylintのエラー）

# 結論
設定ファイル(setting.json)に以下を追記

```json:setting.json
{
    "python.linting.pylintArgs": [
        "--generated-members=numpy.* ,torch.*",
        "--not-callable=torch.*"
    ],
}
```

# 解説
pythonにおいて変数に動的にオブジェクトを割り当てるのは当たり前なので、エラーを無視するために以下を追加している。

```
  "--generated-members=numpy.* ,torch.*",
```

また、以下のエラーがうざい。これも上記と同じような理由だろう。


> torch.tensor is not callable


なので、以下を追加している。

```
  "--not-callable=torch.*"
```
言語処理100本ノック-52:ステミング

[言語処理100本ノック 2015](http://www.cl.ecei.tohoku.ac.jp/nlp100/)[「第6章: 英語テキストの処理」](http://www.cl.ecei.tohoku.ac.jp/nlp100/#ch6)の[52本目「ステミング」](http://www.cl.ecei.tohoku.ac.jp/nlp100/#sec52)記録です。
**言語処理においてよく使うであろうステミング**です。実際に[後続ノック71本目](https://qiita.com/FukuharaYohei/items/60719ddaa47474a9d670)の機械学習系ノックでも利用しています。関数を呼び出すだけなので、技術的には非常に簡単です。

# 参考リンク

|リンク|備考|
|:--|:--|
|[052.ステミング.ipynb](https://github.com/YoheiFukuhara/nlp100/blob/master/06.%E8%8B%B1%E8%AA%9E%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%E3%81%AE%E5%87%A6%E7%90%86/052.%E3%82%B9%E3%83%86%E3%83%9F%E3%83%B3%E3%82%B0.ipynb)|回答プログラムのGitHubリンク|
|[素人の言語処理100本ノック:52](https://qiita.com/segavvy/items/d47fa799883ed16eddc2)|多くのソース部分のコピペ元|

# 環境

|種類|バージョン|内容|
|:--|:--|:--|
|OS|Ubuntu18.04.01 LTS|仮想で動かしています|
|pyenv|1.2.16|複数Python環境を使うことがあるのでpyenv使っています|
|Python|3.8.1|pyenv上でpython3.8.1を使っています<br>パッケージはvenvを使って管理しています|

上記環境で、以下のPython追加パッケージを使っています。通常のpipでインストールするだけです。今回はノックで指定している[stemmingパッケージ](https://pypi.org/project/stemming/)は使いませんでした。2010年から更新されておらず、今は`nltk`の方が一般的っぽかったからです。

|種類|バージョン|
|:--|:--|
|nltk|3.4.5|


# [第6章: 英語テキストの処理](http://www.cl.ecei.tohoku.ac.jp/nlp100/#ch6)
## 学習内容
> Stanford Core NLPを用いた英語のテキスト処理を通じて，自然言語処理の様々な基盤技術を概観します．
>> [Stanford Core NLP](https://stanfordnlp.github.io/CoreNLP/), ステミング, 品詞タグ付け, 固有表現抽出, 共参照解析, 係り受け解析, 句構造解析, S式

## ノック内容
> 英語のテキスト（[nlp.txt](http://www.cl.ecei.tohoku.ac.jp/nlp100/data/nlp.txt)）に対して，以下の処理を実行せよ．

### [52. ステミング](http://www.cl.ecei.tohoku.ac.jp/nlp100/#sec52)
> 51の出力を入力として受け取り，Porterのステミングアルゴリズムを適用し，単語と語幹をタブ区切り形式で出力せよ． Pythonでは，Porterのステミングアルゴリズムの実装として[stemming](https://pypi.python.org/pypi/stemming)モジュールを利用するとよい．

### 課題補足(「ステミング」について)
「ステミング」は語幹のことで、単語の変化しない前方部分を指します(例：Naturalのステミングはnatur)。ステミングは後に[71本目](https://qiita.com/FukuharaYohei/items/60719ddaa47474a9d670)でも使います。
「ステミング」にはいくつか種類があって今回はポーターのアルゴリズムを使っています(これが有名らしい)。詳しく知りたい人はググったりして調べてみてください。

# 回答
## 回答プログラム [052.ステミング.ipynb](https://github.com/YoheiFukuhara/nlp100/blob/master/06.%E8%8B%B1%E8%AA%9E%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%E3%81%AE%E5%87%A6%E7%90%86/052.%E3%82%B9%E3%83%86%E3%83%9F%E3%83%B3%E3%82%B0.ipynb)

```python
import re

from nltk.stem.porter import PorterStemmer as PS

ps = PS()

with open('./051.result.txt') as file_in, \
     open('./052.result.txt', 'w') as file_out:
    for token in file_in:
        if token != '\n':
            print(token.rstrip(), '\t', ps.stem(token.rstrip()), file=file_out)
```

## 回答解説
プログラムも短くたいして解説することがありません。`ps.stem()`とするだけでステミングでき、呼び出すだけなら非常に簡単です。

### 出力結果(実行結果)
プログラム実行すると以下の結果が出力されます(先頭30行抜粋)。

```text:052.result.txt(先頭30行抜粋)
Natural 	 natur
language 	 languag
processing 	 process
From 	 from
Wikipedia 	 wikipedia
the 	 the
free 	 free
encyclopedia 	 encyclopedia
Natural 	 natur
language 	 languag
processing 	 process
(NLP) 	 (nlp)
is 	 is
a 	 a
field 	 field
of 	 of
computer 	 comput
science 	 scienc
artificial 	 artifici
intelligence 	 intellig
and 	 and
linguistics 	 linguist
concerned 	 concern
with 	 with
the 	 the
interactions 	 interact
between 	 between
computers 	 comput
and 	 and
human 	 human
```
【Python】使い道があるようでなさそうなデコレータつくった。

#はじめに
皆さん`デコレータ`作ってますか？　恥ずかしながら、私は**今日**詳細を知りました。存在には気づいていても今日までは無視してきましたが、勉強しましたので何かアウトプットしようと思って書いています。

#つくったもの
早速ですがこんなものをつくてみました。

```python:deco_test.py
def decof(Func,*_args,**_kwargs):
    def _deco(func):
        def wrapper(*args,**kwargs):
            return Func(func(*args,**kwargs),*_args,**_kwargs)
        return wrapper
    return _deco

def decob(Func,*_args,**_kwargs):
    def _deco(func):
        def wrapper(*args,**kwargs):
            return Func(*_args,func(*args,**kwargs),**_kwargs)
        return wrapper
    return _deco
```

ざっくり説明すると、どちらも**ラップされる関数の戻り値を指定した関数に受け取らせる関数**が作れます。
２つあるのは戻り値を第一引数として受け取るか(`decof()`)一番うしろの引数に受け取るか(`decob()`)で使い分けるためです。
言葉だとわかりにくいので実演すると、

```python:deco_test.py
import numpy as np
from functools import reduce
from operator import sub

@decob(reduce,sub)
@decof(np.array,dtype=int)
@decof(list)
@decof(str)
@decob(pow,2)
@decof(pow,2)
def add(a,b):return a+b

print(add(3,4))
```

```python:出力
-55
#3+4 -> 7**2 -> 2**49 -> '562949953421312' -> ['5', '6', '2', '9', '4', '9', '9', '5', '3', '4', '2', '1', '3', '1', '2']
# -> array([5, 6, 2, 9, 4, 9, 9, 5, 3, 4, 2, 1, 3, 1, 2]) -> 5-6-2-9-4-9-9-5-3-4-2-1-3-1-2 -> -55
```

こんな感じの関数リレーをスッキリ（？）表現できます。
以上です。

#まとめ
今まで避けてきましたが使い方次第ではかなり便利そうなので、また何か思いついたらここで紹介できたらと思います。最後まで読んでくださりありがとうございました。
WordPressのREST APIにエンドポイントを追加する

今回はWordPressのREST APIにエンドポイントを追加する知見を手に入れたので備忘録をしておきます。昨今のNext.jsやNuxt.jsなどを用いたときに活用できます。

# どんなURLを叩くとデータ取得ができるかを考えておく
まずは、どんなURLを叩くとデータが取得ができるかを考えておきましょう。
今回は下記のURLを叩く前提で記事を書いていきます。

`http://xxxxxxxxxx.com/wp-json/masato/v2/aaa/[投稿ID]`

# functions.phpに記述する

```php:functions.php
// エンドポイントを追加する
add_action('rest_api_init', function () {
  register_rest_route('masato/v2', '/aaa/(?P<id>\d+)', [
    'methods' => 'GET',
    'callback' => 'aaa_func',
    'args' => [
      'id' => [
        'validate_callback' => function($id) {
          return ( is_numeric($id) ) ? $id : false;
        }
      ]
    ]
  ]);
});

// callbackに指定した関数
function aaa_func($data) {
  $res = [
    'id' => 1000,
    'title' => 'タイトル情報を入れます！',
    'data' => [
      'status' => 200
    ]
  ];
  $response = new WP_REST_Response($res);
  $response->set_status(200);
  return $response;
}
```

このコードを少しずつ見ていきます。

`register_rest_route('masato/v2', '/aaa/(?P<id>\d+)', [`

この行は叩く想定のURLを見ていただければイメージが付くはずです。
`/masato/v2` と `/aaa/投稿ID` という感じでURLを追加する感じです。

---

次に、 `'callback' => 'aaa_func',` はその名の通り、このURLを叩いたときに処理を走らせる関数を指定します。


---

`'validate_callback' => function($id) {` では、GETした値のバリデーションを行います。自分の好きな感じに条件を追加していきましょう。不正な値については `return false;` とすることで不正な値が入力された場合にはWordPress側が自動的に404を返してくれるようになります。

バリデーションしたらちゃんと値をreturnしておきます。

---

```
function aaa_func($data) {
}
```

は、コールバック関数です。 `$data['id']` で id の値が取得できます。

---

`$response = new WP_REST_Response($res);` では、連想配列で作った `$res` をJSONデータで返すような準備をしてくれます。

---

`$response->set_status(200);` JSONデータのHTTPステータスコードを指定できます。

---

`return $response;` 結果を返してJSONを吐き出します。

---

# めちゃくちゃ簡単！
WordPressのREST APIは簡単にエンドポイントを追加できます。
これまで固定ページなどで無理やりにJSONを吐き出していた方は、ぜひとも適切な形でデータ問い合わせをするようにしましょう！

※記事用にコードを書き直したので動かなかったらすみません...。
エクスプローラ活用術

今回短いです。
本当は「業務効率が上がるフォルダ構成」とか書きたかったのですが、
あまり時間が取れなかったため一部を切り出してます。

#**始めに**
みなさんはこれまで、
必要なファイルが見つけられず余計な時間をとられた、
といった経験はありませんか。

デスクトップが散らかっている、
プロジェクトのフォルダ構成やファイルの格納場所が
めちゃくちゃで覚えられない、等々、
理由は様々でも身に覚えがある人は多いのではないでしょうか。

フォルダ構成を把握し、ファイルやフォルダをこまめに整理しておけば
無駄な時間は短縮していけます。

本当はそのあたりを書きたいのですが、
本記事では汎用的なフォルダ構成ではなく
あくまで、実作業をスムーズに行うための方法をご紹介します。

#**実作業ごとのフォルダを作成！**

**1.デスクトップにフォルダを作成する!**
　まず、フォルダを切っていきます。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530030/79ea6fa7-8fe4-3702-343c-779128a7a10d.png)

**2.作業単位でフォルダを作成する**
　先ほど作成したフォルダ内に、実作業ごとのフォルダを作成します。
　このとき、番号を付番しておくと管理しやすいです。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530030/211d2aa4-c155-8f8c-de6b-d0127a96907b.png)

**3.作業手順や管理表を格納する**
　最後に、作成した作業ごとのフォルダに手順書や管理表、
　関連資料のショートカット等を格納します。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530030/57bb8966-fcd7-5580-ccbb-239e4126f8c1.png)


#**メリットとデメリット**
昔から続いているプロジェクト等だと、フォルダ構成が適当で、
1つの作業を行うのにバラバラなフォルダに格納されている、
複数の手順書や管理表、設計書にとばされるなんてことはよくあります。
格納場所を全て把握できていれば影響は軽微で済みますが、
把握ができていないと相応の手間と時間が発生します。

本記事の方法であれば、1つのフォルダ内で作業が完結するため
探す手間がなくなります。
手が止まらなくなるという意味では便利です。

ショートカットを使う場合、
元ファイルやフォルダの格納場所が変更されると開け無くなってしまします。
自作した作業フォルダ内のショートカットを更新しなければいけないので
注意してください。

#**最後に**
今回はここまでにさせていただきます。

おかしな点や不明点等あれば、ご指摘お願いします。
次回は技術的なこと書きます！（決意表明）
MacでSSH Forwardingを使ってOpenAI gymを動かしたときのエラー

### 環境

MacではXQuartzが動いているとする。
LinuxサーバーでOpenAI gymを動かして遊ぼうとする。

### 問題

```
pyglet.gl.ContextException: Could not create GL context
```

みたいなエラーが出て、画面がMacに表示されない

### 原因

https://heptech.wpblog.jp/2017/02/26/solution-to-fix-opengl-issue-on-recent-xquartz/

MacのXQuartzでOpenGLが有効化してないかららしい。

### 解決法

```
$ defaults write org.macosforge.xquartz.X11 enable_iglx -bool true
```

を実行。
React初心者日記(2日目)

#どんな記事？
Reactをローカルで書けるようにする。
npmとかWindowsで動かないと思ってた。

#参考ページ
[windowsでReactの環境構築] (https://qiita.com/KKoh/items/8aa1bf0bb3673e8e2455)
あとどこかのページ。
[ここだった](https://create-react-app.dev/docs/getting-started/)

#正直参考ページに書かれたことやっただけ
コマンドプロンプトで
`npx create-react-app my-app`
`create-react-app my-apps`
現在のディレクトリにmy-appsフォルダができる
フォルダ内移動`cd my-apps`
サーバー起動`npm start`
なんかアクセス許可するかの選択すると
ブラウザでReactのロゴがぐるぐるしている。
そこに書いてある通りsrc/App.jsをいじると表示が変わる。

#次やること
別のjsファイルからコード読み込む
参考になりそうなページ
[【Q&A】ReactJSのComponentをimport,exportする](https://qiita.com/HIGAX/items/28f3bec814928b7395da)
#後でやること
Tomcat上で動かす。
参考になりそうなページ
[Making a Progressive Web App](https://create-react-app.dev/docs/making-a-progressive-web-app/) (ただし英語)
[Reactを使ってWebサイトを公開するまでの手順](https://qiita.com/takenobi/items/797be00dd0b592f484ef)
#思ったこと
英語読めたい
Qiitaのいいね→LGTMへの変更ブログを読んで、サービス変更通知的に良くないと考えたのでまとめた

# 前提
- Qiitaの今回の変更（いいね→LGTMへの変更）自体の可否ついては言及していません。
- 言及しているのは、今回の変更をリリースする際のユーザへの伝え方です。
- 私はQiitaの１ユーザですが、QiitaまたはIncrements株式会社の関係者ではありません。
- 私は国内向け自社サービスを開発・運営しています。なのでユーザがサービスの変更に対して、どう捉えるか過敏になっている節があるのは否定しません。
- この記事には個人的な見解が多く含まれています。

# 言及しているQiitaブログ記事（2020/3/13 2:14 時点での印象）
https://blog.qiita.com/like-to-lgtm/

## 良くない１：Qiitaユーザへの事前通知が一切ない
これは私が日常的に利用しているTwitterのタイムラインの観測範囲では、変更リリース自体と言及ブログ記事がユーザへの最初の通知であると認識しています。
他情報で事前通知をしていたのであれば、読み飛ばしていただければと思います。

`一般的に、変更にはユーザの混乱が伴います。`
それを軽減するために、問い合わせフォームの設置、FQAや事前通知、プレスリリースを打つなどをするのが王道です。
変更が軽微であればユーザへの通知をしないことも多くありますが、以下の理由から今回の変更が決して小さいものでないことを説明します。

Qiitaサービスでは、ユーザは多種のコンテンツを生成できます。

- Qiita記事
- 編集リクエスト
- コメント
- ストック
- SNS共有（外部サービスではあるが）
- 旧いいね

しかし多種のユーザ生成コンテンツの中で**最も気軽に、多く作られているコンテンツは「旧いいね」**であります。
Qiitaサービスの中でも「旧いいね」は、ユーザの目にする記事への評価軸として一番利用されてきたと考えられます。

今回のようなサービスのミッションに関わる変更は、事前通知を行い、それが仮に批判を浴びたとしても、そのまま続行されると考えられます。
だからこそ**不可逆で永続的な変更**としてユーザに理解・納得してもらう時間は必要であります。その時間と機会が少なければ少ないほど、ユーザからのフィードバックも急なものになり、ユーザの離脱などのデメリットを被ることになります。

### どうしたら良かったのか
事前通知をちゃんとする。
もしくは最初から不可逆で永続的な変更という形では見せず、「旧いいね」をどう使ってほしいかユーザへゆっくりと伝播させる必要があった。

## 疑問：果たして「旧いいね」は「LGTM」に置き換え可能であったのか？
これはやや今回の変更自体に触れています。

自身のQiita記事、またはブックマークしているQiita記事を見る限り、「旧いいね」の数はそのまま「LGTM」の数に置き換わっているように見えます。

言及記事にもある通り、
> ただ面白い記事であれば「いいね」が多く押されているような状況にもなっています

既存のいいねは`自分にとって良いもの`という意味から外れた使い方をされているという印象は、私も抱いています。
だからこそ自分がやっていた「旧いいね」が「LGTM」にそのまま置き換わることは違和感しかありません。

### どうしたら疑問を抱かなかったか
`「旧いいね」≠「LGTM」`だとブログで明言しているのであれば、システム的に別物の表現がされていればよかった。
ジャストアイデアですが、当面は`いいね`数と`LGTM`数を分けて表示するべきで、`LGTM`はどの記事も０からカウントされていれば公平な印象を受けます。


## 良くない2：全社戦略の前に、ミッションと期待される結果を説明しなかった
この言及記事は誰向けの文章なのかは、Qiitaユーザであることは明確であると考えられます。
Qiitaユーザの大部分は、Increments株式会社の社員ではなく、Qiitaサービスで恩恵を預かりたい人たちです。
なので、このような大きな変更をする/したい場合、その変更によって受けられる恩恵自体（WHAT）や何故（WHY）が重要であり、戦略（HOW）はあまり重要視しません。
ぶっちゃけた表現をすれば`どうでもいい`です。
どうでもいい話を前置きに置かれてもユーザは困惑するし、混乱します。

（個人的な話しをすると、私自身サービスをどう発展させていきたいのか、戦略の部分を説明したい欲はもちろんありますが、だからといってユーザがそれを聞きたいかを考えると、聞くメリットがないなと諦めることが多いです）

さらに`利益を創出`といったワードは、使い手側のメリットのみが先行するイメージがあります。
ユーザメリットを明確に説明しないまま、この言葉を使ったことによって、自社利益追求の印象が強くなり、転じてユーザを軽んじている印象を与えかねません。

### どうしたら良かったのか
読み取り手のことを考えた文章構築をする。
ユーザが第一であることを、常に先に表現する。

## よくない3：サービスが期待された使い方をされていなくても、ユーザの責任にしない。少なくともそう表現しないよう努める
> 記事の内容をほとんど読まなくてもつい「いいね」している、ということがわかりました。また、技術情報が主題でなくても、ただ面白い記事であれば「いいね」が多く押されているような状況にもなっています。

> 「Contribution」として表現されることからもその意図は伝わるかと思います。

> 反射的に押すのではなく、一度その対象をよく見てから押してもらえるようになると幸いです。

面白い記事であれば、いいねをしたくなるのは一般的な感情だと考えられます。
それが常人で思いつかないユーモラス溢れていれば多くのいいねが与えられるのは必然ですね。
少なくともそう使ってほしいようにしか見えませんでした。

結果的にもいいねの使われ方は、
> 前提として、Qiitaの「いいね」は他のSNSにある「いいね」とは少し異なる意味を持っています。

ということをユーザは意識できなかった。これはサービス提供者の失敗であり、改善すべき点です。

### どうしたら良かったのか
「そう捉えてほしい」「そう伝わることを期待している」では何も解決しません。
完全に絶対にそうとしか伝わらないシステム表現を目指すべきで、ユーザの行動を咎めることは避けるべきです。
ましてや、最初の最初の変更通知でこれをやってしまうと**『ユーザの使い方が悪いから、自分たちは変えたくないけど、仕方がなく変えてやってるんだぞ』**という捉え方をしてくださいと言っているようなものです。
絶対に止めましょう。

## 小さいよくないこと：あわせてストックアイコンも変更

あわせないでください！！
少なくとも文書上一緒に表現しないほうがいいです。
もっと言えばリリースも分けた方がいいです。

# まとめ
あまりQiita記事を書く人間ではないのですが、言及ブログをひと目読んで、これはよくないなーと思い、走り書きしました。
自分もサービス提供者であって、ユーザへの表現に気をつけるべき人間です。
反面教師として言及記事は捉えていこうと考えています。以上
Qiitaで「LGTM」していない投稿のLGTMを外す

今まで「いいね」した記事がいつの間にか「LGTM」したことになってしまいました。
https://blog.qiita.com/like-to-lgtm/

上記の記事に書かれているように「いいね」というのはカジュアルに押すことがあるものです。

> 記事の評価はこれまで「いいね」という名前の機能で提供してきましたが、他のSNSやコミュニティ系サービスでもよく使われるラベルと同じなので、記事の内容をほとんど読まなくてもつい「いいね」している、ということがわかりました。また、技術情報が主題でなくても、ただ面白い記事であれば「いいね」が多く押されているような状況にもなっています。

一方「LGTM」は「いいね」とは違ってしっかりその内容を読んで押したものと考えられているようです。

> Qiita運営としても、流れてきた記事に「いいね」するのではなく、しっかりその内容を読んで、その内容が少なくとも自分にとって良いものだと思ったときに「LGTM（Looks Good To Me）」と言ってもらった方が良いと考えました。

しかし「いいね」がそのまま「LGTM」に変更されてしまったため、わたしが「LGTM」したわけではない記事が勝手に「LGTM」したことになってしまいました。
自分に正直であるためには「LGTM」を全て外すほかないですね。


## アカウントを消すと「LGTM」も消える

いい話ですね

## APIではいいねを外すことは出来ない

Qiita APIでは「LGTM」を外すことは出来ません。
https://qiita.com/api/v2/docs

## ユーザースクリプトでやる

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">（自分用）LGTMを全部外すユーザースクリプト。 / * [Remove LGTMs on Qiita](<a href="https://t.co/Zka5kc5ZHz">https://t.co/Zka5kc5ZHz</a>)</p>&mdash; M. Higashino (@61503891) <a href="https://twitter.com/61503891/status/1238180345326919685?ref_src=twsrc%5Etfw">March 12, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 

## Selenium IDEで「LGTM」を外す

事前準備

- Selenium IDEをインストールする https://www.selenium.dev/downloads/
- Qiitaにログインする
- マイページの「LGTMした記事」のページネーションが表示されるぐらいの大きさにフォントを調整する

以下のようなテストを実行します。皆様方におかれましては`/hanachin_/like` となっている部分は各自のQiitaのIDに置き換えてください。

https://gist.github.com/hanachin/77fd31da00dd61e4980f78361ffc8c9e

![Screenshot from 2020-03-13 03-05-44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2074/6fe95aa3-a5b1-bb5e-5228-488bb2df66a6.png)

これを「LGTMした記事」に何も表示されなくなるまでSeleniumで実行するだけ。簡単ですね。

## まとめ

LGTM
[Metal]metalファイルをプリコンパイルしつつ実機でもコンパイルする

ランタイムでシェーダをコンパイルするときに、毎回実機でコンパイルエラーを確認するのは辛いですね。
なので、シェーダのプリコンパイルを挟んだ上で実機でコンパイルすることで実行前にシェーダの記述エラーに気がつくことができます。

具体的にはmetalファイルをプリコンパイルした上で、defaultLibraryを使わずにmetalファイルからソースコードを読み込んで実機でコンパイルすれば良いわけです。
しかし、XcodeはMetalファイルを検知すると問答無用でプリコンパイルしてしまう [^1] ためmetalファイルをそのままアプリにバンドルするにはひと工夫必要です。

まず次のようにフォルダにファイルを配置します。

<img width="266" alt="スクリーンショット 2020-03-13 2.57.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24979/faef0fa5-69e9-3dc8-abae-6a85b31d6669.png">

この状態で、フォルダをXcodeにD&Dして「Create folder references」として登録します。

<img width="711" alt="スクリーンショット 2020-03-13 2.58.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24979/e909b277-c7c4-8ca4-59cf-71198caddf22.png">

次のように追加したディレクトリが青色のアイコンで登録されれば、このディレクトリ内のmetalファイルは直接バンドルされるようになります。

<img width="287" alt="スクリーンショット 2020-03-13 2.59.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24979/3a9f2356-a18a-8f88-0ace-5bc99a9e12ed.png">

しかしこのままではコンパイル対象にならないため、metalファイルをツリー内でD&Dしてリファレンスフォルダの外に追加します。

<img width="277" alt="スクリーンショット 2020-03-13 3.00.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24979/41e9d176-c78d-6198-0c46-e66579174fdf.png">

この状態では、Example/Default.metalはプリコンパイルの対象となり、Example/Shader/Default.metalはバンドル対象になります。
また、両方のファイルの参照は同じため片方を編集したらもう片方をコピペするような作業は不要になります。

実際にバンドルされたmetalファイルを呼び出す際は

```swift

let url = Bundle.main.url(forResource: "Shader/Default", withExtension: "metal")!
```

と、フォルダ名を入れてurlを取得します。

[^1]: CompileSourcesPhaseから消してCopy Bundle Phaseに入れてもプリコンパイルします。
【Nuxt.js】グローバルなコンポーネントの設定

Nuxtでコンポーネントをグローバルに使いたい。
意外と記事が出てこない。
ファイルの指定の仕方忘れてる。

というわけで、備忘録的な感じで書きます。

#環境
@nuxt/cli v2.11.0

#事前準備

↓こいつをグローバルに使いたい...

```components/Btn.vue
<!-- 子コンポーネント -->
<template>
  <button>クリック</button>
</template>

<script>
export default {};
</script>

```
　

↓このままでは、importしてないので使えません。

```pages/index.vue
<!-- 親コンポーネント -->
<template>
  <div class="MainPage">
    <子コンポーネント />
  </div>
</template>

<script>
export default {}
</script>

```

#やり方
簡単です。
pagesフォルダとかと同じ階層にある
pluginsフォルダにcomponents.jsファイルを作ります(ファイル名は任意)

そこで下記のように書きます。

```plugins/components.js
import Vue from 'vue'

//componentsファイルにあるグローバルにしたいコンポーネントをimport
import Button from '~/components/Btn'
//それを今回は'Button'というコンポーネント名で設定。
Vue.component('Button', Button)

```



そしてこの.jsファイルをnuxt.config.jsのpluginsに設定してあげます。

```nuxt.config.js
  plugins: [
    '~/plugins/components.js'
  ],
```

終わり！

あとは好きな時に使うだけです。

```pages/index.vue
<template>
  <div class="MainPage">
    <Button /> <!-- さっき設定したコンポーネントが使える -->
  </div>
</template>

<script>
export default {
}
</script>

```

<img width="571" alt="スクリーンショット 2020-03-13 2.33.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601820/57cfc7bc-55ae-5847-69f9-72aa07ff94e1.png">

ちゃんとコンポーネントがグローバルに呼び出されています。

※デフォルトで全てに呼び出す設定なので、すべてのページに読み込まれます。
普通コンポーネントは部品として使うため、importすべきとのこと。
by凄腕エンジニア


##こんな便利なものもあるみたいです。
【Nuxt.js: コンポーネントのファイル名にsuffixを付けるだけで、コンポーネントをどこからでも呼び出せるようにする】
https://qiita.com/bagooon/items/2d1485f418e6523a7b4d
Baiduが公開しているマスク検出を試してみた

# はじめに

マスクを付けているかいないかを判別するプログラムが公開されたのでやってみました

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">コロナウイルスの影響でマスクを着用した顔のデータセットや検出モデルの公開がここ最近急増している😷<br>■ Baiduが公開したオープンソースのマスク着用顔検出モデル<a href="https://t.co/NurgI3KB30">https://t.co/NurgI3KB30</a><br><br>■ 3500枚を超えるマスク検出するためのデータセット<a href="https://t.co/P3bVOaGawq">https://t.co/P3bVOaGawq</a> <a href="https://t.co/xtrVV86abF">pic.twitter.com/xtrVV86abF</a></p>&mdash; MAℝiNA🦋｜Edge AI Biz (@m__sb04) <a href="https://twitter.com/m__sb04/status/1234423447788277760?ref_src=twsrc%5Etfw">March 2, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 環境構築

~~~
$ conda create -n paddlehub python=3.6
$ conda activate paddlehub
$ pip install paddlehub
$ pip install paddlepaddle
~~~

## 実行
PaddleHubの[https://github.com/PaddlePaddle/PaddleHub/releases/tag/v1.5.3](https://github.com/PaddlePaddle/PaddleHub/releases/tag/v1.5.3)からv1.5.3.zipをダウンロードします。

PaddleHub-1.5.3\demo\mask_detectionに移動し、mask_detection.pyを実行しましょう。

~~~
$ cd PaddleHub-1.5.3\demo\mask_detection
$ python mask_detection.py
~~~

カメラが起動するので、マスクを付けたり外したりして検出されるか確かめてみましょう。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Mask Detection using PaddleHub <a href="https://twitter.com/hashtag/%E3%82%B3%E3%83%AD%E3%83%8A?src=hash&amp;ref_src=twsrc%5Etfw">#コロナ</a> <a href="https://twitter.com/hashtag/%E3%83%9E%E3%82%B9%E3%82%AF?src=hash&amp;ref_src=twsrc%5Etfw">#マスク</a> <a href="https://twitter.com/hashtag/COVIT19?src=hash&amp;ref_src=twsrc%5Etfw">#COVIT19</a> <a href="https://twitter.com/hashtag/Python?src=hash&amp;ref_src=twsrc%5Etfw">#Python</a> <a href="https://twitter.com/hashtag/ObjectDetection?src=hash&amp;ref_src=twsrc%5Etfw">#ObjectDetection</a> <a href="https://t.co/6yQIHw0TzQ">https://t.co/6yQIHw0TzQ</a> <a href="https://twitter.com/YouTube?ref_src=twsrc%5Etfw">@YouTube</a>さんから</p>&mdash; 藤本賢志(ガチ本)@pixivFANBOXはじめました (@sotongshi) <a href="https://twitter.com/sotongshi/status/1234688053802762241?ref_src=twsrc%5Etfw">March 3, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# まとめ
- 背景が白かったり、下を向くとマスク着用と誤検出されることが多い
- マスクデータセットを用いて、独自に学習させてみる
【Rails】link_toでdeleteが効かない時の解決方法

#最近たまにある現象
・link_toで実装した削除ボタンが正常に動かない
・deviseを使用したログアウト機能でUsersコントローラーのshowアクションが動く

どちらも、HTTPメソッドに__DELETE__を指定しているにもかかわらず__GET__でリクエストが送られていることが原因でした。

※メソッドの指定はできている状態の話です。まずは検証ツールでHTMLを確認します。

```html:
<a data-method="delete" href="/users/sign_out">ログアウト</a>
```


#結論
###head間は触らないほうがいいです。
__rails newコマンド__でアプリを作成した際、レイアウトファイル（application.html.erb）内のhead間には以下の記述がデフォルトであるはずです。
一見意味がわかりませんが、消さないでください。まとめて貼れば解決します。

```erb:application.html.erb
  <head>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>
    <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
  </head>
```

#今回必要だった記述は2行

###application.jsの読み込み

```erb:application.html.erb
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
```

application.jsを読み込んでいます。これでdeleteメソッドが効くようにはなります。

###CSRF対策
CSRF(クロスサイトリクエストフォージェリ)対策の以下の記述をします。
これがないと意図しないリクエストを受信してしまいます。脆弱性です。

```erb:application.html.erb
<%= csrf_meta_tags %>
```
これがないとこんなエラーが出ます。
<img width="1107" alt="スクリーンショット 2020-03-13 1.04.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156508/71015dab-3513-c656-9314-5f77c577e5d4.png">

Railsのルールのようです。[参考](https://note.com/simesime/n/n4d787b3d1bf7)



#解決しなかった場合
###javascriptのrequireを記述する
app/assets/javascript/application.js内に以下を記述する。

```js:application.js
//= require jquery
//= require jquery_ujs
```
jquery_ujsはハイパーリンクからGET以外のリクエストを生成してくれます。

#なぜJSが必要か
HTMLで使えるHTTPメソッドは__GET__と__POST__のみです。
今回使いたかった__DELTE__はjavascriptで擬似的に作成されるため、HTMLで読み込めなければ動きません。
詳しい動きは[こちら](https://toshiki-tsuji.com/rails%E3%81%A7delete-put%E3%81%AA%E3%81%A9%E3%81%AEhttp%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%82%92%E5%AE%9F%E8%A3%85%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95)が参考になります。


#まとめ
携帯用ホムペの時代からhead間編集（上級者向け）だったことを覚えています。
これに限らず、デフォルトの記述を消す時は本当に大丈夫か一旦調べて考えてみてください。
AKSでInsufficient privileges to complete the operation.みたいなエラーが出る場合の対処法がまるでtomato

今回はAKS（Azure Kubernetes Service）使用中に遭遇した
下記みたいなエラーの対処法を記載します。

ニッチなエラーだとは思いますが、そこそこ調べるのに時間がかかったので
同じエラーでつまずくであろう、5人くらいの方の参考になれれば良いなとおもっとります。めざせ5pv

## 病状

それはこんなコマンドを発行した時に起こりました
`az ad sp create-for-rbac --name $SP_NAME --role Reader --scopes $ACR_ID --query password --output tsv`

な、な、な、、なななななんとこんなエラーがが:scream::scream::scream:

```
Changing "tomato-service-principal" to a valid URI of "http://tomato-service-principal", which is the required format used for service principal names
Found an existing application instance of "<<サービスプリンシパルID>>". We will patch it
Insufficient privileges to complete the operation.
```
...あ、エラーさんですね？お帰りください。間に合ってますので。
いやだから、うちテレビないので！

要するに「パッチを適用しようとしたけど権限がないぜコノヤロー」的なことを言ってるんだと思います、たぶん。知らんけど。

## 解決方法

サービスプリンシパルのクレデンシャル...つまり資格情報をアップデートしてパスワードをリセットしてあげます。
で、AKS様を更新してさしあげます。ありがたく更新させていただくのです。

```
# クラスタのリソースグループをセット
$ AKS_RES_GROUP=tomato-rg-k8s
# クラスタ名をセット
$ AKS_CLUSTER_NAME=tomato-cluster

# サービスプリンシパルのIDをゲット
$ SP_ID=$(az aks show --resource-group $AKS_RES_GROUP --name $AKS_CLUSTER_NAME --query servicePrincipalProfile.clientId -o tsv)
# 資格情報を更新してサービスプリンシパルのパスワードをゲット
$ SP_SECRET=$(az ad sp credential reset --name $SP_ID --query password -o tsv)

# クラスタの資格情報を更新
$ az aks update-credentials  --resource-group $AKS_RES_GROUP  --name $AKS_CLUSTER_NAME  --reset-service-principal  --service-principal $SP_ID  --client-secret $SP_SECRET
```
たぶんこれで直る..きっと、うん。

原因はおそらく、クラスタを何回か構築してたので、サービスプリンシパル名が被っちゃってたとかなんだろうなぁー...

ちなみにサービスプリンシパルのパスワードを忘れてしまった際にも、有効なコマンドであります。
つまり、SP_SECRETに保存されたパスワードは保管しておくのが吉です。

ではまた:tomato:

## さいごに
ZEROBILLBANKでは一緒に働く仲間を募集中です。
なんとかjsとか、ブロックチェーンとか、kubernetesとかでいろんなAPIを作るお仕事。
今のところエンジニアは5人くらい。スタートアップだけど、結構ホワイトで働きやすいです。

[ZEROBILLBANK JAPAN Inc.](https://zerobillbank.com)
[aws,rails]ancestryをawsにデプロイした時に反映されない状況の解決方法

#1.どんな状態だったか
ancestryを利用して、railsのプロジェクト内にあらかじめデータは作成してあり、ローカルでは動くのに本番環境で反映されないという状態でした

#2.原因
ancestryはdb/seeds.rbにデータを保存するのですが、このseedファイルを利用するには、データベースの作成コマンドの他にseedを読み込むコマンドを打つ必要があるのですが、それを忘れてしまっていました。

#3.解決方法
`RAILS_ENV=production bundle exec rails db:seed`というコマンドを打っていただければ反映できます。
※コマンドの説明
・本番環境なので`RAILS_ENV=production`が必要です
・読み込みを早くするためにrailsの実行コマンドの中からdb関係のコマンドがあえて除かれていることがあるので、`bundle exec`をつけています。（はじめに無しで実行してダメだったらつけていただいても良いと思います）

#4.記事の目的
チーム開発をする時に、筆者のようにデプロイを担当する人間が知らない技術が取り込まれることはよくあると思われます。
そのうちの一つが、今回のancestryだったのですが、解決後に、エラーではないのにエラーだと思って検索に時間をかけてしまうのは非常にもったいなかったと思いました。
つきましては取るに足らない内容ではあったのですが、少しでも皆さんの検索時間を減らせれば良いなと思いこの記事を作成しました。

何かのご参考にしていただければと思います。
MacにPowerShellをインストールしてOffice365を操作しようとしてみた

## はじめに

ひょんなことから`Mac`で`PowerShell`を使って`Office365`の操作を試みることがあったのでメモ

**過去の記事**を探ったところ、**できなさそうな雰囲気**はある

* [MacにPowerShellをインストールするが・・・](https://itnews.jp/?p=13114)
    * `ログインはできるようだが、その後には作業ができなかった。`との記載有り
* [MacでPowerShell](https://tech-lab.sios.jp/archives/7805)
    * コメントに`ちなみにOffice365へのPowerShell(Get-MsolUserとか)はまだ、使えないようです。Install-Module -Name AzureADがエラーになりました(´；ω；｀)`との記載有り

## 導入編

公式ドキュメント[macOS への PowerShell Core のインストール](https://docs.microsoft.com/ja-jp/powershell/scripting/install/installing-powershell-core-on-macos?view=powershell-7)を参考に、`brew`で`PowerSHell`をインストールする

```bash
$ brew cask install powershell
```

インストール後、`pwsh`コマンドで`PowerShell`を起動できるので、公式ドキュメント[Office 365 PowerShell への接続](https://docs.microsoft.com/ja-jp/office365/enterprise/powershell/connect-to-office-365-powershell)の[手順 1: 必要なソフトウェアをインストールする](https://docs.microsoft.com/ja-jp/office365/enterprise/powershell/connect-to-office-365-powershell#step-1-install-required-software)を参考に各種モジュールをインストールする。

```bash
$ pwsh
```
```powershell
PS /Users/UserName>
PS /Users/UserName> Install-Module -Name AzureAD

Untrusted repository
You are installing the modules from an untrusted repository. If you trust this repository, change its InstallationPolicy value by running the Set-PSRepository cmdlet. Are you sure
you want to install the modules from 'PSGallery'?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "N"): Y
```

[手順 2: Office 365 サブスクリプション用の Azure AD に接続する](https://docs.microsoft.com/ja-jp/office365/enterprise/powershell/connect-to-office-365-powershell#step-2-connect-to-azure-ad-for-your-office-365-subscription)に従い、`Azure AD`に接続を試みる

```powershell
PS /Users/UserName> Connect-AzureAD
Connect-AzureAD: The term 'Connect-AzureAD' is not recognized as the name of a cmdlet, function, script file, or operable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
```

おや、**インストールに失敗**する・・・。
どうやら**2020/03/11現在**、`Mac`にインストールできる`PowerShell 7.0.0`でも`Office365`の操作はできない模様。
`Get-Credential` は実行できるが、それ以外はできない。
[はじめに](#はじめに)に記載の通り、ログインはできるけどそれ以外の操作はできないんですね・・・。

```powershell
PS /Users/t.setoguchi> $Cred = Get-Credential

PowerShell credential request
Enter your credentials.
User: admin@sampledayo.com
Password for user admin@sampledayo.com: ************
```

## 結論

未だに`Mac`の`PowerShell`では`Office365`は**操作できない**ということが解った。
今後の`Mac`版`PowerShell`のリリースに期待。
Numpyの気持ち悪いぐらいの柔軟性は、Pythonが動的型付け言語だからできることなのか

rustあたりにnumpyのようなライブラリができたら比較できて面白いんだけどなぁ。

https://qiita.com/AKKYM/items/8cd2073432dbded95626