OmniAICreator/Qiita-1.07M huggingface dataset:
GOTOとラベル

なんせ少なくとも四半世紀前の記憶を元に記事を書くものだから説明の誤りや不足があればコメントまたは編集リクエストが欲しいです。

#定義
##`GOTO`とは
BASICにおける`GOTO`とは指定の行またはラベルへと実行行を飛ばす命令である。

```BASIC
10 PRINT "Hello, world!"
20 GOTO 10

RUN
```

BASICのインタプリタは行の先頭の数値を認識し、原則としてその数が少ない行から順に実行する。
`GOTO`を用いると、例外的に実行行の順序を変更することができて便利であった。
上記の例は"10"と書かれた行の命令を実行し続ける無限ループである。

##ラベルとは
BASICには自動で行を割り振ってくれるIDEのようなものがあったが、ソースコードが肥大化するにつれ行番号での実行制御では可読性が下がるのは避けられない。そこで便利なのがラベルという概念であった。

```BASIC
10 *START
20 PRINT "Hello, world!"
30 GOTO *START

RUN
```

上記は先ほどの例と同じ処理をラベルを用いて書き直したものである。

#良くない`GOTO`の使い方
現在においては、おおよそほとんどの`GOTO`命令が非推奨である。理由としては下記の通り。

- ラベルを用いてもなお可読性が低い
- 制御構造がわかりづらい
- ネストが難しい

##ラベルを用いてもなお可読性が低い
`GOTO`命令による実行行の移動が一方向であるため、ソースの読者は行き先のラベルを探して読まなければならず、行き先で再度`GOTO`命令が書かれていた場合、その都度行き先を探さなければ読めなかった。

```BASIC
10 *START
20 GOTO *INIT
30 *MAIN
40 PRINT X
50 GOTO *MAIN
60 *INIT
70 LET X ＝ "Hello, world!"
80 GOTO *MAIN

RUN
```

現代的なスクリプトではこのように書きがちだが、これは以下の文と等価である

```BASIC
10 LET X ＝ "Hello, world!"
20 PRINT X
30 GOTO 20

RUN
```

##制御構造がわかりづらい
単なる実行行の移動なのか、またはループを作るために`GOTO`したのかが読まなければわからない。
これは大きなプロジェクトでは致命的であった。

##ネストが難しい
多重ループ制御を`GOTO`で実装することは可能ではあったが、ラベルを用いてもエンバグの恐れがあり、また可読性は著しく下がるものだった。

#代案
そこで便利だったのが`GOSUB`命令である。`RETURN`命令とセットで用いることにより実行行を飛ばした後でも元の位置に戻って来ることが保証されていた。

##`GOSUB`とは
「最後に実行した`GOSUB`命令の直後」まで自動的に戻ってくる命令である。見た方が早い。

```BASIC
10 *START
20 GOSUB *INIT
30 *MAIN
40 PRINT X
50 END
60 *INIT
70 LET X ＝ "Hello, world!"
80 RETURN

RUN
```

###`GOSUB`命令の注意点

- 引数を指定して`GOSUB`することはできない。
- __`RETURN`命令が返り値を取らない__ことにも注意。

BASICでの`RETURN`はあくまでも「最後に実行した`GOSUB`命令の直後に戻る」命令であり、関数型のサブルーチンを定義するためのものではなかった。
なお、BASICの変数は全て、今で言うところのグローバルなので、宣言や定義に悩むことはなかった。

#本記事について
某キャンペーンとの関係はございません。
CI/CDとは何か？

こんにちは！
今回はCI/CDについて、簡潔にお伝えしていきたいと思います。
様々なサイトを参考にまとめさせていただきました。

## 「CI」「CD」の意味って？
### CIとは継続的インテグレーション
継続的インテグレーション(Continuous Integration)。
ソフトウェア開発において、ビルドやテストを自動化し、短期間で品質管理を行う手法のこと。

>インテグレーションとは、
ITの分野では、コンピュータやソフトウェア、ネットワークなどを組み合わせて一体化し、目的を達成するための情報システムを構築すること
出典：IT用語辞典

### CDとは継続的デリバリー（継続的デプロイ）
継続的デリバリー(Continuous Delivery)または継続的デプロイ(Continuous Deployment(継続的デプロイ)。同じ意味で使用されることもあるようです。

継続的デリバリーは開発者によるアプリケーションへの変更に対して、バグがないか自動的にテストし、リポジトリにアップロードする。

継続的デプロイメントは、開発者による変更をリポジトリから本番環境に自動的にリリースし、顧客が使用できるようにするというもの。

## CI/CDとはビルド、テスト、デプロイを自動化するシステム
CIでビルドやテストを自動化し、
CDでテストされたコードのマージや、本番環境向けのビルドの作成を自動的に行う。
CIとCDの作業を合わせて、CI/CDと呼ばれている。
また、CI/CDは手動でやると手間であるため、ツールを使うことがほとんど。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659719/7dd50626-cbd9-d532-6f2b-3e6b5481209d.png)
出典：NIF CLOUD

## CI/CDを導入するメリット
- 開発工数の削減
 - 「テスト」の自動化・・・エラーの自動チェック、既存機能による影響チェックなど
 - 「ビルド」の自動化・・・ソフトウェアを実行可能な状態にパッケージングする工数を削減
 - 「デプロイ」の自動化・・・パッケージをサーバーに配備して利用可能な状態に整える工数を削減


##参考にさせていただいたサイト
参考：[パーソルテクノロジースタッフ（HP）](https://persol-tech-s.co.jp/hatalabo/mono_engineer/233.html)
https://codezine.jp/article/detail/11083
https://pfs.nifcloud.com/navi/words/ci_cd.htm
https://www.redhat.com/ja/topics/devops/what-is-ci-cd
自分の好きな環境で無料GPUを使う

# GPU使いたいけど高くて買えない…
機械学習を勉強していて、GPUがあった方が学習が高速に回せて、効率よく勉強できる。しかし、高くて買えない…

Google Colaboratoryという手もあるが、どうしてもJupyterNotebookになれないし、自分のいつもの環境で作業したい(ちょっとわがまま)。

そんなとき、[こんな記事](https://towardsdatascience.com/colab-free-gpu-ssh-visual-studio-code-server-36fe1d3c5243)を見つけた!

# ColabにsshでアクセスしてGPUを使う

## ngrokからauthtokenを取得する

[ngrok](https://ngrok.com/)にアクセスし、LOGIN->Authentication->Your Authtokenを開く。
そうすると以下のような画面にauthtokenが表示されているのでコピーしておく。


## Google Colaboratryでngrokを実行する
Google Colabを開きランタイム->ランタイムのタイプの設定を開き、ハードウェアアクセラレータをGPUにする。

以下のコードをコードブロックに貼り付けて実行する。
このとき先ほどコピーしたauthtokenを13行目の`YOUR AUTHTOKEN`のところに貼り付ける。

```python
# Install useful stuff
! apt install --yes ssh screen nano htop ranger git > /dev/null
# SSH setting
! echo "root:password" | chpasswd
! echo "PasswordAuthentication yes" > /etc/ssh/sshd_config
! echo "PermitUserEnvironment yes" >> /etc/ssh/sshd_config
! echo "PermitRootLogin yes" >> /etc/ssh/sshd_config
! service ssh restart > /dev/null
# Download ngrok
! wget -q -c -nc https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip
! unzip -qq -n ngrok-stable-linux-amd64.zip
# Run ngrok
authtoken = "YOUR AUTHTOKEN"
get_ipython().system_raw('./ngrok authtoken $authtoken && ./ngrok tcp 22 &')
! sleep 3
# Get the address for SSH
import requests
from re import sub
r = requests.get('http://localhost:4040/api/tunnels')
str_ssh = r.json()['tunnels'][0]['public_url']
str_ssh = sub("tcp://", "", str_ssh)
str_ssh = sub(":", " -p ", str_ssh)
str_ssh = "ssh root@" + str_ssh
print(str_ssh)
```

実行がうまくいくと以下のように表示される。

```bash
WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

ssh root@0.tcp.ngrok.io -p XXXXX
```

## VSCodeで開いて、使ってみる

VSCodeの`Remote-SSH`の機能を使って`ssh root@0.tcp.ngrok.io -p XXXXX`にssh接続してみる。パスワードを求められるが、`! echo "root:password" | chpasswd`で指定していた`password`と打てばよい。

適当に`main.py`などを作り、以下のコードでGPUが使えることを確認

```python
import torch

print(torch.cuda.is_available())
# True
```

使えた！

# 検証

CIFAR10学習させるというタスクで検証を行いました。
実際に使ったコードは[こちら](https://github.com/makky0620/cnn-pytorch)。

比較に使ったのは以下の環境で、エポック数5で実施しました

|       | GPUあり              | GPUなし                    |
| ----- | ------------------ | ------------------------ |
| OS    | Ubuntu 18.04.3 LTS | macOS Catalina v.10.15.5 |
| torch | 1.4.0              | 1.5.1                    |

torchのバージョンを合わせられなかったのは怠惰。

## 結果(1回ずつしか実行していないので決して正しくない)

|       | 速度      |
| ----- | ------- |
| GPUあり | 256.162 |
| GPUなし | 320.412 |

速度が20%くらい速くなった!

# 最後に
ColabではPytorch, Kerasなどの環境構築が予めされているので、それもまた便利!
refile-s3 本番環境でのエラー

# S3を使用するために本番環境でrefile-s3を導入をしたら、エラーが発生。備忘録メモとして残す


##環境
[環境]
Docker
rails ：6.0.3.2
ruby：2.6.6
画像投稿にrefileを使用

## refile-s3の導入参考URL
https://qiita.com/piyor/items/36d2c3c9b8fd638a71a0


## エラーが出たタイミング
デプロイ後に開発環境で行った変更を、デプロイしたアプリケーションに取り込もうとした。
CSS／JavaScript／画像の変更の変更を反映させようと、$ bundle exec rails assets:precompile RAILS_ENV=productionを実行しようとすると以下のエラーが発生。。。


```ruby:qiita.rb
$ bundle exec rails assets:precompile RAILS_ENV=production
Version 2 of the Ruby SDK will enter maintenance mode as of November 20, 2020. To continue receiving service updates and new features, please upgrade to Version 3. More information can be found here: https://aws.amazon.com/blogs/developer/deprecation-schedule-for-aws-sdk-for-ruby-v2/
rails aborted!
Refile::S3CredentialsError: Credentials not found
```

見慣れないエラーが出ると焦るがよくよく観察してみる。



##Refile::S3CredentialsError: Credentials not found

なんやら、認証情報がないということを言っている。
これはおかしいぞ！開発環境で設定しているはず。。。なんでや？


###本番環境の.envに環境変数渡せてなかった（笑）
githubには.envはpushされてないから、そりゃあかんわ
ということで本番環境でも.envを編集

##もう１度assets:precompile

```ruby:qiita.rb
$ bundle exec rails assets:precompile RAILS_ENV=production

Version 2 of the Ruby SDK will enter maintenance mode as of November 20, 2020. To continue receiving service updates and new features, please upgrade to Version 3. More information can be found here: https://aws.amazon.com/blogs/developer/deprecation-schedule-for-aws-sdk-for-ruby-v2/
rails aborted!
ArgumentError: Missing `secret_key_base` for 'production' environment, set this string with `rails credentials:edit`
```

エラー内容変わった！！！！
次はsecret_key_baseが認識されないよーって出てる。
エラーメッセージに従って EDITOR=vim rails credentials:editを実行。


```ruby:qiita.rb
$ EDITOR=vim rails credentials:edit
Adding config/master.key to store the encryption key: 51a9cf17990831141be76494f7e7feb6

Save this in a password manager your team can access.

If you lose the key, no one, including you, can access anything encrypted with it.

      create  config/master.key

Couldn't decrypt config/credentials.yml.enc. Perhaps you passed the wrong key?
```


masterkeyが正しくないだと？？？
ここには自分で解決できず、現役エンジニアさんに質問して解決してもらった。



##解決するためにやったこと

```ruby:qiita.rb
$ mv config/master.key config/master.key.bak
$ mv config/credentials.yml.enc config/credentials.yml.enc.bak
$ EDITOR=vim rails credentials:edit
```

編集画面が出て保存！！！


```ruby:qiita.rb
$ bundle exec rails assets:precompile RAILS_ENV=production

Version 2 of the Ruby SDK will enter maintenance mode as of November 20, 2020. To continue receiving service updates and new features, please upgrade to Version 3. More information can be found here: https://aws.amazon.com/blogs/developer/deprecation-schedule-for-aws-sdk-for-ruby-v2/
yarn install v1.22.4
[1/4] Resolving packages...
[2/4] Fetching packages...


なんやかんや、、、、


Compiling...
```


コンパイルしてくれた。。。。
Spring Boot本レビュー: Spring Bootビギナーズガイド: Webアプリケーション開発を高速化せよ！

https://www.amazon.co.jp/dp/B00YHIZMJK/

3冊目。これまでのレビューは[こちら](https://qiita.com/tags/springboot%e6%9b%b8%e7%b1%8d%e3%83%ac%e3%83%93%e3%83%a5%e3%83%bc)から。

* Spring Boot 1系

という時点で選外。

仮にSpring Boot1 の入門書を探していたとしても、本書は入門書でなく(良く言っても)手順書なので薦められない。

Amazonのレビューを見る感じ、本書をベースにして

- Spring Boot 2 プログラミング入門 https://www.amazon.co.jp/dp/B07KF4R1HT/

を書いているのではないかと。
とすると、こちらも同様あまり薦められるものではないように思われます。
Rust を書こう！（１）

# Rustを書こう！（１）
## 概要
変数宣言と制御構文を記載しています。
他の言語（CとかC++とかPython）をさわったことがある人向けの荒い内容です...
環境設定については[過去記事](https://qiita.com/geek_777/items/895152fab261819b5ccd)を参照ください。

## Rustでの変数宣言（可変性）
Rustでの変数宣言は以下のようにして行います。

```Rust
let /*可変性*/ /*変数名*/ : /*型*/ = /*値*/;
```
可変性についてですが、/\*可変性\*/のところに何も記載しなければRustではすべての変数が宣言時にinmutableで宣言されます。（宣言時に代入をするとそのあとで書き換えができない）そのため以下のようなコードはコンパイル時にエラーを吐きます。

```Rust:example1.rs
fn main() {
    let num = 1;
    num = 209; // これができない
}
```

変数の書き換えを行いたい場合は宣言時に`mut`という予約後を使用する必要があります。以下に例を示します。

```Rust:example2.rs
fn main(){
  let mut num = 1;
  num = 100;
}
```
また、Rustでは何度も同じ変数名を持った変数を宣言することができ、example1.rsを書き換えた

```Rust:example3.rs
fn main() {
    let num = 1;
    let num = 209;
}
```

は問題なくコンパイルできます。~~ただ、2回目の宣言時に1回目に宣言されたnumはメモリが解放されるのでアクセスができません。~~

## Rustにおけるデータ型
Rustにおけるデータ型は以下のようになっています

|予約語|データ型|
|---|---|---|
|i8,i16,i32,i64,i128|符号付き整数(数字はBit数)|
|u8,u16,u32,u64,u128|符号なし整数(数字はBit数)|
|f32,f64|浮動小数点数|
|bool|bool値（true,false）|
|char|文字|
|str|文字列|
|isze,usize|配列などでのメモリアクセス用の型|

以下に例を示します。

```rust:example4.rs
fn main(){
    let num1 : u32 = 100;
    //ただの数字の場合勝手にi32になるので
    let num2 = 100;// この場合はi32です。
}
```
※Rustではコンパイラがデータ型を自動で推測してくれるので明記する必要はあまりないです。

## 制御構文
### 条件分岐
Rustでの条件分岐は`if /*条件*/ {/*処理１*/} else {/*処理２*/}`で行います。
以下に偶数と奇数の判定をするサンプルコードを記載します。

```rust:exapmle5.rs
fn main(){
    let num = 100;
    if num % 2 == 1{
        println!("odd");
    }else{
        println!("even");
    }
}
```

C言語のように`if`の後に`()`を入れる必要はないです。

### ループ
Rustの繰り返し構文は３つあります。`loop{}` `while/*条件*/{/*処理*/}` `for`の３つです。以下に0〜9までの数字を表示するコードを示します。

```rust:example6.rs
fn main() {

    for i in 0..10{
        print!("{}",i);
    }
    println!();// 改行
    
    let mut i = 0;
    while i < 10 {
        print!("{}",i);
        i += 1;
    }
    println!(); // 改行

    i = 0;
    loop {
        print!("{}",i);
        i += 1;
        if i == 10{
            break;
        }
    }
}
```
`break`を使うことによってループから抜け出します。for文についてはiteratorと併用ができるのでiteratorの紹介をする際にもう一度詳しく紹介します。

次回はRustでのタプルや配列、標準出力、借用を紹介します。
Spring Boot本レビュー: 【後悔しないための入門書】Spring解体新書　Java入門のあとはこれを学ぶべき: Spring Boot2で実際に作って学べる！Spring Security、Spring JDBC、Spring MVC、Spring Test、Spring MyBatisなど多数解説！

結論を先に書いておくと、入門書として薦められる本ではないと私は考えています。

---

https://www.amazon.co.jp/dp/B07H6XLXD7/

初学者に薦められるSpring Boot入門本を探しています。
本書は2冊目。他の書籍については[こちら](https://qiita.com/tags/springboot%e6%9b%b8%e7%b1%8d%e3%83%ac%e3%83%93%e3%83%a5%e3%83%bc)を参照。


さて前回の書籍「[Spring Boot 2 入門: 基礎から実演まで](https://qiita.com/write_once_run_anywhere/items/43ec78ce851f9b1be410)」では、
> * ○ 公式リファレンスへ準拠しようという意志が感じられる。

というように書きましたが、この本は、まさに逆です。
つまり、一次情報を参照する意志が感じられず、二次情報を見たり自分の経験だけで語っているように感じます。
なので、用語の使い方を誤っていたり、概念を正しく理解できていなかったりしている箇所が散見されます。

また、前の方の章で概念の説明をしていて、後ろで実際に実装を行っているのですが、先に説明した概念が後ろのコードに反映されていなかったりして、書籍の中で自己矛盾していたりします。

例えば、依存性を排除するためにインタフェース経由でアクセスするんだ(4.2.1節)、説明しつつ後ろのコードではクラスを直接インジェクションしていたり(8.3.5節 `UserService`)、`@Scope`をつけないとsingleton-scopeになるのでインスタンスが1つしか生成されず大量のリクエストを捌けない(4.4.2節。ちなみにこの説明自体誤っている)と説明しているにも関わらずコード上には一切 `@Scope` が表れなかったり。

---

一次情報をちゃんと確認する習慣がないと、まさにこれくらいで頭打ちになってしまうと思うので、入門者卒業試験として本書にツッコミを入れていく、みたいな使い方はできそうに思います。
が、冒頭に記載した通り、入門書としてはお薦めできません。
Plasm(substrate)のSmart ContractをSolidityで実装出来るようになったので試す！！

# Plasmのチュートリアルが追加されました
- Stake TechnologiesのHPにPlasmのスマートコントラクトが[Solidityで実装出来るようになったという記事](https://docs.plasmnet.io/workshop-and-tutorial/solidity)が出た。
- Stake Technologiesはレイヤー１のパブリックブロックチェーンを作っている企業で凄く注目しています。[ホームページはこちらから](https://stake.co.jp/)
- これはWeb3Foudationのgrant programのようです。(https://solang.readthedocs.io/en/latest/index.html)
- eco systemがますます広がっている感じがして、注目度アップですね。

# さっそくやっていきます
- 何も工夫はありませんので、チュートリアル通りにやってください。
- 環境によるのだと思いますが、少しだけハマったので、そこだけメモとして残します。

# 環境
- ubuntu18.04
- ※試したのはAWS LightSailとWindowsのwslのubuntu18.04

# 問題の箇所
- チュートリアルに記載されている通りにやるとエラーがsolangのコンパイルでエラーになります。

```
sudo apt install llvm openssl libxml2-dev
cargo install --git https://github.com/hyperledger-labs/solang --tag m8
```

- エラーメッセージは昨夜確認したので、消えてしまって覚えていませんが、**「llvmのバージョン８が必要」**という中身だったと記憶しています。

# 回避手段
- 結構時間をかけて調べた割には凄く簡単に回避可能でした・・・
- llvm8のインストールします。

```
sudo apt-get install llvm-8
```
- それでコンパイルすると、**「おお！solangがコンパイルされた」**
- あとはチュートリアル通りにやっていけば動作します。

# substrateでsolidityが使えるのは大きい
- 私はC言語をやっていたので、Rustはそれほど障壁を感じませんでしたが、JavaやPythonから始めたプログラマーにはRustの学習コストは少し高いのかと思っています。
- そういう意味で、Solidityでスマートコントラクトが実装出来るようになったのは非常に大きいことだと思います。
- 当然ながら、Ethereumのサポート言語であることからも、大きいことですね。

# 微力ながらこれからも応援します。
- Plasm Network、これからも本当に微力ながら応援していきたいです。
- 興味がある方は、[Plasmのホームページ](https://docs.plasmnet.io/)にDiscordの招待リンクがありますので、そこからコミュニティにジョインして頂くと良いと思います。
今さらawkでメタ文字エスケープ、コマンドインジェクション対策

# メタ文字（エスケープシーケンス）をawkでエスケープする
## 目的
- LATS(Linux Apache Textfile and Script)でWEBアプリを作っています。
- セキュリティ向上のためHTMLから悪意のある文字列入力がであってもサーバで実行できないようににしたいと思いました。
- 具体的にはダイレクトOSコマンドインジェクションやディレクトリトラバーサルとか呼ばれる攻撃を避けようと思いました。
- rubyには[escapeHTML()](https://techacademy.jp/magazine/12553)があり

> 与えられた文字列中の '、&、"、<、> を実体参照に置換した文字列を新しく作成し返します。

とあります。

- phpにも HTML特殊文字をエスケープする [htmlspecialchars()](https://kudox.jp/php/htmlspecialchars)があります。

- 今回はサーバサイドつまりscriptでHTMLの制御文字だけでなく、[メタ文字（エスケープシーケンス）](https://xtech.nikkei.com/it/article/COLUMN/20060228/231046/)をHTMLの文字実体に変換することを考えます。クライアントサイトでは比較的に簡単に検索できました。でもBrowserだけでなく、curlなどでも攻撃がありえるのでJavaScriptだけでなく、サーバサイドでの対策します。

### クライアントサイド(JavaScript)の例
- [JavaScriptでは](https://qiita.com/saekis/items/c2b41cd8940923863791)、`string.replace()`でできるそうです。

### 実験
- Shell Scriptでは`sed`とか`awk`とかが思いつきます。それで実験してみます。

```{bash}
$ echo '!' | sed -e 's|!|\&#33;|g'                                                                                                                                                                                                                                      
&#33;   
```

とうまくいきそうです。でも２つ以上`-e`の変換コマンドを続けるとうまくいきません。

```{bash}
$ echo '!' | sed -e 's|!|\&#33;|g' -e 's|\&|\&#63;|g'                                                                                                                                                                                                                   
&#63;#33; 
```
これはsedが一つ目の`-e`で置換した結果に対して２つ目の`-e`を適用するためです。一つ目の変換された`&`が２つ目の`-e`でさらに変換されたのです。
awkも次の構文ではうまくいきません。

```{bash}
$ echo '!' | awk '{gsub("!","\\&#33;",$0); gsub("&","\\&#63;",$0);print}'                                                                                                                                                                                               
&#63;#33;
```
sedと同じく、一つ目の`gsub()`は`$0`を書き換えるため、二つ目の`gsub()`でそれを変換するためです。それではどうしましょうか。お風呂に入っていて思いつきました。

### 考え方とテスト
- 文字毎に変換したら終わりのスクリプトにすればいいです。そのため、文を文字に分解して、分解された文字がメタ文字と一致したら一度だけ変換しおしまいにします。
- ツールは万能`awk`を使いましょう。文字毎に変換は`fold -w 1`でもできますが、パイプで渡すくらいなら`awk`だけで処理しましょう。文字列分解の参考は[こちら](https://qiita.com/neko_the_shadow/items/1d869474086c64a93ba0)。`gawk FS=''`で文字分解できました。MacOSの`awk`ではNGでした。

```{bash}
$ cat escapeHTML.bash
#!/usr/bin/env bash
gawk -v FS='' '{
 for (i = 1; i <= NF; i++) {
  if(       $i == "!" ) { printf "&!#34;" 
  }else if( $i == "?" ) { printf "&#63;"
  }else if( $i == "&" ) { printf "&#38;"
  }else if( $i == "#" ) { printf "&#35;"
  }else {printf "%s", $i}
 }
}'        
```

```{bash}
$ echo '!' | ./escapeHTML.awk                                                                                                                                                                                                                                           
&!#34;
```
いい感じです。長い文字列も試してみましょう。

```
$ echo '12345!?&#あいうえお' | ./escapeHTML.bash
12345&!#34;&#63;&#38;&#35;あいうえお
```

うまくいっています。テストコードですがご参考まで。もっといい方法があったら教えてください。

#### 参考
[数字参照](http://atomicbox.tank.jp/special-character/)
FileDialog作成中

```vb:FileAggregater.cls
Option Explicit

Public Sub FilePicker()
Dim DirPath As String
Dim DirPathDisplay As Object
Dim Dialog As Object
Set Dialog = Application.FileDialog(msoFileDialogFolderPicker)
    With Dialog
        .AllowMultiSelect = False
        .Title = "Please pick the file to convert."
        .Filters.Clear
'        .Filters.Add "Picture Files", "*.Jpg"
'        .Filters.Add "All Files", "*.*"
        If .Show() = 0 Then
            MsgBox "No folder is selected."
        Else
            Me.DirPath = .SelectedItems(1)
        End If
    End With

    If DirPath <> "" Then
        MsgBox "There is no file with which could be deal"
    End If
    
    'Set DPD_TXTB = New DirPathDisplay

    'DirPathDisplay.Value = Picker.DirPath
End Sub

```

```vb:FormAggregater.frm
Private Sub CMD_DirSelect_Click()
    Dim Picker As FileAggregater
    Set Picker = New FileAggregater
    Picker.FilePicker
End Sub
```
退職される度に全サーバーのauthorized_keysを編集するのが辛い

そう思っていましたが退職した方から解決策を教えていただきました。AWSのEC2の話になります。

今パブリックに公開しているSSHのポートはセキュリティグループで閉じてしまい、秘密鍵だけがあっても入れないようにしてしまいましょう。
その上でセッションマネージャー使うことで、AWSCLIアクセスキーによる認証でSSHできるようになります。
秘密鍵の制御はサーバーの数だけ作業しないといけませんが、AWSのアカウントはコンソールで一元制御かつ簡単に無効化できるので、サーバーが大量にある場合に特に効果を発揮します。

以下デモです。EC2インスタンスを作成します。EC2インスタンスにロール`AmazonSSMManagedInstanceCore`や`AmazonSSMRoleForInstancesQuickSetup `がアタッチされることで、セッションマネージャーからアクセスできるようになります。初期状態だとロールがないので、セッションマネージャーの高速セットアップで作成しましょう。

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256466/08928ad9-02db-99eb-0cb0-3f6e3bd8fc8c.jpeg">


作成後に5〜10分待つとEC2にロールがアタッチできるようになります。

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256466/58f4c85b-4700-2e10-57a5-f46ba295fb67.jpeg">

、アタッチ後にさらに5分ほど待つと、セッションマネージャーから選択可能インスタンスとして候補に上がりました。ブラウザから開始するか、コマンドで以下のようにもスタートできます。

```bash
$ aws ssm start-session --target i-072i1e2868daf86

Starting session with SessionId: umihico-0d274fa3791c81e3c
sh-4.2$ 
```

最近のAmazonLinux2は最初からSSMエージェントが入っていますが、入ってない場合は以下でインストールできます。

```
sudo yum install -y https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm
```

awscliコマンドではなく、慣れているsshやscpを使えるようにしたいので、.ssh/configに追記します。

```bash:~/.ssh/config
host i-* mi-*
    ProxyCommand sh -c "aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"
    User ec2-user
```

これでsshコマンドも通るようになりました。

```
$ ssh  -i ~/.ssh/umihico.pem i-072i1e2868daf42

       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-2/
9 package(s) needed for security, out of 16 available
Run "sudo yum update" to apply all updates.
[ec2-user@ip-179-41-11-188 ~]$ 
```

セキュリティ的な議論でAWSアクセスキーにスイッチできない場合はauthorized_keysの編集は避けれませんが、Macであれば直接編集するリスクを取らず、`ssh-copy-id`コマンドを使えば楽にできそうです。[こちらが参考になりました。](https://qiita.com/ir-yk/items/af8550fea92b5c5f7fca)

参考

- https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/systems-manager-quick-setup.html
- https://www.karakaram.com/aws-session-manager-tunneling-support-for-ssh/
- https://qiita.com/syoimin/items/6f5f0aca002161d40233
- https://qiita.com/kentarosasaki/items/aa319e735a0b9660f1f0
- https://qiita.com/ir-yk/items/af8550fea92b5c5f7fca
- https://qiita.com/itiut@github/items/94b248ba93efee8960d3
python: 配列(リスト)をインデックス付きで表示するTips (配列の要素が何番目にあるか調べる方法)

# やりたいこと
Pythonで、配列とかが長いとき、自分が取得したいのが何番目にあるかぱっとわからないことがある。
(表とかの列で何列目とってくればいいとか考えるとき)
ググってもあまり出てこなかったのでメモ。

# コマンド

```Python
print([str(i) + ": " + x for i,x in enumerate( YOUR_LIST )])
```
リスト内包表記 + enumerateでできる!

# Example
```Python
list = ["A", "B", "C", "D"]
print([str(i) + ": " + x for i,x in enumerate(list)])

>> ['0: A', '1: B', '2: C', '3: D']
```
ゼロから始めるLeetCode Day89 「62. Unique Paths」

# 概要

海外ではエンジニアの面接においてコーディングテストというものが行われるらしく、多くの場合、特定の関数やクラスをお題に沿って実装するという物がメインである。

どうやら多くのエンジニアはその対策としてLeetCodeなるサイトで対策を行うようだ。

早い話が本場でも行われているようなコーディングテストに耐えうるようなアルゴリズム力を鍛えるサイトであり、海外のテックカンパニーでのキャリアを積みたい方にとっては避けては通れない道である。

と、仰々しく書いてみましたが、私は今のところそういった面接を受ける予定はありません。

ただ、ITエンジニアとして人並みのアルゴリズム力くらいは持っておいた方がいいだろうということで不定期に問題を解いてその時に考えたやり方をメモ的に書いていこうかと思います。

[Leetcode](https://leetcode.com/)

Python3で解いています。

[ゼロから始めるLeetCode 目次](https://qiita.com/KueharX/items/6ee2502c3b620c795b70)

前回
[ゼロから始めるLeetCode Day88「139. Word Break」](https://qiita.com/KueharX/items/ac025ce072d98751e688)

[Twitter](https://twitter.com/kueharx)やってます。

**[技術ブログ](https://kueharx.blogspot.com/)始めました！！**
技術はLeetCode、Django、Nuxt、あたりについて書くと思います。**こちらの方が更新は早いので**、よければブクマよろしくお願いいたします！

# 問題
[62. Unique Paths](https://leetcode.com/problems/unique-paths/)
難易度はMedium。
[コーディング面接対策のために解きたいLeetCode 60問](https://1kohei1.com/leetcode/)からの抜粋です。

問題としてはユニークな経路の数を求める、というものです。
ロボットが`m x n`のグリッドの左上隅に位置しています（下図では「スタート」と表示されています）。

なお、ロボットはどの時点でも下か右にしか移動できません．ロボットはグリッドの右下隅に到達しようとしています（下図では「Finish」と表示されています）。

今回は図を載せないので、噛み砕いて考えたい方は直接問題のリンクで確認してください。

>Example 1:

>Input: m = 3, n = 2
Output: 3
Explanation:
From the top-left corner, there are a total of 3 ways to reach the bottom-right corner:
1. Right -> Right -> Down
2. Right -> Down -> Right
3. Down -> Right -> Right

>Example 2:

>Input: m = 7, n = 3
Output: 28

#解法

ユニークな経路の数を求める問題ですね。
こちらも前回同様Dynamic Programmingで解くのが非常に効果的な問題のタイプです。

ちなみに経路の求め方についてですが、説明は[こちら](https://www.youtube.com/watch?v=GO5QHC_BmvM)の方が英語で超分かりやすく説明してくださっています。あまり馴染みがない方でも比較的理解がしやすいと思うので、初めてこういう問題を解く場合は見てみることをオススメします。

では解答です。

```python
class Solution:
    def uniquePaths(self, m: int, n: int) -> int:
        if m == 1 or n == 1:
            return 1
        if n < m:
            self.uniquePaths(n,m)
        dp = [1]*n
        for i in range(1,m):
            for j in range(1,n):
                dp[j] += dp[j-1]
        return dp[-1]
# Runtime: 28 ms, faster than 84.67% of Python3 online submissions for Unique Paths.
# Memory Usage: 13.8 MB, less than 74.12% of Python3 online submissions for Unique Paths.
```

なお、前半の

```
dp = [1]*n
```

以上のコードは別になくても回答は通ります。
が、どうしても例外が発生する可能性もあるので書いておくほうが無難でしょう。
事実discussの解答でも多くの人が書いていますし、仮にコーディング面接等だったら突っ込まれる可能性があると思いますし。

それから後のコードは基本的には先ほど紹介した動画で説明されていたことをそのままコードにした、という感じなのでそこまで説明が必要ではなさそうです。

ちなみにこの問題をYouTubeで検索するとAmazonで出題されたことがある、というような紹介のされ方をされているので、気になる方は調べてみると良いかもしれませんね。

では今回はここまで。お疲れ様でした。
railsアプリのデフォルトのタイムゾーンを変更する

###問題
公開したアプリのDate.todayが、開発環境ではローカルの時刻を取得できたが、公開したらUTC時刻になっていた。

###やったこと
デフォルトのタイムゾーンを日本時間に変更

```(アプリ名)/config/application.rb
config.time_zone = 'Asia/Tokyo'
```

これによって、データベース上ではUTC時刻で登録されているが、アプリ内ではTokyoの時刻として表示する（UTC＋９：００されたのが確認できると思う）。

本日の日付けを取得するメソッドとして
Date.today→Time.zone.todayに変更

データベース上に、デフォルトではUTC時刻で登録されて、Time.zoneを使ってローカルの日時に変更することが多いので、このやり方を覚えておく。
Python 属性のエイリアス

`property()` をデコレータではなく、ただの関数として使う。
[SQLAlchemy で使われている。](https://github.com/sqlalchemy/sqlalchemy/blob/4d277a24652c1092b2bacd73dbb6b465a5554594/lib/sqlalchemy/sql/selectable.py#L774-L777)

```python
from operator import attrgetter


class A:
    def __init__(self):
        self.foo = "foo"

    f = property(attrgetter("foo"), doc="An alias for the :attr:`.foo` attribute.")


if __name__ == "__main__":
    help(A.f)

    a = A()
    print("A.foo:", a.foo)
    print("A.f:", a.f)
```

実行例。

```sh
$ python sample_alias.py
Help on property:

    An alias for the :attr:`.foo` attribute.

A.foo: foo
A.f: foo
```
CompodocでAngularのドキュメンテーションを生成してみる

##Compodocとは
[Compodoc](https://compodoc.app/)はAngularのドキュメンテーションをコマンドだけで自動生成してくれる便利なパッケージです。一般的なドキュメンテーションに加えて、コンポーネントなどの相関図やDOMツリーなどの一目でわかる図も生成コマンド一つでやってくれます。参考までに[公式のサンプル](https://compodoc.app/guides/demo.html)の図を掲載しておきます。
![Screen Shot 2020-07-16 at 20.53.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343061/ea3dca99-64d8-7803-3b06-8b7dae560a84.png)

##インストールしてみた
![Screen Shot 2020-07-16 at 21.12.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343061/726a24ee-3ceb-976a-c708-eb6f36b605dd.png)


[公式のインストールガイド](https://compodoc.app/guides/installation.html)ではnpmを使っていますが、yarnの場合もターミナルで
```yarn add "@compodoc/compodoc"```と打ち込むだけでインストール完了です。さらにpackege.jsonに

```
//package.json
//tsconfig.app.jsonのディレクトリパスは自分のものを適用してください

"scripts": {
  "compodoc": "npx compodoc -p src/tsconfig.app.json"
}
```

と追加しておけば、```npm run compodoc``` または```yarn compodoc```のコマンドを実行するだけでドキュメンテーションが生成されます。自分の環境では上記のようにしても```main.ts```しか認識されずコンポーネント等は無視されてしまったので、```tsconfig.app.json```の代わりに```tsconfig.json```にパスを通したら正常に生成されました。

また、サーバー起動も```compodoc -p src/tsconfig.json -s```のコマンドでできます。デフォルトのアドレスは```http://localhost:8080```です。例として```npx compodoc -p ./tsconfig.json -s -r 9000```のコマンドでポート指定を変えて```http://localhost:9000```に設定することもできます。

##コメントやタグについて
生成するためのコメントの仕方は特に他の言語のものと変わらないと思います。

```
/**
 * supported comment
 */


/*
 * unsupported comment
 */


/*
  unsupported comment
 */


// unsupported comment

```

タグは[公式ページ](https://compodoc.app/guides/jsdoc-tags.html)を参照してください。JSDocタグのうち全てが使えるわけではないようなので、使う人によっては[TypeDoc](https://typedoc.org/)の方がいいかもしれません。
Pythonプログラミング備忘録（ファイル操作）

あまりにもググるので自分用Pythonプログラミング備忘録
(自分が忘れるものに特化しています)
試験的に1ブロックで書いています。
参考書：[独学プログラマー Python言語の基本から仕事のやり方まで](https://www.amazon.co.jp/dp/B07BKVP9QY/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)
(セクション名などは参考書に従います)
対象言語：Python 3.6.3
# §9　ファイル

### 書き出し・読み込み処理
```python:FileOperation.py
##  OS間のファイルパスの違いを吸収するため、ファイルパスはosモジュールを利用する
import os
os.path.join("Users", "bob", "alice.txt")

##  日本語文字列を書き込む場合はencodingを忘れずに。
Copy = open("paste.txt" , "w", encoding = "utf-8")
Copy.write("「三名様でお待ちの　フ、フリーザ様～」")
Copy.close()
####  with openのほうが自動的に閉じるので楽
with open("paste2.txt", "w", encoding = "utf-8") as f:
    f.write("「さぁ！行きますよ！ザーボンさん、ドドリアさん！！」")

##  CSVファイルの処理はCSVモジュール
import csv
####  書き込み(newlineは改行モードの指定
####  デフォルトではNoneで、このときの動作は、\r、\n、\r\nを改行コードとみなす）
with open("paste.csv", "w", newline = "") as f:
    w = csv.writter(f, deliminater = ",")  # CSVなので区切り文字をカンマに設定
    w.writerow(["one", "two", "three"])
    w.writerow(["four", "five", "six"])
####  読み込み
with open("paste.csv", "r") as f:
    w = csv.writter(f, deliminater = ",")  # CSVなので区切り文字をカンマに設定
    w.writerow(["one", "two", "three"])
    w.writerow(["four", "five", "six"])

```

実行結果

```python:
## ファイルパス結合結果
'Users\\bob\\alice.txt'
```
なぜ配列は 0 から始まるのか

# はじめに
皆さんもプログラミングを学び始めた際に、こう思ったのではないでしょうか。

**配列のインデックスってなんで 0 から始まるの？？**

僕もそのような疑問を抱いた覚えがあります。
なんとなく、 **配列とはそうゆうものだ。** と片付けている方も多いのではないでしょうか。
この機会に是非、配列の歴史を学んでみましょう。

# 初めの頃は 1 だった
配列という概念を持つ最も古い言語は **FORTRAN** と言われています。

>Fortran は1950年代に誕生した、世界初の高級プログラミング言語です。
Fortran は "FORmula TRANslation" の略です。

この FORTRAN という言語は 1 に基づく配列を採用していました。
後に COBOL, BASIC, R, Lua などの言語も、1 に基づく配列を採用するようになりました。

# C言語の登場
C言語の登場により、ポインタ演算には 0 から始まる配列 (zero-based index) の方が使いやすいのではないかという認識が生まれました。

>ポインタ型データは、メモリ上にあるオブジェクトの位置（メモリアドレス）を意味しています。
この「メモリアドレス」は0から始まる整数値であり、ポインタ型データと整数データの間で加減算を行うことで必要なメモリアドレスを計算できるようになっています

これらのメリットを踏まえ、C言語で初めて 0 から始まる配列が採用されることになります。
以降、様々な言語で 0 から始まる配列 (zero-based index) が採用される事となりました。

# 0 or 1 の戦い
とはいえ、現在も様々な議論が行われおり、 0 から始まる配列と 1 から始まる配列のメリデメに関して様々な意見を耳にします。

よく話題に上がる文献としては、オランダ人の計算機科学者であり、チューリング賞を受賞者でもある、エドガー・ダイクストラ先生の [Why numbering should start at zero](http://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/EWD831.html) があるので興味のある方は読んでみてください。

# まとめ
以上、軽くまとめてみましたが、どちらが優れているかという論題になってしまうと、僕も混乱してしまうのが本音です。

とはいえ、なぜ 0 から始める配列が生まれたかを学ぶことで、身近な初心者のモヤモヤを晴らす手助けが出来たらと思います。

参考にさせて頂いた文献には更に詳しい解説が載っているので、興味のある方は是非読んでみてください。

### 参考文献
[Why do array indexes start with 0 (zero) in many programming languages?](https://www.quora.com/Why-do-array-indexes-start-with-0-zero-in-many-programming-languages)
[Why numbering should start at zero](http://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/EWD831.html)
[Zero-based numbering](https://en.wikipedia.org/wiki/Zero-based_numbering#Usage_in_programming_languages)
Hexo 5.0 の新機能、Injectorについてのまとめ

想定読者：[Hexo](https://hexo.io/)向けのプラグインを開発する方

いままでは、Hexoのプラグインで、テーマ(HTMLのテンプレート)を直に編集することなく、cssやjavascriptを挿入する動作を実現することが、困難でした（個人的見解です）。

新バージョンの5.0では、それに対する解となるような、新規機能が登場する~~見込み~~です。
この記事は、そいつの紹介です。

- [【HowTo】Hexoの新しいInjectorについて調べた【5.0】](https://pages.isnot.jp/2020-07/16-HowTo-HexoInject/)
    - 新しいInjectorが登場した背景説明と、APIドキュメントの私家版和訳
- [Hexo 5.0 実装予定のInjectorを試す](https://pages.isnot.jp/2020-07/16-TestForInjectorOfHexo5/)
  - 上記で調べた内容を元にして、実装および開発環境で動作確認しました

- Injectorに対応したプラグインの[実装例](https://github.com/isnot/hexo-tag-google-photos-album/blob/2567db33512742acf769e7f8c2b64866b0274c6c/index.js#L215)

以上。
Ubuntu 18.04 に Elasticsearch をインストール

# 背景
サーバをレンタルして一からESを立ち上げたので手順をメモします

# 前段
sudo apt update

# java
sudo apt install openjdk-11-jdk

# gnupg
sudo apt install gnupg

# Elasticsearch
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
echo "deb https://artifacts.elastic.co/packages/6.x/apt stable main" | sudo tee -a /etc/apt/sources.list.d/elastic-6.x.list
sudo apt install elasticsearch

# その他
ESを叩く際にcurlを使いたいので入れておく
sudo apt install curl
[Salesforce] 新たなソース管理&デプロイツール DevOps Centerとは #TDX20

# 参考資料
![image-9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331690/859d494f-e119-7b81-0bb8-d6059d7d05a0.png)

- **こちら([Trailheadx 20](https://www.salesforce.com/trailheadx/))で発表された機能**
- 現在(2020/07/17)もこの機能を作成中のチームがSalesforceのリリース機能についてアンケートを受付中です。**([Salesforce開発チーム リリース管理の調査アンケート](https://docs.google.com/forms/d/e/1FAIpQLSdO9wN59MWaODZTSB0SVz6K2GfUM3QSdGyIf7924cD722q3nQ/viewform))**

- **[DevOps Center概要 - Salesforce admins](https://admin.salesforce.com/blog/2020/new-devops-center-is-awesome-for-admins)**

- **[DevOps Center Quip - よくある質問事項まとめ](https://quip.com/9acRAAfljeyp/DevOps-Center-FAQ)**


- **[DevOps Center デモ動画](https://trailblazers.salesforce.com/0694S000000dna1)**

# DevOps Center 概要

- **※まだまだ開発段階で詳細不明点が多い**
- **とりあえず劇的にバージョン管理・リリースが楽になりそう！！！**

### Before
- **変更セット = デプロイツール**

### ToBe
- **変更セット = 実質廃止？**
- **DevOps Center = デプロイツール + バージョン管理ツール(GitHub、Bitbucket、GitLab)と連動**

### まとめ
- **開発環境自体(DevOps Center)がリリース&バージョン管理機能を内包**
- **Salesforce内でバージョン管理が可能になる**
- **SandBoxで開発を行ってDevOps Centerで差分を確認して本番環境にプッシュ、本番環境のDevOps CenterでSandBoxの差分をPullしてきてレビュー後マージ？的な感じで簡単にバージョン管理リリースが行える様になる？(GUIで可能)**


## DevOps Centerは変更セットに置き換わるデプロイツール
    
- 変更セットによって提供されている機能を包含することが目的
- DevOps Centerと変更セットの機能が同等になったら、可能な廃止戦略を検討している
- 現在の変更セット機能をさらに拡張する予定はない 

## DevOps Centerはバージョン管理ツールと連携する

- 差分管理 = 開発環境のメタデータを自動的に追跡、DevOps Centerでプルするだけで変更されたソースファイルを識別および管理できる
- GUI操作のみで管理 = ツールはバックグラウンドでコミットし、メタデータソースファイルを接続されたGitHubリポジトリのブランチにプッシュし、プルリクエストも作成、GitHubコマンドを直接実行する必要がない
- GitHub、Bitbucket、GitLabを初めにサポートする
- JIRAやAgile Acceleratorなどのアジャイル作業追跡ツールと連携可能

**※DevOps Centerはバージョン管理ツール(GitHub、Bitbucket、GitLabなど)を使用する必要がある(使うことが前提)**

# リリース予定

- Developer Previewリリースを2020年9月
- 正式版は2021年中旬を目標

# DevOps Centerアドオンの価格

- 無料および有料のサービスを提供する予定
- 価格とパッケージングは未定

# DevOps Centerは管理パッケージとしてリリースされる

- 本番DevHub組織にインストールされ。その後に、Sandbox、Scratch Org、Production Orgに接続して、開発を行い、変更をデプロイできる。
グローバルな定数をJavaScriptで作りたかった

#いきさつ
Railsでモデルに定義した定数をコントローラーのどのアクションからでも呼び出せるような・・・
そんなことをJavaScriptでもやりたかった。

#Railsだと（やりたいこと）
モデル

```ruby
# user.rb
MY_NAME = 'Kyohei'

def piyo
  p MY_NAME
  # => 'Kyohei'
end
```

コントローラー


```ruby
# users_controller
def hoge
  p MY_NAME
  # => 'Kyohei'
end

def huga
  p MY_NAME
  # => 'Kyohei'
end
```
どのメソッド（アクション）からも呼べるし、application_controllerに書いたら本当にどこからでも呼べそうな勢い。

# JavaScriptだと

```javascript


document.getElementById("hoge").onclick = () => {
  const MyName = 'Kyohei'
  console.log(MyName)
  // => 'Kyohei'
};

document.getElementById("huga").onclick = () => {
  console.log(MyName)
  // => 当然エラー
};

```
こんな時、別々の関数で同じ定数が使えたらなーと思ったのです。
もちろん定義は一回でやりたい。

#やったこと
[こちら](https://pisuke-code.com/js-way-to-create-global-constant/)の記事を参考にさせていただきました。
`Object.defineProperty`を使用します。

## 定数を作る関数を書く
まずは共通で使える関数を置くファイルを用意します。
ここではutil.jsとします。

```javascript
// util.js
export const define = (name, value) => {
  Object.defineProperty(window, name, {
    value: value,
    writable: false
  });
```
渡ってきたnameでvalueをwindowに格納します。
また `writeable: false`とすることで書き込みを不可にしています。

## 関数を呼び出す
タイミングはいろいろあると思いますが、
今回は画面が表示されたら定数を定義します。
先ほどのutil.jsをimportし、`window.onload`内でdefineを使います。

```javascript

import { define } from './util';

// 画面が表示されたら定数として定義する
window.onload = () =>{
  define('MyName', 'Kyohei')
};

document.getElementById("hoge").onclick = () => {
  console.log(MyName)
  // => 'Kyohei'
};

document.getElementById("huga").onclick = () => {
  console.log(MyName)
  // => 'Kyohei'
};

```
画面表示時にグローバル変数windowにMyNameを定義したので
どこからでも呼び出せるようになりました。

# あとがき
そもそもフレームワーク(Rails)と言語(js)で比較していることがおかしいかもしれませんが、
つまりはこういうことがやりたかったというお話でした。
いつでもグローバルな定数作れてすっきりです。
【論文紹介】STGCN系まとめ

# これ is 何？？

自分がslideshareに挙げたスライドのリンクまとめ
※新たな論文のサーベイを行い次第，随時更新します．

# 論文紹介リスト

### ①Spatial Temporal Graph Convolutional Networks for Skeleton-Based Action Recognition


[![thumbnail](http://image.slidesharecdn.com/stgcn-200714011900/95/slide-1-1024.jpg)](https://www.slideshare.net/ddnpaa/spatial-temporal-graph-convolutional-networks-for-skeletonbased-action-recognition-236877802)

[![thumbnail](http://image.slidesharecdn.com/stgcn-200714011900/95/slide-2-1024.jpg)](https://www.slideshare.net/ddnpaa/spatial-temporal-graph-convolutional-networks-for-skeletonbased-action-recognition-236877802)

※スライドをクリックすると，slideshareに飛びます
━━━━━━━━━━━━━━━━━━━━

### ②Attention Based Spatial-Temporal Graph Convolutional Networks for Traffic Flow Forecasting

[![thumbnail](http://image.slidesharecdn.com/astgcn-200716021202/95/slide-1-1024.jpg)](https://www.slideshare.net/ddnpaa/attention-based-spatialtemporal-graph-convolutional-networks-for-traffic-flow-forecasting)

[![thumbnail](http://image.slidesharecdn.com/astgcn-200716021202/95/slide-2-1024.jpg)](https://www.slideshare.net/ddnpaa/attention-based-spatialtemporal-graph-convolutional-networks-for-traffic-flow-forecasting)


※スライドをクリックすると，slideshareに飛びます

━━━━━━━━━━━━━━━━━━━━

### ③Next...？？？
dockerのtesseract-ocrでお手軽OCRする

# 概要
dockerで公開されているtesseractを使ってお手軽にOCR(光学的文字認識)する手順です。
公開されている手順そのままになりますが、dockerでの利用が簡単だったので日本語で残しておこうと思います。

# 手順
1. docker pullする
1. scriptファイルをDLする
1. test.shをOCRしたいファイル向けに書き換える
1. 結果の確認

## docker pullする
なにはともあれ

```
docker pull tesseractshadow/tesseract4re
```

## scriptファイルをDLする
[scriptファイル](https://github.com/tesseract-shadow/tesseract-ocr-re/archive/master.zip)をダウンロードして解凍してください
こちらのソース一式にdocker pullしたイメージを使ったshellが入っています。
もちろんscriptファイルがなくてもdocker imageの利用は可能ですが、あったほうが簡単に使えるのでDLします。

## test.shをOCRしたいファイル向けに書き換える
そのままでもサンプルは利用可能ですが、自分が用意した画像に変えたほうが楽しいと思うので、OCRするファイルパスを修正します。

```[bash]
cd /path/to/your/directory/{回答したディレクトリ}
vim test.sh
```

ocr-files以下を好きなファイルパスに変更します。

```[bash]
docker cp ./ocr-files/phototest.tif t4re:/home/work/$TASK_TMP_DIR/
```
こちらのphototest.tifの部分を上記で指定したファイル名に変更します。

```[bash]
docker exec -it t4re /bin/bash -c "mkdir -p ./$TASK_TMP_DIR/out/; cd ./$TASK_TMP_DIR/out/; tesseract ../phototest.tif phototest -l eng --psm 1 --oem 3 txt pdf hocr"
```

## 結果の確認
以下でOCRを実行できます。

```[bash]
sh test.sh
```
以下のディレクトリ以下にできたファイルが確認できると思います。

```[bash]
scripts/ocr-files/output/TASK_xxxxx/out/
```

# 様々なOCR

test.sh内のtesseractコマンドのオプションを修正することで様々な結果が出力されます。
自分が利用したかったのはpsm(page segmentation mode)のレイアウトを考慮してくれるオプションです。

以下の様にpsmのオプションを1から11に変更すると、画像のレイアウトを考慮したOCRをしてくれます。またoemは1を指定する必要があります。

```[vim]
docker exec -it t4re /bin/bash -c "mkdir -p ./$TASK_TMP_DIR/out/; cd ./$TASK_TMP_DIR/out/; tesseract ../phototest.tif phototest -l eng --psm 11 --oem 1 txt pdf hocr"
```

さらに以下のように出力の結果をtsvにすると座標や、何番目のブロックとして文字列を読み取ったかの情報が得られます。

```[vim]
docker exec -it t4re /bin/bash -c "mkdir -p ./$TASK_TMP_DIR/out/; cd ./$TASK_TMP_DIR/out/; tesseract ../phototest.tif phototest -l eng --psm 11 --oem 1 tsv"
```

結果TSV（抜粋）
block_numやtop, left, width, heightといった値が入り、それに該当したテキストが取得できています。これを使えばどの位置にどの文字があるか？というのがわかるので様々な用途に応用できそうですね。

```
level	page_num	block_num	par_num	line_num	word_num	left	top	width	height	conf	text
1	1	0	0	0	0	0	0	640	480	-1	
2	1	1	0	0	0	36	92	582	269	-1	
3	1	1	1	0	0	36	92	582	92	-1	
4	1	1	1	1	0	36	92	544	30	-1	
5	1	1	1	1	1	36	92	60	24	96	This
5	1	1	1	1	2	109	92	20	24	96	is
5	1	1	1	1	3	141	98	15	18	96	a
5	1	1	1	1	4	169	92	32	24	96	lot
5	1	1	1	1	5	212	92	28	24	96	of
5	1	1	1	1	6	251	92	31	24	96	12
5	1	1	1	1	7	296	92	68	30	96	point
5	1	1	1	1	8	374	93	53	23	96	text
5	1	1	1	1	9	437	93	26	23	96	to
```

# 終わりに
tesseractはDeepLearningを利用して文字認識しています。
学習データも様々用意されており、読ませる学習データにより日本語や世界各国の言語が認識できます。
また、もちろん自分で学習データを用意することも可能です。

flutterでもtesseractを利用したライブラリが出ていて、非常に簡単に利用できました。（使い方や精度の問題はクリアしないといけませんが）
flutterでの利用例も別の機会に記載しようかと思います。
Docker で mongodb 環境を用意して接続するだけ

そもそも mongodb の環境ってどうやって作るの？となったのでおぼえがき。

# docker-compose の用意

docker-compose で書くのが好きなので

```yaml
version: "3"
services:
  mongo:
    image: mongo
    restart: always
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: password
    ports:
      - 27017:27017
```

# コンテナの起動

## 外部から接続したい時は

```bash
$ docker-compose up -d
```

もしくは

```bash
$ docker-compose up
```

## 内部でいろいろ試したい時は

```bash
$ docker-compose run --rm --service-ports mongo /bin/bash
```

（`--service-ports` をつけておくと外部にポートが公開される。）

# mongodb の起動

以降は [内部でいろいろ試したい時は](https://qiita.com/drafts/5a739a9bc56b438c6425/edit#%E5%86%85%E9%83%A8%E3%81%A7%E3%81%84%E3%82%8D%E3%81%84%E3%82%8D%E8%A9%A6%E3%81%97%E3%81%9F%E3%81%84%E6%99%82%E3%81%AF) の環境についてのみ記載。特に言及しない限り、コンテナ内での操作とする。

## 起動

```bash
/# mongod
なんやかんや
```

以降の操作は別プロセスで

## デーモンで

```bash
/# mongod --fork --logpath /var/log/mongodb/mongod.log
about to fork child process, waiting until server is ready for connections.
forked process: 50
child process started successfully, parent exiting
```

# 接続

一応プロセスの確認

```bash
/# ps aux | grep mongo
root       50  1.6  0.9 1579820 97448 ?       Sl   16:36   0:01 mongod --fork --logpath /var/log/mongodb/mongodb.log
```

大丈夫そうなので接続

```bash
/# mongo
```

# いろいろ操作

## db 切り替え(作成)

```bash
> use sample
switched to db sample
```

## insert (collection 作成)

```bash
> db.sample_collection.insert({id: 1, name: "taro"})
WriteResult({ "nInserted" : 1 })
```

## find

```bash
> db.sample.find()
{ "_id" : ObjectId("5f107fa8182d6aa721d344fe"), "id" : 1, "name" : "taro" }
```

## exit

```bash
> ^C
bye
```

# ログをみてみる

```bash
/# cat /var/log/mongodb/mongodb.log
いろいろ書いてあった
```

# mongo プロセスの終了

```bash
/# mongod --shutdown
2020-07-16T16:31:30.899+0000 I  CONTROL  [main] Automatically disabling TLS 1.0, to force-enable TLS 1.0 specify --sslDisabledProtocols 'none'
2020-07-16T16:31:30.902+0000 W  ASIO     [main] No TransportLayer configured during NetworkInterface startup
killing process with pid: 50
```




# 参考
https://docs.mongodb.com/manual/tutorial/manage-mongodb-processes/
Pythonプログラミング備忘録（文字列に関する操作）

あまりにもググるので自分用Pythonプログラミング備忘録
(自分が忘れるものに特化しています)
試験的に1ブロックで書いています。
参考書：[独学プログラマー Python言語の基本から仕事のやり方まで](https://www.amazon.co.jp/dp/B07BKVP9QY/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)
(セクション名などは参考書に従います)
対象言語：Python 3.6.3
# §6　文字列操作
### 
```python:StringManipulation.py
## 複数行に文字列が渡る場合は三重クォートを使う
TripleQuote = """ line 1
                  line 2
                  line 3
              """
TripleQuote

## formatメソッド
Word = "Welcome to underground..."
"Hey, {}".format(Word)
Subject = "このコピペ"
Year = "2006"
"{}は{}年に生まれました。".format(Subject, Year)

## 分割
"中学時代のパソコンの授業でインターネットを使った時、みんなが自分の好きな漫画や野球のページを見てる時に自分だけこれみよがしに2ｃｈにつないでAAとかを周りに見せてたこと。しかも「このページって何？」って聞かれた時に「ヤバイ奴らの集会所みたいなもん」とか答えたこと".split("。")

## 空白削除（真ん中は削除されないので注意）
MyGeneration = " Lost Age "
MyAge = "　失われた　10年　"
MyGeneration = MyGeneration.strip()
MyAge = MyAge.strip()
MyAge
MyGeneration 

## 文字検索(index, rindex, find, rfind)
LastSentence = "そいつの耳元で「Welcome to Underground」ってささやいたこと"
LastSentence.index("W")
LastSentence.index("o")  # 最初の文字のインデックス値を返却
LastSentence.rindex("o") # 逆順照会
#### findは存在しない場合-1を返す。indexはValueErrorを返す。
try:
    LastSentence.index("Z")
except:
    print("Not Found")
LastSentence.find("Z")
```

実行結果

```python
## TripleQuoteの実行結果（スペースなどが忠実に反映されている）
' line 1\n                  line 2\n                  line 3\n              '

## formatメソッドの実行結果
'Hey, Welcome to underground...'
'このコピペは2006年に生まれました。'

## 分割結果
['中学時代のパソコンの授業でインターネットを使った時、みんなが自分の好きな漫画や野球のページを見てる時に自分だけこれみよがしに2ｃｈにつないでAAとかを周りに見せてたこと', 'しかも「このページって何？」って聞かれた時に「ヤバイ奴らの集会所みたいなもん」とか答えたこと']

## 空白削除結果
'Lost Age'
'\u3000失われた\u300010年\u3000'

## 文字検索
8
12
26
#### indexとfindの違い
Not Found
-1
```
jsでネットワークVoxelエディターを作る方法

# ネットワークVoxelエディター
7月14日に多人数同時接続が出来るVoxelエディターを公開しました。
[ネットワークVoxelエディター](http://ik1-314-17143.vs.sakura.ne.jp/)

去年作った方
[初期のVoxelエディター](https://ai5.jp/voxel-editor)

これは Node.js、three.js、Socket.io、MongoDBで作っています。（jsの技術総動員）

## 作品

初期のVoxelエディターでこのような作品を作っていただきました。他にも色々と作っていただいたのですが、割愛。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">voxelエディターの動画 <a href="https://twitter.com/hashtag/voxelart?src=hash&amp;ref_src=twsrc%5Etfw">#voxelart</a> <a href="https://t.co/E2dXjmprrj">https://t.co/E2dXjmprrj</a> <a href="https://t.co/QDi5MbhUeD">pic.twitter.com/QDi5MbhUeD</a></p>&mdash; 泉芳樹 #voxel (@izumi_yoshiki) <a href="https://twitter.com/izumi_yoshiki/status/1287039360836091905?ref_src=twsrc%5Etfw">July 25, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## ネットワークVoxelエディターの成長
### ログイン機能
ネットワークVoxelエディターはログイン機能を付けていたのですが、誰もアカウント登録してくれず、多人数同時アクセスなど遠い目標の状態でした。ログイン機能が邪魔で気軽に使ってくれないのだと思い、公開初日でログイン機能を外しました。
### room機能
ログイン機能を外すと、使ってくれる人が現れて、このような感じの物を作ってくれました。
<img width="1467" alt="スクリーンショット 2020-07-16 15.21.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215739/72dd645b-39d8-1295-19cf-48a8349af43f.png">
ここから、使ってくれる人が増えれば、他のキャラクターも作りたい人が出てくるのでルーム機能が必要だと気付きました。そして、１日かけてroom機能を追加しました。それに伴うバグ修正に対応するために、サーバーを落としまくりました(-_-;)
### 念願の多人数同時アクセスでの共同作業
マリオのキャラクターを多人数同時アクセスで作りました。
<img width="1313" alt="スクリーンショット 2020-07-16 23.14.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215739/58cc5e47-15d6-5a86-769d-f2abb59f6073.png">
[ネットワークVoxelエディター](http://ik1-314-17143.vs.sakura.ne.jp/)にアクセスしてroom4を見ていただけるとマリオが作られています。


## 動機
最初は、three.jsとphpでブラウザで操作出来るVoxelエディターを作っていました。

何故作ったかというと、ゲームに登場させるキャラクターを簡単に作りたいという思いからでした。
ソースコードだけで作ったキャラクターがこちら
<img width="200" alt="スクリーンショット 2020-07-17 0.00.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215739/069160cf-1fde-cb25-0b22-83dfcfb91eb1.png">

このキャラクターを１体作るのにソースコードで丸１日ぐらいかけて作っていました。
このままでは効率が悪いと思い、エディターを作る事にしました。

## three.jsのサンプルとの出会い
ある日、three.jsのサンプル集を全部見てみようと思い、100個ぐらいあるサンプルを見まくっていたら、今のVoxelエディターの原型になるVoxelエディターのサンプルがありました。このサンプルはOrbitControlsを実装していなかったので、視点を変える事が出来ず使いにくい物でした。最初はこのサンプルにOrbitControlsを付けただけの簡単なエディターの状態で公開しました。

## 初期のVoxelエディターの成長
徐々に機能を増やしていき、データの保存や色変更など出来るようにしました。そしてtwitterで公開して、[たかし](https://twitter.com/tak_akkiy)さん や [もちまぐろ](https://twitter.com/mochimagro)さん に使っていただいて、色々と足りない機能や改善点をアドバイスしていただきました。
特に、操作方法は色々な方々から多種多様なご指摘をいただきました。どの操作にVoxelを置く機能を割り当てるか、視点変更はどの操作でやるのが良いか、という点が1番論点になった熱い話題でした。

## Voxelエディターコンテスト
ここまでの状態で、もっと色々な人達に知ってもらいたいという思いで、お金の力を使って強引に広めようと思いました。そこでVoxelエディターコンテストを開催しました。
しかし、エントリーしてくれた人達は４人でした。
自分の発信力不足を痛感しました。


## 新たなアイデア
色々な人に使ってもらったり、これを紹介したりしていたら、「多人数で同時にアクセスして編集出来たら面白いよね」という意見をもらいました。
そこから今の形になっている「ネットワークVoxelエディター」を作り始めました。
バックエンドをphpで作っていたのを、Node.jsに変えて、Socket.IOを使って多人数同時アクセスが出来るようにしました。


## まとめ
現在、ソースコードがカオスなのですが、一応[GitHub](https://github.com/minmin0530/bokuvoxel)に上げています。
本番用はこのソースを更にカオスにした状態なので、整備できたらQiitaのこの記事に追記報告します。
言いたかった事は、時間や人との出会いを経ると最初のアイデアから、雪だるま式に成長していくという事です。
それと、まだまだ機能追加しまくると思うので、皆さんがアクセスした時は丁度サーバーを落としている時かもしれないです(^^;)
なので、アクセス出来ない時は１日ぐらい待って次の日にアクセスすると使えるかもしれません。
~「クラウドAI開発講座」に挑戦してみたとある高専生の道のり#2~

#目次
-この記事について
- 進捗報告
- 次回の目標

#この記事について
　これは[前回の進捗報告](https://qiita.com/CB_haruna/items/3593af9c71ce2bd46f6e)の続きとなる記事です！


##進捗報告

- step1: Azure For Studentsに登録 消化！:ok_woman_tone1:

- step2: de:cod2020に登録し視聴　消化！:ok_woman_tone1:

-  step3: Microsoft learn for students まだまだ学習不足！:raising_hand_tone1:

- step4:ちょまどさんのレッスン　消化不良！::no_good_tone1:


　[ちょまどさんのレッスン](https://qiita.com/chomado/items/6bda10abde0551f25723)

　現在は自分の圧縮させたファイルをteamsに接続するところまでです。Azureとteamsは正常に接続されているので圧縮ファイルの中身に何か問題が:scream:早く解決して次に行きたい！日々出てくるIT用語をググりながら地道に進めています。

##次回の目標

- Azureをteamsに繋げて完全にちょまどさんのレッスンを消化する！
- Microsoft for learn students で学習しbotのアイデアを決めていく！
JS 配列内で重複しているものは削除して返す

## Lodashのuniq関数を作ってみた

### includeメゾッドの場合

~~~javascript
const uniq = (array) => {
  const uniqArray = []
  for (let i = 0; i < array.length; i++) {
    const setArray = array[i]
    if (!uniqArray.includes(setArray)) {
      uniqArray.push(setArray)
    }
  }
  return uniqArray
}
console.log(uniq([2, 1, 2, 4, 8, 5, 4, 8]))
~~~

### setメゾッドの場合

~~~javascript
const uniq = (array = []) => {
  const uniqArray = [...new Set(array)]
  return uniqArray
}
console.log(uniq([2, 1, 2, 4, 8, 5, 4, 8]))
~~~
[7月20日更新] 
@standard-software さんからご指摘頂き、Set部分の誤った記述を修正しました。
とても助かります、ありがとうございました！！
LaravelでPHPUnitを使う際にテストメソッドに引数を渡す方法

#はじめに

表題の通りLaravelでテストを書いている際にテストメソッドに引数を渡す方法がわからずハマってしまいました。

## 渡す方法

@validateEmailInputDataProviderアノテーションを記述する。
これで、validateEmailInputDataProviderから引数（\$value, \$expect）を受け取ることが出来る。

```test.php
class CustomValidatorTest extends TestCase
{
　　　/**
     * @dataProvider validateEmailInputDataProvider
     */ 
    public function testValidateEmail($value, $expect)
    {
       (省略)
    }

    public function validateEmailInputDataProvider()
    {
        return [
            'nomal' => ['abcd@qiita.com', true],
        ];
    }
```
#### 引用
<a href="https://sawatan.com/php/phpunit%E3%81%AE%E3%83%86%E3%82%B9%E3%83%88%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%81%AB%E4%BB%BB%E6%84%8F%E3%81%AE%E5%BC%95%E6%95%B0%E3%82%92%E6%B8%A1%E3%81%99%E3%80%82">PHPUnitのテストメソッドに任意の引数を渡す。</a>
[UE4] PakBlacklistの使い方メモ

検証Ver：4.25.0

#1.まえがき
プロジェクトのパッケージから特定のアセットを除外したい場合、PakBlacklistという機能を利用することができます。これは[公式ドキュメント](https://docs.unrealengine.com/ja/Engine/Performance/ReducingPackageSize/index.html)でも説明されているように、アセットを1つのファイルに纏める場合(.pakファイルを使用する場合)にのみ有効です。

4.25でも利用することができますが、これはDuplicatedに分類されているため将来的には利用できなくなるかもしれません。代替え機能としてPakFileRuleという機能があり、以下のブログでも説明されています。

[[UE4] uasset以外のアセットにChunkIDを設定する(ue4.22以降)](https://qiita.com/EGJ-Takashi_Suzuki/items/d7e980d7a71e9adb6857)

#2.使い方の補足
## 除外するアセットリストの定義ファイルを配置する
といっても、PakBlacklistはまだまだ利用することができます。
以下のようにビルド構成毎に`PakBlacklist-[BuildConfig].txt`というファイルを`[Project]/Build/[Platform]`に配置するだけです。
例えば`「TP_425というプロジェクトでAndroidのTest構成でのみ特定のファイルを除外したい」`場合、 `PakBlacklist-Test.txt`を作成して、`TP_425/Build/Android/PakBlacklist-Test.txt`のように配置します。

**※ Windowsで適用する場合"Win64"や"Win32"のプラットフォーム名を追加する必要があります**

![2020-07-17_00h25_18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101019/1c66a139-c0e8-88dd-c56c-99dd830c2a49.png)

## 除外するアセットリストを定義する

先ほど作成した定義ファイルの中に除外するファイルを記載します。ここではディレクトリを指定することも、アセット個別で指定することも可能です。

```:
../../../TP_425/Content/StarterContent/Audio/
../../../TP_425/Content/StarterContent/Audio/Collapse_Cue.uasset
../../../TP_425/Content/StarterContent/Audio/Collapse_Cue.uexp
```

**※ プロジェクト内のパスを指定する場合必ず "../../../[Project]/" を指定する必要があります (不一致だと除外されません)**

ここで除外するファイルについてはアセットのリファレンスとは別に強制的にパッケージから除外されることになるため、参照されないことが明らかであることを把握した上で設定を行ってください。除外されたアセットを参照するようなアセットがある場合、それらはロード時にエラーとなります。