OmniAICreator/Qiita-1.07M huggingface dataset:
Docker導入 windows10 pro

Raspberry Piを用いて機械学習モデルを動かしたいと考えています。おそらくDockerを扱うことになるのですが、そもそもDockerで何ができるのか、何が便利なのかを知る必要があるので、実際にDockerを使ってみることで理解を深めようと思います。

※この記事は学習が進み次第再び編集を行います。

#Dockerを使う目的
- アプリ開発環境の構築
- マイクロサービスの実行環境の構築
# Dockerの導入

- windows10 homeだったのでHyper-Vの仮想化機能のついたwindows10 proにアップグレードしました。13824円かかります。アップグレードは5分もかからず終了！
- スタートボタンを右クリックしタスクマネージャを開き、パフォーマンスタブで仮想化が有効になっているか確認
- https://hub.docker.com/editions/community/docker-ce-desktop-windows を開き、ログインしてDockerをダウンロード

# Docker基礎
いくつか用語の確認をします。
###Dockerイメージ
Dockerコンテナを構成するOSやファイルシステム、実行するアプリケーションや設定をまとめたもので、コンテナを作成するために利用されるテンプレートとなるもの
###Dockerコンテナ
Dockerイメージを元に作成され、具現化されたファイルシステムとアプリケーションが実行されている状態

要するにDockerイメージからコンテナが作られ、コンテナの中でOSとして構成されたファイルシステム、アプリが実行されるということです。

#主なdocker コマンド
```docker container ls -q```
コンテナの一覧表示

```docker ls```
動いているコンテナの確認

```docker ls -a```
停止しているコンテナの確認

```docker rm [コンテナID]```
コンテナの削除

```docker images```
手元にあるイメージの確認

```docker rmi [イメージID]```
イメージの削除

```docker --help```
helpの閲覧

ex. ```docker image --help```でimageコマンドのhelpが閲覧できる

```docker image build -t イメージ名[:タグ名] Dockerfile配置ディレクトリのパス```
イメージをビルドする(イメージを構築するという意味)　-t　(タグ付け)はほぼ必須

```docker container ls --filter "[イメージ名]" -q```
ancestorで指定したイメージから作られたコンテナを表示することができます

```docker stop [コンテナID]```
コンテナの停止

```docker container ls --filter "[イメージ名]" -q | % { docker stop $_ }```
filterでコンテナIDを取得し、パイプラインでdocker stopに渡します

```docker run -d -p [イメージ名]```
コンテナの実行。-dはdetachの略で、バックグラウンド実行を行う。-pはpublichの略で、portを指定する。左の数字がホストからの接続ポートで、右の数字がコンテナ側への接続ポートを表す
`docker run`だけだとコンテナを作成(run)したあとすぐにコンテナを出る(exit)ので`docker ps`してもなにも表示されない

 
#参考文献
- Docker/Kubernetes 実践コンテナ開発入門
- https://stackoverflow.com/questions/48813286/stop-all-docker-containers-at-once-on-windows
- https://datawokagaku.com/whatisdocker/
【個人開発】GIF生成アプリを作ってアメリカのProduct Huntに投稿した話

##背景
こんにちは。
キャリアチェンジをしてエンジニアとして就職するためにバンクーバーの専門学校に通っているMarieと申します。 
現在、実績なしで海外就職という難易度高めの問題に立ち向かっています。
もうすぐ就職しなくてはならないのですが、なんせ実績がないので、ポートフォリオに作品を載せて、求人サイトでポチポチ応募するだけでは十分なアピールにはなりません。 
だったら、もっと自分から動かなくては！！と思い、作ったアプリをアメリカのProduct Huntに投稿してみました！というキラキラ（と見せかけてとても泥臭い）お話です。

##Product Huntってなに
[Product Hunt](https://www.producthunt.com/)は、シリコンバレーで生まれたサービスで、世界中のユーザーが新サービスを投稿したり、探したりできるサービスです。
投稿されたサービスに対して、ユーザーが票を入れる（UPVOTEする）仕組みがあり、デイリーランキングとして集計されるのも魅力の１つです。
見ているだけで楽しいので、まだ知らない方は覗いてみると良いと思います。

##何を作ったか
MsgifというGIF生成アプリを作りました。 どんなサービスなのかは画像を見てもらった方が早いと思うのですが、タイピングした文字がGIFアニメーションに変換されるというものです。
![messagif (17).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455381/d6bd12d2-5ffc-d521-681c-de97c535fc78.gif)

##どんな風に作ったか
技術としてはReact.js、ライブラリはstateを管理するためにRedux、HTMLをCanvasに変換するためにhtml2canvas、Canvasで撮った画像をGIFに変換するためにjsgifを使っています。

  仕組みとしては、テキストエリアに文字をタイプする度にキャプチャーして画像に変換し、それを配列に放り込んで、文字を打ち終わったタイミング（CreateGIFというボタンが押されたタイミング）でそれらを１つのGIFファイルにまとめて出力しています。

もしコードに興味がある方は、GitHubに公開していますので、[こちら](https://github.com/marieooq/react-msgif)をご覧ください。

##投稿してみてどうだったか
実は、このエントリーを書いている時点で、Productのデイリーランキングの集計真っ最中です！
 1日でランキングがリセットされてしまうため、前日の0時前後にパソコンの前に座って、「行けー！！！」と力強くエンターキーを打刻。
投下した直後から反応は悪くなかったのですが、なんせ無名で実績もゼロなので、放っておいて票が集まるわけがありません。

Twitter、Facebook、LinkedIn、WhatsApp、LINE…いろんなところでペコペコしながら清き一票をお願いして、現時点でUpvotes:140、ランキング10位の状態です。
![スクリーンショット 2020-02-03 18.42.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/455381/64253bc0-aa3d-91a2-4c14-1158a322fd9e.png)


  個人開発をしていて思うのは、必要なスキルがめちゃくちゃ多くて割と無理ゲーだということです。
コーディングができるだけでは十分ではなく、どうやったら人に見てもらえるか考えるマーケティングの力も要りますし、サービスを知ってもらう営業努力もかかせません。

今日1日だけで色んなところにペコペコしすぎて、とても疲れ…充実していました。
まだ集計中なので、需要がありそうであれば後日結果もご報告できたらなと思います。

##結局宣伝かい
はい...すみません！
いろんなところでペコペコしておいて、このままQiitaでペコペコしないわけにはいきません。
自分としては1年前にはReactなんて触ったこともなかったので、正直サービスをリリースできて感慨深いものがあります。
ユーザーの皆様にはそんなことは関係ないのは百も承知ですが、
もしサービスが面白いと思っていただけたら、1票を入れてUpvoteをしていただけると大変励みになります！！
（Upvoteするにはログインが必要なのでお手数だとは思うのですが…何卒よろしくお願いします🙇‍♀️
）

▼投票はこちらから
https://www.producthunt.com/posts/msgif

長くなりましたが、自分で考えたサービスが世の中の人に使われるというのは本当に嬉しいことです。
多くの人がこのサービスを面白がってくれたら幸いです！
:hoverを使ったら無茶チラついたので気になって悩んでしまった

とっても細かいどうでもいいところをなんとか直したくなり無茶時間かけて
試行錯誤した。解決？はしたっぽいがどういう原理なのかよく分からない・・・・

やっぱりフロントは嫌いだ。

## やりたかったこと。

隣接した要素で、一方にマウスオーバーすると、
display: none;
にしておいたもう一方の要素を出現させて、
出現させた要素のリンクをクリックできるようにしたい。

[CSSで実装する、マウスオーバーで表示される吹き出し](https://www.tam-tam.co.jp/tipsnote/html_css/post9815.html)

どこのサイトも簡単そうに書いてあり、TECHのカリキュラムでもおかしなことは起こらなかったのだが・・・

chromeで開くとなんかムッチャチラつく。何これ？

![画面収録-2020-02-03-21.52.50.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527304/46b33ce9-d5f1-6949-3584-1696e5a940cc.gif)


色々調べたけど同じことになってる記事を見つけられなかったので、
このhoverの部分だけをhtml,cssに切り出した上でプロパティをどんどん削っていってテストした。

最終的にここまでにしたけど、やっぱり改善せず。ちなみに他のブラウザの動きとして、safariはちょっとチラつく。firefoxはチラつき無し。うん、わかんね。

```test.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <link rel='stylesheet' href='./test.css'>
</head>
<body>
  <div class="nickname">名前</div>
  <div class="box"><a href="#">ログアウト</a></div>
</body>
</html>
```

※　scssは、vseditorにLive Sass Compilerっていうのを入れて、css変換して検証してた。

```test.scss
.nickname {
  height: 60px;
  background-color: #f0f0f0;
  &:hover + .box {
    display: block;
  }
}

.box {
  background-color: skyblue;
  display: none;
  position: absolute;
  top: 2em;
  height: 50px;
}
```

最終的に思い至ったのが（元々、そういう風に書いておくものなのかもしれないが・・・）

nickname要素にのみhoverを適用させた状態だと、nickname要素の範囲からマウスが外れてしまった時にbox要素が消えちゃうじゃん、と思いbox:hover{ display: block; }
を追加したらなんとかなった。

```test.scss
.box {
  background-color: skyblue;
  display: none;
  position: absolute;
  top: 69px;
  height: 50px;
  &:hover {
    display: block;
  }
}
```

ちなみに、topを変えて試してみてたが、
**双方の境界部分は、接するか、重ねるかしないとダメ、と思っていたが、
1 pixel離れるのは許容される(1 pixelの隙間にマウスオーバーしてもboxが消えずに済む)ということが分かった！！**
どうでもいいけど。

ブラウザ別に動作が変わるだろうから、きっと接するか、重ねるかしとくのが無難なんだろう。
MS ACCESS　フォームの表示が遅いときの対応メモ

#Access フォームの表示速度改善で行った対応
環境：Access2013　SQLSERVER　リンクテーブル使用


##効果あり
####サブフォームの表示が遅い
サブフォームを複数使用しているフォームの表示が遅い
・ODBCの設定で「接続するSQLServerサーバ名を入力してください」の箇所を**サーバ名からIPアドレスに変更**

表示時間：10秒～20秒→3秒程に

####コンボボックスの表示が遅い
コンボボックスの値集合ソースをリンクテーブル経由で取得している場合、コンボボックス１つの表示に0.5秒前後かかる
・コンボボックスの参照先のテーブルを通常のテーブル（ローカルテーブル）にする
※コードテーブルの扱いを運用でカバーする必要有


##効果未確認（実感できず）
######・IPv6設定の無効化をする


######・下記のレジストリキーを変更する
**※レジストリに不正な値を書き込んでしまうと、システムに重大な障害を及ぼし、最悪の場合、システムの再インストールを余儀なくされることもあります。レジストリ エディタの操作は慎重に行うとともに、あくまで御自分のリスクで設定を行ってください。何らかの障害が発生した場合でも、責任を負いかねます。ご了承ください。**


レジストリキー
HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Office \ 15.0 \ Access Connectivity Engine \ Engines \ ACE \ MaxBufferSizeを50000に変更

また、上記のレジストリキーがない場合はこちらを設定
HKEY_LOCAL_MACHINE \ SOFTWARE \ Wow6432Node \ Microsoft \ Office \ 15.0 \ Access Connectivity Engine \ Engines \ ACE \ MaxBufferSizeを50000に変更

Jetを使用している場合は、
HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Jet \ 4.0 \ Engines \ Jet 4.0 \ MaxBufferSizeを50000に変更



引用：https://social.technet.microsoft.com/Forums/en-US/88542372-0fcb-4521-87ec-e2ab72e688dd/access-2007-very-slow-on-windows-7?forum=officesetupdeploylegacy
JavaからGoogleスプレッドシートを操作する

## 新しいシートの追加

```java

final String spreadsheetId = "my spreadsheetId";

List<Request> requests = new ArrayList<>();
SheetProperties sheetProperties = new SheetProperties().setTitle("New Sheet");
requests.add(new Request().setAddSheet(new AddSheetRequest().setProperties(sheetProperties)));

BatchUpdateSpreadsheetRequest requestBody = new BatchUpdateSpreadsheetRequest();
requestBody.setRequests(requests);

Sheets.Spreadsheets.BatchUpdate request = service.spreadsheets().batchUpdate(spreadsheetId, requestBody);

BatchUpdateSpreadsheetResponse response = request.execute();
```
postgresql 9 系のアップデート後に daemon が起動しなくなる

日付に関する config を標準ではない日本の timezone を指定していると以下の様なログが画面上に出て、daemon が起動しない。

```text
Feb  4 11:35:16 rdb1 postgres[997]: [1-1] LOG:  invalid value for parameter "log_timezone": "Japan"
Feb  4 11:35:16 rdb1 kernel: LOG:  invalid value for parameter "log_timezone": "Japan"
Feb  4 11:35:16 rdb1 kernel: LOG:  invalid value for parameter "TimeZone": "Japan"
Feb  4 11:35:16 rdb1 postgres[997]: [2-1] LOG:  invalid value for parameter "TimeZone": "Japan"
```
postgresql.conf 内の記述が日本の文言に変更が有ったようなので、以下の用に整えてられれば起動するようになる。

* 9.5 以前

```text:postgresql.conf
log_timezone = 'Asia/Tokyo'
timezone = 'Asia/Tokyo'
```

* 9.6 以降

```text:postgresql.conf
log_timezone = 'Japan'
timezone = 'Japan'
```
Laravel で Cloud KMS を使って暗号化/復号化をしてみた。

こんにちわ！ @ktoshi です！

以前、[Cloud KMSをGoで使う](https://qiita.com/ktoshi/items/1fd4f808c955d33c3d28) 記事を書きましたが、今回は PHP（というよりLaravel）で使ってみようと思います。
実際はGoより先にこっちで使い始めてたのですが、諸々あり後発の記事になりました。
そんなわけではじめましょー。

# Cloud KMS
暗号鍵をセキュアに管理できるGCPのサービスです。
自動ローテーションやIAMでの権限管理でセキュアなアクセスを実現できる上、APIを利用した暗号化/復号化を行えるので非常に柔軟な利用が可能です。
類似したサービスはAWSの「KMS」や Azureの「Key Vault」などがあります。

# Key Ring と Key
Cloud KMS では Key を Key Ring で管理しています。
関係性は字のごとく、鍵と鍵束ですね。
ある程度同じ用途で使用される鍵については同じ Key Ring でまとめておくとよいでしょう。
実際に暗号化などで利用されるのは Key となります。

# 目的
Cloud KMS に暗号鍵を用意し、Laravel + Cloud KMS で文字列を暗号化/復号化する。

# 実践
では実際に暗号化/復号化を行いましょう。
大きく分けて作業は3つです。

* 環境準備
* 暗号鍵の準備
* 暗号化
* 復号化

※ 下記手順の[PROJECT_NAME]、[KEY_RING_NAME]、[KEY_NAME] は適宜置き換えてください。

## 前提条件
前提として下記が導入されていることとします。
なお、バージョンは私の環境でのものです。

* PHP: 7.3.10
* composer: v1.9.0
* Laravel: 6.1
* gcloud: 268.0.0
* terraform: v0.12.16

## 環境準備
PHPでCloudKMSを扱うためのライブラリをインストールします。
composer でインストールをします。

```shell
composer require google/cloud-kms
```

## 暗号鍵の準備
暗号をするにはまず暗号鍵を準備しないことには始まりません。
私は terraform を利用しましたが、 gcloud コマンドでも簡単に作成できます。
terraform や gcloud のインストールについては話がそれるので割愛します。

### terraform の場合
```terraform
# 鍵束の作成
resource "google_kms_key_ring" "sample_key_ring" {
  name     = "[KEY_RING_NAME]"
  location = "global"
}

# 鍵の作成
resource "google_kms_crypto_key" "sample_crypto_key" {
  name     = "[KEY_NAME]"
  key_ring = google_kms_key_ring.sample_key_ring.self_link
}

```

### gcloud コマンドの場合
```shell
# 鍵束の作成
$ gcloud kms keyrings create [KEY_RING_NAME] --location global --project [PROJECT_NAME]

# 鍵の作成
$ gcloud kms keys create [KEY_NAME] --location global --keyring [KEY_RING_NAME] --purpose encryption --project [PROJECT_NAME]
```
これで暗号鍵の準備は完了です。

## 暗号化
では、実際に Laravel で暗号化を行います。
今回は処理を行っている箇所のみ抜粋しています。

```php
use Google\Cloud\Kms\V1\KeyManagementServiceClient;

public function encryption(String $str)
{
    $kms = new KeyManagementServiceClient();
    $projectId = '<PROJECT_NAME>';
    $location = '<PROJECT_LOCATION>';
    $keyRingId = '<KEY_RING_NAME>';
    $keyId = '<KEY_NAME>';
    $cryptoKeyName = $kms->cryptoKeyName($projectId, $location, $keyRingId, $keyId);
    return $kms->encrypt($cryptoKeyName, $str)->getCiphertext()
}

```
これで暗号化した文字列を返すことができます。
なお、Cloud KMS では本気で暗号化されるため、帰ってきた文字列が UTF-8 ではなくなり、
DBなどに直接突っ込むことができません。
DBへ突っ込むときなどは [base64_encode](https://www.php.net/manual/ja/function.base64-encode.php) を使ってエンコードしておくと良いです。

## 復号化
暗号化処理はできたので、次に復元しましょう。
やってることはほぼ、暗号化と一緒です。

```php

use Google\Cloud\Kms\V1\KeyManagementServiceClient;

public function decryption(String $str)
{
    $kms = new KeyManagementServiceClient();
    $projectId = '<PROJECT_NAME>';
    $location = '<PROJECT_LOCATION>';
    $keyRingId = '<KEY_RING_NAME>';
    $keyId = '<KEY_NAME>';
    $cryptoKeyName = $kms->cryptoKeyName($projectId, $location, $keyRingId, $keyId);
    return $kms->decrypt($cryptoKeyName, $str)->getPlaintext()
}

```
これで復号化された文字列を取得できます。
なお、暗号化の際に Base64 でエンコードしている場合はデコードしてから渡しましょう
私はこれを忘れてめちゃくちゃ時間食いました。。。


# まとめ
前回、Goで行った処理と同様のものをPHPで行いました。
結局やることとしては、暗号化鍵を取得して、それを使って暗号化/復号化をするだけですね。
前の記事でも記載しましたが、今後セキュアでかつ可逆暗号化が必要となるケースがあると思います。
そんなときにぜひこの記事が参考になればと思います。
それでは、みなさまも引き続き安全で快適な暗号化ライフを。
Amazon Linux から Amazon Linux 2 への移行中 xpath ではまった話

Amazon Linux AMI (2018.03) のサポート期間が2020年12月31日まで延びましたが、目下、過去の遺物を Amazon Linux 2 へ移行しています。
これはそんな中起きた問題で、結論は単純にxpathの演算子の優先順位を勘違いしていたという話です。
自分だけの勘違いではなく、まわりにも何人かいたので、もしかしたら有用かなと思って書きました。

皆さんは、このhtmlの2番目のh3のテキスト "Fuga" をxpathで取りたいときにどう書くでしょうか。

```html:test.html
<!DOCTYPE html>
<html>
    <div>
        <h3>Hoge</h3>
        <h3>Fuga</h3>
        <h3>Gero</h3>
    </div>
    <div>
        <h3>Foo</h3>
        <h3>Bar</h3>
        <h3>Baz</h3>
    </div>
</html>
```

私とそのまわりの何人かは何の違和感もなくこう `'//h3[2]/text()'` 書いていました。

```ruby:scraping.rb
require 'nokogiri'

doc = Nokogiri::HTML(open('test.html'))
p doc.xpath('//h3[2]/text()')
```

これは Amazon Linuxで yum パッケージの ruby2.0 と nokogiri だとこういう結果になります(これが古すぎるというのは置いといて)。

```bash
$ ruby scraping.rb
[#<Nokogiri::XML::Text:0x1160c78 "Fuga">]
```

そして、Amazon Linux 2 に移行すると、rubyは amazon-linux-extras の ruby2.4、nokogiri は gem で入れることになり、結果はこうなります。

```bash
$ ruby scraping.rb
[#<Nokogiri::XML::Text:0x2aea55368304 "Fuga">, #<Nokogiri::XML::Text:0x2aea55368160 "Bar">]
```

**! !**
異なる結果になってしまうのでした。これになかなか気づけずはまっていました。

## 理由

libxml2 の [2.9.2](https://abi-laboratory.pro/index.php?view=changelog&l=libxml2&v=2.9.2) でこういった修正が入っています。

> Fix XPath '//' optimization with predicates (Nick Wellnhofer),

xpath の仕様では、 `[]` 演算子 は `//` よりも優先度が高いので、 `//h3[2]/text()` と書くと `h3[2]` の方に先にバインドされてしまうんですね。上で期待する操作をするときは `(//h3)[2]/text()` こう書くのが正でした。

libxml2 のバージョン 2.9.1 までここが間違っていて、Amazon Linux の yum リポジトリの libxml2 が 2.9.1 だったので、これまでうまく動いてしまっていたということです。

## ちなみに

* Amazon Linux でも gem で nokogiri をインストールしていれば回避できていました
* Amazon Linux 2 でも yum の libxml2 は 2.9.1 なので、 xmllint なんかは間違ったままです
【JavaScript】ツイートボタンのクリック時にイベント計測などをする

[Twitter 公式のツイートボタン](https://developer.twitter.com/en/docs/twitter-for-websites/tweet-button/overview)を使っているとき、ボタンは iframe で実装されているため、通常の click イベントは取れません[^1]。ボタンがクリックされたときになにかしたい場合（例: Google Analyticsのイベント計測など）は、Twitter が提供する widgets.js というスクリプトを使います。

[^1]: 厳密には、別オリジンのフレーム内容へのアクセスとなるためです。同一ドメインのフレームであれば、このような制約は基本的にありません。

# TL;DR

最終形は以下のような感じになります。

```html
<body>
<!-- ... -->

<!-- ツイートボタン（公式から雛形コードをコピペしてボタンを設置したいところに貼る） -->
<a class="twitter-share-button"
  href="https://twitter.com/intent/tweet">
Tweet</a>

<!-- ... -->

<!-- 以下のコードはどこに貼ってもよいが、bodyの閉じタグの前などが無難 -->

<!-- widgets.jsの読み込み（公式から雛形コードをコピペ） -->
<script>window.twttr = (function(d, s, id) {
  var js, fjs = d.getElementsByTagName(s)[0],
    t = window.twttr || {};
  if (d.getElementById(id)) return t;
  js = d.createElement(s);
  js.id = id;
  js.src = "https://platform.twitter.com/widgets.js";
  fjs.parentNode.insertBefore(js, fjs);

  t._e = [];
  t.ready = function(f) {
    t._e.push(f);
  };

  return t;
}(document, "script", "twitter-wjs"));</script>

<!-- widgets.jsを使っていろいろする（自分で書く部分） -->
<!-- 必ず上記の雛形コードの後に書く -->
<script>
twttr.ready(function (twttr) {
  twttr.events.bind('click', function () {
    // ここにツイートボタンが押されたときにしたい処理を書く
    // 例: Google Analyticsのイベント計測
    ga('send', 'event', 'Tweet Button', 'click')
  })
})
</script>
</body>
```

# 解説

## 0. ツイートボタンの設置

ツイートボタンそのものの設置の詳細はここでは触れません。以下のドキュメントなどを参考にしてください。
https://developer.twitter.com/en/docs/twitter-for-websites/tweet-button/overview

## 1. widgets.jsを読み込む

ツイートボタンなどを自分の JavaScript からごにょごにょするには、Twitter が提供する widgets.js という JavaScript を読み込む必要があります。

以下のページから雛形コードをコピーして、ページの HTML に貼り付けてください。場所はどこでもよいですが、`<body>` の閉じタグの前あたりがよいでしょう。
https://developer.twitter.com/en/docs/twitter-for-websites/javascript-api/guides/set-up-twitter-for-websites

## 2. widgets.jsを使ってイベントリスナを設定する

上記の雛形を埋め込むと、**それ以降の行で** `twttr` というオブジェクトが使えるようになります（雛形より上にかかれているコードで `twttr` を使うと未定義エラーになります）。`twttr` でできることを網羅的に知りたい場合は、以下のドキュメントを参照してください。
https://developer.twitter.com/en/docs/twitter-for-websites/javascript-api/overview

今回は `twttr.events.bind` を使って、`click` のイベントリスナ（イベントが発生した時に実行したい処理）を設定します。

ただ、イベントリスナの設定は、`twttr` の初期化が終わってからでないとできません。そこで、`twttr.ready` を使って、「`twttr` の初期化が終わった時に」イベントリスナを登録するように包みます。

```javascript
twttr.ready(function (twttr) {
  // ここに twttr の初期化が完了したときにやりたい処理を書く
  // 今回はclickのイベントリスナを登録する
  twttr.events.bind('click', function () {
    // ここにツイートボタンが押されたときにしたい処理を書く
    // 概ねなんでも可能
  })
})
```

これでツイートボタンをクリックした時になにかできるようになります:ok_woman:
BigQueryであの頃のデータに戻りたい（ただし、1週間前まで）

#BigQueryのデータを元に戻したい
期間を間違えた、同じファイルをもう一度読み込ませてしまった、消してしもうた！、アップデートで`WHERE`忘れた、コンソールで前に書いてたDML残したままクエリ実行してしもうたとか。
そんなときに元に戻す方法を。そんなに難しいことやってません。
#"FOR SYSTEM_TIME AS OF"があるじゃないか
[FOR SYSYTEM_TIME AS OF](https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax?hl=ja#for-system_time-as-of) で指定した日時時点のデータを見ることが出来ます。
ただし、7日前までしか保存していません。それ以前はもう無いです。
こんな感じでクエリを実行します。

```sql:for_sysytem_time_as.sql
SELECT
  *
FROM
  `project_name.dataset_name.table_name`
FOR SYSTEM_TIME AS OF '2020-02-01 10:00:00 Asia/Tokyo'
```
[パーティション分割テーブル](https://cloud.google.com/bigquery/docs/partitioned-tables?hl=ja)を使っている場合は、いつもどおり`WHERE`で指定すればその部分だけを見てくれます。
##DELETEとINSERTを実行する
テーブルのデータを削除して、戻したい日時時点のデータを入れていきます。
消してしまった場合は`INSERT`だけすれば良いと思います。こんな感じ。

```sql:for_sysytem_time_as.sql
#全部のデータを消す
DELETE
FROM
  `project_name.dataset_name.table_name`
WHERE
  1 < 2;

#戻したい日時時点を指定して、そのデータを入れる
INSERT INTO `project_name.dataset_name.table_name`
SELECT
  *
FROM
  `project_name.dataset_name.table_name`
FOR SYSTEM_TIME AS OF '2020-02-01 10:00:00 Asia/Tokyo';
```
ここでも同じように[パーティション分割テーブル](https://cloud.google.com/bigquery/docs/partitioned-tables?hl=ja)を使っている場合は、いつもどおり`WHERE`で指定すればその部分だけを操作することが出来ます。

# 削除したテーブルの復元もある
[削除したテーブルの復元](https://cloud.google.com/bigquery/docs/managing-tables?hl=ja#undeletetable) で、削除から **2 日**以内の指定した日時時点のテーブルを復活することが出来ます。2 日以上前のテーブルはもう無い他、同名テーブル、データセットを作った場合も復活出来ません。
"FOR SYSYTEM_TIME AS OF" の 7 日より短い 2 日です。

```sh
bq cp dataset.deleted@1579878000000 dataset.table
```



#最後に
つまりBigQueryではデータを消そうが、更新しようが、7日前までは全部データが残っているんだなぁと。
一昔前は`Legacy SQL`でしか出来ないと思ってたけど、`StandardSQL`だとDMLが使えるのでこんなことが出来るようになりました。
自分はこれを思い出したりするのが面倒なので`stored procedure`にまとめて、テーブルのリカバリバッチを作りました。
あぁ、久しぶりに書いた。業務で使ってるTipsとか、時々書きますね。ばいなら。
オブジェクトのkeyをtypeで指定する（Mapped types）

### オブジェクトの key を型で指定したい

```ts
type Side = 'send' | 'receive'

function sideCharObj(): { [key: Side]: string } {
  return {
    send: '発',
    receive: '受'
  }
},
```
`{ [key: string]: string }` のように書けそうだが、
これだと下記のエラーが出る
`An index signature parameter type cannot be a union type. Consider using a mapped object type instead.`

### [Mapped types](https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types) で key の型を指定

```ts
type Side = 'send' | 'receive'

function sideCharObj(): { [key in Side]: string } {
  return {
    send: '発',
    receive: '受'
  }
}
```

:x: `{ [key: Side]: string }`
:o: `{ [key in Side]: string }`

## 参考

- https://github.com/microsoft/TypeScript/issues/24220

こちらに、Mapped types についての詳しい記事がありました
https://qiita.com/Quramy/items/e27a7756170d06bef22a#mapped-types
Craft CMS で投票（アンケート）機能をつけられる Poll プラグイン

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8890/a7e74572-55bd-f396-fcaa-f3e44d59f17e.png)


アンケート機能っぽいものを作れるプラグイン。

> Poll
> https://plugins.craftcms.com/poll

GuestEntry をつかうとか、GraphQL 使うとかすればできそうな気がするけど、プラグインでサクッと作れるのは便利かもしれない。
セキュリティマネジメントの勉強-情報セキュリティ

#情報セキュリティ
##情報セキュリティとは
コンピュータの中の顧客情報、技術情報に対するセキュリティ

技術面だけではなく、組織におけるマネジメントも含めて対策が必要
「モレなく、全員で当たり前の事を確実に行う」

決めたルールを守るための仕組みを作る事が重要
組織の戦略により決定、組織の状況により変わるもの

##定義
機密性・・・適切なアクセス権限
完全性・・・改ざん防止
可用性・・・二重化したりしていつでも見れるようにする
真正性・・・主張通りであること(なりすましなどない事)
責任追跡性・・・入退室とかアクセスログで追跡できる事
否認防止・・・エンティティを証明する能力(利用した本人が事後になって否定できないようにする)
信頼性・・・意図した動作が確実に行われる事（人為的でなくても、バグによる意図しない更新も含む）

##ISMS
情報マネジメントシステム
PDCA(計画、運用、監査と見直し、改善)を回る

##脅威
システムや組織に損害を与える可能性があるインシデントの潜在的な要因

##脆弱性
資産がもつ弱点
バグとかセキュリティホールとか
会話による情報漏洩とか施錠ミスは人為的脆弱性という

##リスク
リスクの大きさ＝情報資産の価値＊脅威の大きさ＊脆弱性の度合い

##サイバーセキュリティ経営ガイドライン
###3原則
１：経営戦略としてのセキュリティ投資は責務
２：系列企業やサプライチェーンのBP、委託先も含めた対策が必要
３：平時からセキュリティ対策に関する情報開示をする

###CISOなどに指示すべき10項目
１：セキュリティポリシを策定
２：ＣＩＳＯからなる適切な管理体制を作り、責任を明確化する
３：必要な予算の確保、人材育成などの資源の確保
４：守るべき資産を特定、リスクを洗い出して対処のための計画を策定する
５：リスクに対する保護政策を実施する体制を構築する
６：PDCAを回して、定期的に経営者に対して報告をする
７：インシデント発生に備えてCSIRTや緊急時の対応体制を整備する
８：被害時の復旧体制の整備を行う
９：系列企業やＢＰに対しても自社同様の対策を行わせる事
１０：情報共有活動に参加する(IPAへの情報提供など)
Apple Music API(MusicKit)のDeveloper Token取得方法

いつも忘れてググって色んなサイト飛んだりするので、自分の備忘録として書いておく

## Apple Developerページでの作業

https://developer.apple.com/account/

### Music IDを取得

1. Developer Accountの証明書等々の[一覧ページ](https://developer.apple.com/account/resources/certificates/list)にいく


2. `Identifiers`の**+**ボタンより `Music IDs`を選択

3. `Description`, `Identifier `を入力し、作成


### MusicKit用の秘密鍵を作成

1. [Keys](https://developer.apple.com/account/resources/authkeys/list)ページで**+**ボタンより作成

2. `Key Name`を入力し、`Music Kit`の**configure**ボタンで紐付けたい`Music ID`を設定

3. **Register**ボタンで作成し、**Download**ボタンよりダウンロードしておく。 `.p8`ファイルがダウンロードされる

### Key ID, TeamIDを確認

- **Key ID** ... 先程作成した秘密鍵の詳細ページにて確認
- **Team ID** ... [Developer Membershipページ](https://developer.apple.com/account/#/membership)にて確認

これに加え、先程作成した`.p8` ファイルを用意

## apple-music-token-generatorを使用してDeveloper Token作成

[apple-music-token-generator](https://github.com/pelauimagineering/apple-music-token-generator)をダウンロードし、READMEに従いPython関連をインストール


-  `music_token.py`の内容を自分の秘密鍵, Key ID, Team IDに書き換える

    秘密鍵 ... 先程ダウンロードした`.p8`ファイルの内容

- ターミナル上で`music_token.py`を実行

```
 python music_token.py
```

- 出力されたTokenでApple Music APIにアクセスできる

```
   curl -v -H 'Authorization: Bearer 出力されたToken' "https://api.music.apple.com/v1/catalog/us/artists/36954" 
```
管理画面のURLを変更したいとき

EC-CUBE4のインストール時のサイトの設定で、ついつい適当に「admin」とかに設定しがちな、管理画面のディレクトリ名。
インストール後に変更できるらしいけど、どこで変更できるんだろう…と思って確認。


```/.env
ECCUBE_ADMIN_ROUTE=admin
```
を

```/.env
ECCUBE_ADMIN_ROUTE=hogefugatest
```

とかにすると、管理画面のディレクトリ名は/adminから/hogefugatestになる。
WebとHTML, URI, HTTPの関係について基本的なこと（初学者向け）

# Webとは何か
Webエンジニアへ転職する人が多くなっていますが、「そもそもWebってなんですか？」っていう方のために簡単に説明します。（私も初学者ですので誤りがあればご指摘いただけると嬉しいです。）

## Web(World Wide Web)とは
Webとはインターネットで使用されるドキュメントシステムのことです。
特徴はWorld Wide Web =「世界に広がる蜘蛛の巣」という名前にある通り、インターネット上に存在する情報同士がリンクで繋がっている（ハイパーテキストシステム）点にあります。ちなみに「リンク」とは、文書の中に別の文書のURI(URL)を埋め込むことで、ユーザーがクリックして閲覧できる機能のことです。
その様が蜘蛛の巣みたいだったのでWorld Wide Webと名付けられました。

私たちユーザーはWebブラウザ（ChromeやSafariやInternet Explorerなど）を使って、Webサーバから文書の情報を得ることができます。

この便利なシステムを支えているのが
URI, HTML, HTTPという３つの技術です。

### URI(Uniform Resource Identifier)
まずWeb上に存在する情報（リソース）を特定できるようにするためには、何らかの名前をつけて他の情報と区別しなければなりません。そこでURI(URL)というものでWeb上にあるリソースに名前をつけます。

一般的なURIは
`プロトコル名://ホスト名（ドメイン名orIPアドレス）/パス`
で示されます。
例えばこういうやつです。

`https://qiita.com/junun`

このURI(URL)は「Qiita.comというネットワークの、/junun　というディレクトリに対してHTTPS通信でやり取りする」という意味になります。
ちなみにHTTPSとは、通信を暗号化することでHTTPよりも安全なプロトコルです。

このURIを一意でシンプルかつ寿命が長くなる（変更されない）ように設計することで、文書間のリンクを基盤としたWebが成り立っています。

### HTML(Hypertext Markup Language)

HTMLはマークアップ言語です。マークアップ言語とは、タグ(`<body>`や`<h1>`など)で文書の構造を表現する言語です。HTMLを用いることで文書内に埋め込まれた画像や動画などへのリンクを表現することが可能になります。

### HTTP(Hypertext Transfer Protocol)

ブラウザとサーバのやり取りに使用される通信がHTTPです。HTMLと同様にHypertextとあるようにハイパーテキストを転送するためのプロトコル(通信規約)です。
HTTP通信で行われることを大雑把に説明すると、
1ブラウザからサーバに何らかのリクエストを送ります。
2サーバがそのリクエストに対応するアプリケーションで処理して、ブラウザにレスポンスを返します。

基本的にサーバはリクエストを処理してレスポンスを返すだけという設計になっていることで、サーバのプログラムをシンプルに保つことができています。

「ステートレス」やHTTPメソッド、HTTPメッセージなどの重要な概念についてはまた別の記事にアップしようと思います。


## まとめ
URI, HTML, HTTPという３つの技術が基本となってWebを実現しています。シンプルに設計されているからこそ、拡張性が高く、大規模なシステムが成り立っている点は非常にかっこいいと思います。（感想）

## 参照
- [Webを支える技術](https://www.amazon.co.jp/Web%E3%82%92%E6%94%AF%E3%81%88%E3%82%8B%E6%8A%80%E8%A1%93-HTTP%E3%80%81URI%E3%80%81HTML%E3%80%81%E3%81%9D%E3%81%97%E3%81%A6REST-WEB-PRESS-plus/dp/4774142042/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=3K7XXEPAT4RRG&keywords=web%E3%82%92%E3%81%95%E3%81%95%E3%81%88%E3%82%8B%E6%8A%80%E8%A1%93&qid=1580781074&sprefix=web%E3%82%92%E3%81%95%E3%81%95%2Caps%2C238&sr=8-1)

- [キタミ式イラストIT塾 基本情報技術者 令和02年](https://www.amazon.co.jp/gp/product/B082DT76Z8/ref=ppx_yo_dt_b_d_asin_title_o02?ie=UTF8&psc=1)

- [Webとは - IT用語辞典 e-Words](http://e-words.jp/w/Web.html)
歯磨きとエンジニア ~実態と命名の乖離~

# 磨くのではない

自分は近年、虫歯にならなくなった。
それは歯磨きの仕方を変えた。
正確には歯磨きをやめて、 **歯払い（はばらい）** をするようになった。
歯払いなんて言葉は作った言葉ではある。

歯磨きという言葉から歯を磨く、ゴシゴシしないといけないっていう気がするが、
歯医者さんに聞くと、歯の間に挟まったゴミを掻き出すことが重要らしい。

では、ほうきの掃除のように、ゴミを払い出すことが重要ってことがわかった時に、
歯の掃除のやり方が変わった。

**磨くのではなく、歯の中に挟まったゴミがない状態にする。**

力をいれず、隅の掃除をちゃんとする。
歯の奥歯、右側、左側まで2回に分けて、水を含み、クチュクチュと洗い流す。

# 名前とは

歯磨きという名前にするから、磨くことが重要だと勘違いしてしまうのである。
名前の付け方はとても大事。

つまりは、変数名、関数名、ファイル名はちゃんと意味のある名前をつけようってことである。


# 実例

簡易的なコードで実例を示します。

```:歯磨き
class HamigakiManager {
  polish(){
    // しかし、実態は磨いていない
  }
}
```
polish は 研磨 という意味。

polish だから研磨しているのではと思ってしまう。
でも実態は clean up (掃除)なのである。

つまりは、

```:歯払い
class HabaraiManager {
  cleanUp(){
    // 名前どおり、 clean up (掃除) をしている
  }
}
```
とした方が、意味が通り、理解が簡単になるのである。
jQuery 基礎文法　1

#はじめに
[JavaScript記事はこちらです。](https://qiita.com/raigakun/items/4e9a4e6ae4117ecc5917)
JavaScript(以下、JS)を学んでいく上で、今回はjQueryというものに出会ったので、
jQueryについて1つずつ整理していきます。
私はVScodeでコードを書き、ブラウザでHTMLファイルを開いております。
そして、検証（ブラウザ上で右クリック）のconsole項目に反映されているのか確認しております。
もうすでにご存知の方、省略の仕方等ご存知でしたら、ご教授願います。


#jQueryについて
ユーザーから見えるWEBページの見た目部分は、HTML・CSS・JSで作成する流れです。
①　HTMLでWebページの構成(マークアップ)を行う。
②　CSSでスタイルを装飾する。
③　JSでWebページに動きをつけることができる。

そして、そのJSを簡単に作ることができるのがjQueryとなる。


#jQueryのプラグイン

プラグインとは、jQueryの拡張機能であり、パッケージとなっている。
以下、URLが参考になりました。

[jQueryプラグイン集](https://goworkship.com/magazine/jquery-plugin/)


#jQueryの導入
*この辺は実装次第、訂正するかもです。
*こんな感じかなというニュアンスで見て頂ければ・・・

①動かしたいページのHTMLへjQuery CDNを書き込む。
　CDNについては以下、URLが参考になりました。
　[jQuery CDNについて](https://www.sejuku.net/blog/65045)
②適用したいプラグインファイルを書き込む。（ネットからダウンロードできるようです。）
③CSSへ①と②を書き込む。
といった流れのようです。


#JSとjQueryの文法の比較

私が学習をする上で、混乱してしまったので、整理してみました。

JS : HTML要素のid名やクラス名を指定することで、マッチするノードを取得できる。
jQuery : セレクタと呼ばれるHTML指定方法を用いることで、HTML要素を取得できる。

早速比較してみます。


#####①id要素を取得する

```qiita.js
// JS
document.getElementById("id名");
// jQuery
$("#idSelector")        // $がJSでいうdocumentとなります。
```

#####②class要素を取得する

```qiita.js
// JS
document.getElementsByClassName("クラス名");      //idとは違い、複数のclassがある為、Elementにsがつきます。
// jQuery
$(".classSelector")         //取得したいHTML要素のclass属性の値に.（ドット）を付ける。
```

#####③新しいclass要素を追加する

```qiita.js
// JS
classList.add(追加したいクラス名)  
// jQuery
addClass(追加したいクラス名)
```

#####④指定したclass要素を削除する

```qiita.js
// JS
classList.remove(削除したいクラス)
// jQuery
removeClass(削除したいクラス名)
```



#さいごに
日々勉強中ですので、随時更新します。
皆様の復習にご活用頂けますと幸いです。
Matlab 9.6 R2019a 稼働RuntimeのDockerイメージビルド

*Matlab 9.6 R2019a は 2019年03月リリース*


### Dockerfile準備

```sh:Dockerfile.matlab.R2019a
# Download and install Matlab Compiler Runtime v9.6 (2019a)
#
# This docker file will configure an environment into which the Matlab compiler
# runtime will be installed and in which stand-alone matlab routines (such as
# those created with Matlab's deploytool) can be executed.
#
# See http://www.mathworks.com/products/compiler/mcr/ for more info.

FROM debian:10-slim

ENV DEBIAN_FRONTEND noninteractive
RUN apt-get -q update && \
    apt-get install -q -y --no-install-recommends \
    xorg \
      unzip \
      wget && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*
    
# Install the MCR dependencies and some things we'll need and download the MCR
# from Mathworks -silently install it
RUN mkdir /mcr-install && \
    mkdir /opt/mcr && \
    cd /mcr-install && \
    wget -q http://ssd.mathworks.com/supportfiles/downloads/R2019a/Release/5/deployment_files/installer/complete/glnxa64/MATLAB_Runtime_R2019a_Update_5_glnxa64.zip && \
    unzip -q MATLAB_Runtime_R2019a_Update_5_glnxa64.zip && \
    rm -f MATLAB_Runtime_R2019a_Update_5_glnxa64.zip && \
    ./install -destinationFolder /opt/mcr -agreeToLicense yes -mode silent && \
    cd / && \
    rm -rf mcr-install

# Configure environment variables for MCR
ENV LD_LIBRARY_PATH /opt/mcr/v96/runtime/glnxa64:/opt/mcr/v96/bin/glnxa64:/opt/mcr/v96/sys/os/glnxa64:/opt/mcr/v96/sys/opengl/lib/glnxa64
ENV XAPPLRESDIR /opt/mcr/v96/X11/app-defaults
```

Matlab runtimeパス　/opt/mcr/v96

### Dockerfileイメージビルド

```sh
# タグ指定でイメージビルド
docker build -t matlab-r2019a:latest -f Dockerfile.matlab.R2019a .
```

<br>
ご覧して頂き、どうも有難う御座います!
DSS Ben
Rust学習に役立つリンク一覧 2020.02

## 結論

まずは公式サイトを見よう

## Official sites

- [Home](https://www.rust-lang.org/)
- [Install](https://www.rust-lang.org/tools/install)
- [DockerHub](https://hub.docker.com/_/rust)
- [Playground](https://play.rust-lang.org/)
- [Learning](https://www.rust-lang.org/learn)
- [Tools (editor, test, deploy ...)](https://www.rust-lang.org/tools)
- [Github Repository](https://github.com/rust-lang)
- [Reference](https://doc.rust-lang.org/reference/index.html)
- [Community](https://www.rust-lang.org/community)
- [Reference](https://doc.rust-lang.org/reference/index.html)

## Official sites (jp volunteer)

- [Rustの日本語ドキュメント/Japanese Docs for Rust](https://doc.rust-jp.rs/)
- [rust-lang-ja@Github](https://github.com/rust-lang-ja)

## Awesome articles

- [プログラミング言語Rustのススメ@qiita](https://qiita.com/elipmoc101/items/3c8b6d8332a9019e578c)
- [Rustのリンク集@qiita](https://qiita.com/mosh/items/7e327dafbe53b72ad99d)
- [安全なシステムプログラミング言語Rustへの招待](https://keens.github.io/slide/anzennashisutemupuroguramingugengorusthenoshoutai/)

## Blogs

- [κeenのHappy Hacκing Blog | Lispエイリアンの狂想曲](https://keens.github.io/)
    - 『実践Rust入門』の作者のブログ。Rust関連の記事が多い。

## Books

- [プログラミングRust | オライリー・ジャパン](https://www.oreilly.co.jp/books/9784873118550/)
- [実践Rust入門（言語仕様から開発手法まで）| 技術評論社](https://gihyo.jp/book/2019/978-4-297-10559-4)

## Others

- [reddit | The Rust Programming Language](https://www.reddit.com/r/rust/)


[Qiita Rustタグ](https://qiita.com/tags/rust)をフォローしましょう
【Java】正規表現でズンドコキヨシ

# 流行ったよね、ズンドコ
完全に時期を逃しているのですが、流行ったときに書いて放置してたソースが出てきたので、投稿します。
Javaでは余りこのパターンは見かけなかった感ある。

元ネタはこれ。
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">Javaの講義、試験が「自作関数を作り記述しなさい」って問題だったから<br>「ズン」「ドコ」のいずれかをランダムで出力し続けて「ズン」「ズン」「ズン」「ズン」「ドコ」の配列が出たら「キ・ヨ・シ！」って出力した後終了って関数作ったら満点で単位貰ってた</p>&mdash; てくも (@kumiromilk) <a href="https://twitter.com/kumiromilk/status/707437861881180160">March 9, 2016</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

# ソース
```Java:ZunDokoKiyoshi.java
import java.util.Random;

public class ZunDokoKiyoshi {
	public static void main (String args[]) {
		Random random = new Random(0);
		StringBuilder sb = new StringBuilder("");
		while (!sb.toString().matches("^.*(ズン){4}ドコ$")) {
			String current = new String[]{"ズン", "ドコ"}[random.nextInt(2)];
			System.out.println(current);
			sb.append(current);
		}
		System.out.println("キ・ヨ・シ！");
	}
}
```
# 解説
1. while文内で「ズン」か「ドコ」をランダムに出力
2. while文内で出力した文字をStringBuilderで溜め込む
3. while文の終了条件は「末尾が「ズン」連続4回の直後に「ドコ」」である(正規表現でチェック)
4. while文抜けてから「キ・ヨ・シ！」を出力して〆

真っ先に思い付いたのがコレ、だった記憶。
ビット演算とかstreamとか難しいことはわがんねから、素直に自分の得意なのでやった。
StringBuilder使うなら逐次`System.out.println`しなくてもいい気はする。
でもそうするとあとから改行入れるの面倒になるから逐次にした。
改行入れなくていいんならStringBuilderに全文溜め込むほうがきれいかもだ。

## 追記
別に溜め込む方式も面倒くさくなかったわ。
改行をStringBuilderに溜め込むときに追加するパターンの場合、改行を含む正規表現になっちゃう。
その場合は、while文の終了判定時に`sb.toString().replaceAll("\n", "")`にするほうがいいと思う。

```java
public static void main (String args[]) {
	Random random = new Random(0);
	StringBuilder sb = new StringBuilder("");
	while (!sb.toString().matches("^.*(ズン){4}ドコ$")) {
		sb.append(new String[]{"ズン", "ドコ"}[random.nextInt(2)]);
	}
	System.out.println(sb.toString().replaceAll("(.{2})", "$1\n") + "キ・ヨ・シ！");
}
```

今更気付いたんだけど、「ズン」「ドコ」5つの組み合わせの配列単位で出力すべきだった…？
まあそれにしても出力方法の違いなのでロジックの根本は変わらんけど。
2重ループにしてwhileの内側に5回配列作る分のループ突っ込んで、while文の終了判定がその配列をStringUtilsだったかArrayUtilsのjoinでつなげて正規表現で…って感じになるかな。
WordPressのパーマリンク設定で迷宮入り

**※迷宮入りして未解決です**

# やりたかったこと
既存のパーマリンクを変更して、記事ページの固定リンクからカテゴリー名を含まないようにしたい。

カテゴリーページ：ドメイン/{category}
記事ページ：ドメイン/{post_id}

# やったこと
## 1 パーマリンク設定を`/%post_id%`にする

パーマリンク設定でカスタム構造を選択し、`/%post_id%`に設定する。

functions.phpに追記

```php:functions.php
function remcat_function($link) {
	return str_replace("/category/", "/", $link);
}
add_filter('user_trailingslashit', 'remcat_function');

function remcat_flush_rules() {
	global $wp_rewrite;
	$wp_rewrite->flush_rules(false);
}
add_action('init', 'remcat_flush_rules');

function remcat_rewrite($wp_rewrite) {
	$new_rules = array('(.+)/page/(.+)/?' => 'index.php?category_name='.$wp_rewrite->preg_index(1).'&paged='.$wp_rewrite->preg_index(2));
	$wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
}
add_filter('generate_rewrite_rules', 'remcat_rewrite');
```

→結果、
記事ページは`ドメイン/{post_id}`で表示可能になりましたが、カテゴリーページが404になってしまいました。


## 2 パーマリンクを`/%category%/%post_id%`にする
カスタム構造を`/%category%/%post_id%`に設定すると、カテゴリーページの404は解消されて、リンクが`ドメイン/{category}`になりましたが、記事ページは、`ドメイン/{category}/{post_id}`になってしまします。

ちなみに、`/%category%` = `/category/カテゴリースラッグ`という決まりのようです。
なので、本来のリンク`ドメイン/category/{category}`または`/category/{category}/{post_id}`から`/category`が消え去って上記ののような結果になるようです。

どうすればいいのかよくわからず、プラグインにお任せするかたちになりましたー:sweat:
AWS Route53で無停止サブドメイン委任（すでにサブドメイン以下にCNAME等のレコードが存在するケース）


免責: DNSの専門家ではないので、よりよい方法があればぜひ教えてください！

# 背景
親ドメイン（例: hiroga.cc）のHosted Zone内でサブドメイン（例: sub.hiroga.cc）に関するレコードを管理していましたが、Hosted Zone内の見通しが悪くなってしまったので、サブドメインを分割します。
すでにレコードがあるケースの手順が調べても見当たらなかったため、備忘録とします。

# 手順

1. サブドメイン用のHosted Zoneの作成
2. サブドメイン用のHosted Zone内へ、親ドメインのHosted Zone内のレコードをコピー
3. サブドメインのHosted Zoneに対するNSレコードの作成
4. 親ドメインのHosted ZoneのNSレコードのTTLが過ぎるまで待つ。
5. 親ドメインのHosted Zone内の、2.でサブドメイン側にコピーしたレコードの削除

# 注意点

- 手順2.の段階で親ドメイン内のレコードを削除してはいけません。名前解決ができない時間が発生しますし、最悪悪意ある第三者が同様のレコードを公開するリスクがあると思われます。
- 手順3.が完了した段階で疎通チェックをします。

```
dig NS sub.hiroga.cc   # サブドメイン側Hosted Zoneに対応するレコードが表示されること
dig CNAME some-web.sub.hiroga.cc   # AUTHORITY SECTIONがサブドメイン側Hosted ZoneのNSレコードの値であること
```


# 参考資料:

[クラスメソッド - Route 53でサブドメインを別のHosted Zoneに権限委譲する](https://dev.classmethod.jp/cloud/aws/route53-transfer-hostedzones/)
Wordpress 開発のメモ



##SQL編

###複数行
```
$rows = $wpdb->get_results($query, ARRAY_A); // ココに指定
foreach($rows as $row) {
   $id = $row['ID']; // 連想配列で返る
}
```


###1つの値を返す
count(*) とか、特定の ID で絞った特定のフィールド値を取得するときとか、値が 1 つしか返ってこないときに使う。

```
$wpdb->get_var
```

###1行返す

```
$select_result=$wpdb->get_row

$atai=$select_result->komoku 
```

##ショートコードを使ってphpファイルを呼び出す方法

####funciton.phpでの設定
```function.php
//ショートコードを使ったphpファイルの呼び出し方法
function Include_my_php($params = array()) {
    extract(shortcode_atts(array(
        'file' => 'default'
    ), $params));
    ob_start();
    include(STYLESHEETPATH . "/$file.php");
    return ob_get_clean();
}
add_shortcode('myphp', 'Include_my_php');
```

####投稿ページ・固定ページからショートコードで呼び出す
このケースではfunction.phpと同じ階層にmemeberslogin.phpファイルを作成してそれを呼び出している

```hoge.html
[myphp file='memberslogin']

```
####デバッグモード
wp-config.phpのdefine( 'WP_DEBUG', false );を変更する「false→true」


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346533/cd65240a-9a78-5119-eac9-db40ea3b6348.png)
WSLでGCCをビルドした際のメモ

自分がビルドしたときに突っ掛かったことのメモ。ほとんど公式ドキュメントに書いてある内容。


#環境
Windows 10
Ubuntu on WSL (18.04.1)
GCC-7.4.0で10.0.1をビルド

#しようと思った理由
気軽にWSLでGCCの最新版の機能を使ってみようと思ったが、確認してみたら、普通にインストールしたバージョンが7.4.0だったから。

#必要なツールのインストール
```bash
sudo apt update
sudo apt install build-essential zlib1g-dev gcc-multilib g++-multilib git flex
```

そしてGCCのソース本体のダウンロード

```bash
git clone git://gcc.gnu.org/git/gcc.git　(ダウンロード先の場所)
cd (その場所)
./contrib/download_prerequisites
```



##ビルド用のフォルダを作る
この作業がとても重要らしい

```bash
mkdir build
cd build
```

##configure
手っ取り早く、もともとインストールしてあるGCCで使ったのをパクる。

```bash
../configure (gcc -vででる　configured with:のところをコピペ)
```

相当時間がかかるので、他のことをしながら終わるのを待つ。
enable-languageのところを、自分の必要なのだけにすると幸せになれる。

##ビルド

```bash
make -j4
```

-jオプションはつけた方が早く終わる。
-jオプションの後ろの数字はいくつでもいい(なくてもいい)。
が、数字が大きすぎると、パソコンのメモリーを食いつぶして、パソコンがフリーズする。


この時、コマンドの後ろに、2>error.logなどと書いておくと、失敗したときのエラーを探すときに便利

#テスト
やる必要はないが、実用で使うなら、ぜひやった方がいい。ただし、途方もない時間がかかる。

###まずは必要なもののインストール

```bash
sudo apt install dejagnu tcl
```

###テストを実行して、結果を確認

```bash
make -k check
../contrib/test_summary
```

##あとは、インストールするだけ！

```bash
make install
```

#参考文献

https://gcc.gnu.org/install/
登録後、英語版を日本語版にするには？

登録後、英語版が表示された場合の対処法です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548076/26467918-7493-5103-1209-30f84785651b.png)

右上のメニューからStart Centerを選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548076/dc4fb373-0b48-d4e5-1c71-e0efd1d52aa7.png)

画面が切り替わるので、右上のユーザーアイコンからDefault Informationを選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548076/c44c8474-7ac5-7828-d39f-1f9e91f618eb.png)

画面真ん中あたりのLanguageの虫眼鏡を押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548076/ffd77b39-b161-7a4a-c2d6-730abcd24495.png)

言語の選択画面が表示されたら、ハイパーリンクになっている「日本語」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548076/f49530d0-f458-b8b4-f7ac-3a0b49e0fcad.png)

日本語に変わりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548076/f3f41012-2af3-8945-6e17-9545f3dbb472.png)

OKボタンを押して終了します。
一度、サインアウトして、再度ログインしてください。
※サインアウトは、ユーザーアイコンの右隣のアイコンです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548076/963e07f0-21c5-854c-6f19-445c706f5722.png)
ubuntu18.04でnpm testを使いava実行すると「SyntaxError: Unexpected token {」エラーが出てしまうときの解決方法

なんてことないことでしたがNode.js, npm, avaを使い初めて日も浅くて2～3時間悩んだのでメモです。あまりいないかもしれないですが、他に同現象で困っている人がいたら役立ちますように。

# 現象
初めてavaを使おうと https://www.npmjs.com/package/ava に従ってnpm testをすると以下のエラーとなってしまい実行できない。

```bash
$ npm test

> ava -v

(node:5301) UnhandledPromiseRejectionWarning: /home/shohei/tmp/20200203/shoheihagiwara-cli/node_modules/ava/lib/node-arguments.js:9
                } catch {
                        ^

SyntaxError: Unexpected token {
    at createScript (vm.js:80:10)
    at Object.runInThisContext (vm.js:139:10)
    at Module._compile (module.js:616:28)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)
    at Module.require (module.js:596:17)
    at require (internal/module.js:11:18)
    at Object.exports.run (/home/shohei/tmp/20200203/shoheihagiwara-cli/node_modules/ava/lib/cli.js:261:33)
(node:5301) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:5301) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

```

# 環境

```bash
$ uname -v
#30~18.04.1-Ubuntu SMP Fri Jan 17 06:14:09 UTC 2020
$ node --version
v8.10.0
$ npm --version
3.5.2
$ grep ava package.json -C1
  "scripts": {
    "test": "ava -v"
  },
--
  "dependencies": {
    "ava": "^3.2.0"
  }
$ cat test.js
const test = require('ava');

test('foo', t => {
    t.pass();
});

test('bar', async t => {
    const bar = Promise.resolve('bar');
    t.is(await bar, 'bar');
});
```

# 原因
ava 3 で Node.js v8 はサポートがされていないためです。(https://github.com/avajs/ava/releases)

他にも ava のページには「avaがサポートするのはNode.jsがサポートするもののみ」と書かれていて、2020年2月時点で Node.js v8 自体がNode.jsでサポート切れになっています。(https://github.com/nodejs/Release#release-schedule)


# 解決方法
## 1. サポートされてるNode.jsをインストール
ava 3 がサポートする Node.js をインストールし実行し直します。
自分は v12 をインストールしました。
参照：https://github.com/nodesource/distributions/blob/master/README.md#installation-instructions

```bash
# インストール
$ curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
$ sudo apt-get install -y nodejs

# バージョン確認
$ node --version
v12.14.1

# 実行
$ npm test

> ava -v

  ? foo
  ? bar

  2 tests passed
```
## 2. engine-strict=trueにしておく
これをしておくけば、`npm install ava`をしたときにエラーとなりその場で気がつける。

```console
$ echo 'engine-strict=true' >>  ~/.npmrc
```
[MEMO][TERMINAL] Alacritty

# はじめに
クラスプラットフォームなRust製でGPUアクセラレイトで`dotfile`でカスタマイズできる進んでるターミナルでgitのお星様２万個のお墨付きをもらっているので

# 開発環境

Ubuntu

# Install

https://github.com/alacritty/alacritty

```
sudo add-apt-repository ppa:mmstick76/alacritty
```

```
sudo apt install alacritty
```

# 設定
https://github.com/alacritty/alacritty/wiki

## ウィンドウサイズ

`~/.config/alacritty/alacritty.yml`を設定します

### 解像度とDPIを知る

```
xdpyinfo G -B 2 resolution

screen #0:
  dimensions:    2560x1440 pixels (677x381 millimeters)
  resolution:    96x96 dots per inch
```


```:小さめ
window:
  dimensions:
    columns: 80 # 横幅　(単位はDPI)
    lines: 30 # 縦幅 
```

```:大きめ
window:
  dimensions:
    # 解像度 2560x1440 の設定
    columns: 116 # 横幅　(単位はDPI)
    lines: 100 # 縦幅 
```

```:CLIで設定
alacritty -d [columns] [lines]
```

### ウィンドウの表示位置



```:左寄せ
window: 
  dimensions:
    columns: ...
    lines: ...
  position:
    x: 0  
    y: 0
```
```:右寄せ
# --snip---
  # 解像度 2560x1440 の場合
  position: 1275
    x: 0
```


## フォントスタイル
```:~/.config/alacritty/alacritty.yml
# Font configuration (changes require restart)
font:
  # The normal (roman) font face to use.
  normal:
    family: Ubuntu Mono
    # Style can be specified to pick a specific face.
    style: Regular

  # The bold font face
  bold:
    family: Ubuntu Mono
    # Style can be specified to pick a specific face.
    # style: Bold

  # The italic font face
  italic:
    family: Ubuntu Mono
    # Style can be specified to pick a specific face.
    # style: Italic

  size: 14.0
```


## Theme

### ダーク系

```:~/.config/alacritty/alacritty.yml
# Colors (Monokai Dark)
colors:
  # Default colors
  primary:
    background: '0x272822'
    foreground: '0xF8F8F2'

  # Normal colors
  normal:
   black:   '0x272822'
   red:     '0xF92672'
   green:   '0xA6E22E'
   yellow:  '0xF4BF75'
   blue:    '0x66D9EF'
   magenta: '0xAE81FF'
   cyan:    '0xA1EFE4'
   white:   '0xF8F8F2'

  # Bright colors
  bright:
   black:   '0x75715E'
   red:     '0xF92672'
   green:   '0xA6E22E'
   yellow:  '0xF4BF75'
   blue:    '0x66D9EF'
   magenta: '0xAE81FF'
   cyan:    '0xA1EFE4'
   white:   '0xF9F8F5'
```

### ライト系
```:~/.config/alacritty/alacritty.yml
# Colors (Pencil Light)
colors:
 # Default Colors
 primary:
   background: '#f1f1f1'
   foreground: '#424242'
 # Normal colors
 normal:
   black:   '#212121'
   red:     '#c30771'
   green:   '#10a778'
   yellow:  '#a89c14'
   blue:    '#008ec4'
   magenta: '#523c79'
   cyan:    '#20a5ba'
   white:   '#e0e0e0'
 # Bright colors
 bright:
   black:   '#212121'
   red:     '#fb007a'
   green:   '#5fd7af'
   yellow:  '#f3e430'
   blue:    '#20bbfc'
   magenta: '#6855de'
   cyan:    '#4fb8cc'
   white:   '#f1f1f1'
```
Maximo SaaSを使ってみよう

# Maximo SaaS試用版の登録
[Maximo SaaS 試用版登録サイト](https://www.ibm.com/account/reg/jp-ja/signup?formid=urx-20869)
既にIBMidを持っている場合は、ログインします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548076/6e9db33c-6cad-47e1-4720-93c1eb7f6c6e.png)


# チュートリアルを活用しよう
右上のヒト型のアイコンをクリックして、Take Tourを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548076/595bb070-92a9-ca97-693c-5f30ceb4bfef.png)

[登録後、英語版を日本語版にするには？](https://qiita.com/mykon/items/1c462d7d6d8d7f8a640f)
Maximo SaaS関連記事リンク集

[Maximo SaaSを使ってみよう](https://qiita.com/mykon/items/51c51fed3d77d534bf97)

[登録後、英語版を日本語版にするには？](https://qiita.com/mykon/items/1c462d7d6d8d7f8a640f)
繰り返し使いたいqiita　まとめ

<h3>機械学習・アルゴリズム関連まとめ</h3>
https://qiita.com/meshidenn/items/f903624c70d6fa3c6f3b
<h3>APIまとめ</h3>
https://qiita.com/hamaup/items/cd7212aa1d0b1f0e37de
<h3>新規事業開発</h3>
https://qiita.com/hamaup/items/cd7212aa1d0b1f0e37de
<h3>各種言語の公式ドキュメント</h3>
https://qiita.com/egnr-in-6matroom/items/3847c233be9fbf2a68fc
<h3>量子コンピューター</h3>
https://qiita.com/YuichiroMinato/items/50e7b606023c9e94e812
Python2から3に変更されなかった

# python2から3に変更されない...

```bash
$ python --version
Python 2.7.15

$ brew install python3
$ python3 --version
-bash: python3: command not found
```
あれ、python3がインストールされてない...

# 解決？
```bash
# python3をインストール
$ brew install python3
Ignoring bindex-0.5.0 because its extensions are not built.  Try: gem pristine bindex --version 0.5.0
Ignoring bootsnap-1.3.1 because its extensions are not built.  Try: gem pristine bootsnap --version 1.3.1
Ignoring byebug-10.0.2 because its extensions are not built.  Try: gem pristine byebug --version 10.0.2
Ignoring byebug-9.0.6 because its extensions are not built.  Try: gem pristine byebug --version 9.0.6
Ignoring bindex-0.5.0 because its extensions are not built.  Try: gem pristine bindex --version 0.5.0
Ignoring bootsnap-1.3.1 because its extensions are not built.  Try: gem pristine bootsnap --version 1.3.1
Ignoring byebug-10.0.2 because its extensions are not built.  Try: gem pristine byebug --version 10.0.2
Ignoring byebug-9.0.6 because its extensions are not built.  Try: gem pristine byebug --version 9.0.6
Warning: python 3.7.6_1 is already installed, its just not linked
You can use `brew link python` to link this version.

$ brew link python
Linking /usr/local/Cellar/python/3.7.6_1...
Error: Could not symlink Frameworks/Python.framework/Headers
Target /usr/local/Frameworks/Python.framework/Headers
is a symlink belonging to python@2. You can unlink it:
  brew unlink python@2

To force the link and overwrite all conflicting files:
  brew link --overwrite python

To list all files that would be deleted:
  brew link --overwrite --dry-run python

# unlinkしてみる
$ brew unlink python@2
Unlinking /usr/local/Cellar/python@2/2.7.15_1... 39 symlinks removed
$ brew link python
Linking /usr/local/Cellar/python/3.7.6_1... 28 symlinks created

# 確認
$ python3 --version
Python 3.7.6
```
python3がきちんとインストールされたっぽい？
ニューラルネットワークで用いる関数

#シグモイド関数

```math
h(x)=\frac{1}{1 + exp(-x)}
```
活性化関数の１つ。

#ソフマップ関数
```math
y_k = \frac{exp(a_k)}{\sum_{i=1}^{n}exp(a_i)}
```
分類問題で使われる関数。
出力の総和は１になる。すなわち、出力は確率として機能している。
Ruby　コーティング規約について　構文編　2

# はじめに
[レイアウト編はこちらをクリック願います。](https://qiita.com/raigakun/items/7416db5b4d70ea93046e)
[構文編 1 はこちらをクリック願います。](https://qiita.com/raigakun/items/ecdfe0250c06bd6c76d6)
Rubyの基礎を学習中の方に向けて記載致します。
私自身これからチーム開発を行う上で大事にしたい。知っておきたいことをOutputします。

#構文について
① 本文が１行のときは、if修飾子を優先的に使う。
　 他の良い代替案としては&&を使った制御構文がある。
　　ワンライナーにする。　　

```qiita.rb

str = "is he raigakun?"
#以下、実践します。


#悪い例 （長い）
if str.include?("?")
  puts "yes, he is."
end


# 良い例
puts "yes, he is." if str.include?("?")

#もしくは

if str.include?("?") && puts "yes, he is."
```

② thenは複数行にまたがるif/unlessでは使ってはいけない。
　　私、使ってました・・・

```ruby:qiita.rb

# 悪い例
if some_condition then
  # 本文省略
end

# 良い例
if some_condition
  # 本文省略
end
```

#さいごに
毎日更新します。
皆様の復習等にご活用頂けますと幸いです。
AndroidでImageViewをソースコードで丸くしたい(Kotlin編)

今回はAndroidでImageViewをソースコードで丸くしたいなと思いまして、対応しました。
私のメモレベルです。
よかったら参考にしてもらえると幸いです。

## Javaの場合
Javaをご利用しているは、こちらを参考してください。
https://android.benigumo.com/20140324/imageview-%E3%82%92-%E7%B0%A1%E5%8D%98%E3%81%AB-%E8%A7%92%E4%B8%B8-%E3%81%AB%E3%81%99%E3%82%8B/


## Kotlinの場合
下記の関数を導入します。

```
fun getCroppedBitmap(bitmap: Bitmap): Bitmap? {
        val width = bitmap.width
        val height = bitmap.height
        val rect = Rect(0, 0, width, height)
        val rectf = RectF(0F, 0F, width.toFloat(), height.toFloat())
        val output = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
        val canvas = Canvas(output)
        val paint = Paint()
        paint.setAntiAlias(true)

　　　　　// ここで丸みをつけます。「2.toFloat()」の数字を大きくするほど、
        // 丸みが小さくなります。この状態だと円のように切り抜けます。
        canvas.drawRoundRect(rectf, width / 2.toFloat(), height / 2.toFloat(), paint)
        paint.setXfermode(PorterDuffXfermode(PorterDuff.Mode.SRC_IN))
        canvas.drawBitmap(bitmap, rect, rect, paint)
        return output
    }
```

これを実際に使う場合の例

```
var bmp = BitmapFactory.decodeByteArray(it, 0, it.count())
this.getCroppedBitmap(bmp)?.let {
  bmp = it
}
holder.writerImageView.setImageBitmap(
  Bitmap.createScaledBitmap(
    bmp, holder.writerImageView.getWidth(),
    holder.writerImageView.getHeight(), false
  )
)

```

以上になります。
12月ごろからAndroid開発もするようになりました。
こんな感じで今後もメモを残していきたいと思いますmm
CentOS6.xでLet'sEncrypt運用してたら、自動更新できなくなっていた件について、


##状況
Let'sEncryptで運用していても、エラーメッセージが表示されて、自動更新できない。

```
WARNING: couldn't find Python 3.5+ to check for updates.
Traceback (most recent call last):
  File "<stdin>", line 16, in <module>
  File "/usr/lib64/python3.4/distutils/version.py", line 58, in __lt__
    c = self._cmp(other)
  File "/usr/lib64/python3.4/distutils/version.py", line 176, in _cmp
    if self.version != other.version:
AttributeError: 'StrictVersion' object has no attribute 'version'
```

## 参考情報

[CentOS6系にPython3を入れる方法](http://teityura.wjg.jp/engineer/centos6%E7%B3%BB%E3%81%ABpython3%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)


### ポイント
###  CentOS(7系含む）ではパッケージ管理のYumコマンドがデフォルトインストールのPython2.xで動いているので、デフォルトインストールされているpythonのパスを変えてしまうようなエイリアス設定はしない方が良い



###対応策
参考情報に沿って、Python3.5系以上をインストールします。

###python3のエイリアスのみ変更します。
変更前

```
$ ls -al /usr/bin/python*
lrwxrwxrwx 1 root root     9  7月  5 13:07 2018 /usr/bin/python3 -> python3.4
```

変更後

```
lrwxrwxrwx 1 root root    18  2月  4 09:51 2020 /usr/bin/python3 -> /usr/bin/python3.5
```

もう一度sslのアップデートを実行

```
Installing Python packages...
Installation succeeded.
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer None
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for staging.madoline.on-the-slope.com
Using the webroot path /var/www/html for all unmatched domains.
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
```

無事インストールできました。