OmniAICreator/Qiita-1.07M huggingface dataset:
Androidの画像ロードライブラリ「Coil」のセットアップ&使い方(Kotlin)

## 「Coil」とは？

Android向けの画像ロードライブラリです。

## 画像ロードライブラリの比較

Android向けの画像ロードライブラリを比較しました。

||Picasso|Glide|Coil|
|:--|:--|:--|:--|
|最新バージョン|2.71828|4.11.0|0.9.5|
|最終リリース|2018/03/08|2020/01/09|__2020/02/09__|
|スター数|17,418|__28,772__|2,998|
|提供元|Square|Bump Technologies|Coil|
|特徴|Squareが提供している|スター数が多い|Kotlinファースト|

※2020/04/17現在

CoilはPicassoやGlideよりスター数が少ないのですが、最終リリース日が最も新しく、Kotlinファーストに作られているため、選定しました。

選定後に読んだのですが、パフォーマンスを比較した記事を参考にするのもいいと思います。
https://proandroiddev.com/coil-vs-picasso-vs-glide-get-ready-go-774add8cfd40

## 環境

- OS：macOS Mojave 10.14.6
- Kotlin：1.3.61
- Gradle：5.6.4
- Gradle plugin：3.6.2
- Coil：0.9.5

## セットアップ

### インストール

appフォルダ配下の「build.gradle」に追加するのみです。

```diff_groovy:/app/build.gradle
dependencies {
+     implementation 'io.coil-kt:coil:0.9.5'
}
```

## 使い方

ライブラリをインポートし、ロードするのみです。

```kotlin
import coil.api.load

imageView.load("{画像のURL}")
```

私の場合、以下のビルドエラーが発生しました。

```shell-session
Cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6. Please specify proper '-jvm-target' option
```

appフォルダ配下の「build.gradle」にJVMターゲットを指定することで解決しました。

```diff_groovy:/app/build.gradle
android {
+     kotlinOptions {
+         jvmTarget = '1.8'
+     }
}
```

## おわりに

かんたんに画像をURLから取得して表示することができました！
詳細な使い方は公式ドキュメントをご参照ください。

## 参考リンク

- [coil-kt/coil: Image loading for Android backed by Kotlin Coroutines.](https://github.com/coil-kt/coil)
- [square/picasso: A powerful image downloading and caching library for Android](https://github.com/square/picasso)
- [bumptech/glide: An image loading and caching library for Android focused on smooth scrolling](https://github.com/bumptech/glide)
- [Cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6. Please specify proper ‘-jvm-target’ option - Qiita](https://qiita.com/kph7mgb/items/28ee37957976e80e38f2)
WindowsでもMacみたいにスクショしたいし、ついでにUPLOADしたい。（CloudShot）

MacもWindowsも両方とも愛すことのできる恋柱のひつじです。

最近の仕事で本番環境での作業ログを一生懸命スクリーンショットする人がいて、
「あー久しぶりにこういうの見たなぁ」と物思いにふけりました。

Windowsの標準スクリーンショットで「winキー＋Shift+s」やSnippingToolを使う人も多いと思いますが、
やはりMacのスクショ機能にはちょっと及ばないですよね。

## 本題

って事ですごいツール見つけましたよ！

＿人人人人人人人＿
＞　**CloudShot**　＜
￣Y^Y^Y^Y^Y^Y^Y￣
 
https://cloudshot.com/

## いいなぁと思った機能

1. ボタン一つ(HotKey)でスクショとってローカル保存される。（保存前にテキスト入れなどもできる。）
2. ボタン一つ(HotKey)で画面の動画も行ける。
3. 撮影後にWebにUPLOADできる。(GoogleDrive/FTPサーバ)

<img width="1240" alt="スクリーンショット 2020-04-17 14.34.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319145/a81cb3b5-5d4b-58fc-f3e0-ade945f053b4.png">

## こんな感じで使います。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">CloudShotデモ <a href="https://t.co/EMQgTIQ4EO">pic.twitter.com/EMQgTIQ4EO</a></p>&mdash; ひつじ (@141mhz) <a href="https://twitter.com/141mhz/status/1251023997786972160?ref_src=twsrc%5Etfw">April 17, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
【rails】Markdown記法で投稿を表示する方法をやってみる

railsで投稿した内容をマークダウン形式で入力しても、表示できるようにしました。
また、言語ごとにハイライトをつけることもできます。

#gemをインストール

以下を追加

```rb:Gemfile
# マークダウン形式で表示するためのgem
gem 'redcarpet', '~> 2.3.0'
# シンタックスハイライトに対応させるためのgem
gem 'coderay'
```
その後、`bundle install`

#application_helper.rbに記述

```rb:app/helpers/application_helper.rb
module ApplicationHelper
  # マークダウン形式で記入するためにrequire
  require "redcarpet"
  require "coderay"

  class HTMLwithCoderay < Redcarpet::Render::HTML
    def block_code(code, language)
        language = language.split(':')[0]

        case language.to_s
        when 'rb'
            lang = 'ruby'
        when 'yml'
            lang = 'yaml'
        when 'css'
            lang = 'css'
        when 'html'
            lang = 'html'
        when ''
            lang = 'md'
        else
            lang = language
        end

        CodeRay.scan(code, lang).div
    end
  end

  # マークダウンを可能にするメソッド
  def markdown(text)
    html_render = HTMLwithCoderay.new(filter_html: true, hard_wrap: true)
    options = {
        autolink: true,
        space_after_headers: true,
        no_intra_emphasis: true,
        fenced_code_blocks: true,
        tables: true,
        hard_wrap: true,
        xhtml: true,
        lax_html_blocks: true,
        strikethrough: true
    }
    markdown = Redcarpet::Markdown.new(html_render, options)
    markdown.render(text)
  end
end
```
#show.html.erbに記述
```erb:app/views/posts/show.html.erb
<div class="クラス名">
  <%= markdown(@post.content).html_safe %>
</div>
```
@post.contentは一例です。
表示したい箇所に `<%= markdown(モデル名.カラム名).html_safe %>` を追加します。

#editページで編集してみる
rails s で動かしてから、
用意した自分のアプリ内の編集ページで投稿をマークダウン形式で編集してみます。
![スクリーンショット 2020-04-17 14.47.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574173/5a979c6c-54fb-4880-d482-cca51fbd17c3.png)


「```ruby」のようにするとハイライトができます。
バッククオート3つの隣に言語(拡張子)を書く要領です。

「`」←これは私の使ってるmacだとshiftキー+optionキー+_(アンダーバー)で入力できます。
詳しいマークダウン記法はこちらのサイトにわかりやすく載っています。
https://qiita.com/Qiita/items/c686397e4a0f4f11683d

#showページで確認
![スクリーンショット 2020-04-17 14.36.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574173/e4fe78a8-4f3e-49bc-7791-eabdd2367aff.png)



##参考
・https://qiita.com/shu_0115/items/476a51cb4751515f3ac2
・https://qiita.com/hkengo/items/978ea1874cf7e07cdbfc
jupyter 環境でRを使えるようにする (Anacondaを使わない場合).

# jupyter 環境でRを使えるようにする (Anacondaを使わない場合).

## 前口上
Anaconda 環境であれば Anaconda のダッシュボードで いわゆる "r環境 (r-envとか)" を設定すればそこから jupyter を起動することで jupyter で R をつかうことができるようになりこれが最も簡単な方法であると思われる. **が.** いろいろと作業をしているうちにこの Anaconda が邪魔になってきた. ざっくりいうとほかの環境とのバッティングである. またパッケージの導入に Environments から行うのは気持ち悪い. ということで Anaconda を[消して](https://docs.anaconda.com/anaconda/install/uninstall/) jupyter をPython から入れなおして R を使えるようにしてみた. 結論から言うと極めて快適である. jupyter を Anaconda でなく Python から入れることは想定していたより簡単であった. なおPythonはWindows10の環境ではMicrosoft Storeから導入した.

### 前提
前提というほどの前提はない: ただし:
- OS は Windows10/Ubuntu 18.04 で行った. (この二者でたいして差はない: 違いという意味では R/Pythonの導入は Ubuntu など Linux の場合そのしきたり(apt-getを使う、とか)に従うことくらい).
- R は既に導入されているものとする(こちらは 3.6.3 "Holding the Windsock" が導入済み)
- Python は入っているものとする (こちらは 3.8.2)


## jupyter を 導入する.
[参考:Installing the Jupyter Software](https://jupyter.org/install)
原則としてこのページの "pip" の項を順に実行すればよい.

### pip install jupyterlab
jupyter lab の導入はこのコマンドで行う. このコマンドは **コマンド・プロンプト** から実行する.
導入過程で各種前提パッケージが導入される.
ところでjupyter lab の起動は:
> jupyter lab  

とjupyterとlabとの間にスペースが入るがinstallでは入らない.

### pip install notebook
必要に応じて notebook も導入する.  
たぶんnotebookのほうが需要が多いのではないかと思われるがlabでもほとんど同じことができる. labだとnotebookを複数立ち上げてもブラウザのタブを一つしか消費しないので始末がいい.
起動は:
> jupyter notebook

### pip install voila 
必要に応じて voila も導入する. ただしWindows環境では使えないので意味はない. "Voilà ヴォァラ"なのでnotebookを美しく見せてくれる機能っぽい[参考](https://voila-gallery.org/).
起動は: 
> voila \<path-to-notebook\> \<options\>   

である.

## jupyter に R を加える.

jupyter には python しか入っていないので別途カーネルを導入してやる必要がある.

### Rの起動: 
terminal を開き "R" コマンドでRを起動する.
**N.B.** 必ずterminalないしはそれ相当(e.g. コマンドプロンプト)から実行すること: Rアイコンをクリックなどに拠る起動ではうまくいかない.

### 導入コマンド
以下の二つのコマンドを実行する:

- install.packages('IRkernel')
- IRkernel::installspec() 

なお、install.packages を実行すると直後 packages の導入元を選択するポップアップが出るので適切に選択する.
[参考:github IRkernel のreadme文書](https://github.com/IRkernel/IRkernel)

### 確認
jupyter labなどを起動して確認する."Launcher"に"R"のアイコンが出ていれば良しとする: 
<img width="805" alt="jupyterlab-sample.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311422/2fb33a78-985a-434a-6f92-0fb965f99b2d.jpeg">
cssで字下げするにはblock要素にtext-indentを使おう

#cssで字下げを行うにはtext-indentを使おう
字下げをするにあたり広く知られていることだと思う。しかし私が実際にtext-indentを使ってみると全く変化がなかった。何故かというと、__インライン要素にtext-indentを使っていたから__だ。

__display:block;__と書き加えてやったところ、無事字下げに成功した。

```css:css
 a{
	text-indent: 1em;
	display:block;
	}
```

ここでリンクに下線をつけてやろうなどと思うと以下のようになる。![スクリーンショット 2020-04-17 14.28.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620685/19188f26-b62d-e741-da6b-b16062dd71fb.png)
下線が字下げをした分の左側の余白まで、というか画面いっぱいに広がってしまっている。

dosplay:block;にする以上仕方ないのだが、リンクの装飾と字下げどちらもやりたかった私はtext-indentではなくインライン要素にしてmargin-leftを使うことにした。

```css:css
a{
	margin-left:1em;
	border-bottom:solid 3px #999;
	text-decoration: none;
	}

```
結果この記事のタイトルに背くことになってしまっているがこれ以外にやり方を知らないので許してほしい。誰かいい方法を知っていたら教えてください。
初めてのQt Creator～簡単なプログラムを書く～

#初めてのQtで簡単なプログラムを書きました

久しぶりの投稿です。
最近、ディープラーニングを勉強していて、新しいことが分かる度に投稿しようかと思いましたが、なかなか先のことが理解できませんでした。
また、関数型言語（F#や、Heskell）も勉強中で、モナドとはなんだ？ということがなかなか理解できず、結局投稿する記事のネタが無く、なかなか投稿できませんでした。
ですが、最近少しは分かってきたので、後々いろいろとプログラムを走らせてみて、分かったことなどを記事にしようかと思います。

今回は、Qtで簡単なプログラムを作ってみました。
C++でのプログラミングは久しぶりで、懐かしいC++プログラミングをしたいと思い、Qtと出会いました。

今は、C#をメインに使っていましたので、`->`演算子が懐かしくて・・・`.h`のヘッダーファイルも懐かしくて・・・。

今回は、ただボタンを押すと、テキストボックスに入力した内容を、ラベルに表示する内容にするだけの、何の実用性も無いものです。
でも、プロパティの変更など、どのようにすれば良いのかが分からず、結構はまりました。

##C++プログラム

```c++:Mainwindow.cpp
#include "mainwindow.h"
#include "./ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::on_pushButton_clicked()
{
    ui->label->setText(ui->lineEdit->text());     //追加したのはこの一行だけです。
}
```

自分で記述したのは一行だけです。
`ui->`とするところが、はまりました。

C#だと

```csharp:
label.Text=lineEdit.Text;
```

こんな感じですね。プロパティという機能があるからこそできるんですよね。

##実行結果

![00000000000000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590410/d34bd9e2-7ad9-a753-19c3-18f5e2666c1b.png)
MySQL ERROR 2002 でやってみたこと｡

以下のことで､エラー解決できたので参考までに見てください｡

MySQLを起動しようとおもったら､

```$ mysql.server start```

で起動すると､

```ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)```

とエラーがでました｡


####1､ 権限を確認します｡

```
$ cd /usr/local/var
$ ls -l
```
すると､

```
...
drwxr-xr-x  26 _mysql    _mysql  832 11  8 01:39 mysql
...
```
権限のユーザーが
```_mysql```
となっています｡


####2､ 権限を変更する
```$ sudu chown -R [UerName] mysql```
UserName にユーザー名を入れます｡


```$ ls -l```
で確認すると､

```
･･･
drwxr-xr-x  26 UserName  _mysql  832 11  8 01:39 mysql
･･･
```
で変わっていると思います｡

```
$ mysql.server start
```

起動することができました｡
Rails Seleniumでスクレイピングするときに画像を読み込まない

# 結論

参考：[http://lab.flama.co.jp/archives/1752/](http://lab.flama.co.jp/archives/1752/)

```rb
    capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
      accept_insecure_certs: true,
      chromeOptions: {
        args: [
          '-window-size=1920,1080',
          '--blink-settings=imagesEnabled=false'
        ]
      }
    )

    driver = Selenium::WebDriver.for(
      :remote,
      url: 'http://chrome:4444/wd/hub',
      desired_capabilities: capabilities,
    )
```

## `Selenium::WebDriver::Chrome::Options`ではできなかった

```rb
    capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
      accept_insecure_certs: true
    )
    options = Selenium::WebDriver::Chrome::Options.new
    options.add_argument('--headless')
    options.add_argument('--window-size=1920,1080')
    options.add_argument('--blink-settings=imagesEnabled=false')
    options.add_argument('--disable-gpu')

    driver = Selenium::WebDriver.for(
      :remote,
      url: 'http://chrome:4444/wd/hub', # chromeはdockerサービスの名前
      desired_capabilities: capabilities,
      options: options,
    )
```

## docker-compose.ymlの設定

```
services:
  web:
    container_name: web
    build: .
    environment:
      - TZ=Asia/Tokyo
    ports:
      - 3000:3000
    #command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/hogehoge
      - bundle:/usr/local/bundle
    depends_on:
      - chrome
  chrome:
    container_name: chrome
    image: selenium/standalone-chrome-debug
    ports:
      - 4444:4444
      - 5900:5900
    volumes:
      - /dev/shm:/dev/shm
```
Mac版LINEで通話ができない/クラッシュするときはCamTwistをアンインストール

Mac 版 LINE では、CamTwist をインストールしていると通話ができなかったりクラッシュしたりする不具合があるようです。
その場合、CamTwist をアンインストールすることで解決することができます。
アプリケーションフォルダの CamTwist フォルダにある `uninstall.command` をダブルクリックし、パスワードを入力すればアンインストールの完了です。

参考文献：
https://twitter.com/BeDai/status/474146198706610176
docker + seleniumですべてのchromedriverプロセスを削除する

## 環境

利用しているdocker-compose.ymlは以下のような感じ。

```yml
services:
  chrome:
    container_name: chrome
    image: selenium/standalone-chrome-debug
    ports:
      - 4444:4444
      - 5900:5900
    volumes:
      - /dev/shm:/dev/shm
```


# 結論! bashコマンドで消す

chromeの部分は適宜変更。docker-compose.ymlに書いてある名前。

```bash
 docker-compose exec chrome bash -c "ps aux | grep -E 'chromedriver|/opt/google/chrome/chrome' | grep -v 'grep' | awk '{print \$2}'| xargs kill"
```

## 発生したこと

seleniumを使っていると徐々にPCが熱くなる。
動作ももっさりしてタイムアウトとか発生しまくる。

### 調べたら原因と対策があった。

[プログラム終了後もchromedriverプロセスが残る原因と対策](https://materializer.co/lab/blog/13)

### あぁ、確かに使いっぱなしだったよ。自動で終了してくれないんだね。。

とりあえず、`driver.quit()`をプログラムに追加。
しかしこれでは、予期せぬエラー終了したときに対応できない。

調べたけど使いっぱなしにしてしまったdriverを削除する手立ては見つからず。
自分でどうにかしろってことですかね?

## 解決策

killコマンドで荒々しく削除。

`docker-compose exec chrome bash -c "ps aux | grep -E 'chromedriver|/opt/google/chrome/chrome' | grep -v 'grep' | awk '{print \$2}'| xargs kill"`

chromedriverだけ削除しても、プログラムで利用してた画面とかのchromeプロセスは残っていた。
ので、/opt/google/chrome/chromeでそれらも合わせて削除。
WebSocketが切断された際に、自動的に再接続する方法

先日、WEBサイト制作者さん向けのウェブサービスをリリースしたのですが、制作の際に得た知見をシリーズで共有していこうと思います。

## WebSocket の自動再接続が行われない
[Crew'sHub](https://crewshub.net)には、リアルタイムのチャット機能があり、Web Socketを利用しています。
また、データ管理画面でも、プロジェクトメンバーが編集したら即座に更新されるようになっており、やはりここでもWebSocketを利用しています。

開発中に遭遇した問題として、WebSocketが切断された際に、自動再接続がうまく行われないということがありました。

クライアント側では、Reconnecting WebSocketという、WebSocketがクローズされた際に自動的に再接続が行われるモジュールを採用しています。

**reconnecting-websocket**
https://www.npmjs.com/package/reconnecting-websocket

自動再接続されるはずのモジュールではありますが、ノートPCでスリープから復帰した際など、切断されたままの状態になってしまう不具合が度々発生しました。

そこで、SetTimeoutで定期的にWebSocketのreadyStateを確認して、コネクションが切断されていたら再接続するようにしてみたのですが、それもうまく機能しませんでした。どうもコネクションが切断されているにも関わらず、readyStateにそれが反映しないことがあるようです。

## Ping Pong で接続状況を確認する
WebSocket.readyStateが使えないので、実際にサーバと定期的に通信を行って接続状況を確認する方法に切り替えました。

クライアント側はこんな感じです。

```js
let pingPongTimer = null

const ws = new ReconnectingWebSocket(`wss://${process.env.API_HOST}/api/v1/`)

const checkConnection = () => {
  setTimeout(() => {
    ws.send('ping')
    pingPongTimer = setTimeout(() => {
      console.log('再接続を試みます')
      pingPongTimer = null
      ws.reconnect()
    }, 1000)
  }, 30000)
}

ws.onopen = () => {
  checkConnection()
  ...
}

ws.onmessage = ({ data }) => {
  if (data === 'pong') {
    if (pingPongTimer) {
      clearTimeout(pingPongTimer)
    }
    return checkConnection()
  }
  ...
}
```
以下のような処理が行われます。

1. WebSocketがopenしたら、checkConnectionをコールします。
1. checkConnectionは、呼ばれてから30秒後にサーバにpingを送信します。
1. ping送信後1秒以内にpongが返って来なかったら再接続を試みます。
1. ping送信後1秒以内にpongが返って来たら、checkConnectionを再度コールします。

サーバ側はNodeで構成されており、以下のように実装しています。（一部抜粋）

```js
// ユーザーからのメッセージを処理する
ws.on('message', (message) => {
  // pingの処理
  if (message === 'ping') {
    return ws.send('pong')
  }
  ...
}
```

以上のような処理に変更してからは、コネクションが維持されるようになりました。
現在は、コネクションの確認を30秒ごとに行っていますが、目的によって間隔を調整すると良いと思います。

## 最後に
繰り返しになりますが、WEBサイト制作者さん向けのサービスをリリースしましたので、お気軽にお試しいただけると幸いです。（無料で使えます）
元々は自分たち向けに作ったシステムでして、WEBサイト再作時に大量の情報やファイルを管理・共有するのに疲れ果て、それを解消するために作ったウェブアプリです。なかなか評判が良かったので、一般向けに作り直してリリースしました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ウェブサイト制作に携わる人達に使っていただきたいウェブサービスをリリースしました。<br><br>ウェブサイトを作る際、大量の情報やデータを管理する必要がありますが、それをスッキリ整理整頓できて、簡単にチームで共有できます。<br><br>昨年の夏から作り始めて、やっと公開です。<a href="https://t.co/kFOCip3eUD">https://t.co/kFOCip3eUD</a></p>&mdash; 橋本技研@売れるネットショップ研究所 WEB技術×販促 (@hashimotosubaru) <a href="https://twitter.com/hashimotosubaru/status/1246611675379191808?ref_src=twsrc%5Etfw">April 5, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
new byte[]が許されるのは...

.net Core 3.1 の C#で byte[]をnewする話。

将来的に何度も検索しそうなのでこちらに抜粋

元記事: [LitJWTに見るモダンなC#のbyte[]とSpan操作法](http://neue.cc/2019/05/27_578.html "LitJWTに見るモダンなC#のbyte[]とSpan操作法")

>ようするに、今どきnew byte[]なんてしたら殺されるぞ！

とのこと。

C# 7.2からSpan構造体というのが使えるようになったので
unsafe なしで stackalloc を使えるようになりました。

だから new byte[] が許されるのはC#7.2未満というお話

#####従来の書き方
```C#
var bytes = new byte[Base64.GetMaxBase64UrlDecodeLength(header.Length)];
```

#####(データが)あんまり大きくないのが確定してる場合

```C#
Span<byte> bytes = stackalloc byte[Base64.GetMaxBase64UrlDecodeLength(header.Length)];
```
（stackalloc はスタックメモリ（容量はかなり少ない）を使うので、配列の長さが短いもの限定で）

#####(データが)そこそこ大きいのが来る可能性がある場合

```C#
var rentBytes = ArrayPool<byte>.Shared.Rent(Base64.GetMaxBase64UrlDecodeLength(payload.Length));
try
{
    Span<byte> bytes = rentBytes.AsSpan();
     // ....
}
finally
{
    ArrayPool<byte>.Shared.Return(rentBytes);
}
```
（bytesにデータを流し込んだ後は、.Sliceできちんとサイズ指定して取得します）

(その他参考にさせていただいた記事)

[.NET Core 3.0時代のメモリ管理](https://www.slideshare.net/KageShiron/net-core-30-179286616 ".NET Core 3.0時代のメモリ管理")
[Span<T>を使うべき5つの理由](https://qiita.com/GlassGrass/items/cea3c6f91413c3582b5f "Span<T>を使うべき5つの理由")
[C# - Span のすべて: .NET の新しい頼みの綱を探索する](https://docs.microsoft.com/ja-jp/archive/msdn-magazine/2018/january/csharp-all-about-span-exploring-a-new-net-mainstay "C# - Span のすべて: .NET の新しい頼みの綱を探索する")
[ReadOnlySequence<T>について](https://qiita.com/skitoy4321/items/0fc4dc72bc50dabba92b "ReadOnlySequence<T>について")
Railsチュートリアル11章 SendGrid 凍結問題を解決する

**追記: Railsチュートリアルのテキストで使用されていた SendGrid アドオンは、Mailgun に変更となりました。よって、以下の対応をする機会はなくなるかと思います🙏これまで SendGrid アドオンでうまくいかなかった方も、Mailgun バージョンで再チャレンジしてみてくださいね👌✨**
参考: [Railsチュートリアルヘルプ](https://railstutorial.jp/help)

Railsチュートリアル11章では、本番環境でメール送信する際に、SendGrid を Heroku にアドオンする必要があるのですが、SendGrid アカウントが凍結される方が多くみられたため、解決方法をまとめてみました。

#### 準備: SendGrid アカウントが凍結されているかを確認する
本番環境でメール送信をした後、このような画面が出る。
![](https://i.gyazo.com/2532036ef362837cdfedcb31f6a07308.png)
`heroku logs --tail` でログを確認。メールの文面ログの後に、以下のようなログが含まれていると凍結されている。

```console
Net::SMTPAuthenticationError (535 Authentication failed: account disabled
```
メール文面のログがない場合は、もう一度コードの見直しをした方が良さそうです💦

### 対処方法

米国のSendGridに英語で問い合わせると使える状態にしてくれる、といった情報が多いようですが、自力ですぐに解決できます。

#### 1. 現在の Heroku アプリを削除する
Heroku の setting の一番下から削除します。
![](https://i.gyazo.com/08951f017268701a90056493cb22e778.png)
![](https://i.gyazo.com/b87e55a9b124842c18ce28eafcce9a11.png)

#### 2. 新しく Heroku アプリを作る
https://dashboard.heroku.com/apps から Create new app します。名前は変更した方が確実かと思います。
![](https://i.gyazo.com/9e1074b7a8e922478bbd3534594cf685.png)

#### 3. production 環境の SMTP 設定に URL を追加し`git push` する
Railsチュートリアル11.4 の「Railsのproduction環境でSendGridを使う設定」の `host = '<your heroku app>.herokuapp.com'`部分に新しいHerokuのURLを記入し、`git push` しておく。

```config/environments/production.rb
Rails.application.configure do
  .
  .
  .
  config.action_mailer.raise_delivery_errors = true
  config.action_mailer.delivery_method = :smtp
  host = '<your heroku app>.herokuapp.com'
  config.action_mailer.default_url_options = { host: host }
  ActionMailer::Base.smtp_settings = {
    :address        => 'smtp.sendgrid.net',
    :port           => '587',
    :authentication => :plain,
    :user_name      => ENV['SENDGRID_USERNAME'],
    :password       => ENV['SENDGRID_PASSWORD'],
    :domain         => 'heroku.com',
    :enable_starttls_auto => true
  }
  .
  .
  .
end
```

#### 4. remote 先に新しい Heroku git URL を 設定する
URL は、Heroku の Settings ページで確認できます。

![](https://i.gyazo.com/52931c02c2d7f43d3cc49fe03949fd27.png)

```console
$ heroku git:remote -a https://git.heroku.com/〇〇.git

# 正しく設定されたか確認
$ git remote -v
```

#### 5. Heroku に push する

```console
$ git push heroku
$ heroku run rails db:migrate
```

#### 6. 最後に SendGrid アドオンする

```console
$ heroku addons:create sendgrid:starter

# Herokuの環境変数を表示したい場合
$ heroku config:get SENDGRID_USERNAME
$ heroku config:get SENDGRID_PASSWORD
```

以上で完了です。新しく作った本番環境で、メール送信できるか試してみてください 💌

追記： 一度使えるようになっても、しばらく経つとまた凍結していることがあります。SendGridのセキュリティ上の事情なのかもしれませんが、また同じ手順でAppを作り直すのが早そうです😥

参考： [SendGrid - アカウント凍結のフローとその解除方法について教えてください。](https://support.sendgrid.kke.co.jp/hc/ja/articles/203392245)

> アカウントが凍結される可能性が高いケースとして、次のようなものがあります。

> - SendGridの認証情報（パスワードやAPIキーなど）がパブリックな場所に置かれていることが発覚した等、セキュリティリスクを理由としたケース
- 存在しない宛先への送信（Bounce）や誤った宛先への送信（Invalid）等、レピュテーションが下がることを理由としたケース
- 急激な送信量の増加を検知した等、アカウントの不正利用が疑われるケース
アカウントの停止は、このような重大な事態を防ぐための措置でもあるということをご理解ください。
IntelliJのSpring boot + Thymeleafで変数を参照できない

IntelliJでコントローラからHTML(Thymeleaf) に渡した変数に警告文が出ているためこれを解決
`model.addAttribute("title", "ユーザ一覧");`←Controllerのこの子
![screenshot.14.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619433/da4a58ec-058a-0d43-8800-3ccf9c4e062d.jpeg)


# 確認1
`xmlns:th="http://www.thymeleaf.org"` で名前空間を宣言しているか

```html:test.html
<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
︙
︙
(省略)
```

# 確認2
IntelliJで必要なプラグインがインストールされているか
`Ctrl + Alt + S`でSetting画面を表示Pluginで
Thymeleaf + Spring関係がインストールされているか確認する
自分の場合Spring MVCがインストールされていなかったため警告文が表示されていた。
![screenshot.23.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619433/0d05486c-05f0-cab1-8d76-020fd579a28f.jpeg)

これでHTMLからコントローラまで一気に飛べるようになった！
やったぜ＼(^o^)／
突然yarn installでESOCKETTIMEDOUTが起きた時

## 環境

Windows10

## 状況

ググるとMaterial-iconsがどうとか書いてあるが、MACの時は行けたんだよなーと思いつつタスクマネージャーを見ると`Antimalware Service Executable`がCPU使いまくりだった。

## 解決

`yarn cache dir`で出てきたところを`Windows Defender`の監視対象外にした。

セキュリティ的に合ってるのか？
pandasのto_datetimeで「TypeError: Unrecognized value type: <class 'str'>」

日付として認識できない文字列などが入っていると陥るエラーです。
地味にハマったりするので記事にまとめました。

DataFrame作成時に、日付文字列の間に「日付ではない値」が入っているとobjectとして読み込まれます。
（なお、すべて日付として解釈可能な文字列で構成されている場合は、datetimeとして読み込めます。）

たとえば、実データでよくあるケースとして、日付の間に、ハイフン（-）を入れている等です。

```python
temp = pd.DataFrame(["2020-04-09", "2020-04-10", "-", "2020-04-12"], columns=["date"])
```

|   |date |
|:--|:--|
| 0 | 2020-04-09 |
| 1 | 2020-04-10 |
| 2 | - |
| 3 | 2020-04-12 |

このとき、datetime型への変換を行うとするとエラーとなります。

```python
pd.to_datetime(temp.date)

#エラー出力
TypeError: Unrecognized value type: <class 'str'>
```

対策は下記のとおりです。

## 強制的にpd.to_datetime()を実行する
変換エラーを無視して実行します。
その際、変換NGの箇所は「NaT」となります。

```python
pd.to_datetime(temp.date, errors="coerce")

#変換結果
0   2020-04-09
1   2020-04-10
2          NaT
3   2020-04-12
Name: date, dtype: datetime64[ns]
```

今回のように、ハイフンが入っていてそれを無視することを、前もって理解している上であれば問題ないと思います。
しかし、よく分からないがエラーが出たので使用する、というのは避けたほうが良いかもしれません。

## pd.to_datetime()実行前にデータを正す
事前に不要な文字列を、正しく置き換える、または除去します。
または、データファイルやDBの段階で対処しておきます。

例えば、ハイフンを空文字に置き換えてから実行してやります。
（空文字の場合は、pd.to_datetime()は例外を飛ばさずに実行をやりきれます。）
上記の強制実行と同様に、変換NGの箇所は「NaT」となります。

```python
temp.date = temp.date.replace({"-":""})
pd.to_datetime(temp.date)

#変換結果
0   2020-04-09
1   2020-04-10
2          NaT
3   2020-04-12
Name: date, dtype: datetime64[ns]
```

### 不正箇所を特定する簡単な方法
上記の例では、データが少ないためハイフンが紛れ込んでいることがすぐに分かりますが、データが大量になると把握が難しくなります。
例えば下記のコードで、お手軽に不正文字がチェックができます。
最初の不正箇所で例外が発生します。
全てチェックするには、引っかかった箇所を都度修正しながらチェックを繰り返すイメージとなります。
（あまりにも不正のバリエーションが多い場合は、途方も無い作業になるかもしれないので留意ください。）

```python
def check(x):
    print(x)
    pd.to_datetime(x)
    
temp.date.map(check)
```

以上です。
ROS環境にOpenCVをインストールする際のPython環境問題のシンプルな解決策

# はじめに
ROS Kineticの環境はPython2系を使用しており、インストールする際に各種ライブラリがインストールされ、同時にOpenCVを使用する環境が準備されます。しかしながらPython3系でOpenCVを別途インストールして使用する際に、importが通らない、となった方は非常に多いのではないでしょうか。本件の解決策は環境変数を変更したり、pyenvを導入したり、もうウンザリだから環境を独立させるためにDockerに移行したり、と様々な方法があるかと思いますが、環境を壊すことなくシンプルな解決策をご紹介させて頂きます。

# 環境
- Ubuntu 16.04LTS
- ROS Kinetic Kame
- OpenCV 3.3.0
- Python 2.7.12
- Python 3.5.2

# 課題
課題はシンプルです。Ubuntuのデフォルトの環境にはPython2系と3系のどちらも準備されていると思いますが、ROSをインストールする際に2系にも3系にもROSのPython2系のライブラリのパスが通ってしまっていることです。

Python2系のimportのライブラリパスの確認

```python
: ~/python  # Python2を起動

>>> import sys
>>> import pprint
>>> pprint.pprint(sys.path)
['',
 '/opt/ros/kinetic/lib/python2.7/dist-packages',
 '/usr/lib/python2.7',
 '/usr/lib/python2.7/plat-x86_64-linux-gnu',
 '/usr/lib/python2.7/lib-tk',
 '/usr/lib/python2.7/lib-old',
 '/usr/lib/python2.7/lib-dynload',
 '/usr/local/lib/python2.7/dist-packages',
 '/usr/lib/python2.7/dist-packages',
 '/usr/lib/python2.7/dist-packages/PILcompat',
 '/usr/lib/python2.7/dist-packages/gtk-2.0',
 '/usr/lib/python2.7/dist-packages/wx-3.0-gtk2',
]
```  

続いてPython３系のimportのライブラリパスの確認

```python
: ~/python3  # Python3を起動

>>> import sys
>>> import pprint
>>> pprint.pprint(sys.path)
['',
 '/opt/ros/kinetic/lib/python2.7/dist-packages',  #このパスが問題箇所
 '/usr/lib/python35.zip',
 '/usr/lib/python3.5',
 '/usr/lib/python3.5/plat-x86_64-linux-gnu',
 '/usr/lib/python3.5/lib-dynload',
 '/usr/local/lib/python3.5/dist-packages',
 '/usr/lib/python3/dist-packages',]
```

この環境の状態でPython3でOpenCVをimportしようとすると下記のようにエラーになります。

```python
: ~/python3  # Python3を起動

>>> import cv2  # OpenCVをimport
Traceback (mostrecent call last):
  File "<stdin>", line 1, in <module>
ImportError: /opt/ros/kinetic/lib/python2.7/dist-packages/cv2.so: undefined symbol: PyCObject_Type
```


# シンプルな解決策
ROSでインストールされたデフォルトの環境を壊したくないという理由で、ROS使用用途以外のときは下記のようにPython3使用時にROSのパスだけを削除する１行を入れれば良いのではないかと考えました。

```python
: ~/python3  # Python3を起動

>>> import sys
>>> import pprint
>>> sys.path.remove('/opt/ros/kinetic/lib/python2.7/dist-packages')  # パスの削除
>>> pprint.pprint(sys.path)  # 削除できたか確認
['',
 '/usr/lib/python35.zip',
 '/usr/lib/python3.5',
 '/usr/lib/python3.5/plat-x86_64-linux-gnu',
 '/usr/lib/python3.5/lib-dynload',
 '/usr/local/lib/python3.5/dist-packages',
 '/usr/lib/python3/dist-packages',]
>>> import cv2  # OpenCVをimportできるか確認
>>>
```
エラーがなくなり問題なくOpenCVのimportができました。これでROSの環境を特に変えることなくOpenCVをPython3で使用することが可能となります。注意点としましてはこの方法は実行時だけに有効ですので、使用する際は都度この１行の追記が必要となります。様々な方法を試して、この方法が一番シンプルだということに辿り着きました。
# Link
1. [Ubuntu16.04へのOpenCV 3.3.0インストールメモ](https://qiita.com/nakasuke_/items/51664807bdd7794db0da)
2. [Python3でopencvを使おうとしてハマった話](https://qiita.com/yutatakaba/items/5d20f78719e1bd814d72)
WPF on .NET Core + Azure AD B2C でカスタム Web UI を使って認証したい

2020/04/17 現在 MSAL.NET を使って WPF on .NET Core を使うとシステムブラウザーでの認証になります。さらに、リダイレクト URL で `http://localhost:ポート番号` のように、空いてるポートを自分でみつけないといけないみたいです。

https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/System-Browser-on-.Net-Core

```
B2C and ADFS 2019 do not yet implement the "any port" option. 
So you cannot set "http://localhost" (no port) redirect uri, 
but only "http://localhost:1234" (with port) uri.
```

回避方法としては、実装がされるのを待つか、とりあえず自前でカスタム Web UI の機能を使ってシステム ブラウザーではなく、自前のブラウザーをホストした Window を出すようにするかになります。自前のブラウザーを使う場合は旧 Edge か新 Edgeか、WPF が持ってる IE ベースの WebBrowser コントロールになります。

旧 Edge の WebView は、新 Edge が WebView が出たら置き換えた方がいいものなのすが、いかんせん、まだ開発者プレビューの段階にあります。

https://docs.microsoft.com/ja-jp/microsoft-edge/hosting/webview2

とりあえず、ここでは簡単に WPF 組込の IE がベースの WebBrowser コントロールを使ってみたいと思います。

### 作った

ということで、WPF の WebBrowser コントロールを使ってカスタム Web UI 作ってみました。

https://github.com/runceel/EmbeddedMsalCustomWebUi.Wpf

簡単に試せるように NuGet にしてます。

ということで、Azure AD B2C に適当なアプリを作成して、ネイティブのパブリックアプリケーションを追加します。

https://www.nuget.org/packages/EmbeddedMsalCustomWebUi.Wpf/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70288/41bf6da2-c461-935b-4870-8b260a6c4113.png)

Azure AD B2C にアプリを登録して、以下のように設定しました。API のアクセス許可で適当な API へのアクセス許可も与えておきます。（これしないとアクセストークンが返ってこない）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70288/d520ef9b-20bb-7d1f-7283-1037590cbd67.png)

IPublicClientApplication は MSAL.NET を普通に使うときと同じで、AcquireTokenInteractive をするところで、WithCustomWebUi に EmbeddedBrowserWebUi のインスタンスを渡します。

```csharp
var r = await App.Current
    .PublicClientApplication
    .AcquireTokenInteractive(new[]
    {
        "https://xxx.onmicrosoft.com/xxxxxx-xxxx-xxx-xxx-xxxxx/xxx" // スコープ
    })
    .WithCustomWebUi(new EmbeddedBrowserWebUi(this)) // ここでカスタム UI を設定
    .ExecuteAsync();
```

EmbeddedBrowserWebUi のコンストラクターには、親となる Window のインスタンスを渡します。
ここら辺は、リポジトリー内の TestApp プロジェクトの MainWindow.xaml.cs あたりを見てください。

以下のような感じで動きます。

![signinflow.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70288/34d19ec5-c79a-6b5e-6a34-42d422b8ef03.gif)

## まとめ

そのうち新 Edge を使ったものがリリースされると思うので、リリースされたらそちらに乗り換えるとして、とりあえずアプリ内ブラウザーでログインダイアログを出したい場合は、こんな感じで実装すればいいのではないだろうかという所ですね。
「USBケーブル延長」しすぎて KP41病になっていた（解決済）、そして再発病＆解決

# いまさらですYO
KP41病 なんていまさらなんですが、年末年始に発病したのでその結果です。一人でも完治することを祈っての記事です。
追伸：完治したと思ったら再発しました…それも完治ｗ

# パソコンを新調してみた
去年、消費税が10%増税になるというタイミングでAMD製品のパソコンを新調してみました。というのもあるけど単に 3700X を買ってみてたかったのが本音ですｗ
※8コアすげえええええええ

# 突然襲ってきた KP41病、そして
新しいパソコンを購入すると無駄に周辺機器も新しくしたいってなりません？なりますよね。で
① PCI Express 4.0（Gen4）対応M.2 NVMe SSD 換装
② USB延長ケーブル＆HUB使って USB機器を沢山つなげたい
③ ファンレスGPUちょっといいやつに換装(HDMI, DisplayPort 両方使いたかった)

と周辺機器を拡張し少しだけ自己満足の状態で使い始めるも、そいつは突然やってきました、はい「KP41病」が発症してしまいましたのです…しかもGoogleで「KP41」検索し色々対応して確かめてみるもまったく原因が分からず発症中（現在、完治している模様）。
※動画視聴をしていなければ発症しない

…結論として上記の ② が悪かったようです。[USBが原因なんて](https://bto-mania.com/blog/2736)判らないよ！！

# USBケーブル延長しすぎていた模様
個人的な見解ですが、どうやら「CPUに負荷が発生したときCPUに電源パワーが必要となるが、USBの給電が間に合わず…」という感じです。困ったことにイベントログを確認しても毎回出力されるログ内容が異なるので判りずらいですが「電源監視DLLでクラッシュ」みたいなことがたまにでていたので疑ってみた次第です。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44540/5b8fbad7-d656-cb2c-74c4-bbf54d179864.png" width=50%>


USBケーブル延長の見直しと電源管理設定の見直しをしたことにより KP41が完治した模様
① [USB機器の電源管理設定を無効にする](https://freesoft.tvbok.com/windows7/kp41/sleep_usb.html)
② [Windows側の省電力設定を無効にする](https://freesoft.tvbok.com/windows7/another_kp41/kp41_checkpoint_2015.html)

# 最後に
家のPCは、ネットみたりたまに動画みる位なので対したことしてないのに関わらず、パフォーマンス設定にしないといけないことが若干の不満、、、まあ突然のKP41病よりかはいいのだろうが…

# 再発しました(2020/3/3)
YouTubeみているとまた突然KP41が発生しました。
まるきり判断できないので、SSDに戻したり、USBを全部外してとか、電源OFFにして２時間まつといいとか…

★結局：メモリがちゃんと刺さってませんでした、ちゃんと”かちっ”ってなるまではめましょう！！


# 参考リンク
・[Windows 10で信頼性モニターのグラフからパソコンの状態を確認する方法](https://121ware.com/qasearch/1007/app/servlet/qadoc?QID=020799)
・[イベントビューアーに 警告 WHEA-Logger イベントID 17 のログが発生する件について](http://dspckn.blogspot.com/2018/07/whea-logger-id-17.html)
・[[解決済み] BIOS のバグ? WHEA-Logger が日に何度か記録される現象](https://bucci.bp7.org/archives/45000/)
・[長かった「WHEA-Logger イベントID:17」との戦い。](http://tommu.hatenablog.com/entry/20120525/1337898870)
・[WmiPrvSE.exeのCPU使用率が高いときの対処法](http://blog.hp-improve.com/2018/02/001616.htm)
・[[windows10]SuperfetchがSysMainに改名していたのでやっぱり停止した話](https://doudemo.info/stopped-superfetch-which-was-renamed-sysmain/)
・[【そして解決へ】 KP41病の原因はこれだった！](http://pc.user-infomation.com/hard_soft/so_34.htm)
・https://economoto.org/illust/3128/
Firebase 要素の数をカウントするなら、最初からこの方法でいきましょう！（Cloud Functions）

#はじめに
Firebaseのデータベース**（今回はFirestoreの場合）**に入ってるデータの数を、カウントしたい時ってありますよね？

やり方は色々あるが、**どうせなら「最初から！」このやり方でやった方がいい！**というのを、記事として残していく。

[Firebase で Cloud Functions を簡単にはじめよう](https://qiita.com/tdkn/items/2ed2b01f2656fc50da8c)
Cloud Functionsが一切わからない方は、こちら:point_up:を参考に初めてみては？

#色々とあるカウント方法

[Firestoreコレクションの全データ件数を取得する方法](https://qiita.com/atomyah/items/f94b279febccca030896)
:point_up:こちらにて2つのカウント方法が紹介されている。
が「大量のデータの数を数えたい」という場合は今回の方法をお勧めする。

そして、理由は後記するが「最初から！」このやり方でやった方が良いかも。。

#データが登録されるタイミングで件数をカウントする
まず、`onWrite`トリガーを使い`eventsコレクション`以下を監視する。
（`onWrite`トリガーについは[こちら](https://firebase.google.com/docs/functions/firestore-events?hl=ja)で詳しく解説されてます。）

そしてもし、データが増えていれば`users/{userId}`に**eventCountフィールド**が作成され、そこにカウントがリアルタイムで溜まっていく。



```typescript:index.ts
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
admin.initializeApp();
const db = admin.firestore();

// // Start writing Firebase Functions
// // https://firebase.google.com/docs/functions/typescript

exports.countEvents = functions.region('asia-northeast1').firestore
  .document('users/{userId}/events/{eventId}')
  .onWrite((change, context) => {

    const userId = context.params.userId;
    const FieldValue = admin.firestore.FieldValue;
    const countsRef = db.collection('users').doc(userId);

    if (!change.before.exists) {
      // 登録時に件数をインクリメント
      return countsRef.update({ eventCount: FieldValue.increment(1) } );
    } else if (change.before.exists && !change.after.exists) {
      // 削除時に件数をデクリメント
      return countsRef.update({ eventCount: FieldValue.increment(-1) });
    }
    return;
  });
```

<img width="964" alt="スクリーンショット 2020-04-17 13.13.33.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/185b7d0f-ffd6-30b8-241a-8d109894e122.jpeg">


#あれ？なんでマイナスに？
上の画像、なんかおかしいですよね？
`eventCount`がマイナスになるってあるの？

**あるんです！！！**

仮に`users/{userId}/events/`以下のコレクションに、すでに50件のドキュメントがあったとします。
**新たにevent（events以下に生成される{eventId}）が追加されても、カウントは「51」では無く、「1」となります。**

**つまり、５０個あるevent（ドキュメント）を3つ削除すれば、`eventCount`は-２となるのです。**
最初からこのカウント方法でやっておけばよかった〜・・・っと後悔しないためにも、初めからこの方法でカウントしましょう。。。

元のデータも含めてカウントを開始するには、どうすればよいでしょうか？誰か教えてください:frowning2:

#参考
https://www.sukerou.com/2019/08/firestore.html

https://stackoverflow.com/questions/46554091/cloud-firestore-collection-count
SpringToolsSuitesの構築手順Eclipse版_2020.4時点

Spring Tool Suite(STS)は、Spring開発のための統合開発プラットフォームです。
TERASOLUNA5フレームワークで開発をすることになり導入したため、記事を書きました。

##インストール
[　■OPEN JDK](http://jdk.java.net/)
　　必要なVersionをダウンロード（今回は~~JDK14~~　openjdk-1.8.0.252 を選択）して、インストールした後、
　　JAVA_HOME、PATHの設定をします。※14だとことごとくエラーになり、ハマります。
[　■Spring Tools 4 for Eclipse](https://spring.io/tools)
　　Springのサイトからインストーラーをダウンロードします。
　　ダウンロードしたファイルを実行します。
　　spring-tool-suite-4-4.6.0.RELEASE-e4.15.0-win32.win32.x86_64.self-extracting.jar

##日本語化
[　■Pleiades プラグイン・ダウンロード](https://mergedoc.osdn.jp/)
　　Java アプリケーションを日本語化するためのツールをダウンロードします。
　　解凍し、setup.exeを実行するとセットアップ画面が表示されるのでSpring Tools 4 for Eclipseの実行ファイルであるSTS.exeをドラッグアンドドロップで貼り付け、日本語化を実行します。

##プロキシ設定（設定が必要な環境であれば実施します）
　プロキシサーバを経由する環境の場合、STSでプロキシ設定をしておかないとEclipseマーケットプレイスやMaven（リポジトリがローカルの場合を除く）が利用できません。
####設定方法　
　STSを起動します。
　　└ウインドウ　→設定　→一般→ネットワーク接続
　　　　画面の上にあるアクティブプロバイダネイティブに変更しHTTP,HTTPSなどを自身の環境に合わせて設定します。

##プロパティエディタプラグイン導入
　[eclipseのオールインパッケージ](https://mergedoc.osdn.jp/) 
　eclipseをダウンロードした後、pleiades\eclipse\dropins\Limy\を取り出して、STSの同じフォルダに格納します。クリーン起動すると、そのプロパティファイルを右クリックでlimyでunicodeに開けるようになります。

###参考
---
 こちらの記事を参考にさせていただきました。有難うございました。
[　　★５分で分かるTERASOLUNA5.x ！]
(https://qiita.com/5zm/items/4bdcd22074963d5ecc74)
[　　★Spring Tool Suite (STS)と Spring Boot で始める Web アプリケーション開発（１）](https://www.techscore.com/blog/2016/11/22/start-with-sts-and-spring-boot-1/)
[　　★SpringToolSuite(STS)で使用するプロパティエディタの検討](https://qiita.com/hnkyi/items/3e881e2a994658a6c5f8)
Railsで画像をスライド表示させる"slick"を使うときの注意点

# お！slickって便利そう→あれ、動かない。。

という方向けに書きます。slickの使い方に関しては、こちらの記事をご覧ください。とてもわかりやすいです。

https://qiita.com/i__kobe/items/3e0e7f8fa4fd61b72d05

上記の記事を読んでいる前提でお話ししますね。

私がslick導入に当たって悩んだのは、```turbolinks```（以下、ター坊）の記述を消さなければいけない。というところでした。この記述です。

```application.js
//= require turbolinks
```

なぜかというと、ター坊を消してしまうと他の部分で不具合が発生してしまうから。

どうにかター坊を残したまま、実装したい。ということで、調べました。

すると、ター坊は読み込みを速くしてくれるけど、他のJSの人たちの読み込みを邪魔しちゃうときがあるみたい。

足は速いんだけど、バトンを渡すのが下手なようで。

ということで、邪魔された人たちもター坊の仲間に入れればいいのでは！と思い、

```item.js
  $(document).on('turbolinks:load', ()=> {
    // 省略

    $(function() {
      $('.slider').slick({
        prevArrow:'<i class="fa fa-angle-left arrow arrow-left"></i>',
        nextArrow:'<i class="fa fa-angle-right arrow arrow-right"></i>',
        autoplay:true,
        autoplaySpeed:5000,
        dots:true,
        
      });
    });
  });
```
ター坊のもとにお世話になったところ、うまくいきました！

お役に立てれば幸いです😊

*コロナに負けず、おうちで自分磨きを楽しみましょう！*
Bashズンドコ(until, 正規表現)

たまたま3年前に流行った[ズンドコキヨシの記事 in clisp](https://qiita.com/kedama17/items/82993ad94bacb8f34336)を見たのでBashで短く書いた(なんで)

```bash:ズンドコキ・ヨ・シ！(120B)
until [[ ${a[*]} =~(ズン\ ){4}ドコ ]];do a[++j]+=`shuf -en1 ズン ドコ`;echo ${a[j]};done;echo キ・ヨ・シ！
```

~~多分これが一番短いと思います~~
↓
2020-04-17: 順当により短いコードが存在した…(By @akinomyogaさん)

```bash:ズンドコキ・ヨ・シ！(87B)
a=ドコ;for((;b<4;)){ echo ${a[RANDOM%2?b=c,c=0:++c]-ズン};};echo キ・ヨ・シ！
```
github に proxy 経由で https プロトコルを用いたリポジトリの取得

#github を proxy 経由で取得する忘備録
一度設定してしまうと、なかなか実行しないので、忘備録として書き留めておく。

```text:proxyの設定例
git config --global http.proxy http://鯖の垢:proxy鯖のパスワード@proxy 鯖名:ポート
```

```text:リポジトリ取得
git clone https://githubの垢:githubのパスワード@github.com/githubの垢/リポジトリ名.git 作業ディレクトリ/
```
pythonで関数をpickleするときの注意点

## やった事

pythonの関数をpickleして復元できるかやってみました

## 結論

- importしてるモジュールの関数は別モジュールから正しく呼べる
- 同じモジュール内の関数は同名の関数が呼ばれる

## 実行した手順

1. test1.pyとtest2.pyに同名のfunc()を書いておく
2. test1.pyからfunc()とtest2.func()をpickleで保存する
3. test1.py、test2.pyからpickleファイルを読んで実行

## 結果

```terminal:test1.py
This is test1.func()
This is test2.func()
```

```terminal:test2.py
This is test2.func()
This is test2.func()
```
上記のようにtest2.pyでは同名のfunc()を読んでしまいます。func()がtest2.pyにない場合は「NameError: name 'func' is not defined」でエラーになります。

なお、test1.pyでtest1.pyをimportして、test1.funcをpickle保存すれば正しく読み込めるようになります。

## コード

以下の2つのファイルを同じディレクトリに置いてそれぞれ実行しました。

```python:test1.py
import pickle
import test2


def save_pickle(obj, path):
    with open(path, mode='wb') as f:
        pickle.dump(obj, f)


def load_pickle(path):
    with open(path, mode='rb') as f:
        obj = pickle.load(f)
    return obj


def func():
    print('This is test1.func()')


def main():
    func()
    test2.func()

    path = 'test1_func.pickle'
    save_pickle(func, path)
    func_from_pickle = load_pickle(path)
    func_from_pickle()

    path = 'test2_func.pickle'
    save_pickle(test2.func, path)
    func_from_pickle = load_pickle(path)
    func_from_pickle()


if __name__ == '__main__':
    main()
```


```python:test2.py
import pickle


def load_pickle(path):
    with open(path, mode='rb') as f:
        obj = pickle.load(f)
    return obj


def func():
    print('This is test2.func()')


def main():
    path = 'test1_func.pickle'
    func_from_pickle = load_pickle(path)
    func_from_pickle()

    path = 'test2_func.pickle'
    func_from_pickle = load_pickle(path)
    func_from_pickle()


if __name__ == '__main__':
    main()
```
外部のMYSQLに繋がらない場合の対処方法

外部のMYSQLに繋がらない場合の対処方法

+------------------+--------------+
| user             | host         |
+------------------+--------------+
| sample           | 192.168.11.9 |

ユーザーにIPアドレスを付与していないのが原因


サーバースタート
mysql server start

ログイン
mysql -u root -p mydb

その後パスワードを入れる

ユーザーの作成
CREATE USER "sample"@"192.168.11.9" identified by ******;

権限の付与
 grant all privileges on *.* to "sample"@"192.168.11.9";

確認方法
 select user,host from mysql.user
MacでMySQL起動時にエラー(dyld: Library not loaded: /usr/local/opt/openssl/lib/libssl.1.0.0.dylib)

# はじめに
久々にMacにインストールしているMySQLを使おうと思ったらエラーが発生したので、その解決方法を記載します。
1年くらい前は正常に使えていたのにな。。。

# 環境
* macOS Catalina 10.15.4（19E287）
* MySQL 5.7.21

# エラー内容
MySQLを起動しようとしたら下記のエラーが発生！！

```
% mysql.server start

dyld: Library not loaded: /usr/local/opt/openssl/lib/libssl.1.0.0.dylib
  Referenced from: /usr/local/Cellar/mysql/5.7.21/bin/my_print_defaults
  Reason: image not found
Starting MySQL
.dyld: Library not loaded: /usr/local/opt/openssl/lib/libssl.1.0.0.dylib
  Referenced from: /usr/local/Cellar/mysql/5.7.21/bin/my_print_defaults
  Reason: image not found
dyld: Library not loaded: /usr/local/opt/openssl/lib/libssl.1.0.0.dylib
  Referenced from: /usr/local/Cellar/mysql/5.7.21/bin/my_print_defaults
  Reason: image not found
/usr/local/Cellar/mysql/5.7.21/bin/mysqld_safe: line 198: 38133 Abort trap: 6           nohup /usr/local/Cellar/mysql/5.7.21/bin/mysqld --basedir=/usr/local/Cellar/mysql/5.7.21 --datadir=/usr/local/var/mysql --plugin-dir=/usr/local/Cellar/mysql/5.7.21/lib/plugin --log-error=htanaka.local.err --pid-file=/usr/local/var/mysql/htanaka.local.pid < /dev/null >> /usr/local/var/mysql/htanaka.local.err 2>&1
 ERROR! The server quit without updating PID file (/usr/local/var/mysql/XXXXX.local.pid).
```

# 解決方法
エラーログを見る限り、どうやらopensslが読み込めないらしい。。。入っていないのかな？

```
% brew update
% brew install openssl

Warning: openssl@1.1 1.1.1f is already installed and up-to-date
To reinstall 1.1.1f, run `brew reinstall openssl@1.1`
```
入っているっぽいな。。。入れ直してみる。

```
% brew reinstall openssl

==> Reinstalling openssl@1.1 
==> Downloading https://homebrew.bintray.com/bottles/openssl@1.1-1.1.1f.catalina.bottle.tar.gz
==> Pouring openssl@1.1-1.1.1f.catalina.bottle.tar.gz
==> Caveats
A CA file has been bootstrapped using certificates from the system
keychain. To add additional certificates, place .pem files in
  /usr/local/etc/openssl@1.1/certs

and run
  /usr/local/opt/openssl@1.1/bin/c_rehash

openssl@1.1 is keg-only, which means it was not symlinked into /usr/local,
because macOS provides LibreSSL.

If you need to have openssl@1.1 first in your PATH run:
  echo 'export PATH="/usr/local/opt/openssl@1.1/bin:$PATH"' >> ~/.zshrc

For compilers to find openssl@1.1 you may need to set:
  export LDFLAGS="-L/usr/local/opt/openssl@1.1/lib"
  export CPPFLAGS="-I/usr/local/opt/openssl@1.1/include"

For pkg-config to find openssl@1.1 you may need to set:
  export PKG_CONFIG_PATH="/usr/local/opt/openssl@1.1/lib/pkgconfig"

==> Summary
🍺  /usr/local/Cellar/openssl@1.1/1.1.1f: 8,057 files, 18MB
```
入れ直しても、エラーは発生！！
どうやら、バージョンの問題がある模様。最新版が入っていたので、バージョンを落としてみよう。

```
% brew switch openssl 1.0.2r

Cleaning /usr/local/Cellar/openssl/1.0.2r
Cleaning /usr/local/Cellar/openssl/1.0.2q
Opt link created for /usr/local/Cellar/openssl/1.0.2r
```
解決！！
MySQLが起動できるようになった！！

```
% mysql.server start      

Starting MySQL
. SUCCESS! 
```

opensslをupdateした覚えはないのだけどな。。。
macOSを更新した時に勝手に上がったのかな。。。
とりあえず解決しましたので、お疲れ様でした。
ネット書店の紙の書籍の在庫切れが増加しているのでKindle端末を買っておくと良いかもしれません.

[Amazon](https://amzn.to/34JFPNZ)などのネット書店の紙の書籍の在庫切れが増加[^1]しており，
[^1]: アマゾン「新型コロナウイルスと注文・配送に関するよくある質問」（4月16日現在）の第3項目に曰く「新型コロナウイルス感染症の拡大により、オンラインでお買い物をするお客様が増えています。そのため、通常よりもお届けまでにお時間をいただく場合があります」。https://amzn.to/2wQCvEc

全国的にも明日から図書館が閉鎖されそうですので
今のうちに[Kindle端末](https://amzn.to/3bjNrsI)を買っておくと良いかもしれません. 
タブレットやスマホでは目がとても疲れてしまうので． 

皆さんのお役に立てたら嬉しいです．
undefined method `each' for nil:NilClass　エラーについて

本日からプログラミング勉強の備忘録的に残していこうと思います。

掲示板を作っていて、発生したこのエラー。

<img width="745" alt="スクリーンショット 2020-04-17 8.43.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620533/db99cbf7-36da-2711-6834-0830f0165d8a.png">

ひたすら検索し、海外フォーラムまで見て色々と試してみても、直らず。

１時間ほど経過し、途方に暮れていました。

eachメソッドがClassがNilなことによって起きている・・・？

@boardが関係していると思い、以下を確認。

<img width="526" alt="スクリーンショット 2020-04-17 8.42.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620533/eb15e76c-0ddd-886c-750d-4c339af68402.png">

うーん。

**ん？**

class BoardsController < ApplicationController
def index
@boards　= Board.all
end                                  

#@boards＿　←全角スペースになっている！

少し慣れてくると、まさか全角スペースが紛れ込んでいるなんて思わないようです...。
初歩的なミス、侮れないですね。ハマると中々見つけられません...。
以後、気をつけます。

#zenkaku (VSCodeの拡張機能）
<img width="718" alt="スクリーンショット 2020-04-17 11.43.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620533/2badca1e-69b1-caea-842d-e3a5a05fdd86.png">

VSCodeを使っている方は、こちらを取り入れると全角スペースがすぐに可視化できます！
セマフォ

```py
import logging
import threading
import time

logging.basicConfig(level=logging.DEBUG, format='%(threadName)s: %(message)s')


def worker1(semaphore):
    with semaphore:
        logging.debug('start')
        time.sleep(5)
        logging.debug('end')


def worker2(semaphore):
    with semaphore:
        logging.debug('start')
        time.sleep(5)
        logging.debug('end')


def worker3(semaphore):
    with semaphore:
        logging.debug('start')
        time.sleep(5)
        logging.debug('end')


if __name__ == '__main__':
    semaphore = threading.Semaphore(2)
    t1 = threading.Thread(target=worker1, args=(semaphore,))
    t2 = threading.Thread(target=worker2, args=(semaphore,))
    t3 = threading.Thread(target=worker3, args=(semaphore,))
    t1.start()
    t2.start()
    t3.start()
```

```txt:出力
Thread-1: start
Thread-2: start
Thread-1: end
Thread-3: start
Thread-2: end
Thread-3: end
```
正規表現のキャプチャについて

正規表現を使用していく中でキャプチャという単語を知ったものの、検索してもサクッとキャプチャのことだけ書いてあるページが見当たらなかったのでメモ。

##▼ キャプチャとは
そもそも、キャプチャってなんぞや？というレベルだったのでまずはそこから。

簡単に言うと、`()`で囲った文字列を記憶してくれるとても便利な機能。
記憶した文字列は`$1,$2,$3...`でキャプチャした順に取り出すことができるそう。

**`()`で囲ったら囲った順に`$1,$2,$3`と変数に格納されるイメージですね。**

```shell:例1
#検索対象
I am good hogehoge man

#goodをキャプチャ
(good)

#参照
$1
#$1 => good
```
要はこんな感じになるらしい。ほんとかい。
(上記は完全にイメージです。こんな使い方はできません。たぶん)

##▼ PowerShellで動きを確認してみる
今回はPowerShellを使ってキャプチャの動きを確認してみます。
正規表現は言語によって動作が異なるようなので、まあ確認程度に思っていただければ。

```powershell:capture.ps1
"I am hogehoge man" -replace "(hogehoge)","good `$1"

#出力結果
#I am good hogehoge man
```
上記では`-replace`を使って、文字列を置換しています。

`(hogehoge)`で置換対象を示すと共に、キャプチャを実行。
理論上、この段階で`$1`という変数に`hogehoge`が格納されています。


そして置換する文字に``good `$1``を使用します。
つまり置換する文字は`good hogehoge`になるわけですね。

結果は上記で示したとおり、`I am good hogehoge man`となります。なるほど。

##(余談) なんで$1の前に`(バッククォート)があるわけ？

どうやら、PowerShellで`$1`を使うには\`(バッククォート)を1つ付けてあげる必要があるそう。

試しに先程の例から\`(バッククォート)を取り除いた状態で実行してみましょう。

```powershell:バッククォート取り除いたver
"I am hogehoge man" -replace "(hogehoge)","good $1"

#出力結果
#I am good  man
```
ただの良い人になってしまいました。完全に`$1(中身はhogehoge)`が認識されていません。

正規表現、奥が深い。ついでにPowerShellも奥が深い。
let'sEncryptでのSSL証明書の自動更新でこけていた

この記事はlet'sEncryptでのSSL証明書の自動更新でこけていたときの話です。

let'sEncryptの証明書はcronで
`$ 0 4 1,15 * * certbot renew  --deploy-hook "/etc/letsencrypt/renewal-hooks/deploy/cert_renew_mail.sh" >> /var/log/letsencrypt/letsencrypt.log 2>&`
こんな感じで毎月１日と１５日に更新をかけている。
※--deploy-hook 証明書ごとに実行
※/etc/letsencrypt/renewal-hooks/deploy/にスクリプトを置いてくと、certbot実行時に走る。
※cert_renew_mail.shで更新が成功するとメールを飛ばすようにしてる。

ところが、メールが飛んでいないときがありました。

#まずはログを確認
↓下のほうを抜粋

```/var/log/letsencrypt/letsencrypt.log
MissingCommandlineFlag: Missing command line flag or config entry for this setting:
Input the webroot for xxxx.com:

2020-04-15 04:02:38,222:INFO:certbot.renewal:Cert not yet due for renewal
2020-04-15 04:02:38,222:DEBUG:certbot.plugins.selection:Requested authenticator webroot and installer None
2020-04-15 04:02:38,223:ERROR:certbot.renewal:All renewal attempts failed. The following certs could not be renewed:
2020-04-15 04:02:38,223:ERROR:certbot.renewal:  /etc/letsencrypt/live/xxxx.com/fullchain.pem (failure)
2020-04-15 04:02:38,224:DEBUG:certbot.log:Exiting abnormally:
Traceback (most recent call last):
  File "/usr/bin/certbot", line 9, in <module>
    load_entry_point('certbot==0.31.0', 'console_scripts', 'certbot')()
  File "/usr/lib/python2.7/site-packages/certbot/main.py", line 1365, in main
    return config.func(config, plugins)
  File "/usr/lib/python2.7/site-packages/certbot/main.py", line 1272, in renew
    renewal.handle_renewal_request(config)
  File "/usr/lib/python2.7/site-packages/certbot/renewal.py", line 477, in handle_renewal_request
    len(renew_failures), len(parse_failures)))
Error: 1 renew failure(s), 0 parse failure(s)
```

ココらへんをみると
`Input the webroot for xxxx.com:`
`Requested authenticator webroot and installer None`
webrootが設定されていないから、エラーが起きたように見える・・・。

#原因は？
設定ファイルを確認

```/etc/letsencrypt/renewal/xxx.com.conf
# renew_before_expiry = 30 days
version = 0.31.0
archive_dir = /etc/letsencrypt/archive/xxx.com
cert = /etc/letsencrypt/live/xxx.com/cert.pem
privkey = /etc/letsencrypt/live/xxx.com/privkey.pem
chain = /etc/letsencrypt/live/xxx.com/chain.pem
fullchain = /etc/letsencrypt/live/xxx.com/fullchain.pem

# Options used in the renewal process
[renewalparams]
authenticator = webroot
account = hoge
server = https://acme-v02.api.letsencrypt.org/directory
[[webroot_map]]
```
[[webroot_map]]が空。

#対処
```/etc/letsencrypt/renewal/xxx.com.conf
[[webroot_map]]
xxxx.com = /var/www/html/xxx.com/
www.xxxx.com = /var/www/html/www.xxx.com/
```
こんな感じで設定して
`$ certbot renew`

無事、更新できました！
UnityでLive2Dモデルの線がジャギジャギしてしまったときの対処方法


## 環境

- macOS Mojave 10.14.6
- Unity 2019.2.17f1
- Cubism SDK For Unity 4-r.1 

## 起こったこと

厳密に再現する条件は分かりませんが、ある時点より、UnityでLive2Dモデルを読み込むと、モデルの画質が劣化するようになりました。

問題発生前
<img width="375" alt="iOS の画像 (1).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309048/1546a474-dd14-7990-ff74-12d85936f6f5.png">

問題発生後
<img width="375" alt="iOS の画像 (2).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309048/6bb207a3-c12f-a093-ecec-8e670bbe5d1f.png">

Unityで新規プロジェクトを作成し、CubismSDKを一からインストールし直しても依然として改善せず、むしろ何故以前はくっきりと線が出ていたのか？という状態でした。

## 対策
結局、モデルのテクスチャimport settingsにて、FormatをAutomatic→RGBA 32bitへ変更することで解決しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309048/2145ce10-4316-5fd9-3662-7d06b1125dd5.png)

線がくっきり出ています。
<img width="375" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309048/a0f701ae-7218-b67c-96ba-d41d4be83f4f.png">
Ruby　配列の中の値の最小値を抽出するアルゴリズム

こんにちは、おすしです。

```ruby
a = [11, 2, 3, 4, 213, 5, 6]

def search(ary)
  for i in 1..(ary.count - 1) do
    if ary[0] > ary[i]
      ary[0] = ary[i]
    end
  end
  return ary[0]
end

p search(a)
```

↑コピペして実行してみてください。
配列の中にある値の最小値を求めるアルゴリズムです。

ご覧いただきありがとうございます♪(´ε｀ )
Ruby　配列の中の最大値を抽出するアルゴリズム

こんにちは、おすしです。

```ruby
a = [11, 2, 3, 4, 213, 5, 6]

def search(ary)
  for i in 1..(ary.count - 1) do
    if ary[0] < ary[i]
      ary[0] = ary[i]
    end
  end
  return ary[0]
end

p search(a)
```

↑コピペして実行してみてください。
配列の中にある値の最大値を求めるアルゴリズムです。

ご覧いただきありがとうございます♪(´ε｀ )