OmniAICreator/Qiita-1.07M huggingface dataset:
CodeIgniter4のViewの基礎

前回の記事、[CodeIgniter4のModelの基礎](https://qiita.com/kohenji01/items/b3e947623309d478e02b)の続きです。

#CodeIgniter4のViewってどんなもの？

CIのviewはphpファイルがそのままテンプレートエンジン的な振る舞いをしています。ある意味潔い実装です。
一応ビューパーサクラスが用意してあり、変数へのアサインや、配列を用いた簡単なループも出来ますが、あまり大した機能は持っていません。
その代わりといってはなんですが、比較的容易にSmartyやTwigといった外部のテンプレートエンジンを組み込んで使うことが出来ます。
これらのテンプレートエンジンが簡単に導入できるということは、viewを担当する人にCIのパーサの学習を強いる必要が無いことから結構なメリットになるものと思われます。

この記事を書いている当人も、CIの内蔵のテンプレートパーサを利用したviewの実装というものは、全くというほどしたことがないので、本記事でもここは最低限の説明にとどめておきます。

#viewのファイルの出力の実態
まずviewとして設定されたファイルはどこにあり、どのようにコントローラから指定されて出力されるか？

CIのデフォルトインストールのトップページでは`app/Views/welcome_message.php`というViewのファイルを`app/Controllers/Home.php`というコントローラのファイル内の`index()`というメソッド上でコールされている[`view('welcome_message')`](https://codeigniter4.github.io/userguide/general/common_functions.html?highlight=view#view)というCI上のグローバル関数を叩いてその値を返却してあげることで表示を実施します。

```app/Views/welcome_message.php
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Welcome to CodeIgniter 4!</title>
 
ーーー以下略ーーー

```

```app/Controllers/Home.php
<?php namespace App\Controllers;

class Home extends BaseController
{
	public function index()
	{
		return view('welcome_message');
	}

	//--------------------------------------------------------------------

}
```

なお、`view()`の戻り値はレンダリングされたHTMLそのものなので、`return`で返す前に、そのままメソッド内で`echo`することも可能です。

ここの引数の`'welcome_message'`はズバリそのまま、`app/Views/welcome_message.php`を指しており、引数に拡張子が省略されると`.php`が補われます。要は、この関数の実体は`app/Views/welcome_message.php`の中身を返却せよという動作です。
（ちなみに`view()`のデフォルトパス`app/Views/`は`app/Config/Paths.php`にて定義されている`$viewDirectory`が反映されています。）

#view()を使って表示する。
[前の記事](https://qiita.com/kohenji01/items/b3e947623309d478e02b)では`return`に直接文字列を放り込んで、画面出力を行っていましたが、代わりに`app/Views/result.php`を作ってやり、そこでコントローラで受け取った戻り値などをview()に放り込んあげればその内容をビュー側でハンドリングすることが可能です。

簡単な例として[「CodeIgniter4でDB接続まで」](https://qiita.com/kohenji01/items/ced458da42ce70e067f8)の記事で記したDBの接続テストの結果をビューで表示するようにしてみます。

```app/Controllers/Home.php
<?php namespace App\Controllers;

use Config\Database;

class Home extends BaseController
{
    public function index()
    {
        return view('welcome_message');
    }

    //--------------------------------------------------------------------

    public function connectionTest()
    {
        $db = Database::connect();
        $data['listTables'] = "このDBのテーブル＝" . implode( ',' , $db->listTables() );
        return view('result', $data);
    }
}
```

```app/Views/Result.php
<html lang="ja">
<body>
<p><?php echo $listTables; ?></p>
</body>
</html>
```
このように、view()の第2引数（これはArrayで有ることが必須です）が、キーを変数名としたものに変換されてView上の変数として定義されますのでアクセスの際は`$listTables`のような形で参照します。

詳しくは[CIのマニュアルのViewsのページ](https://codeigniter4.github.io/userguide/outgoing/views.html)を参照してください。
CIのテンプレートエンジンを利用した制御構造や変数等のアサインなどの仕方の記載があります。

次回はCIにViewのテンプレートエンジンとしてSmartyやTwigを組み込んで利用する方法を説明します。
AWS EC2のUbuntuでPython開発(JupyterLabの使用)

# 概要

自分の研究でEC2を使う機会があったので，その時にしたことをメモ書きとして残しておきます．これからEC2でPython開発を行う人の助けになればと思います．

実行環境はMac Catalinaです．
(追記：Windowsでも，同様の内容をGit Bashで行うことで，環境構築ができました．）

## Step.1 インスタンスの作成

自分は無料利用枠で使用できるubuntu 18.04 LSTを使用しました．
nvidiaが提供してるイメージがありますが，そっちで試してうまくいかなかったので，1から作りました．

![スクリーンショット 2020-10-06 15.52.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497731/48389f04-7404-bb64-6f37-7fbc6220add9.png)

インスタンスタイプは無料枠でいいです．環境構築の間に高い使用料を払うことはないです．あとで重い負荷の計算がしたくなったら，その時に変更してください．

他の設定は特にしていないので，「確認と作成」って進んじゃってOKです．

pemファイルの作成などは別途調べてください．
不親切ですいません．以降pemファイルを作成済みという前提で話を進めます．

## Step.2 インスタンスに接続

作成したインスタンスが実行中で，ステータスチェックで2/2のチェックに合格していたら，インスタンスに接続しようとしてみてください．
すると，
EC2 Instance Connect / セッションマネージャー / SSH クライアント
というタブがあるページに飛ぶと思います．
そのSSHクライアントのタブを開いてください．

また，ターミナルで，pemファイルが置いてあるディレクトリに移動してください．
そしてSSHクライアントのタブにある，
chmodから始まるコマンドを実行したのち，
ssi -i "~~~.pem" ubuntu@みたいなコマンドを実行してください．
作成したインスタンスに接続できると思います．

![スクリーンショット 2020-10-07 14.58.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497731/22f08eec-a8c0-3b3f-154c-60e920e3bd85.png)
↑こんな画面です


## Step.3 JupyterLabのインストール

作成したインスタンスで以下のコードを実行していきます．

```
sudo apt update
sudo apt upgrade
sudo apt install -y software-properties-common
sudo apt-add-repository -y ppa:git-core/ppa
sudo apt install -y git
sudo apt install -y python3-pip
sudo pip3 install --upgrade pip
sudo pip3 install jupyterlab
sudo pip3 install ipywidgets
jupyter nbextension enable --py widgetsnbextension
```

これで，今作成したインスタンスにjupyterLabがインストールできました．

## Step.4 JupyterLabに接続

ここまでできたら，一旦インスタンスを停止して，停止が確認できたら，もう一度開始してください．

Step.1同様チェックに合格したら，先ほど同様SSHクライアントで接続を行いますが，コマンドに" -L 8889:127.0.0.1:8889 "を追加してください.

```
ssh -i "***.pem" -L 8889:127.0.0.1:8889 ubuntu@ec2-***-***-***-***.*********.compute.amazonaws.com
```

接続できましたら，次に以下のコマンドをインスタンスで実行し，jupyterLabを起動してください．

```
jupyter-lab --ip=0.0.0.0 --port=8889 --no-browser --allow-root --NotebookApp.token=''
```

何もエラーが出なければ，ブラウザで

```
127.0.0.1:8889
```
に接続してみてください．立ち上げたインスタンスで起動しているjupyterLabに接続できていると思います．

# 最後に

何もエラーが出ないことを祈っております．
このあと，tensorflowをなどのpackageをインストールしましたが，そこでもいろいろ問題が...
現在はその問題も解決しているため，↓で聞いていただければ力になれるかと思います．（場合によっては別の記事として書きます）
読んでいただきありがとうございました．

## 参考にした記事など　（ありがとうございました!!)

SSH先のサーバ上のjupyter notebookをローカルPCで操作する
https://sishida21.github.io/2019/12/12/remote-jupyter-notebook/

【画像で説明】DockerでAnaconda環境をつくり、コンテナの中でVSCodeを使う
https://qiita.com/komiya_____/items/96c14485eb035701e218

昔作成したdockerfileを参照して環境構築を行ったので，当時参考にした記事が他にもあるのはず... なんですが思い出せません...すいません
初学者によるDocker理解まとめ①　〜docker run -pまで〜

#　はじめに
ようやくDockerを学びだしたので自分の理解をまとめておく。

*　Dockerによるコンテナ化によるマイクロサービスの実現
*　`docker run -p` のpはportのp

次回 => https://qiita.com/theFirstPenguin/items/58e6bc5acf90dc497cb0

#　今日の学びをメモ
![スクリーンショット 2020-10-06 16.46.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/f686d791-bdbe-8e42-7511-9b99d022c419.png)



![スクリーンショット 2020-10-06 16.53.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/b93acc45-4776-758a-ffdb-586041e9cd3e.png)


![スクリーンショット 2020-10-06 17.02.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/5b6d1be3-0386-869d-c6da-9228786ddb73.png)


![スクリーンショット 2020-10-07 8.08.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/d19a2543-3f33-8a09-5c80-ced4b0ccb0c9.png)



![スクリーンショット 2020-10-06 17.04.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/bf46b78a-58ae-62fc-766a-00378fc26010.png)


#　まとめ
Dockerを使って処理ごとにホストを分けてデプロイする。疎結合でシステムの信頼性が上がる。
これを理解すれば念願のFargateの世界へ。もうLambdaは卒業できるはず。。。
kerasのRNN系APIの引数return_state, return_sequencesについて

<h1>kerasのRNN系APIのGRUの引数return_state, return_sequencesについて</h1>

大雑把に書きました。

環境
python3

使用する擬似データ

```
B = 1  #バッチサイズ
T = 10 #時系列長
N = 1000 #特徴量
data = np.random.randn(B, T, N)
```

使用するRNN系インターフェース

```
tf.keras.layers.GRU
```


<h2>return_state=True, return_sequences=True</h2>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373549/c70bc2c6-ba11-588f-7722-0352890a8847.png)

赤丸 : return_sequencesをTrue時
緑丸 : return_statesをTrue時

```
gru = tf.keras.layers.GRU(256, return_state=True, return_sequences=True)
B = 1
T = 10
N = 1000
data = np.random.randn(B, T, N)
outputs, states = gru(data)
print("赤丸：", outputs.shape)
print("緑丸：", states.shape)
```

```出力
赤丸： (1, 10, 256)
緑丸： (1, 256)
```

<h2>return_state=True, return_sequences=False</h2>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373549/10675281-5261-2362-88a5-8a7f8ed5f021.png)

赤丸 : return_sequencesをFalse時
緑丸 : return_statesをTrue時


```
gru = tf.keras.layers.GRU(256, return_state=True, return_sequences=False)
B = 1
T = 10
N = 1000
data = np.random.randn(B, T, N)
outputs, states = gru(data)
print("赤丸：", outputs.shape)
print("緑丸：", states.shape)
```

```出力
赤丸： (1, 256)
緑丸： (1, 256)
```

<h2>return_state=False, return_sequences=True</h2>


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373549/bb1e62b5-ed42-d492-fb79-d1978e51422c.png)


```
gru = tf.keras.layers.GRU(256, return_state=False, return_sequences=True)
B = 1
T = 10
N = 1000
data = np.random.randn(B, T, N)
outputs = gru(data)
print("赤丸：", outputs.shape)
print("緑丸なし")
```

```出力
赤丸： (1, 10, 256)
緑丸なし
```

<h2>return_state=False, return_sequences=False</h2>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373549/8b9be5eb-4987-23f7-d91d-82b4d1d0f598.png)


```
gru = tf.keras.layers.GRU(256, return_state=False, return_sequences=False)
B = 1
T = 10
N = 1000
data = np.random.randn(B, T, N)
outputs = gru(data)
print("赤丸：", outputs.shape)
print("緑丸なし")
```


```出力
赤丸： (1, 256)
緑丸なし
```
real-time-Personal-estimation（新たなモデル構築編）

## はじめに
前々回は環境構築
前回は学習編と来ています.
次はちゃんと使えるモデル構築をしたいと思います.
## このプロジェクトのゴール
前回,このプロジェクトのゴールについて書いたのですが,ゴールはずばり「乃木坂ちゃん分類器を作る」ということでした.
まぁ達成はしていないものの作り方はわかったのでとりあえず,ゴールを半分くらい達成してしまいました.ってことで,どうしようかなぁと悩んでとりあえず決めました.
yoloで認識した人をもとにそれを観測できるツールも開発していこうということです.
これは昔,授業で似たようなコードを書いてあるのでそれを改良することも視野に入れています.詳しくは,gitを
ってことでそれがこのプロジェクトの今のところのゴールです.
## モデル構築
前回の記事でモデルの構築方法については述べているのでそれを参考に構築していきます.
あんまりこの記事で皆さんにお披露目するようなことは正直ありません.
もはや自分の為の記録になりますのでご了承ください.

(1)与田ちゃんの画像を集める.
前回は適当に与田ちゃんの画像を10枚集めてそれを加工してモデルを作りました.
まぁこれじゃうまくいかないよなとか思いながらやってたんですけどまぁうまくいかないよな
ってことでモデルを作る為には素材が必要なので,素材集めの方法から考えていきます.

```search.py

from icrawler.builtin import BingImageCrawler
crawler = BingImageCrawler(storage={"root_dir": "asuka"})
crawler.crawl(keyword="検索したい名前", max_num=100)
```
モデルをもとにアノテーションを作っていくのですが,これは大変でした.
一応モデルのファイルみたいのを載せておきます.

```data.yaml
train: test1/train/images
val: test1/valid/images
nc: 2
names: ['asuka', 'yoda']
```
## 結果を出力
約100枚2カテゴリ300epochで学習させました.時間がものすごくかかったので正直
現実的ではないです.
まぁできたので認識しているかをチェックする為に訓練データとは別の画像を使って推論させてみました.
結果はこちら
![1199469.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567360/91992a61-2576-c764-d81b-f2dc6a8e6688.jpeg)
結果としてはうまくいっています.
これが動画とかでもできるのかな.
ちょっと後でやってみます.
## 問題点
学習にかかる時間がローカルPC(CPU)だとえげつない時間が現在かかっています.
なんだったら今の感じだと130枚でも何時間もかかる予感しかしません.
そう考えると,クラウド上の実行（GPU）を使うやり方のが効率的かなぁって感じたりしています.(まぁ当たり前ですけどね)
追記
2カテゴリ,だと2カテゴリ内の推論はうまくいくけど,それ以外の人の画像を入れたときにどうしてもうまくいかない.
ここを対策する方法を模索中です.
![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567360/600098e2-18e6-4555-2e3b-02033182018c.jpeg)
検討事項
・計算スピードの向上
モデルを多く作って検討する為にまずはモデルをたくさん作る必要がある.
したがってモデルを早く作る方法を検討しなければいけない.
・ローカルマシン（GPU）を使ったモデル作成の検討
## 次回
次はこれをどう使うかに特化して書いていこうと思います.
追記
追記したところをどうにかしたいので誰かアドバイスがあれば教えてください.
AWS SDK for Ruby  profile変更 & assume role

AWS SDK for Rubyにてcredentialsのprofile指定とassume role方法についてわかりづらかったので記載

↓profileはaws-cliで下記のように作成した際のもの

```bash
$ aws configure --profile hoge
```

### profile指定
Clientの引数に渡すだけ
例：EC2

```ruby
ec2 = Aws::EC2::Client.new(
  profile: "hoge",
  # ...
)
```


### assume role
```ruby
require 'aws-sdk-core'
require 'aws-sdk-ec2'

role_credentials = Aws::AssumeRoleCredentials.new(
  client: Aws::STS::Client.new(opts),
  role_arn: "arn:aws:iam::xxxxxxxxxxxx:role/hoge_role",
  role_session_name: hoge
)

ec2 = Aws::EC2::Client.new(
  credentials: role_credentials,
  # ...
)
```
Web制作の基本(HTML)

#概要

Web制作を始めるにあたっての基本です。
HTMLの基本的な書き方についても紹介します。

#テキストエディター
まずWeb制作を始めるにあたって、HTMLを書いていくためにテキストエディターというアプリケーションが必要となります。
これは制作する上で役に立つ補完機能がたくさん付いているのでダウンロードしてから始めましょう。
Atom、Visual Studio Codeなど、たくさんのテキストエディターがありますが、自分にあった物を見つけるのがいいと思います。


#そもそもHTMLとは

HTMLとはWebページを作る上で基本となる言語です。(マークアップ言語と言います。)
インターネット上にあるたくさんのWebサイトがHTMLを使って作られています。

#HTMLを記述してファイルを保存する

テキストエディターにコードを記述し、ファイル保存します。

```
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>タイトル</title>
</head>

<body>
<h1>タイトル1</h1>
<p>段落１</p>
</body>
</html>
```

#HTMLのファイル名のルール
HTMLのファイル名には拡張子をつける必要があります。
拡張子とは、そのファイルの種類を表す文字列のことで、ファイルの中でピリオドより後ろの部分です。
ex. blog.html

HTMLファイルの場合はhtmlと後ろにつけて保存しましょう。
そのファイルを開くと、ウェブブラウザーが立ち上がり、記述した内容が表示されます。
[ServiceNow] スケジュールジョブの強制終了のやり方

#概要
スケジュールジョブが無限ループに入ってしまったり、処理が重くてなかなか終わらなくなってしまったりで、強制終了させたい場合があります。
本記事では、スケジュールジョブの強制終了のやり方を説明します。
結論から言うと、System Diagnostics > Active Transactions (All Nodes) に行き、スケジュールジョブの Transaction を Kill すれば、強制終了することができます。
#手順
通常はなかなか強制終了させたい状況になりませんので、10分間スリープするだけのジョブを登録し、そのジョブを強制終了させる手順を説明します。

1 System Definition > Scheduled Jobs に行き、以下のスクリプトをスケジュールジョブとして登録します。

```javascript
gs.info("Sleep job test start");
gs.sleep(600000);
gs.info("Sleep job test finish");
```
ジョブ名は、Sleep job test としました。

2 ジョブ定義画面で、Execute Now ボタンをクリックしこのジョブを実行します。
3 実行後、System Logs > System Log > All に行き、「Sleep job test start」というメッセージが書き込まれ、ジョブが始まっていることを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/756088/9c2e1db4-0f19-4c20-e3a0-9e4407abc814.png)
4 ジョブ実行後、System Diagnostics > Active Transactions (All Nodes)
に行くと、Type が Scheduler のトランザクションがありますので、そちらを選択して、Kill を実行します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/756088/48871ce3-2714-b60f-d644-0c6907f6a21d.png)
5 実行後、Refresh をクリックすると、該当のトランザクションが消え、ジョブが強制終了されます。強制終了されたので、10分以上経っても、「Sleep job test finish」というメッセージはログに書き込まれないはずです。

以上です。
#補足
Execute Now ボタンからの実行ではなく、スケジュールされた時間にジョブが自動実行された場合、Active Transactions (All Nodes) の画面の URL 欄にジョブ名が以下のように表示され、どのトランザクションがどのジョブのものかわかるようになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/756088/44989c59-9b02-9631-022f-d1a33f11de92.png)
Nuxt.jsのプロジェクトをGitHub ActionsからAWS S3へデプロイする

Nuxt.jsのプロジェクトをGenarateして静的ファイルを作成し、そのファイルをS3にアップロードする作業をGitHub Actionsで行いました。
とても簡単だったので、今後の備忘録としてまとめておきます。
今回はNuxt.jsのプロジェクトで行いましたが、特にフレームワークなどの縛りはなくS3へアップロード可能です。

# GitHub Actions用のIAMユーザーを作成する

まずはGitHub Actionsを使用するためのIAMユーザーをAWS側に作成します。
今回はとりあえず `AmazonS3FullAccess` の権限を与えたユーザーを作成しました。
![スクリーンショット 2020-10-06 16.18.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/279032/47f728b3-a0e2-1c94-f6c8-9db65678f307.png)

# GitHub上にSecretsを登録

IAMユーザーのアクセスキーを、GitHub上の Setting -> Secrets から登録します。
また、デプロイするS3のバケット名も登録しておきます。（バケットはすでに作成している想定です）

`Name` は任意ですが、今回は下記のような `Name` を設定して、それぞれ登録しました。

* AWS_ACCESS_KEY_ID
* AWS_SECRET_ACCESS_KEY
* S3_BUCKET_NAME

![スクリーンショット 2020-10-06 16.23.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/279032/782e929a-82e1-afbd-7df8-6f57943fc726.png)

# workflowを作成

プロジェクトの `.github/workflows/` 内に、GitHub Actionsで行いたい処理を記述したファイルを作成します。
今回は `deploy_to_s3.yml` という名前のYAML形式のファイルを作成しました。

`develop` ブランチがpushやmergeなど更新された場合、指定したS3のバケットにデプロイされます。

```yaml:.github/workflows/deploy_to_s3.yml
name: deploy to s3

on:
  push:
    branches:
      - develop

jobs:
  build:
    runs-on: ubuntu-latest
    timeout-minutes: 5

    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: setup node
        uses: actions/setup-node@v1
        with:
          node-version: '12.x'

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ap-northeast-1

      - name: Cache dependencies
        uses: actions/cache@v1
        with:
          path: ~/.npm
          key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            ${{ runner.os }}-node-
      - name: Install packages
        run: npm ci

      - name: Run test
        run: npm run lint

      - name: Genarate files
        run: npm run generate

      - name: Upload dist files to S3
        env:
          S3_BUCKET_NAME: ${{ secrets.S3_BUCKET_NAME }}
        run: aws s3 sync ./dist s3://$S3_BUCKET_NAME/ --quiet
```

簡単ですね！
NVIDIAグラボ搭載PCへのUbuntuインストール時の注意と解決策

# はじめに
PCを自作し，Ubuntu18.04をクリーンインストールしようと思ったが，おそらくグラフィックボードのドライバ周りでトラブルが発生して詰まってしまった．いくつかのサイトを巡って解決したのでまとめる．

|環境|型番|
|---|---|
|MB |ASUSTeK COMPUTER INC. PRIME X299-A II|
|CPU|Intel Core i9-10920X|
|GPU|MSI GeForce GTX 1660 AERO ITX 6G OC||
|OS |Ubuntu 18.04.5 LTS 5.4.0-48-generic x86_64|

# Ubuntuのクリーンインストール方法

多くのサイトに載っている情報のため，詳しくは不要かと思うが，USBインストールメディアを作成し，そこからシステムドライブにインストールを行った．

## インストールメディアの作成
作成方法は[こちら](https://diagnose-fix.com/topic2-003/)参照．4GB以上のUSBを用いれば良い．

## OSのインストール
空のシステムドライブを使用しているため，BIOSから（このマザーボードでは起動中に```F2```or```Del```）ブートディスクを選択した．
以下のような画面が表示されるので，上から2つ目の"Install Ubuntu"を選択してそのまま進めて問題なかった．EFIパーティションなどはクリーンインストールを指定すれば勝手にやってくれるので，デュアルブート等でなければ深く考える必要はない．細かく設定してインストールするなら[こちら](https://qiita.com/koba-jon/items/240e6b9a9bee6a0b28cc)など参照．
![install.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613158/055b786e-9874-17ce-0f10-a40103421964.png)

# 画面のクラッシュ
OSがインストール完了すると，再起動を促す画面がでる．このまますすめると，ログイン画面で画面がクラッシュしてしまった（背景黒に紫のラインが一部入ったような状態）．キーを試しにいくつか押してみたが状況は全く変わらなかった．

調査したところ，どうもUbuntu 18.04 LTSでデフォルト設定でログイン画面につかわれる「Wayland」とNVIDIAグラフィックボードの相性が良くないようで，ログイン画面が表示されなくなる問題が多くあるらしい．以下のサイトを参考に，「Wayland」を停止してリカバリモードでログインすることで，この問題は解決した， **かのように思えた**.
参照：https://linuxfan.info/ubuntu-gdm-wayland-false

# 再度のクラッシュ，ドライバの入れ直し
その後Ubuntuを再起動すると，また同じ問題が発生した．
リカバリウィンドウで行った設定が消えたかと思ったが，もう一度確認すると```WaylandEnable=false```の設定は正常に保存されていたので，この設定**＋リカバリモード**での起動が必要なようだった．

毎度リカバリモードで入るわけにも行かないので，根本的な原因を解決する方法を探したら，勝手に入ってきたNvidia Driverを削除して，Ubuntu用のドライバーを入れ直せば良さそうということがわかった．
参考：[Ubuntuを起動した後、グラフィカルログイン画面が表示されない](https://www.it-swarm-ja.tech/ja/nvidia/ubuntu%E3%82%92%E8%B5%B7%E5%8B%95%E3%81%97%E3%81%9F%E5%BE%8C%E3%80%81%E3%82%B0%E3%83%A9%E3%83%95%E3%82%A3%E3%82%AB%E3%83%AB%E3%83%AD%E3%82%B0%E3%82%A4%E3%83%B3%E7%94%BB%E9%9D%A2%E3%81%8C%E8%A1%A8%E7%A4%BA%E3%81%95%E3%82%8C%E3%81%AA%E3%81%84/997916704/)

リカバリモードでログインした状態で以下のコマンドをターミナルで入力．

```bash:
$ sudo apt purge nvidia-*
$ sudo apt autoremove
$ sudo ubuntu-drivers autoinstall
```
これを実施後，再起動を行うことで，無事ログインでき，またドライバもきちんと動いて画面サイズ等が推奨設定で認識されるようになった．

# まとめ
Ubuntu18.04では（それ以降も？）NVIDIAグラフィックボードとの相性の悪さがあるようなので，適切なドライバをインストールし直す必要がある．そのためにリカバリモードで「Wayland」をOFFにしてログインした．
VPC Service ControlとGCSの公開バケットの関係性

#はじめに
VPC Service Control(VPC SC)でGCSを制限するサービスに追加した時の、公開バケットに対するアクセス制限について確認してみました。

#結論
gsutilなどのAPIを使ったアクセスは、VPC SCで制限されます。
curlなどで、直接オブジェクトにアクセスした場合は、VPC SCのアクセス制御は適用されず、ファイルの取得が可能です。

#理由
VPC SCは、指定した制限付きのGCPサービスにアクセスする時にアクセス制御されます。つまり、認可時の制御となります。
Google Cloud Consoleにログインするときは、認証には影響がありません。

gsutilなどのAPIを使ったアクセスは、認可設定が確認されますが、
公開バケットに対して、curlなどで、直接オブジェクトにアクセスした場合は、認可設定が確認されないため、対象のファイルにアクセス可能となります。

#試してみる

VPC SCを設定して、VPCとTrusted network外からのアクセスが拒否されることを確認する。

```
$ gsutil ls
AccessDeniedException: 403 Request is prohibited by organization's policy. vpcServiceControlsUniqueIdentifier: 14455679eb6241a0
```

curlでファイルを取得してみる。

```
$ curl -X GET   -o "/home/atsum/istio.png"   "https://storage.googleapis.com/storage/v1/b/my-pubic-bucket-*****/o/istio.png?alt=media"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1550  100  1550    0     0   151k      0 --:--:-- --:--:-- --:--:--  151k
$ ls istio.png
istio.png

```
プログラミングとは「これから起こること」を書くもの

# はじめに
ポエムだよ

## 背景
　ある晴れた平日、社内ツールを作成していた日に、エンジニア以外の人から「プログラミングとはなにか？」と聞かれることになった。
　プログラミングとはなんだろうか？一般解では、「プログラミング言語を用いてシステムを構築すること」になるだろうか。とはいえ、エンジニア以外の人にとっては、これは要領を得たものではないように感じる。プログラミング言語とは？システムとは？と新たな用語に出会うことだろう。
　イメージできるように説明することが、こういった質問の際には大切であると考える。全員がイメージでき、また本質と矛盾がない言葉はなんだろうか？私は、「これから起こることを書く」ことがプログラミングであると考える。

# これから起こることとは？
　プログラミングとは「これから起こることを書く」ことである。
　例えば瀟洒なホテルに泊まって、フロントに言伝をする。「1時間後にワインを持ってきて」と言えば、部屋で一休みしているときに完璧な状態に保たれたワインが運ばれてくるだろう。あなたはうっとりとした表情でワインクーラーからワインを引き抜く。
　フロントはコンピューター、言伝をプログラミングと解釈してほしい。世の中は複雑なので、言伝もどんどん複雑になっていく。赤白ワインやロゼ、シャンパン、チリワインやカリフォルニアワインなどの種類を指定することが必要かもしれない。持ってくる時間は？風呂に入っている時に持ってきてほしくなければ、そう伝える必要もあるだろう。考えるべきは「起きること」である。「ポートワインを持ってきて、ただし私が風呂に入っていないときに」。優秀なホテルスタッフは暗黙に了解しているが、コンピューターはいきなり扉を開けることがある。
　起きてほしいことはなんだろうか。例えば家を建てる時に、土台から設計するのではなく、体験から家を設計してみよう。リビングの扉を開けた時に広がっている景色を想像して、そこにある暖炉の暖かさを決める。また、部屋のライトをつけた時に、暗い部屋にどのように光が溢れるかを記していく。土台は制約に過ぎない。あなたは文字だけで家を建てていく。コンピューターの中ならあまり予算はかからない。
　家を建てた後は、友人を呼ぶことになる。友人は残念ながら、あなたが意図しない動きをするだろう。扉を開けた後そのまま引き返したり、靴を想定の場所で脱がないかもしれない。ここが注意点になるが、「これから起きてほしいこと」は書くことができない。本人がそう書いているつもりでも、「これから起きてほしいこと」と「これから起きること」は異なり、家自体がひっくり返るようなこともしばしば発生する。あなたは「起きてほしいこと」を予言するが、言い間違いによって思わぬ不具合が起きることがある。

## どう書くべきか？

　webサイトにおいて考えてみる。ユーザーがサイトにアクセスした時のレイアウトや動きを、あなたは書いていく。あなたはまず、表紙ともいうべきtopページを作成する。ユーザーがどこかボタンを押すかもしれない。その、ボタンが押された時の動作も書く必要があるだろう。先程の例と同じく、問題はこれから起こることしか予言できない点にある。あなたが書いたものに不具合があった場合、それがそのままユーザーが経験することになる。
　これから起きることを準備することが大切になる。例えば少年少女、例えば老人がサイトにアクセスすることを想定する。ボタンは見やすいほうがいいだろうか。それとも洗練されたデザインのものがいいだろうか。どちらにもメリットとデメリットがあるだろう。例えばスマホ、ラップトップ、20年もののデスクトップPCで見ているものもいるかもしれない。
　ボタンの挙動も同様に、連続してボタンを押すもの、ボタンを押した後にPCをシャットダウンするものもいるかもしれない。自動車免許の試験のように気をつけて書いていく必要がある。あなたの言い間違えや想定漏れが思わぬ大事故を引き起こす。

## なぜ書くか
　人狼というゲームがあり、そこにも予言者が出てくる。狼は日に1人村人を食い殺す。村人は投票で狼を殺害する。予言者は1人を指名して、その者が狼かどうか判明させることができる。うまくバランスの整ったゲームで、予言者はその能力を活かしきれぬまま狼に食われることも多い。
　プログラミングによってつくられたプログラムやシステムも同様に、期待されたことさえできないこともある。ただし、これは明らかに悲観している。予言者の力をうまく活用できれば、狼を早期に判明させ、ゲームに勝つことができるだろう。現実も同様に、数多くのプログラムやシステムが困難な問題を解決している。システムトラブルなどのニュースが賑わうこともあるが、それよりも多くの成果がある。
　あなたが「起きてほしい」と願うことを書くこともあれば、誰かの願いを具現化することもある。それも、失敗と困難が続く急峻な山坂のような道になるだろう。ただ、挑む価値はある。「これから起こること」を書くことができるという点だけで、人生を賭けるに値する。
bundle install？yarn install？何してるの

#installが多いな
gemやappをインストールした時にbundle installやら　yarn installやらたくさんインストールがあって何を表しているのかわかっていませんでした。

#bundle install
bundlerというgemが他のgemのバージョンを管理していて、

```
bundle install
```
とコマンドで実行することで、gem同士互換性があるかをチェックしている。

#yarn install
yarnはパッケージマネージャー。gemのbunderのようなもの。

```
yarn install
```
とコマンドで実行することで、javascriptに関係するパッケージ（ライブラリをまとめたもの）のバージョンを管理して互換性があるかチェックしている。
Python: pydub の使い方 （再生）

pydub で再生をする方法です。

```py:play.py
#! /usr/bin/python
#
#	play.py
#
#						Oct/06/2020
#
# ------------------------------------------------------------------
import sys
from pydub import AudioSegment
from pydub.playback import play

# ------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")
#
file_in = sys.argv[1]

audio_aa = AudioSegment.from_wav(file_in)
play(audio_aa)
#
sys.stderr.write("*** 終了 ***\n")
# ------------------------------------------------------------------
```

実行方法

```text
./play.py input.wav
```
Address already in use :::(ポート番号)の対処方法

#はじめに
アプリケーションを起動中にプロセスを終了させずにターミナルを終了させる
↓
「Address already in use :::(ポート番号)」のエラーメッセージ

というような事をもう何度も繰り返しているため、備忘録代わりに記事を投稿します。

#解決方法
###1.lsofコマンドを使用して、現在開いているポートを確認
**lsof[オプション][パス名]**コマンドを使用して現在開いているポートを確認して、該当のアドレスを終了させます。
lsofは開いているファイル名を表示させるコマンドで、これに**「-i」**オプションをつけることで「ネットワーク」が対象になり、さらにポート番号も分かれば**「パス名」**にポート番号も入力することで、開いているネットワークアドレスを絞り込むことができます。

```
// 現在開いているネットワークアドレスを確認(localhost:3000の場合)
lsof -i :3000

//実行結果
COMMAND　PID　USER　FD　TYPE　DEVICE　SIZE/OFF NODE NAME
Node    1234  user 12u Ipv6  102711  oto     TCP   *:3000(LISTEN)
         ↑これを次のコマンドで使用します
```
終了させたいネットワークが出てきました。
その後、下記のコマンドを入力してプロセスを終了させます。

```
kill 1234
```

これでOKです。

#まだわからないこと

今回のケースは私の場合Webpackで自分で構成したReactアプリで発生するのですが、「create-react-app」コマンドで作成したReactアプリでは起動中にターミナルを終了させても起こりません。
起動中に終了してもlisten状態のままにならない設定でもあるのでしょうか・・・・
また判明したらここに記そうと思います。
【pandas高速化】mergeが遅いと思ったらmapを使え

#mergeが遅い！

と感じませんか？
特にコンペで行数が多いときとかマジで遅い。特徴量作成にどんだけ時間使うねん！
そういう時はmapを使うと速くなります。

#例

それなりに行数がないと差が出ないので今回はkaggleのタイタニックを使います。
その中にAgeというカラムがあるので、それのカウントエンコーディングをしたい。

```merge_map.py
import pandas as pd
import time

df = pd.read_csv("train.csv")
df["Age"] = df["Age"].dtype("str")
t1 = time.time()

#pettern 1
df = pd.merge(df,df.Age.value_counts().reset_index().rename(columns = {"Age":"Age_count1"}),
 　　　　　　　　　　　　　　　　　　　　　　　　left_on = "Age", right_on = "index", how = "left")
t2 = time.time()

#pettern 2
df["Age_count2"] = df["Age"].map(df.Age.value_counts())
t3  =time.time()

print(t2-t1)
print(t3-t2)
```

```
#output
0.004603147506713867                                                                                                                                                                                                                        
0.0012080669403076172
```

この場合、mapの方が４倍高速です。
target encodingなんかもmapでできます。

```
df = pd.merge(df,　df.groupby("Age").Survived.mean().reset_index().rename(columns = 
　　　　　　　　　　　　　　　　　　　　{"Survived":"Age_target1"}), on = "Age", how = "left")
t4 = time.time()
df["Age_target2"] = df["Age"].map(df.groupby(["Age"]).Survived.mean())
print(t4-t3)
print(t5-t4)
```

```
#output
0.005101919174194336                                                                                                                                                                                                                        
0.001428842544555664
```

これも４倍くらいはやいです。このスケールならまだしも、10秒か40秒か。1分か4分かっってなってくるとだいぶ違います。

#キーが２つある場合
mapはキーが1つじゃないといけません。
その場合は無理やりキーを作ります。

```
df = pd.merge(df, df.assign(sex_age_count = 0).groupby(
["Sex", "Age"])["sex_age_count"].count().reset_index(),on = ["Sex", "Age"] ,how = "left")

t6 = time.time()
#キーを無理やり作る
df["Sex_Age"] = df["Sex"] + df["Age"]
t7 = time.time()
df["Sex_Age_count"] = df["Sex_Age"].map(df["Sex_Age"].value_counts())
t8 = time.time()

print(t6-t5)
print(t8-t7)

```

これも4倍くらいはやいです。

```
#output
0.006415843963623047                                                                                                                                                                                                                        
0.0015180110931396484    
```
RubyOnRailsで環境変数を使用する方法

■英語の記事↓
[How to Use Environment Variables in Ruby On Rails]
(https://qiita.com/alokrawat050/items/0d7791b3915579f95791)

# 環境変数とは
各アプリケーションには、外部サービス用の電子メールアカウント資格情報やAPIキーなどの構成設定が必要です。環境変数を使用して、ローカル構成設定をアプリケーションに渡すことができます。
Ruby On Railsで環境変数を使用する方法はいくつかあり、FigaroGemのようなgemもあります。
この記事には、local_env.ymlファイルを使用して、実装の方法を共有させていただきます。

# 環境変数ファイルをプライベートとして保持する
GitHubを使用してコードを保存および共有していて、プロジェクトがオープンソースである場合、開発者は誰でもコードにアクセスできます。 個人情報やAPIキーを一般の人と共有したくない、プライベートgitリポジトリを使用してチームで共同作業している場合、ローカル設定がチームのすべてのメンバーに適しているとは限りません。

# local_env.ymlファイルを使用:
標準のYAMLファイル形式を使用して、各環境変数のキーと値のペアを含む単純なファイルを作成します。

**config/local_env.ymlファイルを作成:**

```yaml
MAIL_USERNAME: 'Your_Username'
MAIL_PASSWORD: 'Your_Password'
```
**.gitignoreに設定**
アプリケーションのgitリポジトリを作成した場合、アプリケーションのルートディレクトリには.gitignoreという名前のファイルが含まれている必要があります。
.gitignoreファイルに以下の行を追加

```
/config/local_env.yml
```

**Railsアプリケーションファイルに設定**
環境変数を設定後で、ファイル「local_env.yml」は「config/application.rb」に設定が必要です。
**config/application.rb**ファイルに下記のコードを設定

```rb
config.before_configuration do
  env_file = File.join(Rails.root, 'config', 'local_env.yml')
  YAML.load(File.open(env_file)).each do |key, value|
    ENV[key.to_s] = value
  end if File.exists?(env_file)
end
```

上記のコードは、local_env.ymlファイルから環境変数を設定します。

**コードに環境変数を使用**
RailsアプリケーションでENV ["MAIL_USERNAME"]を使用することができます。
例：

```rb
ActionMailer::Base.smtp_settings = {
    address: "smtp.gmail.com",
    enable_starttls_auto: true,
    port: 587,
    authentication: :plain,
    user_name: ENV["MAIL_USERNAME"],
    password: ENV["MAIL_PASSWORD"],
    openssl_verify_mode: 'none'
    }
```
コーディングを楽しみましょう！:grinning: :grinning:

ご不明な点がございましたらご連絡して頂ければと思います。

以上です。よろしくお願いいたします。
今更聞けない！Runtime Application Self-Protection(RASP)とは？


ITが好きでやまない非技術職です。今回は初投稿ですが、私が今注目しているRASPと呼ばれるセキュリティ技術について紹介したいと思います。

#概要
アプリケーションを守る技術としてRASPというのがありますが、RASPとは何でしょうか。その名の通り、アプリケーションまたはアプリケーションを実行するランタイム環境で、セキュリティ機能を導入しリアルタイムでアプリケーションまたはアプリケーション実行環境を脅威から守るセキュリティ技術です。

#なぜRASP?
サーバ上で動くアプリケーションであれば、サーバに何かしらのウイルス対策ソフトをインストールし、なんとなくアプリケーションも守られていて、安心してしまいます。
昨今、クラウドやコンテナ技術が注目を浴び、クラウド環境であれば例えばAWSのfargateといった環境では、マネージドサービスでOSレイヤーを制御できない環境も普通になってきました。
マネージドサービスになると、サーバと同等なセキュリティ対策ができないことが多く、WAFでセキュリティ対策を済ませることも多々あります。
WAFは多くの場合ですと、見れるレイヤーが限られていて、対策できる脅威も限定的である場合が多いです。
また、最近のアプリケーションの多くの場合は、APIを使用し、Webアプリケーションを経由して、バックエンドサーバやデータベースとの通信しますので、適切に保護されてない場合、アプリケーションが簡単に乗っ取られて、最悪な場合はユーザデータが盗まれることもあります。
このような背景もあり、クラウドネイティブ環境などにおいては従来通りのセキュリティレベルでの対策が求められます。
ここでRASPという技術が注目されています。

#RASPのメリット
RASPは多くの場合は、アプリケーションそのものに組み込むため、OSへの依存が少なく、コンテナ環境やAWS Lambdaといったサーバレス環境にも導入することができます。
RASP自体は新しい技術ではありませんが、OSへの依存度が低い分、クラウドネイティブ環境との相性が抜群です。
また、汎用性があり、異なるアプリケーションに同様なセキュリティ機能を持たすことができます。

次回は実際にRASPをアプリケーションに導入してみたいと思います。

【追記】
【必見！！！】Cloud One - Application SecurityをWebアプリケーションに組み込んでみた
https://qiita.com/chankoba/items/9c2fe085665ccb470aa8
Python: pydub の使い方

オーディオファイルを編集する方法です。

入力ファイル
![input.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/9587782d-fc2d-847a-4f6f-628563aeae7c.png)

出力ファイル
![out.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/1ff36c55-3c05-5ac0-c177-c5a23c56be37.png)

変換プログラム
入力ファイルから 3sec から 7sec までを切り出します。

```py:edit.py
#! /usr/bin/python
#
#	edit.py
#
#						Oct/06/2020
#
# ------------------------------------------------------------------
import sys
from pydub import AudioSegment

# ------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")
#
file_in = sys.argv[1]
file_out = sys.argv[2]

audio_aa = AudioSegment.from_mp3(file_in)
start = 3 * 1000
end = 7 * 1000
audio_bb = audio_aa[start:end]
audio_bb.export(file_out, format="wav")
#
sys.stderr.write("*** 終了 ***\n")
# ------------------------------------------------------------------
```

実行方法

```bash
./edit.py input.wav out.wav
```

次のバージョンで確認しました。

```text
$ python --version
Python 3.8.2
```
PythonからFilemakerを操作する

Pythonを使ってFilemakerを操作してみようってことでやってみました。

#環境
サーバー
windows server 2012 R2
Filemaker server 17

クライアント
windows 10 pro
office 2016

Python 3.8.1
Pycharm Community Edition 2020.2

#やりたいこと
Filemaker serverにアップロードした適当なデータベースに対して検索、更新を行います。想定している業務はマスターメンテナンスです。FilemakerはCRM的な使い方をされることが多いと思うのですが、会計システムなどからマスターを流し込めたら便利ではないかと思います。まあ手でやればいいのかもしれない。

#準備
Filemaker Serverに適当なデータベースがあるものとします。当データベースはWebAPIが公開されてWebAPIでアクセスできるユーザーが既にいるものとします。SSL通信のための証明書は導入していないものとします。

requestsを使います。importしてください。

## アクセストークン取得
    headers = {'Authorization': 'Basic XXXXXXXXXXXXXXXX', 'Content-Type': 'application/json'}
    r_post = requests.post(https://[hostname]/fmi/data/v1/databases/[databasename]/sessions', headers=headers, verify=False)

Excelでゴリゴリ書いていたものがたったの２行で実現できる！素晴らしいぞPython。Basicの後ろはidpwをbase64でエンコードした文字列をコピペしてください。この辺りもっとうまいやり方があるのかもしれないですね。[hostname]と[databasename]はお使いの環境にあわせてください。

## 検索する
    headers = {'Authorization': 'Bearer ' + token, 'Content-Type': 'application/json'}
    query = {'query': [{"検索対象フィールド名": keyword}]}
    r_post = requests.post( https://[hostname]/fmi/data/v1/databases/[databasename]/layouts/[layoutname]/_find, json=query, headers=headers, verify=False)

非常に簡単ですね。requests.postにはjsonとdataの二つの指定の方法があるみたいですがFilemakerが相手の場合はjsonが楽です。検索のkeywordに対してはFilemakerの検索モード時の指定の仕方、*とか=とかが使えるようです。

## 更新する
    headers = {'Authorization': 'Bearer ' + token, 'Content-Type': 'application/json'}
    fieldData = {'fieldData': {'更新対象フィールド名' : value1, '更新ン対象フィールド名' : value2}}
    r_post = requests.patch(https://[hostname]/fmi/data/v1/databases/[databasename]/layouts/[layoutname]/records/[recordId], json=fieldData, headers=headers, verify=False)
メソッドがpatchなんだとわかるまで２時間かかりました・・・。精進が足りない。

#おわりに
これで手元のCSVファイルを１行づつ読み取ってFilemaker上にあるマスター系データーベースを部分的に更新することができるようになりました。一括で全データを置換するのであればこんなめんどくさいことはしなくてもよさそうです。
AIR GOで無料でAndroid/iOSアプリの脆弱性診断

「[AIR GO](https://air.line.me/air/product#airgo)」はLINEが提供しているセキュリティープラットフォーム「[AIR](https://air.line.me/air/what_air)」のプロダクトの１つで無料でモバイルアプリの脆弱性診断を行ってくれるSaaSです。

AIRの[アカウント登録](https://air.line.me/member/signup)を行えば直ぐに使い始めることができます。

作ったAIRアカウントでログインしてAIR GOを開き、AndroidならAPKファイル、iOSならIPAファイルをアップロードするだけで、直ぐに脆弱性診断が行えます。
URLを入力すると参照先にマルウェアが含まれていないかチェックできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96507/7ddfa51c-dd58-7d0a-eae5-85091dd22b5d.png)

脆弱性診断結果は次のようなレポート形式で表示されます。

![test.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96507/b275c4cc-9a20-2b9b-9aa9-bee9b04dfad1.png)

無料でここまで脆弱性診断できるのは素晴らしいですね。

…

ただし、「一つのアカウントごと1回のみスキャン可能です。」とメッセージがでている通り、１アカウントで１回しか検査ができません…。
「１アカウントにつき１日１回」かと思いきやマジで１回のようです。

じゃあ、それ以降はどうすればいいかの情報が見つからないので確かなことはわかりませんが、おそらく有償版が必要になると思われ。

その有償版のサブスクリプションはAmazon SaaS Storeで買えるようです。
https://www.amazon.co.jp/dp/B0814HJGH9
Redmine の API で情報取得

# はじめに

TestLink というテストケース管理ツールから Redmine にバグチケットを発行させたいと思ったのだけど、 Redmine の API で情報を取得しないといけないことが分かった。

まずは、Redmine の情報を取得してみよう

ちなみに、TestLink で最小限必要なものは以下の項目です。

- APIキー
- トラッカーID
- ステータスID

# 準備
まずは、「管理者ユーザ」でログインし、「管理」→「設定」→「RESTによるWebサービスを有効にする」を有効にしなければならない

https://redmine.jp/glossary/r/rest-api/

# Redmine で API キーの取得

まずは Redmine の上にある「個人設定」をクリックすると、右のメニューにAPIキーを設定する項目が出てくる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304109/f9bacb1f-7542-6242-dde4-72144778a8bf.png)

すでに設定している場合は、「表示」で出てくる。再設定したい場合は「リセット」をクリックする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304109/831491f2-bd76-daad-5982-c7aebe769c87.png)

# API 実行

- プロジェクト一覧取得
- チケット一覧を表示

## プロジェクト一覧の取得

Redmine のプロジェクト一覧を取得する

```
https://＜ホスト名＞/redmine//projects.xml?key=＜APIキー＞&limit=10&page=1
```

## チケット一覧を取得

プロジェクトのチケット一覧を取得する。
＜プロジェクトID＞ は「プロジェクト一覧」を表示すると出てくる。

```
https://＜ホスト名＞/issues.xml?key=＜APIキー＞&project_id=＜プロジェクトID＞&limit=100&page=1
```

# おわりに
もっといろんなものが取得できるのだろうけど、とりあえずわかっているものからメモを残していく
ReShaperでLiveTemplateを設定

# 前説

LivetTemplateのプロジェクトを編集していて、素のVisualStudioでは展開されるsnippetがReSharperを入れた環境でうまく動かないので、なんとかしたかった。

前提環境は、
- VisualStudio2019
- ReShaper2020.2
- Livet 3.2.3


## ReShaper用のSnippet(LiveTemplate)を設定する

ReShaper側で新たに設定する。
まずメニューから、 **拡張機能**→**ReShaper**→**Tools**→**TemplatesExplorer**を開く。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23242/71df64ab-6974-bf41-adf0-ebda1d386fb0.png)

上部の殻ツールボタンから NewTemplateをクリック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23242/ef305d36-1c1f-7569-fb11-3ebc2e6b268e.png)

編集画面が後ろに表示されるので、[元のテンプレート](https://github.com/runceel/Livet/tree/master/Templates/Livet.Extensibility/Snippets/CSharp/LivetSnippets)などを見つつ適当に設定する。

```
Shortcut: lprop
Description: Create a Livet property
など
```

左側にsnippetのテンプレートを入力するタブが開いているはずなので、同様に入力。
おおむね互換（らしい）

```
private $type$ _$name$;

public $type$ $name$
{
get
{ return _$name$; }
set
{ $END$
if(_$name$ == value)
return; 
_$name$ = value; 
RaisePropertyChanged();
}
}
```

1つだけはまったのが、_\$end\$_ 。
[Microsoftのドキュメント](https://docs.microsoft.com/ja-jp/visualstudio/ide/code-snippets-schema-reference?view=vs-2019#keywords)によるとテンプレート展開後にカーソルを持ってくる場所らしい。

JetBrains IDEのテンプレートだと、大文字で \$END\$ なので、ここだけ修正する。

テンプレートを入力すると、＄マークのついたパラメータの処遇を右側で聞かれるようになる。
今回型をあらわす _\$type\$_ がいるので、Choose Macroから↓を選択してみた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23242/14b8d9b7-16fe-03c0-7ef3-624da8327bd2.png)

とりあえず、上記設定などで `lsprop[tab]` の操作で、スニペット展開されるようになった。

雑に設定しているので、なにか足りないかもしれない。詳しくは[公式ドキュメント](https://pleiades.io/help/resharper/Creating_a_Live_Template.html)をちゃんと読む。
ServiceNow - コンマ区切り文字列に含まれているかチェックする

#概要
ServiceNowフォーラムに挙げられた質問です。
フォームに入力されたコンマ区切りの数字がすべてシステムプロパティで定義されているコンマ区切りの数字に含まれているか確認するスクリプトを作成します。簡単な要件ですが、少しはまりました

#問題点
ServiceNowで対応しているJavaScriptのバージョンはECMAScript5です。そのために.some()や.every()が使えない。
https://docs.servicenow.com/bundle/paris-application-development/page/script/JavaScript-engine-upgrade/concept/c_JS_engine_upgrade.html

それではコンマ区切りのも文字列を.split()は配列に変換してループしてindexOf()したらよいはず。ServiceNowのバックグラウンドスクリプトで正常に動作することを確認した後にスクリプトインクルードに複写して動かして見たら、何時もfalseになる。フォームやシステムプロパティからコンマ区切りの数字を取得するのではなく、最初から数字の配列にすると正常に動作する。

問題はスクリプトインクルードの配列にあるようです。バックグラウンドスクリプトでは正常に動作されるけど、スクリプトインクルードでは型が正しく変換されないのか.indexOf()が正しく動作しない。最終的にはsplit()した配列を読み返して数字配列に変換したら正しく動作するようになりました。


スクリプトインクルード

```
var ArrayValidateUtil = Class.create();
ArrayValidateUtil.prototype = Object.extendsObject(AbstractAjaxProcessor, {
    isIncluded: function() {
        var user_prop = this.getParameter('sysparam_check_value').trim();
        var sys_prop = gs.getProperty('ozawa.check.values');

        sys_prop_array = sys_prop.split(',').map(Number);
        user_prop_array = user_prop.split(',').map(Number);

        return sys_prop_array.filter(function(elem) {
            return user_prop_array.indexOf(elem) > -1;
        }).length == user_prop_array.length;
    },

    type: 'ArrayValidateUtil'
});
    type: 'ArrayValidateUtil'
});
```

クライアントスクリプト

```
function onChange(control, oldValue, newValue, isLoading) {
   if (isLoading || newValue == '') {
      return;
   }

    var ajax = new GlideAjax('ArrayValidateUtil');
    ajax.addParam('sysparm_name', 'isIncluded');
    ajax.addParam('sysparam_check_value', newValue);
    ajax.getXMLAnswer(function(answer) {
		if (answer == "true") {
            g_form.showFieldMsg('check_field_name', 'All elements are OK', 'info');
        } else {
			g_form.showFieldMsg('check_field_name', 'Some elements are invalid', 'error');
		}
    });
}
```
【3D OD LiDAR編】VoteNet : 物体の中心点推定からの3D Object Detection

<h1>Deep Hough Voting for 3D Object Detection in Point Clouds</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/ea2c2889-3350-1b3f-6551-5ba6632efc8d.png)

PointCloudから物体の中心へのOffsetを推定し、Votes(物体の中心点に寄った点)を得る。任意の数にVotesをClusterし、ClusterされたPointの特徴から3D Bounding Boxを推定する手法。



<h1>アルゴリズム</h1>
<h2>seeds</h2>
N個のpoint(x,y,z)をPointNet++に入力し、M個のpoint(x,y,z, +c)の特徴量を推定する
M個のpointを選び出すのがvotingという作業。

<h2>vote</h2>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/5f71ae5c-7907-75d0-706e-c2a935dbc44b.png)
なるほど〜。Voteとはそれぞれの点から物体の中心までのoffsetを推定する作業のことか。
だから物体の周りに赤い点が固まってるのね


<h2>Vote clusters</h2>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/34b46694-65a2-a7f1-9f57-0420d7a163e0.png)

farthest point sampling(均等に点をpickしてくれる)を使ってk個のvote(offsetを加味したpoint)を選び出す。
選ばれなかったすべてのvoteは最短の選ばれたvoteにclusteringする

<h2>output 3D boundingbox</h2>
clusterの周りのvoteを入力にPointNet++を使って物体のクラス分類と3DのBounding Boxの推定をする。
出力はK個のBounding Boxとなる。



<h1>結論</h1>
・RPN(Region Proposal Network)の物体の3D Bounding Boxを提案して、そこからoffsetを推定するのに似ていると思った。VoteNetの場合は物体の中心を提案して、そこから3D Bounding Boxを直接推定する。

<h1>参考文献</h1>
Deep Hough Voting for 3D Object Detection in Point Clouds
https://arxiv.org/pdf/1904.09664.pdf
Amazon Linux2にECS Agent登録&デバッグ

# ECSでEC2を使う場合のデバッグ
- Amazon Linux2に[公式マニュアル](https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/ecs-agent-install.html)を元にecs-agentを入れてクラスターにつないでみた
- マニュアルのとおりにやっても正常に起動しない場合があり、そういう時にどうやってデバグするのか情報がまとまっていなかったので、自分のメモがてら記事にしてみる
- 今回のケースではAmazon Linux2に手動でagentをインストールした場合を扱います。他のケースだと細かいパスとかは違っているかもしれません

# デバッグに有用なファイルのパス
```shell
# 設定情報
## 設定情報。どのクラスタに所属させるか、などを設定
/etc/ecs/ecs.config
## エージェント状態ファイル。インスタンスがクラスターに作成された後に作られる。曲者なやつ。
/var/lib/ecs/data/ecs_agent_data.json

# ログファイル
## 初期化ログ。起動、失敗、再起動、終了がイベントベースでざっくり載っている。
## なんで止まったとかは書いてないけど、何回リトライしたかとかはここを見ると追える
/var/log/ecs/ecs-init.log
## エージェントログ。実際のデバッグに有用な情報は大体ここ
/var/log/ecs/ecs-agent.log
## ボリュームログ。ecsエージェントがmountするdockerのvolumeのログ？まだあまり使ったことはない
/var/log/ecs/ecs-volume-plugin.log

```

# デバッグのステップ
## systemdの確認
まずはsystemdでちゃんとecsのデーモンが動いているか確認。Activeがactive(running)になっていなければ、ECSエージェントが正しくインストールされていないかも。

```
$ sudo systemctl status ecs
● ecs.service - Amazon Elastic Container Service - container agent
   Loaded: loaded (/usr/lib/systemd/system/ecs.service; enabled; vendor preset: disabled)
   Active: active (running) since 月 2020-08-24 20:42:32 UTC; 3 days ago
     Docs: https://aws.amazon.com/documentation/ecs/
  Process: 5195 ExecStopPost=/usr/libexec/amazon-ecs-init post-stop (code=exited, status=0/SUCCESS)
  Process: 5179 ExecStop=/usr/libexec/amazon-ecs-init stop (code=exited, status=0/SUCCESS)
  Process: 5213 ExecStartPre=/usr/libexec/amazon-ecs-init pre-start (code=exited, status=0/SUCCESS)
 Main PID: 5279 (amazon-ecs-init)
    Tasks: 7
   Memory: 3.4M
   CGroup: /system.slice/ecs.service
           └─5279 /usr/libexec/amazon-ecs-init start
```

## metadataの取得
jsonが表示されればOK。うまく動いていない場合は何も表示されない

```
$ curl -s http://localhost:51678/v1/metadata | python -mjson.tool
{
    "Cluster": "my-cluster",
    "ContainerInstanceArn": "arn:aws:ecs:ap-northeast-1:xxxxxxx:container-instance/1111-22222-33333-44444",
    "Version": "Amazon ECS Agent - v1.39.0 (61d418ea)"
}
```

## 上記2コマンドで異常が検知された場合のやること
- [公式マニュアル](https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/ecs-agent-install.html)に従ってちゃんとecs agent入れるコマンド打っているか確認
- /etc/ecs/ecs.configにちゃんとECS_CLUSTERが正しく指定されているか確認

```
ECS_CLUSTER=my-cluster
```
- /var/log/ecs/ecs-agent.logのログ内容を確認
    - エラーの内容を確認。明確なエラー原因がつかめなかったら、とりあえず次のステップを行う
- /var/lib/ecs/data/ecs_agent_data.jsonの中身を消す
    - 何回か発生した不具合のほとんどは、ここのデータが更新されていないために発生していた。ecs.configの内容の書き換えや、EC2インスタンスのタイプを変更しての再起動など、何か環境が変わった場合、基本はここをリセットしないとうまく立ち上がってくれない
ALBでHostBasedRouting

#概要
アプリケーションを複数のサービスの集合体として運用している場合に、それぞれのドメインごとにALBを立てて管理する方法と、ALBのリスナールールで管理する方法がある。後者の方が管理コストが低いので試してみた。
#ALBの設定
設定はすごく簡単、EC2からロードバランサーを選択、対象のロードバランサーをチェック
![スクリーンショット 2020-10-06 14.38.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209804/1dc1a0ac-d0ab-7cdb-acc1-e3fbba08f015.png)
編集したいリスナーを選び、ルールの編集をクリックし、ルールの追加をクリック。
条件式をホストヘッダーにし、ドメインを記入、このドメインの時に転送する転送先（ターゲットグループ）を選択。以上
![スクリーンショット 2020-10-06 14.39.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209804/cf24eaad-6a28-1b9e-8f5a-9724ac1fd844.png)
#おまけ
更新するときなど、メンテナンスモード用の固定レンスポンスを設定しておくとメンテナンス時にルールの順序を変更するだけなので至極簡単
![スクリーンショット 2020-10-06 14.40.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209804/3b9cf6b5-e6ea-6afa-45cf-2bbb994212f0.png)
PrivateSubnetのEC2からgithubにssh-agent使用してアクセス

#概要
Local -> 踏み台EC2(PublicSubnet) -> EC2(PrivateSubnet)->踏み台EC2（PubicSubnet）又はNATGateway->github

認証情報系はすべてローカルにある状態で、PrivateSubnetにあるEC2インスタンスからgithubにアクセスする。ローカルから接続する際は、踏み台を経由するがEC２からgithubからアクセスする際には踏み台経由でも、NATGatewayでも良いが今回は踏み台でやってみた。

# ローカル設定

```shell:.ssh/config
Host git-code-manager
  Hostname github.com
  IdentityFile ~/.ssh/id_rsa_git_code_manager
  User git
  ForwardAgent yes

Host aws-step-server
  Hostname YourStepServerHost
  User ec2-user
  IdentityFile ~/.ssh/keys/aws-step-server.pem
  ForwardAgent yes

Host aws-api-server
  Hostname YourStepServerHost
  User ec2-user
  IdentityFile ~/.ssh/keys/aws-api-server.pem
  ProxyCommand ssh aws-step-server -W %h:%p
```

#踏み台設定

```shell:.ssh/config
Host git-code-manager
  Hostname github.com
  User git
  ForwardAgent yes
```

#PrivateSubnetEC2設定

```shell:.ssh/config
Host git-code-manager
  Hostname github.com
  User git
  ForwardAgent yes
  ProxyCommand ssh -W %h:%p aws-step-server

Host aws-step-server
  Hostname YourStepServerHost
  User ec2-user
  ForwardAgent yes
```

#接続テスト

```terminal
ssh -A aws-api-server ssh git-code-manager

Hi CodeManager! You've successfully authenticated, but GitHub does not provide shell access.
Killed by signal 1.
```

#うまくつながらない時は
ssh-agentが起動しているか確認

```terminal
ssh-add -l
*起動していれば登録した認証情報がリストで表示される
```
起動していなければ起動

```terminal:Linux
eval `ssh-agent`
```
FlutterでAndroidのパッケージ名をちゃんと変更する方法。

##Androidのパッケージ名
Google play Storeでアプリの識別IDの役割を果たす奴です。
「com.example」とか。
これをFlutterで変更しようとすると、かなり、かなりめんどくさいことがわかったので、正しいやり方を記録しておきます。

##変更する箇所は６つ！
かなり多くてびっくりです。一括で変更するパッケージがあってもいいんじゃないかと・・
全てちゃんとやらないと、エラーで起動できなくなったり、ストアにアップロードできなくなったりします。
エラーメッセージはこんな感じ。
「java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.MainActivity}

###一つ目、build.gradle
ストアに認識される部分です。ここを変えないとストアにアップできません。
./android/app/src/build.gradle
を開いて、中のapplicationIDの部分を変更します。
（./android/app/build.gradleじゃないよ）
![スクリーンショット 2020-10-06 14.12.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/762871/bddfc6a6-fe79-d50b-663b-c3fec6693e68.png)

###２−４つ目、AndroidManifest.xml
以下の３つのファイルを開いて、「package=com.*****」のところを全て変更します。
./android/app/src/debug/AndroidManifext.xml
./android/app/src/main/AndroidManifext.xml
./android/app/src/profile/AndroidManifext.xml
![スクリーンショット 2020-10-06 14.17.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/762871/7f736245-e537-5c3d-a2b3-21adbfff4b74.png)

###5つめ、フォルダの変更。
少しわかりにくいですが、./android/app/src/main/kotlinフォルダの中のフォルダ構造を変更します。

例えば、変更前のパッケージ名が 「com.example.before」だったとすると、
./android/app/src/main/kotlin/com/example/before/MainActivity
というcomフォルダ、exampleフォルダ、beforeフォルダの３つの入れ子でMainActivity
ファイルが入ってます。

これを、「com.example2」に変更するんだとすると、
./android/app/src/main/kotlin/com/example2/MainActivity
というふうにフォルダ名並びに構造を変更してください。
ファイルエクスプローラでやればすぐできます。

###６つめ、MainActivityファイル
上記のMainActivityファイルを開いて、packageの部分を変更したら終了です。
![スクリーンショット 2020-10-06 14.26.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/762871/553460fa-f9cf-882d-e4f7-3b1f2b4fada6.png)
ワンクリックでタイトルとURLをいい感じにコピーする

## やりたいこと

Webページを共有するときに、URLだけじゃなくてタイトル付きでコピーしたい。

```text:これじゃなくて
https://qiita.com/
```

```text:これをコピーしたい
Qiita
https://qiita.com/
```

## 結論

以下のコードをブックマークレットとして保存して実行する。

```bookmarklet:bookmarklet
javascript:(function(){const e = document.createElement('textarea');e.value = `${document.title}\n${location.href}\n`;document.querySelector('body').append(e);e.select();document.execCommand('copy');e.remove();})();
```

## 前提

- いちいち Console 開いてコード書いたりSnippet実行はしたくない。クリックでどうにかしたい。

　　  -> ブックマークレットを使う。

- JavaScript でクリップボードにテキストをコピーする方法は２つ。
  - [Document.execCommand() - Web APIs | MDN](https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand)
  - [Clipboard.writeText() - Web APIs | MDN](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/writeText)

    ２つの方法のうち`Clipboard.writeText()`では、
    （誤解を恐れず言うと）マウスカーソルがWebページ上に乗ってないとエラーになる。
    つまりブックマークレットでは使えない。（`setTimeout`などで回避する方法はあるけど使い勝手が悪い。）
    [参考：navigator.clipboard.writeText() で「Document is not focused.」エラー](https://b.hatena.ne.jp/entry/button/?url=https%3A%2F%2Fnote.kiriukun.com%2Fentry%2F20200908-document-is-not-focused-error-on-calling-navigator-clipboard-writetext&layout=basic-label&lang=ja&mode=popup)

    　-> `Document.execCommand()` を使う。

- `Document.execCommand()`では、DOM要素を作ってそのvalueをコピーできる。
  ただし `input` タグのvalueには改行（`\n`）を使えない。

　　  -> `textarea`を使う。

## 結果

こんなコードを実行すれば解決！

```javascript
(function() {
    const e = document.createElement('textarea');
    e.value = `${document.title}\n${location.href}\n`;
    document.querySelector('body').append(e);
    e.select();
    document.execCommand('copy');
    e.remove();
})();
```

ブックマークレットにコピーするためのコードはこちら。

```bookmarklet:bookmarklet
javascript:(function(){const e = document.createElement('textarea');e.value = `${document.title}\n${location.href}\n`;document.querySelector('body').append(e);e.select();document.execCommand('copy');e.remove();})();
```
mongoseでfindして、そのobjectに値を追加できない | node.js

lean()使うとできるようになる。

```
Item.findById(req.params.id).lean().exec(function(err, doc) {      
  ...
});
```
```
doc.new = "Hi"
```


https://stackoverflow.com/questions/18554350/unable-to-add-properties-to-js-object
ExcelからFilemakerを操作する。

# はじめに
FileMaker便利だけれどUIとかレコード記録のタイミングが独特です。使い慣れたExcelからFilemakerへレコードを登録できれば便利ですね。ということでやってみました。

# 環境
サーバー
windows server 2012 R2
Filemaker server 17

クライアント
windows 10 pro
office 2016



# 準備
ExcelにMicrosotf XMLライブラリを追加する。これはやってもやらなくてもよい。
# Filemaker側
アクセス先のデータベースを作る
SSLはテスト用のものが初期設定されているのでまあなくてもいい
管理コンソールからFilemaker Date APIを有効にしておく
アカウントにFilemaker Date API経由のアクセスを許可する


#JSONをパースする
VBA-JSONを使おう

# FileMakerからトークンを取得する
    Dim strToken As String
    Dim objHTTP As Object
    Set objHTTP = CreateObject("MSXML2.XMLHTTP.6.0")

    objHTTP.Open "POST", "https://[ホスト名]/fmi/data/v1/databases/[データベース名]/sessions", False
    objHTTP.setRequestHeader "Authorization", "Basic [idpw]"
    objHTTP.setRequestHeader "Content-Type", "application/json"
    objHTTP.send

[データベース名]は日本語なら日本語のままで構わない
[idpw]はidとpwを:で連結した文字列をまとめてbase64エンコードする

# FileMakerからとりあえずレコードを取得してみる
    objHTTP.Open "POST", "https://[ホスト名]/fmi/data/v1/databases/[データベース名]/layouts/[レイアウト名]/records?_limit=5", False
    objHTTP.setRequestHeader "Authorization", "Bearer " & strToken
    objHTTP.setRequestHeader "Content-Type", "application/json"
    objHTTP.send

[データベース名]はさっきのもの、[レイアウト名]は[データベース名]と同じく日本語なら日本語のままで構わない。limit=5で最大5件指定。

# FileMakerから検索してレコードを取得する
    Dim jsonObject As Object
    Set jsonObject = New Dictionary
    
    objHTTP.Open "POST", "https://[ホスト名]/fmi/data/v1/databases/[データベース名]/layouts/[レイアウト名]/_find", False
    objHTTP.setRequestHeader "Authorization", "Bearer " & strToken
    objHTTP.setRequestHeader "Content-Type", "application/json"
    objHTTP.send JsonConverter.ConvertToJson(jsonObject, Whitespace:=2)

jsonObjectにクエリをディクショナリー形式で作成してVBA-JSONでJsonを生成する。
クエリの作成がややめんどくさい。以下のような感じで作成した。

    Dim jsonObject As Object
    Set jsonObject = New Dictionary    
    Dim issues As Object
    Set issues = New Dictionary
    
    jsonObject.Add "query", New Collection
    jsonObject("query") = Array(issues)
    issues("項目名") = "検索条件"

jsonObject("query")は検索条件の配列が格納されなければならない。
そしてissuesは項目と条件が対となったディクショナリー形式でなければなない。