OmniAICreator/Qiita-1.07M huggingface dataset:
Viコマンド（UNIX）

今回テラタームでviを扱ったのでメモ

## Viとは
viは、UNIXに標準で備わっているテキストエディタである。多少とっつき にくい面があるが、慣れると高速で編集作業ができるようになる。
テキストを操作するにはviコマンドを用いる。
似たものにvimがあるがこれはviの派生系でより高機能。コマンドはほとんど同じである。


## UNIXとは
UnixはOSの一種で、現存する中でもっとも古いOSのひとつ。古いだけあって、色々なOSの土台になったOS。特徴としては安全性が高く、また余計な機能が少ないので軽いことがあげられる。Linuxと似ている。どちらも基本黒いコマンド画面で操作する。
UNIXコマンドとLinuxコマンドはほとんど同じである。


## コマンドモードの操作について
起動時はコピペ・検索が可能なコマンドモードになっている。

個人的によく使うコマンドは、
「cd　パス」でディレクトリ移動し、
「ls」でディレクトリ内ファイル全表示。(ls -l（＝ll）でさらに詳細に表示)
「cat ファイル名」で中身を見たりできる。

「mkdir　ディレクトリ名」でディレクトリ作成
「touch　ファイル名」で新規ファイル作成
「cd ~」最上部のディレクトリに移動
「cd ..」1つ上のディレクトリに移動
「cd」home/ユーザに移動

編集時は
escでコマンドモードにしてして以下のコマンドを使用。
ａ：カーソル右に文字挿入モード
ｉ：カーソル左に文字挿入モード
x：カーソル上の文字削除
o：現在行下に行追加し、文字挿入モード
O（大文字）：現在行上に行追加し、文字挿入モード
dd：現在行削除（実態は切り取り）
u：直前の操作をやめる（1回だけ、複数回できる時もあるが？）
:set nu：（一時的に）行番号表示
:set nonu：行番号非表示
G：最下行へ移動
数字 + G：数字行へ移動
hjkl：←↓↑→（移動）
yy：現在行コピー
p：ペースト
/文字 ：検索
n :検索の繰り返し
r：カーソルの一文字のみ置き換え（入力直後の1文字のみ）
J：現在行と次の行を結合

文字挿入モード等各コマンドの状態から抜け出すにもescを多用する。
コピーはマウスカーソルで指定範囲選択するだけ（ctrl＋Cは必要ない）。
ペーストは右クリック。
ctrl＋Cは処理を止める時に使う。パスワード入力モードの取消しにも使える。

※「mkdir」はmake directoryの略

Linuxコマンドはここによくまとめられており、
初学者にもわかりやすい → [参照](https://eng-entrance.com/category/linux/linux-command)
## Vi(入力モード)の操作について
#### Viでファイルの中身を直接編集可能となる
「vi ファイル名」で入力しエンターを押すと入力モードとなり、ファイルが開く。

```例：パスは適当.
vi /usr/local/WEB-INF/jsp/AAA.txt
```
「i」を押下すればファイル内容を編集できる。
入力モード(i)の確認方法は画面下部に「-----INSERT-----」と表示される。
ESCを押すとコマンドモードとなり編集不可に戻る。
Viを抜け出すには、
「:wq」上書き保存し終了
「:q!」保存せず終了
のどちらかを入力するといい。

「ZZ」(大文字)でもViを終了でき、
「ZZ」は内容が編集されていれば保存してくれる。

※「cat ファイル」でもファイルの中身を確認できるが、編集はできない。
※「Vi　新規ファイル」で新規ファイルを作ると同時に編集もできる。
#### cpでファイルを置き換える
「cp コピー元ファイルA コピー先ファイルB」でAの内容をBへ上書きする。

```例.
cp /usr/aa/A.properties /usr/bb/B.properties 
```

ファイルごとのコピペは「cp コピー元ファイルA コピー先ディレクトリ」でAのファイルをBへコピーする。
コピーしてリネーム作成は「cp コピー元ファイルA コピー先新規ファイル名」。

#### cdでディレクトリを移動し直接上書きも可能。
bb配下へ移動し
B.propertiesにA.nondebugの内容を上書き。
つまり、現在地からのパスを記載してあげればいい。

```例.
cd /usr/bb
cp /aa/A.nondebug B.properties
```
詳しくはこちら　→　参照：[Viリファレンス](http://hp.vector.co.jp/authors/VA016670/unix/vi_reference.html)

https://docs.oracle.com/cd/E19253-01/816-3946/editorvi-tbl-83/index.html

### メモ
｜（パイプ）：右の結果を左に渡して実行する。
lsの結果対してwcを実行。
```
ls | wc
```
**>** 出力先 ：出力のリダイレクト。出力先を指定できる。
catの内容をlogへ出力。
ファイル全体が上書きされるので、追記するなら「>>」とする。
エラー内容だけ出力するなら「2>」にする。追記なら「2>>」。
```
cat textA > log
```

「<」なら入力のリダイレクト。入力先を指定できる。

### AIXメモ
AIXはkshなのでbashのように↑↓矢印キーでコマンド履歴を表示できない。
escキー押下後に、k(↑)、j(↓)キーで操作可能。
参考

https://myokoym.github.io/entries/20130223/a0.html

`bash --login`すれば、↑↓も使用できるし、TABキーで補完もできる。こっちがオススメ。

## Linux
#### パス検索
任意の文字列を含むファイル名表示(/等の文字は検索できない)
構成：find パス　オプション　文字列
-type f：　ファイルのみを検索
-name：ファイル名で検索
```find . -type f -name '*123*'```

#### gerp検索
構成：gerp 文字列　パス
-r：再帰的
```grep -r '123' .```

123かつABCも含むものを検索
```grep -r '123' . | xargs grep -l 'ABC'```
学習曲線をプロットするメソッド

#学習曲線をプロットするメソッド
### 入力
- X_train
- Y_train
- pipe:パイプライン
- cvnum:分割数

### 学習曲線
トレーニングデータを増減させることで学習不足してるか過学習してるかを分析できる。



```python
import matplotlib.pyplot as plt
from sklearn.model_selection import learning_curve
def draw_learning_curve(X_train,Y_train,pipe,cvnum):
    train_sizes, train_scores, test_scores =\
                    learning_curve(estimator=pipe,
                                   X=X_train,
                                   y=Y_train,
                                   train_sizes=np.linspace(0.1, 1.0, cv_num),
                                   cv=cvnum,
                                   n_jobs=1)#0.1~1の10刻み（割合になっている）

    train_mean = np.mean(train_scores, axis=1)
    train_std = np.std(train_scores, axis=1)
    test_mean = np.mean(test_scores, axis=1)
    test_std = np.std(test_scores, axis=1)

    plt.plot(train_sizes, train_mean,
             color='blue', marker='o',
             markersize=5, label='training accuracy')

    plt.fill_between(train_sizes,
                     train_mean + train_std,
                     train_mean - train_std,
                     alpha=0.15, color='blue')

    plt.plot(train_sizes, test_mean,
             color='green', linestyle='--',
             marker='s', markersize=5,
             label='validation accuracy')

    plt.fill_between(train_sizes,
                     test_mean + test_std,
                     test_mean - test_std,
                     alpha=0.15, color='green')

    plt.grid()
    plt.xlabel('Number of training samples')
    plt.ylabel('Accuracy')
    plt.legend(loc='lower right')
    plt.ylim([0.8, 1.03])
    plt.tight_layout()
    plt.show()
```
【Rails,Ajax】$.ajaxのurlについて

##やりたいこと
画面に値を入力し、非同期通信でtodos_controllerのcreateメソッドへ送り、登録処理を行う。

##疑問
$.ajax内のurlに「/todos.json」を設定しているが、なぜcreateメソッドが呼び出されるのか？
createへ行くには「/todos」を指定すべき？

````
$.ajax({
      type: 'POST',
      url: '/todos.json',
      data: {
        todo: {
          content: todo
        }
      },
      dataType: 'json'
    })
```

```
Prefix Verb  URI Pattern          Controller#Action
todos  POST  /todos(.:format)     todos#create
```
##調べてわかったこと
(.:format) によって、「/todos.json」のような拡張子の指定もできる。
よって上記url指定でもcreateメソッドが呼び出される。

ちなみにurlを「/todos」にしても正常に動作しました。
jQueryで連想配列形式のname属性のキーを取得する

#前提
下記のようなname属性の時（このめいめいの時点でミスってる気がする）に`piyo`の部分を取得したい

```
<input type="text" name="hoge[0][piyo]">
<input type="text" name="hoge[1][piyo]">
<input type="text" name="hoge[2][piyo]">
<input type="text" name="hoge[3][piyo]">
```

#手法
jQueryでそれっぽい`input`を取得して、`name`を地道に切り出す

```js:app.js
$('input[name^="hoge"]').each(function(){
    const name = this.name;
    const startPoint = name.indexOf(']') + 1;
    const endPoint = name.lastIndexOf(']');

    //[piyo]がとれる
    // const parsedName = name.substr(startPoint, endPoint);
    //piyoがとれる
    const parsedName = name.substr(startPoint + 1, endPoint - 1);

})
```

正規表現でやりたかった...
【備忘録】can't find gem bundler(Gem::GemNotFoundException)というエラーの解決法

# 何をしようとしていた時に起きたエラーなのか
git cloneで他の人が作ったアプリをローカル環境に移し、bundle installする時に以下のエラーが起きた。

```terminal

can't find gem bundler (>= 0.a) with executable bundler (Gem::GemNotFoundException)
```

「実行できるbundlerが見つかりません」というエラーである。

# やってみたこと

とりあえず、bundlerもgemなので 'gem list'コマンドを実行して確認してみる。

```terminal

$ gem list
```
すると、

```
bundler (2.1.4)
```
自分のローカル環境でbundler発見。

次に、外からcloneしたアプリのGemfile.lockを確認してみる。

```
BUNDLED WITH
   2.0.2
```
あれ、バージョンが一致してないぞ？

# 原因

今回のエラーの原因は、自分がローカルで使用するbundlerと他の人のGithubからcloneしてきたアプリで使用されていたbundlerのバージョンに差異があったことだった。

# 解決法

一度cloneしてきたアプリのGemfile.lockを削除して、再度bundle install。

```terminal
$ rm -rf Gemfile.lock
$ bundle install
```

そうすることで、自分がローカルで使用しているbundlerのバージョンが反映されたGemfile.lockがまた生成されるので、無事にbundler関連のコマンドが使えるようになる。
Unity ARkitのFaceTrackingでシーン遷移するとクラッシュする

#どんな問題か
UnityでFaceTrackingのアプリを作ったら起こった問題
FaceTrackingシーンから他のシーンに遷移するとき、IOS実機だと落ちる
>libc++abi.dylib: terminating with uncaught exception of type Il2CppExceptionWrapper
(lldb) 

こんなのを残してさよなら

#解決方法

[ios - Unity Switch between ARKit Face Tracking and Rear Camera? - Stack Overflow](https://stackoverflow.com/questions/51821732/unity-switch-between-arkit-face-tracking-and-rear-camera)
↑
これで治った。
ExampleのUnityARFaceAnchorManager.cs を改変した人は注意

永遠悩んでた。海外質問フォームって偉大だなぁ、
Laravel で .env の値が取得できない

## おさらい

- Laravel では環境変数の設定に `.env` を使う
- `.env` の値にアクセスするには `env('<config>.<key>')` とする
    - 例： `env('app.url')`
- [設定 5\.7 Laravel](https://readouble.com/laravel/5.7/ja/configuration.html)

## 問題

- ある状況で `env('app.url')` で `null` が返ってくるようになった
    - とくになにもアプリケーションコードさわってない

## 原因

- 設定ファイルをキャッシュすると、`env()` 関数が `null` を返すようになる
    - `php artisan config:cache` ね

> Note: 開発過程の一環としてconfig:cacheコマンド実行を採用する場合は、必ずenv関数を設定ファイルの中だけで使用してください。設定ファイルがキャッシュされると、.envファイルはロードされなくなり、env関数の呼び出しは全てnullを返します。
>
> 設定 5.7 Laravel https://readouble.com/laravel/5.7/ja/configuration.html#configuration-caching

## 対策

- config ファイルで `env` 関数を使う

```php:config/app.php

<?php
  
return [
    'name' => env('APP_NAME', 'Laravel'),
    'env' => env('APP_ENV', 'production'),
    'debug' => env('APP_DEBUG', false),
    // ...
```

- そして `config()` 関数でアクセスする
win10 で docker desktop を 2.2.0.0 にしてから Host での変更の同期が激遅になったので 2.2.0.2 にアプデしたら治った

タイトルがすべて。
2.1.0.5 の頃は問題なく同期されてたので 2.2.0.0 のバグらしい。

##DL先
https://github.com/docker/for-win/issues/5530#issuecomment-583017342
ここ。
そのうち正式にリリースされると思いますが、とりあえず速報ということで。
ランダムフォレストで特徴量の順位付け

特徴量がたくさんあったときにどの特徴量がどの程度重要なのかランダムフォレストで順位付けを行うことができる。

```python
from sklearn.ensemble import RandomForestClassifier
def feature_evaluation(X_train,Y_train,f_labels):
    forest = RandomForestClassifier(n_estimators=100,
                                    random_state=1)
    forest.fit(X_train, Y_train)
    importances = forest.feature_importances_
    indices = np.argsort(importances)[::-1]

    for f in range(X_train.shape[1]):
        print("%2d) %-*s %f" % (f + 1, 30, 
                                f_labels[indices[f]], 
                                importances[indices[f]]))

    plt.title('Feature Importance')
    plt.bar(range(X_train.shape[1]), 
            importances[indices],
            align='center')

    plt.xticks(range(X_train.shape[1]), 
               f_label[indices], rotation=90)
    plt.xlim([-1, X_train.shape[1]])
    plt.tight_layout()
    plt.show()
```
gRPC でテキストと画像を取得 (python)

参考ページ
[gRPCとProtocol Buffersによるアプリケーション間通信 / Python](https://note.com/npaka/n/n5c3263ad88ff)

```text
$ tree
.
├── in01.jpg
├── simple_client.py
├── simple.proto
└── simple_server.py
```

設定ファイル

```text:simple.proto
syntax = "proto3";

package simple;

//RPCインタフェースの定義
service SimpleService{
  rpc SimpleSend (SimpleRequest) returns (SimpleReply) {}
}

//リクエスト
message SimpleRequest{
}

//レスポンス
message SimpleReply{
  string text = 1;
  string image = 2;
}
```

サーバープログラム

```py:simple_server.py
#! /usr/bin/python
#
import time
import grpc
import simple_pb2
import simple_pb2_grpc
import base64
from concurrent import futures

# シンプルサービスサーバーの定義
class SimpleServiceServicer(simple_pb2_grpc.SimpleServiceServicer):
	# 初期化
	def __init__(self):
		pass

	# 受信時の処理
	def SimpleSend(self, request, context):
		text = 'Hello Everybody!'
		b64 = base64.encodebytes(open('in01.jpg', 'rb').read()).decode('utf8')
		return simple_pb2.SimpleReply(text=text, image=b64)

# サーバーの開始
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
simple_pb2_grpc.add_SimpleServiceServicer_to_server(SimpleServiceServicer(), server)
server.add_insecure_port('[::]:50051')
server.start()
print('サーバーの開始')

# 待機
try:
	while True:
		time.sleep(3600)
except KeyboardInterrupt:
   # サーバーの停止
	server.stop(0)
```

クライアントプログラム

```py:simple_client.py
#! /usr/bin/python
#
import grpc
import simple_pb2
import simple_pb2_grpc
import base64
import sys
#
# サーバーとの接続
with grpc.insecure_channel('localhost:50051') as channel:
	stub = simple_pb2_grpc.SimpleServiceStub(channel)

	# データの取得
	response = stub.SimpleSend(simple_pb2.SimpleRequest())
	print('text:', response.text)
	img_file = 'client.jpg'
	with open(img_file, mode='wb') as f:
		f.write(base64.b64decode(response.image))
		sys.stderr.write(img_file + "  is saved.\n")
```

gRPC のコードを作成します。

```bash
python -m grpc_tools.protoc -I. \
    --python_out=. \
    --grpc_python_out=. \
    ./simple.proto
```

サーバープログラムの起動

```bash
/simple_server.py
```

クライアントプログラムの実行

```text
$ ./simple_client.py 
text: Hello Everybody!
client.jpg  is saved.
```
SQL 基礎用語&文法　2

#はじめに
[SQL 基礎用語＆文法 1 はコチラをクリック願います。](https://qiita.com/raigakun/items/7bbb9f935ca8fd26a5e1)
SQLを学んでいく上で、用語等を中心に整理していきます。
ターミナルにて入力する。もしくはSequelProのクエリにて入力するようにしております。
もうすでにご存知の方、省略の仕方等ご存知でしたら、ご教授願います。

#テーブルにあるデータを検索する。
- SequelProにて行います。
- テーブルにデータが入っていることを想定する。

###基本的な検索の構文

```sql

SELECT *
FROM テーブル名
```
＊ は全てのカラムを意味しています。ワイルドカードという。
　→　ワイルドカード：文字の代わりとして使うことができる記号
####FROM句

```sql
FROM テーブル名  --検索するテーブル名を指定する。
```

####SELECT句

```sql
SELECT カラム名  --取得するカラム名を指定する。
```

##取得するレコードを制限する。
SELECT句、FROM句と併用します。

####WHERE句

- 条件には比較演算子や論理演算子を使用できる。
- 条件内容が文字列や日付の場合、””で囲う必要がある。

```sql
-- 式
WHERE 条件

-- 実践してみます。
SELECT *
FROM users
WHERE family_name = "雷牙"
```

##論理演算を使用する。
####AND演算子

- 複数の条件を指定して式をつくる。
- その条件が全て正であるとき、式が正となる。

```sql
-- 式
WHERE a AND b

-- 実践してみます。
SELECT *
FROM users 
WHERE age = 5 AND prefecture = "福岡県"
```

####OR演算子

- 複数の条件を指定して式を作り、その条件のうちどれか1つ以上が正となれば、式は正となる。

```sql
-- 式
WHERE a OR b

-- 実践してみます。
SELECT *
FROM users
WHERE age = 5 OR prefecture = "福岡県"
```

####NOT演算子

- 1つの条件を指定して式を作り、式の正誤はその条件と逆になる。

```sql
-- 式
WHERE NOT a

-- 実践してみます。
SELECT *
FROM users
WHERE NOT prefecture = "東京都"
```

####BETWEEN演算子

-  単一カラムの範囲検索
-  1つのカラムに対して、上限と下限を指定して式を作る。
-  カラムの値がその値に含まれるとき、その式は正となる。

```sql
-- 式
WHERE カラム名 BETWEEN 下限 AND 上限

-- 実践してみます。
SELECT *
FROM users
WHERE age BETWEEN 3 AND 5
```

####IN演算子

- 単一カラムのリスト検索
- 1つのカラムに対してリストを指定し、カラムの値がそのリストに含まれるとき、その式は正となる。

```sql
-- 式
WHERE カラム名 IN (値1, 値2, ...)   --(値1, 値2, ...)のところがリストとなる。

-- 実践してみます。
SELECT *
FROM users
WHERE prefecture IN ("東京都”, "福岡県")
```

#さいごに
日々勉強中ですので、随時更新します。
皆様の復習にご活用頂けますと幸いです。
Rails　コーティング規約について　2

# はじめに
Ruby、Railsの基礎を学習中の方に向けて記載致します。
[Rubyのコーティング規約はコチラをクリック願います。](https://qiita.com/raigakun/items/80ba30671d7b2b18c44e)
[Railsのコーティング規約 1 はコチラをクリック願います。]
(https://qiita.com/raigakun/items/cdf4dbfacada59990627)
私自身これからチーム開発を行う上で大事にしたい。知っておきたいことをOutputします。

#ActiveRecord Queries
####idを指定してひとつのレコードを取得する場合は、whereよりfindを使う。


```ruby:qiita.rb

# 悪い例
User.where(id: id).take

# 良い例
User.find(id)
```

####複数の属性を指定してひとつのレコードを取得する場合は、whereよりfind_byを使う。

```ruby:qiita.rb
# 悪い例
User.where(first_name: 'Raiga', last_name: 'Yoshida').first

# 良い例
User.find_by(first_name: 'Raiga', last_name: 'Yoshida'))
```

#さいごに
コーティング規約については毎日更新します。
皆様の復習等にご活用頂けますと幸いです。
Docker(+ Docker-Compose) + MySQL を入れる（２）

# Docker(+ Docker-Compose) + MySQL を入れた後の話
[前回](https://qiita.com/bonkoturyu/items/c4cd08dcce3f2b88d4d4) ので、MySQLを用意してデータを作るとこまで出来たので、
MySQLを起動するとこの話だけ書いておく。

## Docker-Compose の MySQL を起動する
あとで、もう一つのUbuntu環境にある Express から接続できる状態にしておく。

```
docker-compose up -d --build
```

これだけ。--build のオプションがとても重要。

次は Ubuntu(Express環境) から Ubuntu(MySQL環境) へ接続して表示をするよ！！！

# 参考
- docker-compose コマンドまとめ
  - https://qiita.com/wasanx25/items/d47caf37b79e855af95f
- DockerのMySQLコンテナに外部のサーバーから接続する
  - https://qiita.com/Esfahan/items/70047ea2e4fecab4e2cc
HTML&CSS忘備録 "初学者1〜3ヶ月向け”

#この記事について
　自分の忘備録のために、HTML&CSSの記事まとめを作成します。そのため、メモがわりに使いながら、随時肉付けをしていきます。また、私は初学者であるため、この記事を見る方は勉強を始めて1〜3ヶ月くらいの方を想定しています。

##学習
###◆Udemyのおすすめ動画コース①
https://qiita.com/kurosawa_kuro/items/d3927bdaa68b02a42036
世界的に人気のUdemyを使って、学習するおすすめ動画コースのまとめです。
30代半ばから学習をはじめ、ブロックチェーンとデータサイエンスの研究をされている方(@kurosawa_kuro)の記事です。

##環境構築
###◆フロントエンドの開発環境を構築する
https://qiita.com/C3REVE/items/273646ad028e98758e70
GoogleChromeすらインストールしていない状態でもOKです。
いっぱしの開発がスタートできるようになります。

##HTML


##CSS
###◆Flexboxのチートシート
https://www.webcreatorbox.com/tech/css-flexbox-cheat-sheet#flexbox14
Flexboxのビジュアルでわかりやすい解説と、チートシートのダウンロードができます。

###◆CSSの擬似要素と擬似クラスの解説
https://www.asobou.co.jp/blog/web/css2

###◆リセットCSSまとめ
https://webdesign-trends.net/entry/8137
CSSをリセットする際のおすすめセットです。
Bogoで言語別にタグ毎の記事一覧を出力

# 動作確認バージョン
- WordPress: 5.3.2
- Bogo: 3.2.1

# サンプル
```php

<?php
// 現在のロケールを取得
$locale = get_locale();
?>

<div class="entry_content">
  <h1>tag list</h1>
  <?php
    $original_query = $wp_query;
    // slug順にタグを取得
    $tag_all = get_terms( 'post_tag', array(
      'fields' => 'all',
      'orderby' => 'slug'
      )
    );
    foreach( $tag_all as $value ):
  ?>
  <h2>tag-name: <?php echo $value->name; ?> <small>tag-slug: <?php echo $value->slug; ?></small></h2>
  <?php
    $arg_tag = array(
      // 現在のロケールの記事
      'suppress_filters' => false,
      'lang' => $locale,
      // 全件取得
      'numberposts' => '-1',
      'orderby' => 'ASC',
      'tag' => $value->slug
    );
    $posts = get_posts( $arg_tag );
    global $post;
  ?>
  <ul>
    <?php foreach( $posts as $post ): ?>
    <li><?php the_time( 'Y.m.d' ); ?> <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
    <?php endforeach; ?>
  </ul>
  <?php
    endforeach;
    $wp_query = $original_query;
    wp_reset_postdata();
  ?>
</div>

```
今更ながらCentOS7にLet's Encryptの設定をしてみた

# Let's Encryptで認証されたWebサーバを作ってみた

##　まずはDocumentRootとServerNameを設定
インストールしたばかりのサーバの設定をする。
当然この前にFirewalldの設定をしておいて80番や443番を開けておく。

```
touch /etc/httpd/conf.d/hoge.example.com.conf
vi /etc/httpd/conf.d/hoge.example.com.conf
```

```hoge.example.com.conf
<VirtualHost *:80>
  DocumentRoot /var/www/hoge.example.com
  ServerName hoge.example.com
</VirtualHost>
```
SSLも設定

```
<VirtualHost _default_:443>
DocumentRoot "/var/www/hoge.example.com"
ServerName hoge.example.com:443
････
```
httpdのプロセス再起動

```
systemctl restart httpd.service
```

## Let'sEncryptをインストール

```
yum install epel-release
yum install certbot python-certbot-apache
```
接続して設定する

```
certbot certonly --webroot -w /var/www/hoge.example.com/ -d hoge.example.com
```
途中で聞かれること

```
Enter email address     　　　　　←　メールアドレスを入力
Prease read the Terms  ...      ←　同意してAgree
Would you be willing ...        ←　メールで連絡をくれるらしい　任意
```
こんな感じで進んでいくと、

```
IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/hoge.example.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/hoge.example.com/privkey.pem
   Your cert will expire on 2020-05-07. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
   "certbot renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le
```
と表示されるので、本当にできたかどうかを確認してみる。

注）この際、Let's Encryptのサイトからアクセスがあるのでサーバは設定しているURL（この場合hoge.example.com）がLet’s Encryptのサイトから80番や443番でアクセスできるように設定しておかなければいけない。

```
# ls -l /etc/letsencrypt/live/hoge.example.com/
合計 4
-rw-r--r-- 1 root root 692  2月  7 11:33 README
lrwxrwxrwx 1 root root  41  2月  7 11:33 cert.pem -> ../../archive/hoge.example.com/cert1.pem
lrwxrwxrwx 1 root root  42  2月  7 11:33 chain.pem -> ../../archive/hoge.example.com/chain1.pem
lrwxrwxrwx 1 root root  46  2月  7 11:33 fullchain.pem -> ../../archive/hoge.example.com/fullchain1.pem
lrwxrwxrwx 1 root root  44  2月  7 11:33 privkey.pem -> ../../archive/hoge.example.com/privkey1.pem
```

ssl.confに登録

```/etc/httpd/conf.d/ssl.conf
...
SSLCertificateFile /etc/letsencrypt/live/hoge.example.com/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/hoge.example.com/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/hoge.example.com/chain.pem
...
```
httpdのプロセス再起動

```
systemctl restart httpd.service
```

スマホなどを使って、httpsでアクセスすると、信用おけるサイトとなっていた。

## 証明書の自動更新
Let's Encryptは3ヶ月で証明書が切れる。
切れないように、cronで更新をする。
rootさんでcrontabを編集。

```
crontab -e
```

``` 
00 04 01 * * certbot renew && systemctl restart httpd
```

これで毎日更新される。一応httpdもリスタートするようにしてある。
one-hot変換

# one-hot 変換
教師ラベルリストをone-hot表現に変換する。

```python
from sklearn.preprocessing import OneHotEncoder
def onehot(array):
    array = np.array(array).reshape(-1,1)
    enc = OneHotEncoder(categories="auto", sparse=False, dtype=np.float32)
    array = enc.fit_transform(array)
    print(array)
    return array
```
SessionNotCreatedExceptionの対処法2選

# はじめに
アプリ作成記事（[あなたの代わりに勤怠ボタン押す太郎くん](https://qiita.com/rereton/items/6dafc768a3dba25e49da)）の中で紹介した方法を別途切り出してご紹介。
PythonでSelenium使っているとある日突然SessionNotCreatedException出てきますよね。

```
SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version 76
```
これが出てきた時の対処法。

# Seleniumのサポートしているバージョン外のChromeDriverを使用している場合
まずサポート対象のdriverを持ってきましょう。
[ChromeDriver](https://chromedriver.chromium.org/downloads)
持ってきたらプロジェクト内の適当な場所においてその場所をdriverのexecutable_pathに指定します。

```
# chromedriverのバージョンを指定
driver = webdriver.Chrome(options=options, executable_path='chromedriver.exeの場所')
```

# ChromeのバージョンとChromeDriverのバージョンが異なる場合
使用しているChromeブラウザのバージョンを確認します。
メニュー　＞　ヘルプ　＞　Google Chromeについて
バージョンを確認したら同じバージョンのChromeDriverを取得してプロジェクトの適当な場所に配置します。
（例えばブラウザが79.0.3945.130だったらChromeDriver 79.0.3945.36をDLする）
あとは↑と同じでドライバーの場所を指定します。

# まとめ
今のところこのどちらかで解消してるので参考にしてください。
エラーが発生してから手動でバージョン合わせる以外の方法ないかなあ。。
formのonsubmitが実行されないケース

formに`onsubmit`を付けているとき、例えば以下のようにすると`calledBeforeSubmit();`が実行されない。

```html
<form action="/hoge" onsubmit="return calledBeforeSubmit();">
	<input type="hidden" name="hiddenValue" value="fuga">
	<input type="button" onclick="this.form.submit();"><!-- ここが駄目 -->
</form>

<script type="text/javascript">
const calledBeforeSubmit = () => {
	// 処理...
	return true;
};
</script>
```
どうやら`<input type="button" onclick="this.form.submit();">`のようにonclick属性からformをsubmitするとonsubmitが実行されないぽい。

以下のように素直に`<input type="submit">`を使う必要がある。

```html
<form action="/hoge" onsubmit="return calledBeforeSubmit();">
	<input type="hidden" name="hiddenValue" value="fuga">
	<input type="submit"><!-- これなら大丈夫 -->
</form>

<script type="text/javascript">
const calledBeforeSubmit = () => {
	// 処理...
	return true;
};
</script>
```

調べてみると、[MDNのドキュメント](https://developer.mozilla.org/ja/docs/Web/API/HTMLFormElement/submit)にこんなことが書いてあった。

> Gecko ベースのアプリケーションからこのメソッドを呼び出すときに、フォームの onsubmit イベントハンドラ (例 : onsubmit="return false;") はトリガされません。一般的に、ユーザエージェントによる呼び出しは保証されていません (※参照 : http://lists.w3.org/Archives/Public/www-dom/2012JanMar/0011.html)

「Gecko ベースのアプリケーション」が何なのかはイマイチわからないが、ブラウザのUserAgentにはよく「Gecko」という単語を見かけるので、おそらくそれの事なんじゃないかと思っている。
Jenkins Job実行エラー org.openqa.selenium.WebDriverException: unknown error: cannot find Chrome binary

CentOS7


google.core.GoogleCrawler > crawler FAILED
    org.openqa.selenium.WebDriverException: unknown error: cannot find Chrome binary
      (Driver info: chromedriver=72.0.3626.69 (3c16f8a135abc0d4da2dff33804db79b849a7c38),platform=Linux 3.10.0-1062.12.1.el7.x86_64 x86_64) (WARNING: The server did not provide any stacktrace information)
    Command duration or timeout: 77 milliseconds
    Build info: version: '3.14.0', revision: 'aacccce0', time: '2018-08-02T20:19:58.91Z'
    System info: host: 'ik1-343-31541.vs.sakura.ne.jp', ip: 'xxx.xxx.xxx.xxx', os.name: 'Linux', os.arch: 'amd64', os.version: '3.10.0-1062.12.1.el7.x86_64', java.version: '1.8.0_242'
    Driver info: driver.version: SelenideDriver
    selenide.url: https://www.google.co.jp
    selenide.baseUrl: http://localhost:8080
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)


### 解決方法

```bash
vi /etc/yum.repos.d/google-chrome.repo
[google-chrome]
name=google-chrome
baseurl=http://dl.google.com/linux/chrome/rpm/stable/x86_64
enabled=1
gpgcheck=1
gpgkey=https://dl.google.com/linux/linux_signing_key.pub

yum update
yum install -y google-chrome-stable
```
【Python】csvファイルを1次元配列のデータとして格納する方法

#目的
```csv:sample.csv
a,b,c,d,e
```
上記のようなcsvファイルを下のような一次元配列に格納する。

```
['a','b','c','d','e']
```
機械学習によって分類したlabelデータの結果として保存したcsvを、またpythonプログラム内で扱うために作成したが、よりよい方法があればコメントにて教えていただきたいです。

#方法
sample.csvとread_csv_flatten.pyが同じディレクトリにある場合、以下のコードを実行することでdataにcsvの内容が一次元の配列に格納される。
同じディレクトリ内に無い場合は、適当なpathを指定する必要がある。

```python:read_csv_flatten.py
import csv
import numpy as np

with open("sample.csv") as fp:
	reader = csv.reader(fp)
	data = [ e for e in reader ]

data = np.array(data).reshape(-1)

#以下確認のための出力
print(data)
```

#結果
```
['a' 'b' 'c' 'd' 'e']
```

以上のように、csvの内容が一次元の配列に格納されていることがわかる。
Ionic アプリ起動時にオフラインなら警告を出す（Capacitor）

#はじめに
この記事を確認して欲しい
[ionic ネットワーク接続を確認する 【Capacitor】](https://qiita.com/kokogento/items/c5130225f44128721b32)

上記の記事は私が前に書いたものだ。
最近発見したのだが、この記事で紹介してあるコードには**1つ大きな欠落**があった。。

タイトル通りだが、**アプリの起動時にオフラインなら警告アラートが出ないのだ！！！**

今回はその欠落を埋める。

#なぜアプリの起動時にオフラインなら警告アラートがでない？
「はじめに」で紹介した記事より、コードを引用

```typescript
startListenNetwork() {
    this.listener = Network.addListener('networkStatusChange', (status) => {
      if (!status.connected) {
        this.networkAlert();
      }
    });
  }
```

これは**ネットワークの状態が変化した場合**の処理なのだ。

通信がonからoffになった時、もしくはoffからonになった時。
そして、もし通信がonからoffになった時は、アラートを出す。

こんな感じである。

**つまり、アプリ起動時に通信がoffだろうと`startListenNetwork()`は、何も実行されない！**

#結論、こうすれば良い

```typescript:home.service.ts
import { AlertController } from '@ionic/angular';
import { Plugins, NetworkStatus } from '@capacitor/core';
const { Network } = Plugins;

@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})
export class HomePage {
  status: NetworkStatus;
  constructor(private alertCtrl: AlertController) { }


  // ネット接続の状態を取得
  async getStatus() {
    try {
      this.status = await Network.getStatus();
      if (this.status.connected === false) {
        this.networkAlert();
      }
    } catch (error) {
      console.log('エラー ' + error);
    }
  }

 // ネット接続の確認を開始
  startListenNetwork() {
    this.listener = Network.addListener('networkStatusChange', (status) => {
      if (!status.connected) {
        this.networkAlert();
      }
    });
  }

// ネット接続の確認を終了
  stopListenNetwork() {
    if (this.listener) {
      this.listener.remove();
    }
  }

  async networkAlert() {
    const alert = await this.alertCtrl.create({
      header: '接続エラー',
      message: 'インターネット接続がオフラインです。。インターネット接続を確認して下さい！',
      buttons: ['OK']
    });
    await alert.present();
  }
}
```

```typescript:home.page.ts
constructor(
    private homeService: HomeService,
  ) 

ionViewDidEnter() {
    this.homeService.getStatus();
    this.homeService.startListenNetwork();
  }

  ionViewWillLeave() {
    this.homeService.stopListenNetwork();
  }
```


どこが変わったかというと`getStatus()`のところ。

これで、もしアプリ起動時にオフラインならアラートがでる。
深夜のテレビで流れるアレをCSSで実装してみた


ピーーーーーーーーーーーーー
<p class="codepen" data-height="400" data-theme-id="default" data-default-tab="result" data-user="saeka-hirai" data-slug-hash="NWqWaJr" style="height: 400; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="color-bar">
  <span>See the Pen <a href="https://codepen.io/saeka-hirai/pen/NWqWaJr">
  color-bar</a> by saeka-hirai (<a href="https://codepen.io/saeka-hirai">@saeka-hirai</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## 実装方法

### HTML

```html
<section class="color-bar"></section>
```
これだけ

日頃装飾のために空divを無駄遣いしている諸君
これくらいのモノならCSSの擬似要素使えば実装できるゾ

### CSS
#### linear-gradientというポテンシャルの塊
「CSS グラデーション」を検索にかけるとほぼほぼ出てくる
**linear-gradient**というproperty。
文字通りグラデーションを実装するときに使います。
参考URL : https://developer.mozilla.org/ja/docs/Web/CSS/linear-gradient

でも、実は他の使い道もあるポテンシャルの塊なんです:smirk: 
**linear-gradient**の値は、先の後と次の前の配分を同じ値で繋げると、
なんと単色で色を置くことができます。
さらに配分次第では何色も追加することができる優れもの:wink: 
(同じ値で繋げなくてもグラデーションになるだけです:sparkles: )
あとは入れたい色数分繋げていくだけで、
一つの要素にたくさんの色を入れることができます。
こんな感じ

```css
 background: linear-gradient(to right, navy 20%, white 20% 40%, purple 40% 60%, gray 60% 72%, dimgray 72% 77%, gray 77% 82%, silver 82% 87%, black 87% 100%);
```
20 -> 20 40 -> 40 60
ってなっているのがわかりますか？ :thinking: 


## 応用(?)編

### 梨汁ブシャー
<p class="codepen" data-height="350" data-theme-id="default" data-default-tab="css,result" data-user="saeka-hirai" data-slug-hash="vYOYdjb" style="height: 350px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="funassyi">
  <span>See the Pen <a href="https://codepen.io/saeka-hirai/pen/vYOYdjb">
  funassyi</a> by saeka-hirai (<a href="https://codepen.io/saeka-hirai">@saeka-hirai</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

※変数機能、Sassだけじゃなくて実はCSSも標準で持ってます


### ＼\ 月に代わっておしおきよ :crescent_moon:  /／
<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="css,result" data-user="saeka-hirai" data-slug-hash="LYVPKbw" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Slice Pretty Guardian">
  <span>See the Pen <a href="https://codepen.io/saeka-hirai/pen/LYVPKbw">
  Slice Pretty Guardian</a> by saeka-hirai (<a href="https://codepen.io/saeka-hirai">@saeka-hirai</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

Slice Herosっていうゲームの問題に出てくるキャラの色味を再現してみました。
遊んでみてね。


## グラデーション作りたい人は
このサイトが画期的なので遊んでみてください！
(どんなに濁る組み合わせで色を入れても、
いい感じのグラデーションを作ってくれる優れもの:joy: )
https://mycolor.space/gradient
UiPath セレクターを理解してみる【part0】

# セレクターを意識していますか？
UiPathを使っていて、「セレクター」について意識しながらワークフローを作っている人ってあんまりいないんじゃないでしょうか。
「セレクターを意識していない」と言える代表例を以下に挙げます。

- 自動生成されたセレクターをそのまま使用している
- UiExplorerを使わない

では、「セレクターを意識している」とはどのような状態でしょうか。
まず、UiPathが自動生成したセレクターを見てみましょう。下記のような形式がほとんどだと思います。

```xml
<html app='iexplore.exe' title='example' />
<webctrl name='button' tag='INPUT' />
```

このセレクターの**XML文字列**について、どの程度理解しているでしょうか。
このXML文字列の意味をある程度理解し、セレクターを自在に扱い、ワークフローの安定性向上や効率化を目指して初めて「セレクターを意識している」と言えます。

セレクターを意識しない場合のデメリットは以下のようなものが考えられます。

- ワークフローが落ちやすい
- 不必要なロジックが増える
- アクティビティが期待通りに動作せず、ワークフロー作成を断念してしまう

それでは、導入はこれぐらいにして本題に入っていきましょう。
今回はPart0ということでセレクターの基礎を理解していきます。

# セレクターってなに？
UiPathでワークフローを作るとき、必ずアクティビティを使用します。アクティビティには一部を除きセレクターが存在します。

では、セレクターとはアクティビティのどんな役割を担っているのでしょう。
それは、アクティビティがアクションを起こす画面の位置(座標)を指し示していると言えます。

しかし、x軸y軸のような2次元座標ではないことに注意してください。

GUIアプリケーションもプログラムであるため、全ての画面要素はプログラミングされています。
つまり、そのプログラムを解析すれば、画面要素そのものを特定することが可能です。
そして、その特定した要素の位置情報を記録したのが**セレクター**です。

単純な2次元座標ではないため、UiPathは操作するウィンドウの位置が変わってもアクティビティが正しく動作するのです。

# 終わりに

最後までご覧いただき、ありがとうございました。
セレクターについて、仕様が公表されていないため、いまだに分からないところが多くあります。
しかし、少しずつ検証して記事にまとめていけたらと思っています。

次回はセレクターの「手動生成」について話したいと思います。
[手動生成について投稿しました。](https://qiita.com/k_rana/items/1ec80345e33d013d3f53)
RSpecのassignsメソッドを復習するぞ

#assignsメソッドの使い方

assignsメソッドはコントローラのインスタンス変数をテストするメソッド。
引数にインスタンス変数をシンボル型で渡す。（超重要）

```categories_controller_spec.rb
require 'rails_helper'

RSpec.describe Potepan::CategoriesController, type: :controller do

  describe "GET #show" do
    let!(:taxon) { create(:taxon, name: "Bags") }
    before { get :show, params: { id: taxon.id } }
    
    it "assigns @taxon" do
      expect(assigns(:taxon)).to eq taxon
    end
  end
end
```

この場合、コントローラ側で@taxonというインスタンス変数を定義していることになる。

テストの内容としては、コントローラで作成した@taxonというインスタンス変数とテスト内で作成したtaxonというテストデータが一致しているかを検証している。
Phoenix LiveView 親LiveViewと子Live Componentの連携

# Phoenix LiveView コンポーネント親子間の連携

LiveViewいいですね！
[docs](https://hexdocs.pm/phoenix_live_view/Phoenix.LiveComponent.html#module-targeting-component-events)に書いてあったけど、少し行き詰まったので、復習がてらメモ。

## 問題
子コンポーネントでhandle_eventしようとしたが、親コンポーネントにイベントが行ってしまう。

```elixir

defmodule PakaWeb.Live.HeroComponent do
  use Phoenix.LiveComponent

  def render(assigns) do
    Phoenix.View.render(PakaWeb.LiveView, "hero_component.html", assigns)
  end

  def mount(params, _session, socket) do
    {:ok, assign(socket, query: "", message: "[Init-child]")}
  end
　
　# ここで処理したかった。が、来ない。
  def handle_event("menu", query, socket) do
    IO.inspect socket
    {:noreply, update(socket, :message, fn x -> "pakaだよーbakaじゃないよ" end)}
  end
end


```

子には来ないで、親の方のhandle_eventで処理されてしまう。

```
[error] GenServer #PID<0.717.0> terminating
** (FunctionClauseError) no function clause matching in PakaWeb.Live.Index.handle_event/3
```

親の方にhandle_eventを移植すると動きました。
しかし、子で処理して必要なものだけ親に委ねたい。

## 原因

statefulな子コンポーネントのidが未設定。

leexの方で、phx-clickとともにphx-targetを設定する。
phx-tagetのidは、子コンポーネントのrenderするleexのidにしたらうまくいった。

```html
<section class="hero" id="hero">  // ここのid
// 省略
      <div class="container">
        <ul>
          <li class="is-active"><a>Coffee</a></li>
          <li ><a phx-click="menu" phx-target="#hero">Menu</a></li>
　　　　　// このphx-targetが必要
          <li><a>Access</a></li>
          <li><a>Blog</a></li>
        </ul>
      </div>
    </nav>
  </div>
<section>
```
これで、うまくいった。

# 子コンポーネントから親LiveViewに処理をたくす
子で処理できるようになったら、そのついでに親に処理を投げたい。
（ページレイアウトの変更など）

## やり方
1. 子のhandle_event内でsend self(), hogehoge を使う。
2. 親のhandle_infoで受け取る。

```elixir
defmodule BunkadoWeb.Live.HeroComponent do
  use Phoenix.LiveComponent
  # 省略

  def handle_event("menu", query, socket) do
    send(self(), {:menu, "menu 押されたよ！親に送るね"})

    {:noreply, update(socket, :message, fn x -> "子の処理" end)}
  end
end
```

```elixir
defmodule PakaWeb.Live.Index do
  use Phoenix.LiveView
　# 省略

　# ここで親は受け取る。
  def handle_info({:menu, message}, socket) do
　　IO.puts "親で受け取ったよ！やったね！#{message}"
    {:noreply, assign(socket, message: message)}
  end
end
```

# おわりに
すごく久しぶりに時間が取れてコードかけたんですが、elixirは何を書いていたのかすぐ思い出せました。
Vueのprops使う連携より書きやすい気がしました。
Phoenix LiveViewの進化が楽しみ。
stanのパラメータのTrace Plotが見づらいから少し考えた

#はじめに
現在，stanを使ってモデリング，パラメータ推定を行っているのですが，Trae plotがつぶれて見ずらいので少し見やすくする方法があったので共有します．(知っている人にとっては当たり前かも...)
あと，もっと良い方法があったら教えてください．

#環境
|||
|:----:|:------:|
|OS|Windows10|
|Python|3.7.4|
|PyStan|2.19.1|

#早速...
```python:stan_model_ver1.py
import arviz
import pandas as pd

data = pd.read_csv("~~.csv")

dat = {"辞書で定義"}

model = StanModel(file="~~.stan")

fit = model.sampling(data=dat, n_jobs=-1, seed=999, iter=1000,chains=1)

arviz.plot_trace(fit)
```
でこのようなものが描かれます．
![stan_Figure_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208370/eaefff02-68db-f109-7851-ee23e5bcd19d.png)

しかし，パラメータ数が多いと滅茶苦茶見づらいです...

そこで，

```python:stan_model_ver2.py
import arviz
import pandas as pd

data = pd.read_csv("~~.csv")

dat = {"辞書で定義"}

model = StanModel(file="~~.stan")

fit = model.sampling(data=dat, n_jobs=-1, seed=999, iter=1000,chains=1)

'''====以下変更＝＝＝'''
fit_df = fit.to_dataframe()

index = fit_df["draw"]
lenght = len(fit_df.keys())-7
for i in range(lenght):
    ob = fit_df[fit_df.keys()[i+3]]
    plt.subplots(figsize=(15, 7))
    plt.title(f"{fit_df.keys()[i+3]}")
    plt.subplot(1, 2, 1)
    sns.distplot(ob)
    plt.subplot(1, 2, 2)
    plt.plot(index, ob)
    plt.savefig(f"figure/stan_figure/{fit_df.keys()[i+3]}.png")
    plt.show()
```
とします．

データフレーム化して，パラメータ1つずつ可視化することで，時間は少しかかりますが，
![Y[1,2].png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208370/5ce3c039-31cf-b964-c26e-20c90a489ec9.png)

このように各段に見やすくなります．

#おまけ？
パラメータ数が多いと`print(fit.stansummary())`をして各パラメータの収束状態を確認しようとしても，表示しきれないことがあるかもしれません．(特に時系列モデルを考えると)
そんな時は，

```python:omake.py
summary_df = fit.stansummary()

file = open('summary_stan.txt', 'w')
string = summary_df
file.write(string)
```
このようにテキストファイルとして保存してしまえば見たいパラメータの状態を確認することができます．
pythonのtkinterで有効期限を表示するだけの処理

# 事の発端
ソフトの有効期限を表示する処理を作って、関数をクラスにしてファイルに分離したので、コードをちょいと公開しようと思いました。

# 動作環境
windows10
PyCharm
Python

# コード
まずは、関数だけのコードです。コンソールに使用期限を表示します。

```python
import datetime

def main():
    dict_end_date = {"年": 2020, "月": 2, "日": 8, "時": 23}

    dt_now = datetime.datetime.now()
    end_date = datetime.datetime(dict_end_date["年"], dict_end_date["月"], dict_end_date["日"])

    if end_date < dt_now:
        print("ソフトの使用期限が終了しています。")
    else:
        print("ソフトの使用期限は、" + str(dict_end_date["年"]) + "年" + str(dict_end_date["月"]) + "月" +
              str(dict_end_date["日"]) + "日です。")


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

# クラス化したコード
関数をクラス化しました。ボタンなどコールバック関数から呼ばれてもいいように`__call__`メソッドを実装してます。

```python 
import datetime
import tkinter as tk
import tkinter.messagebox


class ShowMessageEndDate:
    def __init__(self, parent=None):
        self.parent = parent
        self.dict_end_date = {"年": 2020, "月": 7, "日": 31, "時": 23}
        self.dt_now = datetime.datetime.now()
        self.end_date = datetime.datetime(self.dict_end_date["年"], self.dict_end_date["月"], self.dict_end_date["日"])
        self.str_end_data = "{0}年{1}月{2}日".format(str(self.dict_end_date["年"]), str(self.dict_end_date["月"]),
                                                  str(self.dict_end_date["日"]))
        self.msg = "試用版のソフトの利用期限は、" + self.str_end_data + "です。"

    def __call__(self, event=None):
        self.show_message()

    def show_message(self):
        root = tkinter.Tk()
        root.withdraw()
        if self.end_date < self.dt_now:
            tk.messagebox.showinfo('確認', "{0}\n有効期限が切れています。終了します。".format(self.msg))
            return False
        else:
            tk.messagebox.showinfo('確認', self.msg)
            return True


def main():
    ShowMessageEndDate().show_message()


if __name__ == "__main__":
    main()

```

# 呼び出し側のコード
```python
# tkinterのフォームを表示するクラス
class ClassForm:
    def __init__(・・・省略・・・)
        （・・・省略・・・）

        if (ファイル名).ShowMessageEndDate().show_message() is False:
            return

        if __name__ == "__main__":
            self.root.title("タイトル")
            self.root.mainloop()
```

処理を別ファイルに分離できるので、便利です。呼び出し元の変数を使いたいときは、実引数にselfを指定すると、インスタンス変数のparentに代入され使えるようになるので、処理が複雑になっても問題ないです。
ASP.NETでAPIサーバーの返却をXMLしたい

ASP.NETでサーバのときXMLでデータ返却したいメモ

###Microsoft.AspNetCore.Mvc.Formatters.Xmlインストール
NuGetで「Microsoft.AspNetCore.Mvc.Formatters.Xml」を参照してインストール（最新版がエラーだったので2.1.1使用）
![NoName_2020-2-7_12-28-9_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48015/c6f5107d-c4fa-47aa-e25f-756e35112aca.png)


###Startup.csにoptons追加

RespectBrowserAcceptHeaderをtrueにしたらXMLになったのでメモ

``` C#
public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc()
        .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

    services.AddMvc(options =>
    {
        // XMLを返すフォーマッターとそのMIME Typeと拡張子のマッピングを登録
        // XmlDataContractSerializerOutputFormatterはASP.NET Web API相当
        options.OutputFormatters.Add(new XmlDataContractSerializerOutputFormatter());
        // options.OutputFormatters.Add(new XmlSerializerOutputFormatter());
        options.FormatterMappings.SetMediaTypeMappingForFormat("xml", "application/xml");
        options.RespectBrowserAcceptHeader = true; // false by default
    });
}
```


###ブラウザ表示

![NoName_2020-2-7_12-23-47_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48015/d30963bb-12bf-3a00-436a-ce15eb0e589f.png)

###参考サイト

ASP.NET MVC Core 2.0で作ったAPIでXMLなどの形式を返したい
https://www.misuzilla.org/Blog/2017/08/26/ConfigureFormattersInAspNetMvcCore2

C#(ASP.NET core)でWeb APIを作ってみる（Hello World編）
https://qiita.com/rawr/items/85abf5f646e20e3438a1#%E3%82%B3%E3%83%B3%E3%83%88%E3%83%AD%E3%83%BC%E3%83%A9%E3%83%BC%E3%82%92%E8%BF%BD%E5%8A%A0%E3%81%97%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%82%92%E5%AE%9F%E8%A3%85%E3%81%99%E3%82%8Bget%E3%81%A0%E3%81%91
php7.3に上げたらcomposer installがエラーになったので解決する

composer 1.2系を使用していてphpを7.3にアップデータしたら
composer installでエラーになりました。

```
[ErrorException]
  "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"?
```
php7.3から、switchのbreakの代わりにcontinueを使えなくなったようです。
ただ、どこで使用しているからエラーになるのかまでは分かりませんでした。。

解決策は
1. php7.2に下げる
2. composerをアップデートする

1はそもそも選択肢には入らなかったので、composerをアップデートしました。

```
> composer self-update
```

```
> composer -v

で確認して、
Composer version 1.2
→
Composer version 1.9.2
```


ということで現状最新の1.9.2がダウンロードされて最新までアップデート。
で、``composer install``を再度試したら成功しました。

composerはキャッシュも残すので
composer installをする前に
一度``composer clear-cache``しててもいいかもしれません。
windowsのpowershellでvenv環境

# powershellでvenv環境を構築する
まず管理者権限でpowershellを起動し以下のコマンドを実行することでスクリプトファイルが実行できるようにする

```sh
PS > PowerShell Set-ExecutionPolicy RemoteSigned
```
次に対象のローカルファイルでvenvファイルの作成

```sh
PS > python -m venv venv
```
次に仮想環境の起動

```sh
PS > venv\Scripts\activate.ps1
```

出るときは

```sh
PS > deactivate
```
MariaDB と MySQL のバージョン比較


どこにも見やすい相対表が無かったので作りました。

ただ、よく調べてみると、MariaDB が MySQL よりも先に特定の機能を先に導入したりしていて、 **完璧な相対は出来ない** です。（まあ完璧に同じだったらなぜ別の製品を作らないといけないのかという話になりますよね）。

なので、この相対表を仕事で使うのは絶対におすすめしません (免責)。

[MariaDB公式サイトの MySQL との比較ドキュメント](https://mariadb.com/kb/en/mariadb-vs-mysql-compatibility/)を参考に作成しました。

MariaDB | MySQL
--------|------
5.1  | 5.1
5.2  | 5.1
5.3  | 5.1
5.5  | 5.5
10.0-10.1 | 5.6
10.2~3 | 5.7 (*)
10.4~11 | 8.0 (*)


## バイナリ＆レプリカ互換

両ソフト 5.5 まではほぼ完全互換。

MariaDB 10.0~3 は InnoDB の互換性の問題がるものの、ほぼバイナリ互換があります。

MariaDB 10.2 サーバーは、MySQL 5.7 サーバーのレプリカサーバーとしても機能するらしいです。MySQL の一部情報、Global Transaction IDs (GTIDs) events は MariaDB GTID events の置き換えられてしまうらしいです。

MariaDB 10.3 と MySQL 5.7 とそれ以前は、バイナリ互換があります。

バイナリ互換を簡単に説明すると、MySQL 5.7 をアンインストールして、サーバー上の `/var/lib/mysql` に生の DB データを残したまま、MariaDB 10.3 をインストールすると、そのまま DB 情報を引き継いで使い続けることができるということです。

MySQL 8 は、MariaDB とバイナリ互換がありません。

## MySQL 8 と MariaDB 10.4 以降は注意

MySQL 8 と MariaDB 10.4~ はバイナリ互換性が無くなっています。

差分がすごく細かいので、[MariaDB公式サイトの MySQL との比較ドキュメント](https://mariadb.com/kb/en/mariadb-vs-mysql-compatibility/)を参考にすると良いです。


## Concrete CMS は MySQL 5.1.5 から対応

Concrete CMS (旧 concrete5)は 5.7.0〜8.5.2までは MySQL 5.1.5 から対応しています。

絵文字 (utf8mb4) の対応は 8.5.0 からです。

## 絵文字対応

大多数に絵文字を利用するには、utf8mb4 の collation や charaset である必要があります。
InnoDB で Antelope なデータベースだと、DBの変換時に Index エラーが起きる場合があります。

MySQL 5.7.9 以降だと [InnoDB の設定追加](https://techracho.bpsinc.jp/hachi8833/2016_08_25/25044)が不要になったので、MySQL 5.7.9 以降の選択をおすすめします。

```
innodb_file_per_table
innodb_file_format = Barracuda
innodb_file_format_max = Barracuda
innodb_large_prefix
```

## こぼれ話

MySQL の My はオリジナルコード作者の Michael "Monty" Widenius の娘の名前。
MariaDB は、MySQL が当時サン・マイクロシステムズ社に買収され、退社した後に作った互換DB。名前の Maria も、Widenius氏の娘の名前。まさに姉妹DB。

参考
https://mariadb.com/kb/en/mariadb-vs-mysql-compatibility/
https://enterprisezine.jp/dbonline/detail/4220
https://www.s-style.co.jp/blog/2018/04/1709/
GCP アップデート (2/7-2/13 2020)

### Cloud Build: [Feb 6, 2020](https://cloud.google.com/cloud-build/release-notes#February_06_2020)
- GitHubトリガと連携できるGitHub App triggersがGAになったよ！
- ダッシュボードがGAになったよ！
  - ビルドの平均時間とか履歴が見やすい。

### CloudSQL: [Feb 6, 2020](https://cloud.google.com/sql/docs/release-notes#February_06_2020)
- 1st Genが新たに作成できなくなったよ。

### AI Platform: [Feb 5, 2020](https://cloud.google.com/ai-platform/docs/release-notes#February_05_2020)
- トレーニングとプレディクションが1.15でGPUが使えなかった問題が治ったよ。

### AppEngine: [Feb 6, 2020](https://cloud.google.com/appengine/docs/standard/go/release-notes#february_6_2020)
- Spending limitsが新たに作成できなくなったよ。
  - インスタンス数とかで管理してね。

### AI Platform: [Jan 21, 2020](https://cloud.google.com/ai-platform/deep-learning-vm/docs/release-notes#January_21_2020)
- M41リリース
  - TensorFlow Enterprise 2.1が利用できるように。
  - MXNetが1.5.1にアップグレード
  - PyTorchが1.4.0にアップグレード
  - XGBoostが0.90にアップグレード

### Compute: [Feb 7, 2020](https://cloud.google.com/compute/docs/release-notes#february072020)
- G Suite管理者がOSログインのAPIでドメイン名(@...)を含むかを決められるようになったよ。(GA)

### Compute: [Feb 11, 2020](https://cloud.google.com/compute/docs/release-notes#february112020)
- BYOLをサポートするために、sole-tenantを利用している場合は、ホストのメンテナンスの際に、sole-tenantノードグループ内でライブマイグレーションできる設定がベータで出たよ。

### LB: [Feb 10, 2020](https://cloud.google.com/load-balancing/docs/release-notes#February_10_2020)
- NEGでGCP外のリソースを扱う機能がベータになったよ！
  - オンプレや他クラウドをバックエンドとしてCDNのバックエンド等に利用することが可能。

### AppEngine: [Feb 11, 2020](https://cloud.google.com/appengine/docs/standard/go/release-notes#february_11_2020)
- URLにリージョンIDを含める機能が新しいものから有効になったよ。
  - 新しいのからリージョン指定が必須に。
  - 前にもアナウンスされてる。

### GKE: [Feb 11, 2020](https://cloud.google.com/kubernetes-engine/docs/release-notes#february_11_2020)
- デフォルトが1.14.10-gke.17に。
- ノードのアップデートスピードと影響を管理できるsurgeアップグレードがGAになったよ。

### BigQuery: [Feb 11, 2020](https://cloud.google.com/bigquery/docs/release-notes#February_11_2020)
- Magnitude Simba ODBCがアップデートされたよ。

### AI Platform: [Feb 10, 2020](https://cloud.google.com/ai-platform/docs/release-notes#February_10_2020)
- 1.15でPython3.7利用時のカスタムルーチンの不具合が修正されたよ。

### AI Platform: [Feb 11, 2020](https://cloud.google.com/ai-platform/docs/release-notes#February_11_2020)
- トレーニングジョブを作成する際に最大実行時間を設定できるようになったよ。
  - 設定した時間を超えたジョブはキャンセルされる。

### Anthos Config Management: [1.2.1](https://cloud.google.com/anthos-config-management/docs/release-notes#121)
- 1.2.1がGAに。

### dataprep: [Feb 12, 2020](https://cloud.google.com/dataprep/docs/release-notes#February_12_2020)
- 機能が色々リリース。以下はサンプル。20個ぐらいあるので、見てみてください。
  - マクロへの対応
  - RapidTargetの高速化
  - プロファイルダウンロード機能追加
  - バージョン違いでもインポートできるようになった

### Compute: [Feb 12, 2020](https://cloud.google.com/compute/docs/release-notes#february122020)
- VM上のパッケージや設定を管理できるOS configuration managementがベータになったよ！

### ディスクレーマ
- アップデートの内容はあくまでも個人の理解していることを書いています。正しい内容はリリースノート等を確認下さい。
- リリース内容できるだけ拾うようにしているのですが、抜けていそうなリリースノートが追加するのでぜひ教えて下さい！(一覧[ここ](https://qiita.com/kenzkenz/items/ac18a359b803dbb6b490)で更新してます。)
【メモ】A5:SQL Mk-2でUnexpected sever response

##【事象】##
a5-mk2でSELECTコマンド実行時、
**『SQL   : Unexpected server response :  』**
というエラーになった。

特定のテーブルというわけではなく、（全部実行はしてないけどたぶん）全てのテーブルについてUnexpected server responseになった。

他のPCのa5-mk2で同じコマンドを打ち込んだら正常にクエリが返ってきた。なのでサーバーの問題ではない。

##【対処】##
・C:\Users\[USERNAME]\AppData\Local\CrashDumps
を削除したら直ったという報告があったけど、CrashDumpsというフォルダはなかった。

・クエリにlimitを付けると解消されました。という報告があったけど、
変化なかった。

・a5-mk2を2回再起動したら直った。何かの偶然だと思うけど謎。

【備考】
a5-mk2のバージョンはともに2.10.1。
a5-mk2は、**フィルタが機能しないバグがある（フィルタだと0件だが、同条件でコマンド打つと1件以上）**ということもあるので、便利なツールだけど、全信用はしない方がいいのかな。

（2014/04/02buildのバージョンを使ってるのもおかしい気がするけど）
外部URLをCALLしているfaradayのrequestのretry機能のRSpecテストの書き方

経緯：
サービス内において、Faradayを利用して外部のAPIをcallしている（salesforceとかそういうとこ）
だがリクエストに対してたまにTimeoutエラー（Faraday::TimeoutError）を返してエラーになる

そこでFaradayにretryオプションを指定して特定のエラーが起きた時のみretryをかけたい。
https://github.com/lostisland/faraday/blob/master/lib/faraday/request/retry.rb
faradayの中を調べるとこう書けとある。

```
    # @example Configure Retry middleware using intervals
    #   Faraday.new do |conn|
    #     conn.request(:retry, max: 2,
    #                          interval: 0.05,
    #                          interval_randomness: 0.5,
    #                          backoff_factor: 2,
    #                          exceptions: [CustomException, 'Timeout::Error'])
    #
    #     conn.adapter(:net_http) # NB: Last middleware must be the adapter
    #   end
```

sampleの通りに書いたらretryできた。

コードを書いたらテストも書かないといけない。
テストを書かないとt_wadaに [こんな感じ](https://www.amazon.co.jp/dp/B07V6VZN85/) で「圧」をかけられる

ちなみにリクエストをテストするにはWebMockのstub_requestがよい
https://github.com/bblimke/webmock

サンプルにある通り

```
stub_request(:post, "www.example.com").
  to_return(body: "abc")
```
こんな感じでテストが書ける。
テストの中でfaradayをMockせずとも外にリクエストを投げずにテストできる。
CIサーバの自動テストでも安心

今回やりたいタイムアウトの表現はこんな感じで書ける。

```
subject { (なんか post している処理) }
request = stub_request(:post, "www.example.com").
  to_timeout.times(2).then. # ２回タイムアウトして
  to_return(body: "abc") # その後正常に値が返る

expect(subject.status).to eq(200) # 正常にリクエストが返ってくる
expect(subject.body).to eq('abc')
expect(request).to have_been_requested.times(3)
```
エラーで終わる場合はこんな感じ

```
request = stub_request(:post, "www.example.com").
  to_timeout.times(3).then. # ３回タイムアウトして
  to_return(body: "abc") # もし次があればその後正常に値が返る

expect { subject }.to raise_error(Faraday::ConnectionFailed)
expect(request).to have_been_requested.times(3)
```

stub_requestはリクエストがパラメータなどの条件を満たさなかったり、３回呼ばれるはずが４回とか呼ばれたりするとエラーになるので安心
ただし回数が足らなくてもエラーにならないので、have_been_requested.times(回数)でチェックする必要がある

なお、実は上記テストは失敗する。
なぜかと言うと、webmockのstub_requestがto_timeoutで返すエラーは
Faraday::ConnectionFailedであり、faradayのretryされるエラーにはデフォルトではFaraday::ConnectionFailedは含まれない。

https://github.com/lostisland/faraday/blob/master/lib/faraday/adapter/net_http.rb#L64-L89
ここを見るとfaradayはtimeoutエラーを
・相手がrequestを受け取れなかったらFaraday::ConnectionFailed
・相手がresponseを返せずTimeout::Error, Errno::ETIMEDOUTになったらFaraday::TimeoutError
と区別している。

そしてfaradayのretryはデフォルトでは [Faraday::ConnectionFailedをretry対象に含まない](https://github.com/lostisland/faraday/blob/master/lib/faraday/request/retry.rb#L26-L29)
対策は二つ。
テストをFaraday::TimeoutErrorに合わせる

```
request = stub_request(:post, "www.example.com").
  to_raise(Faraday::TimeoutError).times(3) # ３回タイムアウトする

expect { subject }.to raise_error(Faraday::TimeoutError)
expect(request).to have_been_requested.times(3)
```

もう一つはfaradayにFaraday::Error::ConnectionFailedでもretryしてくれるよう設定する

```
  Faraday.new do |conn|
    conn.request(:retry, max: 2,
                         interval: 0.05,
                         exceptions: Faraday::Request::Retry::DEFAULT_EXCEPTIONS + [Faraday::Error::ConnectionFailed]
                )
    ...
  end
```

以上終わり
#Mac のコンソールでコマンドの結果をシェル変数に代入する、クリップボードにコピーする、標準出力もする ( #Shell )

```
result=$(some_command) && echo "$result" | pbcopy && pbpaste
```

# 例

```
$ result=$(ls) && echo "$result" | pbcopy && pbpaste
./
../
a.txt
b.txt
```

コンソールで変数を出力


```
$ echo "$result"
./
../
a.txt
b.txt
```

他のエディタ、アプリでペースト

![image](https://user-images.githubusercontent.com/13635059/73899116-f3dc8600-48ce-11ea-97b3-ba6ff10f6fc0.png)


# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2977








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->