OmniAICreator/Qiita-1.07M huggingface dataset:
MacでYarnが実行できるようにする

2020.10.31時点

# やりたいこと
Macでフロントエンド開発ができるようにYarnを実行できるようにしたい。

# 結論
必要最小限のコマンドはこんな感じ。

```
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
brew install nodenv
echo 'eval "$(nodenv init -)"' >> ~/.bash_profile
source ~/.bash_profile
nodenv install 14.15.0
nodenv rehash
nodenv global 14.15.0
brew install yarn --ignore-dependencies
```

# やったこと
下記のアプリをインストールしました。
1. homebrew
2. nodenv
3. Node.js
4. Yarn

# 説明
導入したものの用途とよく使うコマンドはこんな感じです。

## homebrew
https://brew.sh/index_ja
macにApp Storeでは提供していないアプリをインストール、管理するためのツールです。
アプリをおいてあるところをセラー、アプリのことをボトルっていうらしいです。

### よく使うコマンド
```
# アプリ名を検索
brew search アプリ名

# アプリ名をインストール
brew install アプリ名

# アプリ名をバージョンアップ
brew upgrade アプリ名
```

## nodenv
https://github.com/nodenv/nodenv
Node.jsのバージョン管理ツール（nvm： node version manager）です。
Node.js自体のバージョンアップが頻繁＆バージョン違いで動かないパッケージが多いということでツールで管理します。
他にもアプリはありますがnodenvは全体のバージョンと、各プロジェクト（ディレクトリ）ごとのバージョンを別に管理できる点が便利です。

### よく使うコマンド
```
# インストール可能なNode.jsのバージョンを表示
nodenv install --list

# 指定したバージョンをインストール
nodenv install 指定したバージョン

# 新たなバージョンをインストールしたあとのおまじない
nodenv rehash

# 全体で使用するバージョンを指定
nodenv global 指定したバージョン

# コマンドを実行したディレクトリ以下で使用するバージョンを指定
nodenv local 指定したバージョン
```

## Node.js
https://nodejs.org/ja/
javascriptの実行環境といえばいいのでしょうか。
その昔はブラウザーでしか動作しなかったjavascriptを他のアプリと同様にローカル上で実行できるようにしてくれます。
パッケージが豊富で今やフロントエンド開発にとどまらないツールです。

### よく使うコマンド
```
# 後述のYarn経由で使用するため、そのままつかうことはほぼないです
```

## Yarn
https://classic.yarnpkg.com/ja/
Node.jsで実行するパッケージを管理するアプリです。
似たようなものにnpmもありますが、なんとなくこちらを使います。

### よく使うコマンド
```
# パッケージを追加
yarn add パッケージ

# パッケージを開発モードで追加
yarn add -D パッケージ

# パッケージを削除
yarn remove パッケージ

# pacckage.jsonに記載されているパッケージをまとめてインストール
yarn install

# package.jsonに記載されているコマンドを実行
yarn コマンド
```
Laravel学習　ルーティングとコントローラ入門してみた


##はじめに
laravel学習をしていて学んだことをまとめてみました。
認識違いなどありましたらご指摘いただけると幸いです。

#ルーティング
→アクセスしたアドレスを元に処理を割り振ること。
Laravelは各ファイルごとブラウザに表示されるわけではなく、アドレスに割り付けられたプログラムの実行によって表示される？ため。アドレスに対しての処理をそれぞれ関連付ける必要がある。

▼routesフォルダ
ルーティングについて取りまとめているフォルダ。
・web.php※→　一般的なwebページとしてアクセスさせるためのルーティング（関連付け）
・api.php→API機能の割り振りなど
・channels.php→ブロードキャストチャンネルのため？？
・console.php→コンソールプログラムのため？？

##各ファイルの解説（※今回はweb.phpのみ）

▼web.phpとは
・概要
ブラウザにリクエストがあった場合に指定のファイルに誘導させることができる、アクセス処理を司る。

・使い方

```
Route::get('①アドレス', ②処理→function(){
    return ③view('ファイル名');});
//view()とは・・・指定したファイルをレンダリング※１すること
//ここに①がリクエストされた時に②の処理をするよという命令を行える

viewファイルの中身をview関数で呼び出して表示させている
```

#コントローラ
→ルーティングによって実行される処理。アプリケーションの処理を「MVC」の３つの要素の組み合わせとして構築していく。

・Model→DBアクセスの処理全般
・View→画面表示を担当
・Controller→全体の制御を担当。viewやModelがないと機能しない。

Laravelの開発は”Controller”を作成することからはじまる

##welcom.blade.phpの中身
Bladeとは＠ではじまるコード？

▼ルートパラメータの利用

```
・使い方
（例）
『https://OO/hello/sample』にアクセス

Route::get('hello/{設定したいパラメータ名}',function(＄パラメータを取得したい変数){
    ＄パラメータを取得したい変数に’sample’が代入される

・任意パラメータ
Route::get('hello/{○○？}〜
パラメータに”？”をつけることで任意パラメータとなり、パラメータ（url）を付けなくてもブラウザに表示される

```
・ルートパラメータを使うメリット
ここはまだ理解できていません。。

▼コントロ-ラの作成からアクション実行まで
①ターミナルにartisanコマンドにてコントローラを作成

``` 
#ターミナル
$php　artisan make:controlle　コントローラ名（○○Contorollerとつけるのが常識らしい）
```

②アクションの追加

```
#App\Http\Controllers\○○Contoroller.php

class ○○Contoroller extends Controller
{
    public function アクションメソッド {
        return アクション内容　；
    }
}
```

③アクションの実行

```
#web.php
Route::get('hello','App\Http\Controllers\○○Contoroller@アクションメソッド名');
```

▼アクションとアドレスの関係
基本的にはアドレスとコントローラまたはアクションの関連は以下のように対応させるのが一般的

```
http://アプリアドレス/コントローラ/アクション
```

▼シングルアクションコントローラ
１つのコントローラに対して、１つのアクションだけしか用意しないというような設計をすることがある。この場合には「シングルアクションコントローラ」としてクラスを用意する。

```
#○○Controller.php

class コントローラ extends Controller{
public function __invoke(){
アクション処理
}}

//＿invokeメソッドをしようして処理を実装するだけ

#web.php

Route::get('アドレス','コントローラ名'）；
//ルート情報を設定は　アクションの指定はせずコントローラを設定するだけ、
```

・メリット
→__invoke ならこのコントローラーではこれ以外のことはしないと分かりやすい。単一アクションの方が可読性が上がるから？

##不明だった用語
※１レンダリング
→表示用のデータをもとに、内容を整形して表示すること

▼スクリプト
→書いて、すぐ実行できるプログラムのこと





▼ヒアドキュメント
→<<< EOM〜文章〜EOM；の間に書いたHTMLは改行を自動で行ってくれる。長い文章に有効
ファイル単位で表示するか処理単位で表示、処理されるかの違い。そのため処理の関連付けを行うことがルーティング。ファイル数を減らせることがメリット？

▼パラメータ
→URLの後ろにつく「？」以降の文字列
[PHP]スクリプト実行中に途中経過を確認する


PHPスクリプトを実行する際、処理が全て終わった後に結果がページ上に表示されるのが普通ですが、処理が重く時間のかかるページで途中経過を確認したい場合には、flush関数を使い出力バッファをオフにすることにより、リアルタイムで確認することができます。

まずob_end_flush関数を呼び出し、出力のバッファリングをオフにします。
※ブラウザのバッファ対策のため、あらかじめ空白文字列を出力しておきます。

```php
echo str_pad(' ', 4096);
ob_end_flush();
```

次にob_start関数を呼び出し、出力のバッファリングを有効にします。

```php
ob_start('mb_output_handler');
```

以下のようなスクリプトを実行し、1秒ごとに途中経過を出力します。

```php
for ($i = 1; $i <= 10; $i++) {
    ob_flush();
    flush();
    sleep(1);
    echo $i.'秒経過しました';
}
```

あまりにも処理が重いと、ちゃんと動いているのか不安になったりするものですが、処理が終了するまでに途中経過をチェックしたい時に役立ちそうですね。
Numpyの型ヒント備忘録(NDArray)

`Numpy` の型ヒント・型チェックについて、ちょっとハマったので備忘録として残します

今回使っているのは `nptyping` という numpy 用の型付けのためのライブラリです。リポジトリ: [GitHub - ramonhagenaars/nptyping](https://github.com/ramonhagenaars/nptyping)

# ベクトルのとき
下の二つは要素が `int` でなくても `True` となります。**(`Any` は標準ライブラリの `typing` からインポートします)**

```python
vec = np.array([1, 2, 3], int)
isinstance(vec, NDArray[3, int]) # True
isinstance(vec, NDArray[(3,), int]) # True
isinstance(vec, NDArray[(3, ...), int]) # True
isinstance(vec, NDArray[(3,), Any]) # True
isinstance(vec, NDArray[3]) # True
```

# 行列のとき
一番上は $(any)\times3$ 行列。下の二つは `int` じゃなくても `True` になります。**(`Any` は標準ライブラリの `typing` からインポートします)**

```python
mat = np.array([[1, 2, 3], [4, 5, 6]], int)
isinstance(mat, NDArray[(Any, 3), int]) # True
isinstance(mat, NDArray[(2, 3), int]) # True
isinstance(mat, NDArray[2, 3]) # True
isinstance(mat, NDArray[(2, 3), Any]) # True
```
色々なrailsのマイグレーション操作

#この記事で扱うこと

- NOT NULL制約の付いたカラムに制約を追加/削除する方法
- 複数カラムを紐付けたカラムからindexを削除する方法
- reference型で作成した外部キーをつけたカラムを削除する方法

#NOT NULL制約を追加/削除する
##NOT NULL制約を追加したいとき

```
def up
  change_column_null :posts, :content, false
end

def down
  change_column_null :posts, :content, true
end
```
ポイントはchangeメソッドを使用せず、up/downメソッドを使用すること

##NOT NULL制約を削除したいとき

```
def up
  change_column_null :posts, :content, true
end

def down
  change_column_null :posts, :content, false
end
```

#複合キーindexを付けたカラムからindexを削除する

```
def change
  remove_index :likes, column: [:user_id, :post_id], unique: true
end
```
単一カラムからindexを削除する時は以下のように

```
def change
  remove_index :likes, column: :micropost_id, unique: true
end
```

#reference型で作成した外部キーをつけたカラムを削除する方法

```
def change
  remove_reference :posts, :user, null: false, foreign_key: true
end
```
foreign_key: trueで外部キーを設定していたらそれもつけてあげると良いです

#おまけ
あるカラムにindexが付いているか確認する(MySQLにて)

```
mysql > SHOW CREATE TABLE tbl_name
```

#参考

[https://dev.mysql.com/doc/refman/5.6/ja/show-create-table.html](mysql)

[https://railsguides.jp/active_record_migrations.html](references)

[https://qiita.com/akinov/items/852fe789fe98a44350a9](null)
全国の都道府県知事の年齢と当選回数を調べる

[全国知事会](http://www.nga.gr.jp/index.html)の[知事ファイル](http://www.nga.gr.jp/app/chijifile/)から現職の知事をスクレイピング


```python
import datetime
import re

import pandas as pd
import matplotlib.pyplot as plt


def wareki2date(s):

    m = re.search("(昭和|平成|令和)([ 0-9元]{1,2})年( [0-9]{1,2})月([ 0-9]{1,2})日", s)

    if m:

        year, month, day = [1 if i == "元" else int(i.strip()) for i in m.group(2, 3, 4)]

        if m.group(1) == "昭和":
            year += 1925
        elif m.group(1) == "平成":
            year += 1988
        elif m.group(1) == "令和":
            year += 2018

        return pd.Timestamp(year, month, day)

    else:
        return pd.NaT


df = pd.read_html("http://www.nga.gr.jp/app/chijifile/", attrs={"summary": "検索結果一覧"})[0]

# 和暦を西暦に変換
df["生年月日"] = df["生年月日"].apply(wareki2date)
df["選挙施行日"] = df["選挙施行日"].apply(wareki2date)
df["任期満了日"] = df["任期満了日"].apply(wareki2date)
df["就任年月"] = df["就任年月"].apply(wareki2date)

df["年齢"] = df["年齢"].str.rstrip("歳").astype(int)
```

# 年齢

```python
df["年齢"].value_counts(bins=[30,40,45,50,55,60,65,70,75,80]).sort_index().plot.bar()
```
![ages.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36151/7fa868e7-d8f6-ed65-fb28-b190c1febf6e.png)


```python
df["年齢"].describe()
```
count    47.000000
mean     61.680851
std       9.273868
min      39.000000
25%      56.000000
50%      60.000000
75%      69.500000
max      78.000000
Name: 年齢, dtype: float64

# 当選回数

```python
df["当選回数"].describe()
```
count    47.000000
mean      2.765957
std       1.447828
min       1.000000
25%       1.000000
50%       3.000000
75%       4.000000
max       7.000000
Name: 当選回数, dtype: float64

# 全国市長会

[全国市長会](http://www.mayors.or.jp/city_mayorssearch_result.php)の一覧は名前しか載っていない
kubectl topで負荷順にソートする方法

`kubectl top`でメモリやcpuの負荷順に見たい場合の対応方法が[githubのissue](https://github.com/kubernetes/kubernetes/issues/81270)で公開されていたのでここで紹介します.

`--sort-by` オプションが利用可能ですが、バグが含まれていて正常にソートされず、v1.18で[修正](https://github.com/kubernetes/kubernetes/pull/82333)されているようです(未確認).

ということで、v1.18未満の場合は以下のシェルでソートしましょうとのこと

``` shell
# CPUで降順ソートする場合
kubectl top pod | sort --reverse --key 2 --numeric

# メモリで降順ソートする場合
kubectl top pod | sort --reverse --key 3 --numeric
```
---
```
NAME CPU(cores) MEMORY(bytes)
```
この順で出力されるので、 `--key 2`を指定すれば二列目のCPUで、 `--key 3`を指定すれば三列目のMEMORYでソートされるというわけです.
HTML/CSS:レスポンシブ対応した背景画像設定

#【概要】

1. <b>[結論](#1結論)</b>
2. <b>[どのようにコーティングするか](#2どのようにコーティングするか)</b>
3. <b>[注意しないといけないこと](#3注意しないといけないこと)</b>
4. <b>[開発環境](#4開発環境)</b>

#1.結論

<b>`background-size: cover;`</b>を使用する！

#2.どのようにコーティングするか

```html
<header class="header" id="image">
</header>
```

```css
#image {
  background-image: url("../img.png"); /* ---1 */
  background-size: cover; /* ---2 */
  background-repeat: no-repeat; /* ---3 */
}
```

1. `../`で相対パス指定をしています。`./`においてはカレントディレクトリ、`/`から始まるのは絶対パスになり、このファイルのおおもとであるルートディレクトリを示します。
2. `cover`は、縦横比を保ちつつ、背景全体を最小で完全に表示した状態で拡大縮小します。他にも`contain` `auto`があります。
3. `no-repeat`は画像を1枚のみ表示したいのでこのようにしています。

#3.注意しないといけないこと

HTMLのdivタグにおける表示サイズと画像解像度で大きすぎて全体の背景画像が表示されないことがあります。小さすぎてみずぼらしくなるので画像自体の調整が必要です。

#4.開発環境

HTML5
CSS3
文字列から数字だけを取り出す（例３years→3）→DataFrameの要素と置き換える

#はじめに
この記事は数弱体質の体育大学生である私が、知りたかったことや躓いたところを書き留めておく備忘録です:santa_tone5:
間違いがあれば訂正をよろしくお願いします。

環境とか：windows10 python vscode 

#文字列から数字を取り出す
 ```python
import re
re.sub(r"\D","","2years")
```
第一引数で文字列のうちで置換させたい場所を指定
→r"\D"は数字以外の部分を指定

第二引数で何に置換する指定
→今回は消すことが目的のため　""　を書く。

第三引数で対象の文字列を指定


#DataFrameの要素と置き換える

```python
#空のリスト作成
import pandas as pd
k = []
#繰り返し処理でdata['col1']の置換を行いリストに入れる
for i in range(len(data['col1'])):
    j = data.iloc[i]['col1']
    k.append(re.sub(r"\D", "", j))


col1_new = pd.DataFrame({'col1_new':k})
data_new = pd.concat([data,col1_new],axis=1)

#変更前のデータを消去
data_new.drop(['col1'],axis=1)
```

#最後に
不足している情報は私の学習進度に応じて追加していきます。:hotdog:
Lobeで学習したモデルをPythonで利用する方法

Lobeは、マイクロソフトが公開した機械学習のmodelが簡単に構築できるツールです。
下記の記事ではその使い方を説明しました。
[マイクロソフトが公開した機械学習モデルの訓練を容易にできる「Lobe」を試してみた。](https://qiita.com/tkinjo1/items/5cfe561b8765add0b7d0)

本記事では、Lobeで学習したmodelをエクスポートしてPythonから利用するまでの手順を書いていきたいと思います。

## 学習したmodelをエクスポートする

[File]->[Export]を選択します。
![スクリーンショット 2020-10-31 20.30.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19516/bee0c9e8-4acd-51c5-ad7e-735f7e3f63ce.png)

今回はTensorFlowを使用するのでそちらを選択し保存先を指定します。
![スクリーンショット 2020-10-31 20.35.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19516/2ae3f6e8-c044-c16e-8cf1-f1c6f711fbca.png)

Optimize&Optimizingを選択するとmodelを最適化した上で保存することができます。 
![スクリーンショット 2020-10-31 20.39.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19516/ff11479b-3644-df44-ec09-eb1b1cae962a.png)

ここまでの手順で学習したmodelをエクスポートすることができます。

## 学習済みmodelをPythonで利用する
エクスポートしたmodelの保存先にexampleというフォルダがあります。
その中にTensorFlowから利用するためのサンプルコード(tf_example.py)が入っています。

コマンドライン利用する場合:

```
# python example/tf_example.py '画像パス'
```

以下、サンプルコードから最低限必要な箇所だけを記載します。

### 必要なライブラリのimport

```predict.py
import json

import numpy as np
import tensorflow as tf
from PIL import Image
```

### Signatureから出入力情報を読み込む

```predict.py
with open("modelを保存したパス/signature.json", "r") as f:
    signature = json.load(f)

inputs = signature.get('inputs')
outputs = signature.get('outputs')
```


### modelを読み込む

```predict.py
# TensorFlow1系の場合
session = tf.compat.v1.Session(graph=tf.Graph())
tf.compat.v1.saved_model.loader.load(sess=session, tags=signature.get("tags"), export_dir='modelを保存したパス')

# TensorFlow2系の場合
model = tf.saved_model.load('modelを保存したパス')
infer = model.signatures["serving_default"]
```

### 予測する画像を用意する

```predict.py
# inputのサイズを取得
input_width, input_height = inputs["Image"]["shape"][1:3]

# TensorFlow1系の場合
image = Image.open('画像のパス')
image = image.resize((input_width, input_height))
image = np.asarray(image) / 255.0
feed_dict = {inputs["Image"]["name"]: [image]}
fetches = [(key, output["name"]) for key, output in outputs.items()]

# TensorFlow2系の場合
image = Image.open('画像のパス')
image = image.resize((input_width, input_height))
image = np.asarray(image, dtype=np.float32) / 255.0
image = np.expand_dims(image, axis=0)
```

### 予測を実行する

```predict.py
# TensorFlow1系の場合
output = session.run(fetches=[name for _, name in fetches], feed_dict=feed_dict)
print(output[0][0].decode())

# TensorFlow2系の場合
predict = infer(tf.constant(image))['Prediction'][0]
print(predict.numpy().decode())
```

上記のようにLobeで学習したmodelはとても簡単にPythonから利用することができます。

サンプルコードをgitにアップしました。
[lobe_py](https://github.com/tkinjo1985/lobe_py.git)

TensorFlow Servingと組み合わせてREST APIを作ってみました。
[Lobeで学習したモデルとTensorFlow Servingを使ってREST APIを作る。](https://qiita.com/tkinjo1/items/4fd9f0202aa8e3949845)

[FastAPIと組み合わせてREST APIを作ってみました。](https://github.com/tkinjo1985/lobe_fastapi)

Lobeは10/31現在はBeta版となっています。
作成することができるmodelも画像分類のみですが、今後物体検出やデータ分類なども追加されて行くようです。
node.js+ExpressでAPIに呼び出し制限を実装する

node.js＋ExpressでAPI作成するときに回数制限をかけたかったので実装メモ

#redisのインストール

Redisとは永続可能なインメモリデータベースです。
Redis上にアクセス情報を保持してアクセス制限を実施します。

yumでインストール

```
# yum install -y redis
```

バージョン確認

```
# redis-server --version
Redis server v=3.2.12 sha=00000000:0 malloc=jemalloc-3.6.0 bits=64 build=7897e7d0e13773f
```

redisサーバー起動

```
# sudo service redis start
```

#express-limiterの利用

回数制限をするミドルウェアのインストール

```
npm install express-limiter --save
```

```
var express = require('express')
var app = express()
var client = require('redis').createClient()
 
var limiter = require('express-limiter')(app, client)
 
/**
 * you may also pass it an Express 4.0 `Router`
 *
 * router = express.Router()
 * limiter = require('express-limiter')(router, client)
 */
 
limiter({
  path: '/api/action',//リクエストへのルートパス
  method: 'get',//対象のメソッド　get、post、put、delete、all
  lookup: ['connection.remoteAddress'],//制限対象のキー（この場合IPアドレスで制限）
  total: 150,// 150回制限 
  expire: 1000 * 60 * 60, //制限対象の時間(ms)この場合１時間
　onRateLimited: function (req, res, next) {//リミットに到達した場合の処理
    next({ message: 'Rate limit exceeded', status: 429 })
  }
})
 
app.get('/api/action', function (req, res) {
  res.send(200, 'ok')
})
```

path: リクエストへのルートパス
method: httpメソッド。get、post、put、delete、all
lookup: 制限対象になるキー
total: 制限回数
expire: 制限対象の時間（ms）
whitelist: function(req) ホワイトリストの関数
skipHeaders: レート制限のためにHTTPヘッダーの送信をスキップするかどうか
ignoreErrors: redisから生成されたエラーにより、ミドルウェアがnext（）を呼び出すことができるかどうか。デフォルトはfalseです。
onRateLimited: Function リクエストが設定されたレート制限を超えたときに呼び出されます。



その他細かい設定は[こちら](https://www.npmjs.com/package/express-limiter)を参考に
【Java】Mathクラスの使い方

#プログラミング勉強日記
2020年10月31日
数値を扱うMathクラスの主なメソッドとそれぞれの使い方を簡単にまとめる。

#Mathクラスとは
　平方根や指数関数、対数関数などを使用できる数値処理を実行するためのメソッドがまとめられたクラス。Mathクラスはjava.langパッケージにあるので、インポートをする必要がない。
　下記でMathクラスの主要関数の使い方をまとめる。

#absメソッド
　absメソッドは絶対値を求めるメソッド。

```:基本的な書き方
絶対値 = Math.abs(対象の数値);
```
　ここで引数はint型、double型、float型、long型の数値を1つ入れることができる。(戻り値は同じ引数の型)

#maxメソッドとminメソッド
　値の大小を求めるためのメソッドで、数値を比較してより大きい値を求めるときにはmaxメソッドを、より小さい値を求めるときにはminメソッドを使用する。

```:基本的な書き方
大きい値 = Math.max(比較する値, 比較する別の値);
小さい値 = Math.min(比較する値, 比較する別の値);
```
　absメソッドと同様に、引数はint型、double型、float型、long型の数値を1つ入れることができる。(戻り値は同じ引数の型)
　
#ceilメソッド、floorメソッド、roundメソッド
　数値を切り上げるときはceilメソッド、切り下げの時はfloorメソッド、四捨五入するときはroundメソッドを使う。

```:基本的な書き方
切り上げた値 = Math.ceil(対象の数値);
切り下げた値 = Math.floor(対象の数値);
四捨五入した値 = Math.round(対象の数値);
```
　引数の型はdouble型の数値を入れることができ、戻り値もdouble型で返ってくる。

#powメソッド
　powメソッドは値を累乗するためのメソッドである。

```:基本的な書き方
累乗の値 = Math.pow(底, 指数);
```
　ceilメソッド、floorメソッド、roundメソッドと同様に引数の型はdouble型の数値を入れることができ、戻り値もdouble型で返ってくる。


#sqrtメソッドとcbrtメソッド
　aqrtメソッドは平方根を、cbrtメソッドは立方根を求めるためのメソッドである。

```:基本的な書き方
平方根 = Math.sqrt(対象となる数値);
立方根 = Math.cbrt(対象となる数値);
```
　powメソッド同様に、引数の型はdouble型の数値を入れることができ、戻り値もdouble型で返ってくる。


#参考文献
[JavaのMathクラスの使い方について現役エンジニアが解説【初心者向け】](https://techacademy.jp/magazine/34805)
[Mathクラス](https://eng-entrance.com/category/java)
カラム名 BETWEEN 文字列 AND 文字列は機能するのか？

SELECT  * FROM テーブル WHERE カラム名（※26進数の文字列） BETWEEN 文字列 AND 文字列
が機能するかどうか、POSTGREで確認してみました。 

**【結論】**
**・桁数が可変だとBETWEENでの抽出は機能しない。**
**・桁数が固定ならBETWEENでの抽出は機能する。**

**【確認手順】**
テスト用のテーブルを2つ作成し、予め用意しておいた下記の26進数データをCOPYコマンドで格納。

<details><summary>**テーブルA（固定桁数でない場合）**</summary>
1,B
2,C
3,D
4,E
5,F
6,G
7,H
8,I
9,J
10,K
11,L
12,M
13,N
14,O
15,P
16,Q
17,R
18,S
19,T
20,U
21,V
22,W
23,X
24,Y
25,Z
26,BA
27,BB
28,BC
29,BD
30,BE
31,BF
32,BG
33,BH
34,BI
35,BJ
36,BK
37,BL
38,BM
39,BN
40,BO
41,BP
42,BQ
43,BR
44,BS
45,BT
46,BU
47,BV
48,BW
.
.（中略）
.
39976,CHDO
39977,CHDP
39978,CHDQ
39979,CHDR
39980,CHDS
39981,CHDT
39982,CHDU
39983,CHDV
39984,CHDW
39985,CHDX
39986,CHDY
39987,CHDZ
39988,CHEA
39989,CHEB
39990,CHEC
39991,CHED
39992,CHEE
39993,CHEF
39994,CHEG
39995,CHEH
39996,CHEI
39997,CHEJ
39998,CHEK
39999,CHEL
40000,CHEM
</details>

postgres=# select * from tableA where カラム名 = 'BS';
で、BSは44番目です。
BからBSまでの44個を取得しようと、
SELECT COUNT(*) FROM tableA WHERE カラム名 BETWEEN 'B' AND 'BS';
→結果は12656になりました。

<details><summary>**テーブルB（桁数3桁固定の場合）**</summary>
1,AAA
2,AAB
3,AAC
4,AAD
5,AAE
6,AAF
7,AAG
8,AAH
9,AAI
10,AAJ
11,AAK
12,AAL
13,AAM
14,AAN
15,AAO
.
704,BBB
.（中略）
.
17562,ZZL
17563,ZZM
17564,ZZN
17565,ZZO
17566,ZZP
17567,ZZQ
17568,ZZR
17569,ZZS
17570,ZZT
17571,ZZU
17572,ZZV
17573,ZZW
17574,ZZX
17575,ZZY
17576,ZZZ
</details>

postgres=# select * from tableB where カラム名 = 'BBB';  
でBBBは704番目でした。
AAAからBBBまでの704個を取得しようと、
postgres=# select count(*) from tableB where カラム名 between 'AAA' and 'BBB';
→結果は704でした。

**結論として、桁数固定なら26進数での範囲抽出は機能することがわかりました。**

自分の想定と合っていました。

とはいえ、BETWEENに文字列を指定するのはあまり推奨されるものではないと言われているようなので、今後使う機会はないかもしれません。
Dockerの操作方法

# 1. 目的
Dockerを使用することが増えたので、簡単な使い方を備忘録として残す。
[Dockerの使用方法について](https://leico.github.io/TechnicalNote/Docker/basic-container)

# 2. Dockerの基本的なコマンド
この節では、Dockerの簡単なコマンドの使用例について説明する。

```
プロセス中のコンテナを確認する。
$ docker ps -a 

もし使用していないコンテナがあれば削除する。
$ docker rm コンテナのID

ローカルのフォルダをマウントし、コンテナからフォルダ直下を扱えるようにする。
$ docker run -v ローカルフォルダのパス:コンテナのフォルダのパス  -it ubuntu 

コンテナがプロセス中になったか確認する。
$ docker ps

コンテナから離れる。
ショートカット「CTRL+P+Q」
コンテナに戻る。
$ docker attach コンテナID


コンテナを止める。
$ exit
止めたコンテナを再開する。
$ docker restart コンテナID
$ docker attach  コンテナID


イメージの確認
$ docker images

もし使用していないイメージがあれば削除する。
$ docker rmi イメージのID

コンテナをイメージに保存
$ docker commit -m "環境の説明とかを書きます" コンテナID イメージ名
```

## 2.1 jupyter/datascience-notebookの動作方法

```
$ docker run -it -v /mnt/c/Users/yoshi/Desktop/yhdk:/home/jovyan/work --name datascience jupyter/datascience-notebook /bin/bash

```


## 2.2 tensorflow/tensorflowの動作方法
[googleのチュートリアル](https://www.tensorflow.org/install/docker?hl=ja#gpu_support)

```
Pytorch環境のコンテナを利用する場合
$ docker run -it --gpus all -v ~/unko:/workspace --name unko_torch pytorch-lab

Tensorflow環境のコンテナを利用する場合
$ docker run -it --gpus all -v ~/unko:/home tensorflow/tensorflow:latest-gpu

Nvidiaの確認
$ nvcc --version | grep "release" | awk '{print $6}' | cut -c2-
$ nvidia-smi

GPU が利用できるかどうかを確認します。
$ lspci | grep -i nvidia

nvidia-docker がインストールされたことを確認します。
$ docker run --gpus all --rm nvidia/cuda nvidia-smi

tesnsorflowがGPUを認識しているかの確認
$ python
$ from tensorflow.python.client import device_lib
$ device_lib.list_local_devices()
```

## 2.3 WSL2でのVisual Studio Codeでの開発

- [WSL](https://docs.docker.com/docker-for-windows/wsl/#develop-with-docker-and-wsl-2)

Visual Studio Codeでリモートで作業する。これを行うには、ターミナルを開いて下記のように入力する。画面の下隅にチェックできるデフォルトのLinuxディストリビューションにリモートで接続された新しく開いたVisual Studio Code上で開発する。

```
$ wsl
$ code .
```

### 2.4 Jupyter notebook


```
基本的な操作
$ docker run -p 8888:8888 jupyter/datascience-notebook

ファイルをマウントするときの操作
$ docker run -v /mnt/c/Users/yoshi/OneDrive/デスクトップ/yhdk:/home/jovyan/work -p 8888:8888 jupyter/datascience-notebook 
```
PowerShellのプロンプトが長い

Windows を常用していると、PowerShell のプロンプトが長くて（カレントディレクトリが深くて）見づらくなってしまうことがありますね。
よく訓練されたWindowsユーザーは、息を吐くように以下のコマンドを実行します。

```powershell
function prompt { "PS> " }
```

もっと凝ったこともできますが、そういうのは `$profile` に入れておきましょう。
これは他人のPCを触ることが多い人やWindowsサーバの管理者のための方法です。

ちなみにコマンドプロンプトでは以下のようにします。

```cmd
prompt $G
```
そろばんの読み上げ算を出題するバッチファイル

そろばんの読み上げ算（暗算）を出題するバッチファイル。
表示するだけじゃなく、ちゃんと しゃべる。
とりあえず、加算 １桁 ５口の出題。
桁数を上げたり、演算種類を増やせば難易度が上がる。
小学生の計算の勉強に、または大人の頭の体操に。
眠れないときの睡眠導入にも役立つかも。

以下のファイルをダブルクリックで実行。
文字化けするときは UTF-8 じゃなく Shift-JIS (ANSI) で保存。
(Windows10, Window7 等)
(アプリ アプリケーション ソフトウェア プログラム 無料 フリーウェア)

soroban.bat

```dosbatch

@echo off

call :_sp2 "加算 １桁 ５口 の 読み上げ 算です。"
call :_sp2 "願いましては、"

set /a total=0
> nul timeout 2

setlocal enabledelayedexpansion
rem １～４口め
for /L %%i in (1,1,4) do (
  set /a aa=!random! %% 9 + 1 
  set /a total+=aa
  call :_sp1 "!aa!円なり、"
)
rem ５口め
set /a aa=%random% %% 9 + 1 
set /a total+=aa
call :_sp1 "%aa%円では？"

> nul timeout 5
call :_sp2 "その答えは、"
call :_sp1 "%total%円です。"
> nul timeout 5

goto :eof


遅く しゃべる
:_sp1
echo %~1
PowerShell "Add-Type -AssemblyName System.Speech; $h = (New-Object System.Speech.Synthesis.SpeechSynthesizer); $h.SelectVoice('Microsoft Haruka Desktop'); $h.rate = -3; $h.Speak('%~1');"
goto :eof


普通に しゃべる
:_sp2
echo %~1
PowerShell "Add-Type -AssemblyName System.Speech; $h = (New-Object System.Speech.Synthesis.SpeechSynthesizer); $h.SelectVoice('Microsoft Haruka Desktop'); $h.rate = 0; $h.Speak('%~1');"
goto :eof

```

実行結果

```
加算 １桁 ５口 の 読み上げ 算です。
願いましては、
4円なり、
1円なり、
4円なり、
8円なり、
1円では？
その答えは、
18円です。
```

眠る前などで１００問出し、そのあと自動シャットダウンするバッチファイル。
soroban100mon.bat

```dosbatch
for /L %%i in (1,1,100) do .\soroban.bat
shutdown.exe -s -f -t 0
```

しゃべらない？　なら、
マイクロソフトスピーチプラットフォームをインストールしてますか？

マイクロソフトスピーチプラットフォーム

http://www.microsoft.com/en-us/download/details.aspx?id=27225

　x86_SpeechPlatformRuntime￥SpeechPlatformRuntime.msi
　　または
　x64_SpeechPlatformRuntime￥SpeechPlatformRuntime.msi

日本語を追加

http://www.microsoft.com/en-us/download/details.aspx?id=27224

　MSSpeech_SR_ja-JP_TELE.msi
　MSSpeech_TTS_ja-JP_Haruka.msi
YouTubeAPIを使ってあるチャンネルの動画情報を新しい順に取得


#作ったもの
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737206/07600d32-9b6b-8553-5c21-f7dc17ebb916.png)
ばっちり新しい順に動画リストを取得できました。
すみません、個人の趣味が入ってしまうので何を取ったかは塗らせていただいています。
限定公開のものではないのでたぶん大丈夫ｗ

#何故やるのか
　今回お試しで趣味のチャンネルで情報を取れるかをやってみましたが、
　実は業務に生かそうとしています。
　動画のアップロード情報をメールで受け取って、YouTubeの別のお仕事に使っていました。
　しかし、**8月あたりに仕様変更**でメールが送られなくなったので、
　自動で何とか情報を取得できないかと考えていてちょうどよい機会になりました。

　アウトプット先が何で平文のメッセージになっているのかというと、
　ただ単に**きれいに送る方法がわからなかった**からです！
　業務では自分のTeamsに綺麗に送れるようにしたいところです。


#気を付けるところ
　事前にYouTube Data APIの有効化が必要！
　⇒GASで使用してよいという「有効化」と、YouTubeAPIを使う時の認証をする必要がある。

　YouTube Data　APIには取得件数には制限がある。

#今後直していきたいポイント
　１．取得件数の変更　上限がありますがもう少し数を増やします。
　２．ページ数の制御　数を増やした時に次ページへのトークンの設定などうまくやりたいです。
　３．アウトプット先を変える　スプレッドシートにする。
　４．３を踏まえてスプレッドシートに更新がかかったら、**お知らせ**するようにする。
　５．お知らせを綺麗なメッセージにする。
　６．**アップロードされた分だけ**取得するようにする。

#環境
Google Apps Script
YouTube Data API v3

#ソース

```javascript
function getYouTubeMovies() {
  // 処理を送り先Webhook URL
  const URL = 'webhookURL';

  // YouTubeの動画リストを取得
  var y_res = YouTube.Search.list('id,snippet', {
    maxResults: 5, 
    channelId: 'チャンネルID',
    order: "date",  // 取得順序は、最新動画順にしてある
    type: "video"
  })   
  console.log(y_res);
  // 動画の情報が欲しかったので動画リストだけ保存
  var movie_list = y_res.items;
  
  // レスポンスのJSONを分解してテキストに突っ込む。たぶんスプレッドシートに記入するならそのままかける。
  let text = "";
  for(var i = 0; i < movie_list.length; i++){
    var title = movie_list[i].snippet.title;
    var p_time = movie_list[i].snippet.publishTime;
    var video_id = movie_list[i].id.videoId;
    text = text + "title:" + title +  ",uldate:" + p_time +  ",url:https://www.youtube.com/watch?v=" + video_id + "; ";
    
  }
  // POSTする中身
  const teamsPayload = {
    'title': 'YouTube最新動画5個',
    'text': text,
  };
  
  // UrlFetchAppのオプション
  const params = {
    'method': 'POST',
    'contentType': 'application/json',
    'payload' : JSON.stringify(teamsPayload),
  };
  console.log(params)
  // HTTPリクエスト送信
  const res = UrlFetchApp.fetch(URL, params);
}
OwlgardenRPA - 遊んでみる5

# 遊んでみる その5

1. 入力ボックスから割る数、割られる数を設定
2. 除算結果をメッセージボックスで表示
3. ゼロ除算が発生した場合、エラー処理

## 共通変数定義（メイン）
| 変数名 | データ型 | 備考 |
|:-:|:-:|:-:|
| num_1 | 文字列型 | 割られる数 | 
| num_2 | 文字列型 | 割る数 | 

## シナリオの流れ（メイン）

### 1. 登録用のデータテ－ブルを構築

- COM名：入力ボックス
    - ボタンやリストを使って入力を制限しているが、省略
    - 関数が使えず、一度文字列型の変数に格納しなければいけない模様

| プロパティ名 | 設定値 |
|:-:|:-:|
| メッセージ | "割られる数を入力" |
| 入力文字 | num_1 |

- COM名：入力ボックス
    - 同上

| プロパティ名 | 設定値 |
|:-:|:-:|
| メッセージ | "割る数を入力" |
| 入力文字 | num_2 |

- COM名：サブシナリオ

| プロパティ名 | 設定値 |
|:-:|:-:|
| サブシナリオ | （以下のサブシナリオを指定） |

- 値の引き渡し
    - サブシナリオの変数は小数型だが、decimalValue関数で渡せる模様

| サブシナリオの変数 | 値の引き渡し |
|:-:|:-:|:-:|
| num_1 | num_1.decimalValue() |
| num_2 | num_2.decimalValue() |


## 共通変数定義（サブ）
| 変数名 | データ型 | 備考 |
|:-:|:-:|:-:|
| num_1 | 小数型 | 割られる数 | 
| num_2 | 小数型 | 割る数 | 
| result | 小数型 | 除算結果 | 

![pic_09.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/340394/dabff0e6-ee6e-439d-ba77-69fdb9c5d39d.jpeg)


## シナリオの流れ（サブ）

### 2. 除算結果をメッセージボックスで表示

- COM名：例外処理

| プロパティ名 | 設定値 |
|:-:|:-:|
| 例外処理 | A20005008:演算処理 - ゼロ除算 |

- COM名：変数値の置き換え（正常系に配置）

| プロパティ名 | 設定値 |
|:-:|:-:|
| 置き換え対象変数 | result |
| 置き換え値 | (num_1 / num_2) |

- COM名：メッセージボックス（正常系に配置）

| プロパティ名 | 設定値 |
|:-:|:-:|
| メッセージ | "答えは " + result.toString() + " です。" |


### 3. ゼロ除算が発生した場合、エラー処理

- COM名：メッセージボックス（異常系に配置）

| プロパティ名 | 設定値 |
|:-:|:-:|
| メッセージ | "割る数に0を指定しないでください。" |

![pic_10.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/340394/fbb7424c-44f6-990d-18ea-3c78b9ec8266.jpeg)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/340394/34e658ed-6f40-14ef-ac36-be7808185c3f.png)

## 雑感
- （整数型変数÷整数型変数）の除算結果を、小数型変数に格納することができない。
    - データ型を一致させなければいけない、小数に変換する関数も見当たらない？
        - 整数÷整数 → 整数型の変数に格納
        - 小数÷小数 → 小数型の変数に格納
- 除算結果が無限小数になる場合、エラーが発生する。
    - trunc関数を使って桁数を切り落としても回避不可？
- サブシナリオの呼び出し、例外処理は分かりやすく作られている印象がある。
    - 例外処理は、U○PathのTry-Catchよりとっつきやすい印象がある。
    - 但し、Finallyがないなどやれることはもちろん限られる。
初回のuseEffectの処理を抑制する方法

普段useEffect()を使っていて、「初回だけ処理を走らせたくない」みたいなケースが結構あると思います。
今回はそれを抑制する方法と、custom Hookの作り方を紹介します。

### コード
具体的な方法としては、**useRefで指定した値が初回レンダリングが終わるまではcurrentに入らない**ことを利用して実現します。

```react
import React, {useState, useRef, useEffect} from 'react';

export default function App() {
  const [click, setClick] = useState(false);
  const [clicked, setClicked] = useState(false);

  const initialRender = useRef(true);
  
  useEffect(() => {
    if(initialRender.current) {
      initialRender.current = false;
    }else {
      setClicked(true);
    }
  }, [click]);

  return (
    <div>
      {clicked && <div>Button has clicked!</div>}
      <button onClick={() => setClick(true)}>
        Click
      </button>
    </div>
  )
}
```
上記のように書くことで、初回レンダリングが終わった直後にはinitialRender.currentにはtrueが入るため依存配列が変化すれば任意の副作用を走らせることができます。

### Custom Hook
上記の処理を都度書くのは煩わしいので、Custom Hook化して使いまわせるようにしてしまいましょう。

```react
import {useEffect, EffectCallback, DependencyList, useRef} from 'react';

export const useNonInitialEffect = (effect: EffectCallback, deps?: DependencyList) => {
  const initialRender = useRef(true);

  useEffect(() => {
    let effectReturns: void | (() => void | undefined) = () => {};

    if(initialRender.current) {
      initialRender.current = false;
    }else {
      effectReturns = effect();
    }

    if(effectReturns && typeof effectReturns == 'function') {
      return effectReturns;
    }
  }, deps);
};
```
通常のuseEffectを使うのと同様の感覚で、上記Custom Hookを用いれば初回レンダリング時の処理を抑制しつつ副作用を持たせることができます。
getallheaders()関数がnginx で使えない件について

#追記
本記事について@tadsanさんからアドバイスをいただきました


>現在おそらくいちばんよく使われてるのはralouphie/getallheadersで、guzzle/psr7もこれに依存していて、 Content-Length や Content-Type についてのワークアラウンドが入っています。
Nyholm/psr7-server/ServerRequestCreator.phpはすこし実装が異なっていますが、PHP: PHP による HTTP 認証を使わなければ特に問題は起こらないでしょう。 (2020年現在ではあえて使われることは少ないと思います)

どうやらライブラリで解決できるそうですね、、、





オレオレフレームワーク自作している時に詰まったので残しときます

エラーで未定義の関数と指摘されたのでggった所自前で用意する必要がありそう

```php:php
<?php
  if (!function_exists('getallheaders')) {
    function getallheaders() {
      $headers = array();

      foreach ($_SERVER as $name => $value) {
        if (substr($name, 0, 5) == 'HTTP_') {
          $headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value;
        }
      }

      return $headers;
    }
  }
  
  // ヘッダー情報を出力
  print_r(getallheaders());
?>
```

無事出力はできたんですけどこれだと工数食うわ当初の目的とずれるのでApacheサーバに変えときます、、、

#引用先
https://gist.github.com/ryonakae/9f5e99c92ac9986791166438aa14cc53
CDNについて

# 概要
AWSの勉強をしている中で、CDNについて調べる機会があったので基本的な部分だけまとめてみます。

# CDNとは
- Content Delivery Network の略。
- 「Content」電子的媒体の情報、デジタルデータのこと。
- 「Delivery」配達すること。ここではコンテンツを配信、配達すること。　
- 「Network」ネットワーク。ここでは仮想ネットワークのことを示す。
    - 配信を行う為のサーバーを結んだ仮想ネットワーク。

# CDNを使用すると何が嬉しいのか
- ファイルを高速で配信できる。(国際配信の場合)
- 安定したファイルの配信が継続できる。
- 配信コストが削減できる

# CDNの仕組み
- ざっくり言うとCDNは三つの要素によって構成される。
    - オリジンサーバー
    - CDNサーバー
    - DNS

## オリジンサーバー
- 元となるサーバーのこと。
- ユーザーとは直接繋がることはない。

## CDNサーバー
- CDNサーバーの構成方法は二通り存在する。
    - キャッシュサーバー
    - ミラーサーバー
- CDNサーバーは複数台配置される。

### キャッシュサーバー
- こちらが主流。
- オリジンサーバーとユーザーの間に配置され（論理的）、ユーザーからのリクエストを受け付ける。
- ユーザーからリクエストされたコンテンツをオリジンサーバーから取得する。
- コンテンツをユーザーにレスポンスとして渡す。
- サーバーの内部ストレージにコンテンツをキャッシュ(保存)する。
    - 一度キャッシュしたコンテンツがリクエストされた場合は、キャッシュサーバーから配信する。
    - コンテンツの更新に対応するためにキャッシュの生存時間(TTL)の設定をする必要がある。
    - キャッシュを削除するとなった場合、全てのキャッシュサーバーから削除するのには時間がかかる。

### ミラーサーバー
- オリジンサーバーとユーザーの間に配置され（論理的）、ユーザーからのリクエストを受け付ける。
- オリジンサーバーと常に同期を取り、あらかじめすべてのファイルをコピーしておく。
    - オリジンサーバーに更新が有っても、常に同期を取っているので最新ファイルが配信可能。
    - オリジンサーバーに更新が多いとオリジンサーバーとCDNサーバーの通信量がどうしても増える。
- ユーザーからのアクセスがあれば、オリジンサーバーにアクセスすることなくコンテンツを配信する。

## DNS
- DNSの設定をすることで、CDNの仕組みが実現している。
- DNSのCNAMEレコードを利用することで、オリジンサーバーのURLへのアクセスをキャッシュサーバーに向ける。
    - リダイレクトとは異なる

## 所感
CDNは思っていたよりもかなり複雑。
git clone 方法

##手順
###1. GitHubでリポジトリのメインページにアクセス
###2. Codeボタンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689109/163ea8d9-f67a-fdb8-c7ed-42afc81d9446.png)
###3. URLをコピー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689109/4a766041-f432-b4e3-0996-59457383e572.png)
###4. ターミナルを開く
###5. カレントワーキングディレクトリをディレクトリをクローンしたい場所に変更
###6. git clone と入力して前の手順でコピーしたURLを貼り付ける
例）

```
$ git clone https://github.com/YOUR-USERNAME/YOUR-REPOSITORY
```

###7. Enterを押してローカルクローンを作成
例）

```
$ git clone https://github.com/YOUR-USERNAME/YOUR-REPOSITORY
> Cloning into `Spoon-Knife`...
> remote: Counting objects: 10, done.
> remote: Compressing objects: 100% (8/8), done.
> remove: Total 10 (delta 1), reused 10 (delta 1)
> Unpacking objects: 100% (10/10), done.
```

##参考記事
https://docs.github.com/ja/free-pro-team@latest/github/creating-cloning-and-archiving-repositories/cloning-a-repository
産業用ネットワークについて調べたことをまとめてみた。少しEthercatも

#概要
以下について調べたので自分なりにまとめてみた。
・産業用ネットワーク
 -独自ネットワーク
 -オープンネットワーク

・オープンネットワークのひとつEhtercatの特徴

#産業用ネットワーク
産業用ネットワークとは工場で稼働する機器同士を通信する技術である。フィールドバスという言われ方もしてきた。
産業用ネットワークには、ベンダ(製造元)が独自に決めた通信プロトコルの独自ネットワークとプロトコルが標準化さらたオープンネットワークがある

#独自ネットワークとオープンネットワーク
独自ネットワークとオープンネットワークそれぞれの特徴について述べる
独自ネットワーク：
ベンダの製品とセットとなるネットワークなので他の製品と差別化でき特殊仕様が要求される分野で活躍できる。その反面汎用性はない。

オープンネットワーク：
独自ネットワークに比べて特殊仕様にはできないが、通信プロトコルが共通なのでユーザは複数のベンダが開発した機器から最適な機器を選択できる。もしくは組み合わせることができる。またベンダ側も通信インターフェイスの開発はしないで済むためアプリケーション側の開発に集中できる。

#オープンネットワークの一つEthercatとは
私たちが普段お世話になっている、Lanケーブルを使った通信はEthernet通信と呼ぶが、このEthernetを産業用特化に考えられたのがEthercat通信である。
その特徴は2つ
1：高速通信   Mbps~Gbps
2：高精度同期 100ns以下

産業界、特にディスクリート産業(車の組み立てとか)ではこの2つが求められている。
工場現場でアームロボットを使用する場合を考える。アームロボットの各関節に組み込まれているサーボモータはMaster(アームロボットに指令を与えるコントローラ)からの指令を受け取り、その指令通りに駆動する。理想系はMasterが指令を送った同タイミングで各サーボモータが駆動してくれること。しかし実際は通信データフレームの遅れやジッタ(データが到着する時間のばらつき)が存在するため、各サーボモータがの動き出しには多少のずれが生じる。そのずれが大きいと、ロボット手先の軌道が本来の軌道から外れてしまう可能性がある。そのため、このずれを極力すくなくするために上2つが求められる。高速通信、高精度同期が実現できる通信がEthercat通信である。

#参考
産業用ネットワークの教科書
いまさら聞けない EtherCAT 入門
Open xINT CTF 2020: Easy-Onion Write-up

[Open xINT CTF 2020](http://xintctf.wpblog.jp/)のEasy-OnionのWrite-upです．

# 問題
Tor上のあるサイトが動いているサーバーのIPアドレスを割り出す．

# 考察
まずこのサイト上では，GlobaLeaksのBIANCO(?)という告発用のWebアプリケーションが動作していました．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183667/81ce347f-ffc8-dd61-47ff-3786bee499fe.png)
このアプリケーションはソースコードを見ると，SPAとして作成されていることがわかります．

見つけ出すのはIPアドレスなので，基本的に，本来TorからしかアクセスできないものがサーバーのグローバルIPに直接アクセスすると閲覧できるというのを考えました．そういった場合，Censysなどのクローラーが記録している可能性が高いです．

そこでまずは単純にCensysで"Globaleaks"で調べてみます（ソースに含まれる文字列）と，360件ほどが出てきます．この中のページを見ていると，関係ないものも多く含まれているようでした．

ですので，次にレスポンスのSHA256ハッシュで検索します（Censysではレスポンスのハッシュも検索可能）．

[80.http.get.body_sha256:d2183ff2a4f998f492ba26e37a4fe9f8505ff1fbef1aec50223c108a3d835724](https://censys.io/ipv4?q=80.http.get.body_sha256%3Ad2183ff2a4f998f492ba26e37a4fe9f8505ff1fbef1aec50223c108a3d835724)

これでも件数が結構あります．全部帰ってくる内容が同じなので，まだIPアドレスは特定できなさそうです．
とはいえこれ以上の手掛かりは思いつかないので，とりあえず出てきたIPアドレスにアクセスしてみます．
これをいろいろとやっているうちに面白い挙動がありました．Torを経由すると，.onionへリダイレクトがされるようになっています．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183667/2b82f37a-d427-7af3-0c53-1a9e636f4f49.png)
なので，出てきたIPアドレスにすべてTor経由でアクセスしてみて，ターゲットの.onionにリダイレクトしてくるサイトがあれば発見成功です．

# 感想
リダイレクトの挙動に気が付くのに時間がかかってしまった．
EOFError: EOF when reading a line は標準入力の値がセットされていない


このサイトで解決しました
<a href="https://teratail.com/questions/94621?sip=n0070000_019"> 
【terateil】書いたコードの間違いがわからなくて困ってます
</a>

自分がミスったもの

```lesson.py
while True:
    line = input()
    if line == "_":
        break
    team.append(line.split(","))

```

line=input()
の時点で詰まっているというクソ。

```
EOFError: EOF when reading a line
````

というエラーが出てしまいました。

そもそも、標準入力で"値を取り出す"のに、値をセットし忘れるという初歩的なミスです。
このエラーが出てしまった時は、標準入力をセットし直しましょう。
公式サイト以外からpip installしてSSLError(SSL認証エラー)が出たときの解決法

```pip install```でパッケージを入れる時SSL認証エラーが出ることが多々あるかと思います。

```
WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1091)'))': /v1/nc_2520839e1f9641b08211a5c85243124a/sudachi/SudachiDict_core-20190718.tar.gz
  WARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1091)'))': /v1/nc_2520839e1f9641b08211a5c85243124a/sudachi/SudachiDict_core-20190718.tar.gz
  WARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1091)'))': /v1/nc_2520839e1f9641b08211a5c85243124a/sudachi/SudachiDict_core-20190718.tar.gz
  WARNING: Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1091)'))': /v1/nc_2520839e1f9641b08211a5c85243124a/sudachi/SudachiDict_core-20190718.tar.gz
  WARNING: Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1091)'))': /v1/nc_2520839e1f9641b08211a5c85243124a/sudachi/SudachiDict_core-20190718.tar.gz
ERROR: Could not install packages due to an EnvironmentError: HTTPSConnectionPool(host='object-storage.tyo2.conoha.io', port=443): Max retries exceeded with url: /v1/nc_2520839e1f9641b08211a5c85243124a/sudachi/SudachiDict_core-20190718.tar.gz (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1091)')))
```
こんな感じ。

公式からダウンロードする場合はpipyの公式サイトのドメインを```--trusted-host <ドメイン名>```オプションで強制的に信用してしまえば解決できます。

具体的には・・・、

```
pip install --trusted-host pypi.org --trusted-host pypi.python.org --trusted-host files.pythonhosted.org <パッケージ名>
```

#公式以外のサイトからパッケージをダウンロードする場合はこれだけじゃダメ

でも、公式以外のサイトからインストールする場合はこれだけではうまくいかないことがあります（だって、そのサイトのドメインはpipyのドメインとは関係ないから）。

例えばこう、

```
pip install https://object-storage.tyo2.conoha.io/v1/nc_2520839e1f9641b08211a5c85243124a/sudachi/SudachiDict_core-20190718.tar.gz
```

当たり前ですけど、このパッケージをインストールする場合は、パッケージを保存場所を表すURLのドメインを```--trusted-host```オプションで信用してもらう必要がありますね。

上の例の場合なら、```--trusted-host object-storage.tyo2.conoha.io```ってぐあいです。

すごい簡単な話でしたが、だいぶ自分ははまったので同じ目にあった人は試してみてください。


それでは。
transformの使い方

#CSS

![スクリーンショット 2020-10-31 19.34.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/633943/e4411827-89e5-1847-1fa3-0e852a6c1a5c.png)

transform: translate(○,○);で画像などを移動できます。

```css
.hover-action:hover {
  -webkit-transform: translate(0, -4px);
  transform: translate(0, -4px);
}
```
OwlgardenRPA - 遊んでみる4

# 遊んでみる その4

1. Excelのデータ取得
2. デモサイトの登録ページへ移動
3. 取得済みのデータを使って全件登録

## 共通変数定義
| 変数名 | データ型 | 初期値 |
|:-:|:-:|:-:|
| table_data | テーブル型 | - |
| count | 整数型 | 1 |

## シナリオの流れ

### 1. Excelのデータ取得

- COM名：Excel接続
    - UiPathにおけるExcelアプリケーションスコープのようなもの
    - あらかじめデモサイトからDLLしたExcelファイルを使用

| プロパティ名 | 設定値 |
|:-:|:-:|
| 対象Excelファイル | （ファイルのパスを設定） |

- COM名：Excel範囲取得
    - 接続済みのExcelを選択して使用するという見せ方が分かりやすい
    - テーブル項目設定プロパティを使用して、対象のExcelからテーブル構造を構築（おもしろい）

| プロパティ名 | 設定値 |
|:-:|:-:|
| 接続先Excel | 上記のCOMで設定したExcel |
| シート名 | "Sheet1" |
| セル番号 | "A2:D4" |
| テーブル項目設定 | （※以下参照） |
| 取得セル情報 | table_data |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/340394/d115e6bd-b4f7-96e1-5107-04916f404ff7.png)

### 2. デモサイトの登録ページへ移動

- COM名：アプリケーション実行
    - U○Pathのデモサイトを使わせてもらおう…

| プロパティ名 | 設定値 |
|:-:|:-:|
| 実行パス | （chromeの実行パスを設定） |
| 実行引数 | "--new-window https://www.expense-demo.com/" |

- COM名：クリック
    - 経費登録ボタンを押下


### 3. 取得済みのデータを使って全件登録

- COM名：繰り返し
    - 以下、すべてのCOMを繰り返しの内部に配置
    - 繰り返し回数指定、条件指定、拡張For文タイプを使用可能（使いやすい）
    - 今回は回数指定にしてみたが、このシナリオの処理はどの方法でも指定可能

| プロパティ名 | 設定値 |
|:-:|:-:|
| 繰り返し方法 | 指定回数 |
| 繰り返し回数 | table_data.getRecordCount() |

- COM名：クリック
    - 明細登録ボタンを押下


- COM名：文字貼り付け

| プロパティ名 | 設定値 |
|:-:|:-:|
| 入力文字 | table_data.rows(count).column("タイトル") |

- COM名：リストボックス選択

| プロパティ名 | 設定値 |
|:-:|:-:|
| 入力文字 | table_data.rows(count).column("種別") |

- COM名：文字貼り付け

| プロパティ名 | 設定値 |
|:-:|:-:|
| 入力文字 | table_data.rows(count).column("金額") |

- COM名：文字貼り付け

| プロパティ名 | 設定値 |
|:-:|:-:|
| 入力文字 | table_data.rows(count).column("備考") |

- COM名：クリック
    - 登録ボタンを押下

- COM名：クリック
    - 戻るボタンを押下

- COM名：変数置き換え

| プロパティ名 | 設定値 |
|:-:|:-:|
| 置き換え対象変数 | count |
| 置き換え値 | count+1 |

![pic_08.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/340394/8b89ec8e-0b83-2ff4-a08d-b8107d378544.jpeg)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/340394/27da15d9-07c6-d59f-4b6c-063f6d3736dd.png)
viの使い方を覚え始めた

## はじめに
今まではWindows関連の仕事が多かったので、viを使う機会は殆どありませんでした。そのため、最低限のコマンドだけしか覚えずに、10年以上過ごしてきました。
最近になってLinuxサーバの構築の機会が増えたので、ようやくviのコマンドを覚え始めました。

## 最低限覚えていたコマンド
Windowsの場合、viでなければダメな場面はほとんどなかったので、viを覚えるメリットがありませんでした。それでも、ESC, i, :wq, :!q この４つのコマンドだけは忘れないようにしてました。これだけ覚えていれば、滅多に無いviしか使えないときでも、編集と保存ができるので何とか凌ぐことができました。

|操作  |結果 |
|---|---|
|ECS  |入力モード -> コマンドモード   |
|i  |カーソルの位置に文字を入力  |
|:wq  |保存して終了  |
|:!q  |保存してせず終了  |

## 最近覚え出したコマンド
#### １行の編集
httpd.confなどの設定ファイルは１行単位で記述されていることが多いので、まずこれらのコマンドを覚えました。削除の方がよく使います。

|操作  |結果 |
|---|---|
|yy  |１行のコピー   |
|p  |ペースト  |
|dd  |1行の削除  |

#### 検索
設定ファイルに間違いがないときは使うことはなかったのです。でも、サーバが思ったとおり動かず、原因を調べるために設定ファイルを検索したくなることが増えたので、使い出しました。

|操作  |結果 |
|---|---|
|/キーワード  |キーワードを検索  |
|n  |次の検索  |

#### 最終行へ移動
ログファイルを確認するときに、最終行へ移動して確認するときに使いました。

|操作  |結果 |
|---|---|
|G  |最終行への移動  |

## おわりに
今後も使う場面に応じて、少しずつ覚えていきます。
RDS Snapshotと既存コードからElastic Beanstalk環境を複製

## 目標
最近ステージング環境が壊れたのですが、DBは残っているのでスナップショットから復元して新たなElastic Beanstalkの環境を作成しようと思います。

## 手順

Applicationを選んで、そこから新たなEnvironmentを作成します。Consoleから作成したほうがいいと思います。コマンドラインだとスナップショットからの復元などはできなかった気がする。

![Screen Shot 2020-10-31 at 15.56.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396623/3daa7a0e-90eb-9333-7385-1064d12d578d.png)

Web Server Environmentを選びます。

![Screen Shot 2020-10-31 at 15.56.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396623/5e831f7c-4d5c-5425-6007-9e76244a9dff.png)

Staging用の環境を作成します。

![Screen Shot 2020-10-31 at 15.28.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396623/e2d54787-fbd4-fde0-83fd-9b2fe91fa555.png)

コードもすでにDjangoで用意してあるので、Existing Versionから作成します。
そして、Create Environmentではなく、Configure more optionsを選びます。

![Screen Shot 2020-10-31 at 15.28.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396623/a6567711-235d-3387-7fc4-cd34ea8a41f3.png)

Databaseの下のeditを押します。

![Screen Shot 2020-10-31 at 15.32.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396623/6f31bb4c-25ca-917d-10d9-e89ab6e9d8f6.png)

ここでSnapshotから復元するようにします。今回はup-envのsnapshotを選びました。Snapshotの作成方法はまた別の記事で説明したいと思います。

![Screen Shot 2020-10-31 at 16.03.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396623/005b95d9-98c4-a197-a6a8-38006a356154.png)

SecurityもeditしてSSHのためのkeypairも覚えさせておきます。

![Screen Shot 2020-10-31 at 15.34.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396623/8c9f7f22-f93a-a059-6a1b-d457cf4b7564.png)

これでcreate environmentします。

20分ぐらいかけて新たな環境が構築されるはずです。
Snapshotを作成し、アプリのバージョンさえ覚えておけば同じ環境を作成することが可能なわけですね。
なぜフルスクリーン要素のwidthは100%でheightは100vhなのか

# はじめに
某プログラミングスクールのカリキュラムでRailsでアプリケーション作成中、背景画像のようなフルスクリーン表示の要素について、viewportを考慮してサイズ設定をする状況になりました。

```css
.hoge {
  width: 100vw;
  height: 100vh;
}
```
と記述したのですが、模範解答は

```css
.hoge {
  width: 100%;
  height: 100vh;
}
```

見え方は一緒なのに、この違いは何故…と気になり色々検索。


**要素をページの高さいっぱいに配置する場合は100vhを使い、
要素のページの横幅いっぱいに配置する場合は100%を使うのが多い**

という内容の解説をいくつか目にしました。
何故使い分けるのかが気になり、調べてみました。


# 考察・検証
まずはおさらいから。

**viewport**
ブラウザで表示されている領域のことを指します。
パソコンに限らず、スマートフォンやタブレットからもブラウザを閲覧する現代では、viewportを意識したページの見た目作りが重要となります。

**vw(viewport width)**
widthをviewportの幅に対する割合で指定する単位。
1vw = ブラウザで表示されている幅の1%

**vh(viewport height)**
heightをviewportの高さに対する割合で指定する単位。
1vh = ブラウザで表示されている高さの1%


ここまで来ると、フルスクリーン表示の要素はCSSをvwとvhで指定したくなるのですが、「フルスクリーン要素のwidthは%、heightはvhを使うのが一般的」と言われるのは何故でしょうか？



##### 〜なるほどな解説を見つけました〜

[CSSのwidth（幅）とheight（高さ）の指定方法をマスターしよう](https://saruwakakun.com/html-css/basic/width-height
)

ここで改めて注意したいのが、100%と100vhの違いです。
100%は、親要素に対しての割合。
100vhは、viewport(画面サイズ)に対しての割合。



**widthについて**


> bodyまで一切pxで幅が指定されていないと、ブラウザの幅＝bodyの幅になります。つまり見る端末によって、またブラウザウィンドウの大きさによって、bodyの幅が変わるのです。

上記引用から、widthは親要素にpxが全く指定されていないと、**ブラウザの幅がbody要素の幅**になることが分かります。
つまり、この場合のbody要素(親要素)に対する100%のwidthは、ブラウザ基準の100vwと同じ意味になるということです。
結果として、フルスクリーン背景要素のwidth100%は100vwと同じ見え方になるから、「widthは%」でもこの場合は良いということだと考えられます。



**heightについて**
> とくにCSSで指定しない限り、要素のheightの値はautoとなり、高さが自動で決まります。
> 基本的に横いっぱいに広がるwidth: autoと異なり、height: autoは縦いっぱいには広がりません。文字や画像などの要素の中身の分だけの高さになります。
> 中に子要素が入れば、その分だけ高さは大きくなります。


上記引用から、**「親要素の高さ＝中身の高さ」**ということが分かります。
つまり、参照する高さが無ければ子要素に％で指定ができません。
結果、フルスクリーン背景のようなの要素については、vhで高さをブラウザ高さ基準に指定する必要がある、ということだと考えられます。


こちらの解説から、今回の場合

- 要素のページの横幅いっぱいに配置する場合
→100vwと同じ見え方になるので100%

- 要素をページの高さいっぱいに配置する場合
→高さをブラウザ基準にしないといけないので100vh

という意味だったのだとスッキリしました。


# 終わりに
まだまだ初学者なので、知識を定着させるためにも
こういうものだという「作法」だけで覚えず、作法の元の「仕組み」から理解することを意識し続けたいと思います。

少しでも参考になれば幸いです。
最後まで読んでいただき、誠にありがとうございました。

##### 追記
2020/10/31
[[CSS]ビューポート(vw, vh)とパーセント(%)、レスポンシブに適した単位の賢い使い分け方法
](https://coliss.com/articles/build-websites/operation/css/viewport-vs-percentage-units-by-ire.html)
こちらの記事では、widthの%指定について
> 「vw」はビューポートの幅に基づいてそのサイズを決定します。このビューポートの幅というのは、ブラウザのスクロールバーを含んだサイズで計算されます。
> もしページが長く、スクロールバーが表示されているのであれば、ビューポートの幅はhtml要素の幅より大きくなります。
> そのため、もし要素に「100vw」を設定すると、その要素はhtmlとbodyより大きいサイズになってしまいます。

というように、スクロールバーがあった場合のズレを防ぐためにも
widthは%での指定が良いと解説しています。
より納得しました…！


##### 参考記事
[[CSS]ビューポート(vw, vh)とパーセント(%)、レスポンシブに適した単位の賢い使い分け方法
](https://coliss.com/articles/build-websites/operation/css/viewport-vs-percentage-units-by-ire.html)
[CSSで要素の高さを指定する100vhと100%の違いを現役エンジニアが解説【初心者向け】](https://techacademy.jp/magazine/38188)

[知らないと損！CSSのvh/vwの使いこなしでレスポンシブなサイト制作が捗る](https://www.webprofessional.jp/css-viewport-units-quick-start/
)

[CSSのwidth（幅）とheight（高さ）の指定方法をマスターしよう](https://saruwakakun.com/html-css/basic/width-height
)
Spring Boot(Kotlin) + Gradle Kotlin DSLでJarファイル、Warファイルを作成する

# はじめに
Spring Boot(Kotlin) + Gradle Kotlin DSLを利用している場合に、実行可能ではない通常のJar、Warファイルの作成方法です。
利用用途としては、既にあるTomcat Serverへのデプロイや、AWS Elastic Beanstalk、Azure App Serviceへのデプロイを想定しています。

# 環境前提
- Spring Boot Ver 2.3.5.RELEASE
- Gradle Ver 6.7

# Jarファイル作成方法
## 1. `build.gradle.kts` に `jarタスク` を追記する

  ```kotlin
  //////////////////////////////////////
  // Generate Jar
  //////////////////////////////////////
  tasks.withType<Jar> {
    enabled = true  // 未設定時は実行可能Jarファイルが作成される
  }
  ```

## 2. `gradle jar` タスクを実行すると、 `build/libs` 配下にJarファイルが作成される。

  ```shell
  ./gradlew jar
  ```

# Warファイル作成方法
## 1. `build.gradle.kts` に以下war pluginを追記する

  ```kotlin
  plugins {
    // 他pluginは省略
    id("war")
  }
  ```

## 2. `build.gradle.kts` に `warタスク` を追記する

  ```kotlin
  //////////////////////////////////////
  // Generate War
  //////////////////////////////////////
  tasks.withType<War> {
    enabled = true  // 未設定時は実行可能Warファイルが作成される
  }
  ```

## 3. `gradle war` タスクを実行すると、 `build/libs` 配下にWarファイルが作成される。

  ```shell
  ./gradlew war
  ```


# 余談
通常のGradleの例は多数あったのですが、 Gradle Kotlin DSLの例が少なかったので備忘的に記載しました。誰かのお役に立てば幸いです。


# 参考情報
- [Gradle Jar](https://docs.gradle.org/current/dsl/org.gradle.jvm.tasks.Jar.html#org.gradle.jvm.tasks.Jar)
- [Gradle War](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.bundling.War.html#org.gradle.api.tasks.bundling.War)
Kubernetes で アプリ(Pod)を停止する

# Kubernetes でアプリ(Pod)を停止する

Docker の場合、docker stopでコンテナIDを指定するとアプリケーションが停止しますが、
Kubernetesの場合、stopのコマンドがありません。

この記事では、代用のコマンドで停止と同じ状態を実現します。

# レプリカ数の設定
Kubernetes のアプリケーション(Pod)の起動数は、レプリカ数(replicas)の数で決まっています。
「1」以上を指定することで、指定した数だけPodが起動します。

このコマンドを応用し、「0」を指定することでアプリケーションが立ち上がらなくなり、停止と同じになります。
（レプリカ数を「1」から「0」に変更すると、ただちにアプリは終了処理を行い、停止状態になります。）

``` 
#kubectl scale deployments [Deployment Name] --replicas=0
```

レプリカ数の確認は、以下のコマンドで確認できます

```
#kubectl get deployments
```

停止状態のアプリを再び起動する場合は、先ほどのScaleコマンドで1以上を指定します。

``` 
#kubectl scale deployments [Deployment Name] --replicas=1
```
【2021-11-28追記あり】Windows 10からWSL上のEmacsへのテキストのコピペが急にできなくなる

※2021-11-28追記あり。末尾参照

Windows 10上のWSL（1）のUbuntu上でEmacsを使っているが、WindowsでCtrl_Cでコピペしたテキストを、EmacsにC-yでペーストしようとしたら「Kill ring is empty」と怒られるようになった。
昨日まで（たぶん）快調に使えてたのに、ある日急に使えなくなった。
（もっと前から使えてはいなかったのかもしれないけど、分からなくなっている）

いぜんも同じ症状になって、そのときは~/.emacs.d/init.elに

```
(setq x-select-enable-primary t)
```

というのをどこかで調べて追加すると直ったのだが（原理も分からないし、どこで調べたのかも分からなくなっている。スミマセン）今日また同じ症状になった。

分からないなりに調べて、以下のブログに行き当たった。

https://jb102.blogspot.com/2018/09/emacs-on-wsl.html

以下のコードを~/.emacs.d/init.elに追加。

```
(defun wsl-paste ()
  (interactive)
  (insert (shell-command-to-string "powershell.exe -command 'Get-Clipboard'")))
(global-set-key (kbd "C-c C-v") 'wsl-paste)
```

これで、C-cC-vでWindows 10のクリップボードからペーストできるようになった。
こっちも原理は分からないが、動いているので助かる。
ひどい内容だが今シュラバなのでこれにて失礼。

# 環境：

Windowsのバージョン (winver):
Windows 10 Pro バージョン1903 (OSビルド 18362,1139）

Emacs (M-x emacs-version)
GNU Emacs 26.3 (build 2, x86_64-pc-linux-gnu, GTK+ Version 3.24.13) of 2019-12-25

Linuxのバージョン (uname -a)
Linux DESKTOP-TB4M341 4.4.0-18362-Microsoft #1049-Microsoft Thu Aug 14 12:01:00 PST 2020 x86_64 x86_64 x86_64 GNU/Linux

※2021-11-28追記
その後、WSL2に変えたりしたら「どういうわけか・・・」WindowsクリップボードとEmacs Kill Ringの共有ができていた（EmacsからM-wでコピーができ、EmacsへC-yでペーストできる状態）のだが、先週あたりから「どういうわけか・・・」またできなくなったので、上記のelispにお世話になることになった。

それで、EmacsからWSLへのコピペが上記だけではできないのだが、こちらはこれで解決した。

https://qiita.com/mhangyo/items/02b2b316c01cf56039e7

```
  (defun wsl-copy (start end)
    (interactive "r")
    (shell-command-on-region start end "clip.exe"))
  (global-set-key (kbd "C-c c")  'wsl-copy)
```

なお、「powershell.exe -command 'Get-Clipboard'」がたまに（不規則に）エラーを返すことがあるが、その場合は

https://blog.himanoa.net/20/

で紹介されているwin32yank.exeを使ってもいい。

https://github.com/equalsraf/win32yank/releases

その場合、「powershell.exe -command 'Get-Clipboard'」を呼んでいる行は以下のようになる。

```
  (insert (shell-command-to-string "win32yank.exe -o")))
```

同じように、clip.exeの代わりに

```
    (shell-command-on-region start end "win32yank.exe -i"))
```

でもいいっぽい。

（終わり）