OmniAICreator/Qiita-1.07M huggingface dataset:
#ITエンジニアからITコンサルを目指そう、ITコンサルへの下克上。

#ITエンジニアからITコンサルを目指そう、ITコンサルへの下克上。


ITエンジニアとして働いているが、年上は扱いづらいという思想があるこの社会で
ずっとプログラマ人材をやっていては需要がなくなるだろう。
というわけでITコンサルの道にどうやってなるかということを模索してみる。
わかりやすいことを例を出している下記の動画を参考に解説してみる。


#◆うつさん：【転職】未経験可！ITコンサルタントへの転職【年収1千万】
https://www.youtube.com/watch?v=p2XHxGAAXq8
[解説]
(人事)(経理)(マーケティング)(営業管理)(調達)(生産部門)
上記の職業からのコンサル移行はチャンスあり！
上記の仕事の経験者を生かしたパッケージやクラウドを導入などを進めるITコンサルの仕事は増えた。
ITクラウドのパッケージが増えたため、それらの仕事が増えた。

下記、右の仕事は左のクラウドパッケージで解決出来る。(ERP)

(人事)→SmartHR
(経理)→SAP
(マーケティング)→Adobeクラウド
(営業管理)→sales force
(調達)→ORACLE NETSUITE
(生産部門)→EXPLANNER/J

人事の知見をもってこのSmartHRをITコンサルとして導入をしていく仕事がある。
導入側の仕事はとても単価が高い。
だが上記職業経験を丸３年以上の業務経験×幅広い経験を提示しないと転職は厳しい
パッケージの利用経験は必須


#◆けんたさん：DevOpsエンジニアになる方法と将来性について
https://www.youtube.com/watch?v=hM2j9VlChwo

2019年のDevOps/MLOpsエンジニアの標準的スキルセット
https://qiita.com/poly_soft/items/8dd105341869f93b129c
[解説]
DevOpsエンジニアとは？
「サービスを安定稼働させたままユーザからのフィードバックを迅速に取り入れて
　新機能や改善をスピーディにサービスに反映していくためのあらゆる技術的に
　取り組みを行うエンジニア」
「詳細なビジネスロジックを書く役割のエンジニアが
　スムーズにコードを本番環境に反映できるように
　様々な仕組みを作っておくのがDevOpsエンジニアの重要なタスク」


重要スキル①インフラのコード化、アズコード化
[必要性]
インフラのコード化インフラをコード化していないと別環境でインフラ構築の際に
また手動で同じ作業を行う必要があったりその作業が手順管理になってしまったり
現在のインフラの正確な構成が誰にも把握できなくなってしまったり
色々なデメリットがあるのでインフラを安定運用したりインフラを更新する際の
リードタイム（工程に着手してからリリースされるまでの時間）を短縮するためには
インフラをコード化して管理しておく必要がある。

[ツール]
インフラコード化ツールで最も人気があるのはterraform、AWSでもGCPでもどちらでも
同じノウハウが使える、独自のコード化ツールよりterraformに慣れておこう。

重要スキル②「CI/CDパイプライン構築」
CI→継続的インテグレーションの略
例えば何らかのCIツールとgithubを連携させておくとコードがgithubのブランチにpushされる
度にビルドや単体テストや統合テストが自動的に実行できるので
早期にエラーを検出可能になりさらにエラーの発生しているプルリクをマージ出来ないように
設定したりしておけば、アプリケーションの安全性を手間をかけずに維持することが可能になる。

CD→継続的デリバリーの略
基本的にCIの後に実行されるのですがCIが実行されてコードの安全性が検証されて
特定のリリース用ブランチにコードがマージされた際にCD機能によってアプリケーションの
デプロイを自動的に実行できるようにしておくことで「手順書」「デプロイ職人」に頼らずに
迅速に本番環境にコードを反映できるようになる。

このようにgithubのようなソースコード管理ツールとcicdツールを連携させて
アプリケーションのビルドやテストやデプロイまでの一連の手順を自動化することを
「CI/CDパイプライン構築」と言う。

cicdツールで最も人気があるのは「CircleCI」
そのうち「github action」に抜かれるかもしれないが現時点では「CircleCI」

他、AWSのマネージドサービスを全部使いこなせて適所で使うことが出来ると良い。


#◆マイナビ・SEからITコンサルへの転職まとめ
https://mynavi-agent.jp/it/knowhow/itconsultant_inexperience/
https://www.liber.co.jp/kenzo/column024.html
[解説]
突発的な問題にも対処できる「論理思考能力」や「コミュニケーション力」が重要なので、資格は重要でない。
ITコンサルタントへの転職は、経験と高いコミュニケーション能力があれば、
高いコミュニケーション能力があれば（大事なことなので二回言いました。）
年齢に関わらず成功する可能性は十分ある。

結論：
ITコンサルの仕事は　IT効率化の知見×高いコミュニケーション能力




#フリーランスITエンジニアで稼ごう ITエンジニアのフリーランスサイト一覧：

フリーランスエージェント一覧（エンジニア専門）【2019年最新版】
https://free-engineer.xyz/
【フリーエンジニア】エージェントおすすめランキング【2018年最新版】
http://free-engineer.xyz/agent-top-picks/
VScodeでGo開発環境のセットアップ(Ubuntu18.04)

# 環境
バージョン: 1.41.1
コミット: 26076a4de974ead31f97692a0d32f90d735645c0
日付: 2019-12-18T15:04:31.999Z
Electron: 6.1.5
Chrome: 76.0.3809.146
Node.js: 12.4.0
V8: 7.6.303.31-electron.0
OS: Linux x64 4.15.0-76-generic

# 拡張機能のインストール
`Extensions` から `Go`インストール
`Ctrl+Shift+P`でコマンドパレットを開いて、`GO: Install/Update tools`を実行
全ツールを選択してインストール


# サンプルコード
```golang
package main

import (
	"fmt"
)

func main() {
	fmt.Println("hello world.")
	i := 101
	fmt.Println(i)
}
```



#はまったこと

デバッグ実行したらなんか怒られた。

```
version of go is too old for this version of delve (minimum supported version 1.11, suppress this error with --check-go-version=false)
```
色々調べると、aptでgolangをインストールすると`1.10`が入るっぽく、
delveは`1.11`以上を要求するのでデバッグできないみたい。

https://golang.org/doc/install?download=go1.13.7.linux-amd64.tar.gz
ここを参考に手動で`1.11`以上のVersionを入れてPATHを通す。

```
tar -C /usr/local -xzf go1.13.7.linux-amd64.tar.gz
export PATH=$PATH:/usr/local/go/bin
```

# うごいたー！！

![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133206/d2bf3bff-a98b-1782-a040-e661f121be42.jpeg)

おわり。
コードヘルス - レビューコードを理解する

*このポストは[Code Health: Understanding Code in Review](https://testing.googleblog.com/2018/05/code-health-understanding-code-in-review.html)を翻訳したものです。*

あなたにコードレビューを送ってきた開発者があなたよりも賢く、そのため彼のコードが理解できないということは十分にありえるでしょう。

しかし実際には、**もしコードが理解し難いのであれば、おそらく複雑すぎます**。もし、あなたが使われているプログラミング言語に詳しいのであれば、**健全なコードを読むことはあなたの母語で本を読むとの同じぐらい簡単であるはずです**。

開発者がPythonのこんなブロックをレビューに送ってきたとしましょう:

```python
def IsOkay(n):
  f = False
  for i in range(2, n):
    if n % i == 0:
      f = True
  return not f
```

このとき、**理解するために何秒もかけないこと**。コードレビューのコメントには単にこう書きましょう「私にはこのコードが理解できません」あるいは、より具体的に「関数名や変数名をもっと分かりやすいものにしてください」と。

**すると開発者がコードを書き直して**、もう一度レビューにと送って来ました:

```python
def IsPrime(n):
  for divisor in range(2, n / 2):
    if n % divisor == 0:
      return False

  return True
```

こんどは私達にもとても簡単に読むことができます。これがそうすることの利点です。

しばしば、**開発者にコードを分かりやすくしてほしいとお願いするだけで、根本的な改善がなされます**。この例では、開発者はコードの見通しが良くなったことでパフォーマンスの改善に気づきました --- 関数は数が素数でないときより早く終了し、繰り返しは n ではなく、 n/2 だけ実行されます。

**しかしながら、このコードが簡単に理解できるようになったので、多くの問題が見えてきます**。例えば、0や1のときの挙動がおかしいです。他にもまだ問題はあります。なにより大事なことに、今では、この関数全体を取り除いて数が素数であるかを検出する既存の関数に置き換えた方がいいということが明らかです[^1]。コードを分かりやすくすることは開発者もレビューアも助けます。

まとめると、**よく分からないコードのレビューに時間を無駄にするのはやめましょう。単に分かりやすくするようにお願いすればいいのです**。実際、そういったレビューコメントはコードレビューアの持つ最も便利で重要なツールです。

[^1]: [sympy.ntheory.primetest.isprime](https://docs.sympy.org/latest/modules/ntheory.html#sympy.ntheory.primetest.isprime) でしょうか。
GitHubにSSHで接続する

# GitHubにSSHで接続する

何番煎じわからないけど、備忘録としてまとめる。

## SSH keyの作成

```bash
cd ~/.ssh/
ssh-keygen -t rsa -b 4096 -C "your_email@gmail.com"
...
Enter file in which to save the key (/Users/you/.ssh/id_rsa): [id_rsa_git]
Enter passphrase (empty for no passphrase): [Type a passphrase]
...
```

## SSH keyをGithubに登録

右上のアイコン -> Settings -> SSH & GPG keys -> New SSH key

- Title: 適当につける
- Key: 作成した`id_rsa_git.pub`の中身をコピペ

## ローカルの設定

### SSH config

```bash
vim ~/.ssh/config
...
Host github.com
  User git
  Hostname github.com
  IdentityFile ~/.ssh/id_rsa_git
...
```

### SSH agent

```bash
eval `ssh-agent`
ssh-add ~/.ssh/id_rsa_git
```

### 接続確認

```bash
ssh github.com
...
Enter passphrase for key '/home/pi/.ssh/id_rsa_git': 
PTY allocation request failed on channel 0
Hi xxxxxx! You've successfully authenticated, but GitHub does not provide shell access.
Connection to github.com closed.
...
```

## 終わり

ここまでやるとgit cloneできるはず
計算ドリルを作りました

``` python![ABC432DF-00C5-4D49-8C78-E86736A47C97.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569373/3e8c7176-ca7f-b9b3-37d4-866bfe98146b.png)

import random

ichi = random.sample([1,2,3,4,5,6,7,8,9], 9)

ni = random.sample([1,2,3,4,5,6,7,8,9], 9)
#1〜9のリストからランダムに被り無しで9回取り出す
for ICHI in ichi:
    for NI in ni:
        kaitou = int(input(str(ICHI) + '+' + str(NI) + '='))
        #ランダムに出力された計算式をinputで回答を入力できるようにする
        while (kaitou != ICHI + NI):
            print('😷ぜんぜんちがう🦠')
            kaitou = int(input(str(ICHI) + '+' + str(NI) + '='))
          #while文でICHI + NIが成立しない時はループ                         
        if kaitou == ICHI + NI:         print('😇あってるよ😇') ```
ColabのGPUのRAMを最大限に活用したい。

#方法
機械学習ではバッチサイズを大きくしたいのでメモリをできるだけ多く使いたい。
colabでの通常のメモリ

```
!free -h

              total        used        free      shared  buff/cache   available
Mem:            12G        562M         10G        900K        2.0G         11G
Swap:            0B          0B          0B
```
casheで2Gも食ってる。

`[_ for _ in range(10000000000)]`
これで強制的にメモリを溢れさせると...


```
!free -h
 
              total        used        free      shared  buff/cache   available
Mem:            25G        603M         24G        900K        427M         24G
Swap:            0B          0B          0B
```
427mにcasheが減っている。
そしてメモリが12Gから25Gに変更
Macでkubectlの入力補完をできるようにする

Macでkubectlの入力補完をできるようにする方法について記載
（bash completionを導入する）


1.まず、bashのバージョン確認

```

$ bash --version

```



2.bashのバージョンが3.2系の場合

```

$ brew install bash-completion
$ echo '[ -f $(brew --prefix)/etc/bash_completion ] && . $(brew --prefix)/etc/bash_completion' >> ~/.bashrc

```


2.bashのバージョンが4.1以上の場合

```

$ brew install bash-completion@2
$ echo '[ -f $(brew --prefix)/share/bash-completion/bash_completion ] && . $(brew --prefix)/share/bash-completion/bash_completion' >> ~/.bashrc

```

以上




参考

https://kubernetes.io/docs/tasks/tools/install-kubectl/
Resolved APIというnuxt.jsのプラグインを作った話

# vuex疲れ
普段からnuxt.jsやvue.jsを利用している方ならご存知かと思うのですが
vuexは複雑なデータ構造を渡すと
stateが更新されない事があります。

僕はそれが原因でしばらくvuex無しで
pagesのvueファイルで一枚岩に実装するなんて言う
ソースコードが腐る方法で実装していました。

しかし、そんな実装ではメンテナンス性が最悪である事も
当然、自覚はありました。

そろそろ、なんとかしなくてはと思うものの
やむなくvuexを利用するのはやはり違うという事で
自作でvuexに替わるプラグインを作る事にしました。

# Resolved APIというプラグインを作った話
[Resolved API](https://github.com/gqlkit-lab/rapi)(以下、rapi)
自作プラグインというのは大袈裟で
別に単にES6をふんだんに使ってパッケージ分割しただけです。

apiをcontextに流し込むメインの`index.js`と`resolvers`
`resolvers`にはQuery、Mutation、client.js、cache.jsがあるのみです。
vuexとか、Apolloのcacheだとかは結構、複雑なアーキテクチャで構築されていますが
正直、独自にプラグインを作ると拍子抜けするほど
シンプルなアーキテクチャで作れてしまいます。

rapiは、
非常にシンプルで薄く柔軟なカスタマイズが可能なように作りました。
client.jsを編集する事でGraphQLにも、REST APIにも対応できます。

cacheへの読み書きは、デフォルトはjormというgormライクなcache ORMを使って行える
ようにしていますが
cacheに関しても、別にlowdbなどのapiに替える事もできます。


# jormというcache ORMを作った話
rapiは完全にフロントエンドに埋め込まれたサーバーというコンセプトで設計しています。
なので、参考にしたアーキテクチャはgqlgenによって生成されるGraphQLサーバーのアーキテクチャです。

となると、DBであるcacheに読み書きするため
cache ORMというツールも必要になるでしょう。
という事で
gormを参考に[jorm](https://github.com/gqlkit-lab/jorm)というcache ORMも作りました。

# GraphQLにもREST APIにも対応
上述もしている通りrapiは、client.jsを書き換えるだけで
GraphQLにも、REST APIにも対応できます。
(ES6は偉大ですね。)
gqlkitはGraphQLアプリを開発するためのフレームワークなので
gqlkitのrapiのデフォルトはGraphQLです。

なので、REST APIでの具体的な実装例として
resas apiを使った人口動態グラフの例も紹介しておきます。
(resas apiの認証トークンはアカウント登録して取得してください。)
https://github.com/inadati/total-population-trends-sample

#まとめ
この、rapiというプラグインを使い始めてから
フロントエンドの実装が格段に楽になりました。
コンポーネント側のソースコードも全く汚染されません。
それもそのはずです。
「Resolved API」というのは

- サーバーからのデータの取得、書き込み
- キャッシュへのデータの書き込み、取得
- コンポーネント(クライアント)サイドに必要な形式へのデータの組み替え
- GraphQLの場合クエリの管理

などなど、文字通りあらゆる問題を「解決済み」としたAPIをコンポーネントに提供するわけです。
コンポーネント側では、ほとんど余計なことはしないで済むということです。

ちなみに一応、nuxt.jsのプラグインと言いましたが
別にcontextに、データストアを挿入可能なフレームワークであれば利用可能かと思います。
svelteでもできるかと
reactは不明
reactはコンポーネントとデータが密結合でよく分からないです。
reactはあまり深く触れたことなくてよく分かりません。
レスポンシブWebデザインとは

# レスポンシブWebデザインが使われる場面

 現在のフロントエンド開発においては、デスクトップブラウザだけでなく、

スマートフォン等のモバイルブラウザへの対応も必要となっています。

他にもタブレットや、ゲーム用のデバイス等の専用ブラウザを対象とすることもありますよね。

 単純にデバイスごとでディスプレイのサイズや仕様も異なりますから、ケースによって想定していた通り描画されていない！というのはよくある話です...。

じゃあどうするかとなったときに、単に対応する必要のあるデバイスごとに固有のビューページを用意すれば良いかと言えばそれは不可能な場合が多いです。

デバイスと一括りに行っても近年は多様化していて１つ１つに最適化することは時間的に難しいことが多いです。

じゃあどうするの？ってなったときにアプローチの１つとして使われるのがレスポンシブWebデザインとなるわけです。

# 具体的にレスポンシブWebデザインとは何

レスポンシブWebデザインは2010年ごろからある`スクリーンサイズ`を基準としたテクニックです。

### レスポンシブの３つの要素

レスポンシブには以下の３つの要素があります。

> メディアクエリ (Media Queries)
> フルードグリッド (Fluid Grid)
> フルードイメージ (Fluid Image)

Fluid（流動的）という言葉通り、テキストや画像、レイアウトを`スクリーンサイズに対して動的に変化させる`ことによって
サイズに対応したコンテンツの見せ方をさせることになります。

具体的には`メディアクエリ`を用いて、指定条件下でのスタイル、振る舞いを指定することが一般的ですね。

指定条件というのは、基本的にはスクリーンサイズの幅を指定することが多いです。
またこのスクリーンサイズの幅の線引きのことを`ブレークポイント`といったりします。

以下例のコードです

```Sample.css
/* ブレークポイントを900pxに指定（900pxより広い場合のスタイル） */

@media all and (min-width: 900px) {
  .column {
    width: 30%;
  }
}
```

このようにして組み合わせていくことで、レスポンシブに対応したWebサイトを作成していきます。

長くなりそうなのでpart1はこの辺りで切っておきます:wave:
DotPlotlyでゲノムスケールのdotplotが描きたい

#### ゲノムスケールのdotplotが描けたら...
大規模な構造変異を可視化しやすい
de novoアセンブルしたゲノムとリファレンスの比較がしやすい
今回はde novoアセンブルしたゲノムを公開されているゲノムと比較することでミスアセンブルがないか検証する

----
#### どんなツールがあるの？
知っている範囲(2020.2.21現在)だと
1. D-GENIES
2. DotPlotly

#### D-GENIESとは？
ウェブ上でゲノムスケールのdotplotを描いてくれる
楽チン。  

**ref**
https://peerj.com/articles/4958/
Cabanettes & Klopp. *PeerJ* (2018)
http://dgenies.toulouse.inra.fr/

**使い方**
1. ウェブにTargetとquery2つのfastaファイルを投げる
2. しばらくまつとメールが届く
3. リンクからdotplotの結果を見ることができる 
4. 
**便利な点**
Dotplotの結果をインタラクティブにいじれる (e.x. 配列の向きを変えたりノイズを除去したり)
Targetに対してqueryの配列をソートできる
ソートしたfastaをダウンロードできる(ただしdotplot上で配列の向きを変えてもそれは反映されない)
**不便な点**
遅い
相手方のサーバーがトラブると解析できなくなる (2020.2.21現在D-GENIESがうまく動かない)
  
**そこでDotplotlyに乗り換えることにした**

----

#### Dotplotlyとは？
Rベースのインタラクティブなdotplot作成ツール
mummerもしくはPAFフォーマットのアライメント結果を投げると作図してくれる
**ref**
https://github.com/tpoorten/dotPlotly

**事前準備**
スクリプトを落としてくる

```
git clone https://github.com/tpoorten/dotPlotly.git
```
Rにパッケージをインストールしておく
マニュアルに書いてあったツールは以下の３つ。足りない場合は何かしらのエラーを吐いて止まるのでエラーコードを確認する。

```R
install.packages(c("optparse", "ggplot2", "plotly"))
```

**Dotplotlyで作図**  

今回はminimap2でアセンブルされたゲノムをリファレンスにマップし、得られたPAFファイルを用いてDotplotの作図

```sh
#minimap2でマップ
minimap2 referece.fasta draft.fasta >output.paf
#dotplotlyのスクリプトで作図
/path/to/pafCoordsDotPlotly.R \
-i output.paf \
-o out \
-s \
-t \
-m 10000 -q 1000000 \
-l
```
そうすると`out.html` `out.png` `out_files` の3つのファイルが出来上がる
オプションについては `/path/to/pafCoordsDotPlotly.R -h` で確認すべし
ゲノムスケールのdotplotなら`-m 10000 -q 1000000` がノイズが少なくて良さげだった

あとは好きなように!

----
**追記.1**
reference.fastaは上から順に(たとえばChr1, Chr2, Chr3...という具合)にプロットされるのかと思いきや、長さでソートされた順でプロットされるのでちょっと困った。

----
**追記.2**
`-r`をつけてreferenceのヘッダーをコンマ区切りで書いたらその順番で表示されるようになった。
たとえば自分の場合だと
`-r Chr1,Chr2,Chr3,Chr4` という具合にやればうまくいった
C++の実行まで

## はじめに

C++で競技プログラミングを始めてみようと思いましたので、
実行方法までをまとめました。

## プログラム

下記のファイルを作成します。

```c++:file.cpp
#include<stdio.h>

int main(){
    printf("Accepted!\n");
    return 0;
}
```

## コンパイルと実行

コンパイルすると`a.out`というファイルができるのでそれを実行します。
`Accepted!`と表示されていれば成功です。

```console
$ c++ file.cpp
$ ./a.out
Accepted!
```
テイラー展開の再帰的導出法

# はじめに
機械学習では二次近似あたりまではよく出てきます。ニュートン法は一次近似＝ゼロを解いて更新則が導出されますし、ベイズ事後分布の正規分布近似（ラプラス近似）は対数事後分布の二次近似ですね。（最大化や最小化にニュートン法を用いる場合は、勾配（一階微分）の一次近似＝ゼロを解くので二階微分が出てきて二次解法（Quadratic Solver）と呼ばれますね。）

そんなテイラー展開の公式を忘れたとき、思い出すのに使える導出法です。パズルみたいでおもしろいです。

# テイラー展開の再帰的導出法
無限回連続微分可能な関数$f(x)$に対して

```math
\begin{align*}
f(x)
 &= f(x_0) + \int_{x_0}^x f^{(1)}(z_1) dz_1 \\
f^{(1)}(z_1)
 &= f^{(1)}(x_0) + \int_{x_0}^{z_1} f^{(2)}(z_2) dz_2 \\
f^{(2)}(z_2)
 &= f^{(2)}(x_0) + \int_{x_0}^{z_2} f^{(3)}(z_3) dz_3 \\
 &\hspace{2mm} \vdots
\end{align*}
```
で再帰的に代入すると

```math
\begin{align*}
&f(x) \\
&= f(x_0) + \int_{x_0}^x f^{(1)}(z_1) dz_1 \\
&= f(x_0) + \int_{x_0}^x \left( f^{(1)}(x_0) + \int_{x_0}^{z_1} f^{(2)}(z_2) dz_2 \right) dz_1 \\
&= f(x_0) + \int_{x_0}^x \left( f^{(1)}(x_0)
 + \int_{x_0}^{z_1} \left( f^{(2)}(x_0) + \int_{x_0}^{z_2} f^{(3)}(z_3) dz_3 \right) dz_2 \right) dz_1 \\
&\hspace{2.6mm} \vdots \\
&= f(x_0) \\
&\hspace{4mm} + f^{(1)}(x_0) \cdot \int_{x_0}^x 1 \; dz_1 \\
&\hspace{4mm} + f^{(2)}(x_0) \cdot \int_{x_0}^x \int_{x_0}^{z_1} 1 \; dz_2 dz_1 \\
&\hspace{4mm} + f^{(3)}(x_0) \cdot \int_{x_0}^x \int_{x_0}^{z_1} \int_{x_0}^{z_2} 1 \; dz_3 dz_2 dz_1 \\
&\hspace{6.2mm} \vdots \\
&\hspace{4mm} + f^{(k)}(x_0) \cdot \int_{x_0}^x \cdots \int_{x_0}^{z_{k-1}} 1 \; dz_k \cdots dz_1 \\
&\hspace{6.2mm} \vdots
\end{align*}
```
となります。**$f^{k}(x_0)$はk階微分の$x_0$での値（定数）**で、その**係数は1のk重積分**です。
1のk重積分をk=1から順に求めていくと

```math
\begin{align*}
\int_{x_0}^x 1 \; dz_1
 &= (x - x_0) \\
\int_{x_0}^x \left( \int_{x_0}^{z_1} 1 \; dz_2 \right) dz_1
 &= \int_{x_0}^x (z_1 - x_0) dz_1 
  = \frac{1}{2} (x - x_0)^2 \\
\int_{x_0}^x \left( \int_{x_0}^{z_1} \int_{x_0}^{z_2} 1 \; dz_3 dz_2 \right) dz_1 
 &= \int_{x_0}^x \frac{1}{2} (z_1 - x_0)^2 dz_1 
  = \frac{1}{2 \cdot 3} (x - x_0)^3 \\
 &\hspace{2.5mm} \vdots
\end{align*}
```
と、**一つ前の解をもう一度積分していく**形になります。これよりk重積分は

```math
\begin{align*}
\int_{x_0}^x \cdots \int_{x_0}^{z_{k-1}} 1 \; dz_k \cdots dz_1
 &= \frac{1}{k!} (x-x_0)^k
\end{align*}
```
となることがわかります。$k=0$のとき$0! = 1$、$(x-x_0)^0=1$なので、$f(x_0)$も

```math
\begin{align*}
f(x_0) = f^{(0)}(x_0) \frac{1}{0!} (x-x_0)^0
\end{align*}
```
と書けます。以上より、テイラー展開（テイラー級数）：

```math
\begin{align*}
f(x)
&= f(x_0) \cdot \frac{1}{0!} (x-x_0)^0 + f^{(1)}(x_0) \cdot \frac{1}{1!} (x-x_0)^1 + f^{(2)}(x_0) \cdot \frac{1}{2!} (x-x_0)^2 \cdots\\
&= \sum_{k=0}^\infty \frac{1}{k!} f^{(k)}(x_0)(x - x_0)^k
\end{align*}
```
を得ます。
【今日教わった】プログラミング始め方/ 学び方の勧め

![IMG_0631.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590589/ac49e225-dfaf-9349-c7ac-c374f89d39a6.jpeg)
『エンジニアのキャリアについて考える』という大学生エンジニアの方の勉強会に行きました。
明瞭なプレゼンに感動&&わくわくしました！　熱が冷める前に書き留める！


## 0. このまとめについて

初心者には、たくさんある勉強法も、かえって何をすればいいのかわからず、結局雲を摑むよう。

a) プログラミングに興味がある、でも始め方がわからない
b) または、始めたはいいけれど、どのように学習を継続させていけばいいのかわからない（＊僕はここ）

などなど、問題は山積み。

今日、僕が参加した勉強会で紹介されていたことが、めちゃくちゃ腑に落ちたので、簡単ではありますが書き留めておきます。

ご参考までに！

## １.  初歩の初歩からの始め方/ インプット

### 学び始められる場所
##### 噛み砕いて教えてくれる無料サイトたち
* [Progate](https://prog-8.com/)（比較的読み込み中心学習）
* [ドットインストール](https://dotinstall.com/)（動画学習型　1~3分の動画）
* [picoCTF](https://picoctf.com/)（つよつよのためのセキュリティーに関する勉強--全英語:innocent:）

##### 挑戦できる場
* [Piaza](https://paiza.jp/) (競技プログラミング：自分のランクが上がると企業からどんどんオファーが届く）
* [Connpass](https://connpass.com/)　(勉強会の告知等：勉強会に参加→トレンドなどを理解、面白い人との出会い）

##### 壁にぶち当たった時は

- **Stackoverflow** （質問できる！！--英語だが確実に情報量が日本語より多い）
- Qiita (いろんなことが書いてある！）

基本は公式ドキュメントから学ぶべきだがその次ぐらいにStackoverflowに頼りたい

## ２. 学び方の見通し/ アウトプット

自学にせよ学校に通うにせよ学ぶところまでは**インプット**です。
それをインプットで終わらせず、**アウトプット**まで持っていくことで、自分の確実な成長につながります。

### How to output:
1. 学んだことを書き出す（BlogやQiita、noteなどを活用）
2. **勉強会**や**学会**に参加して発表
3. 実際にAppを制作してみる
    - フィードバックがもらえる（楽しい！！&&思わぬ成長につながる）
    - Firebaseを活用 (GoogleのBaas：アプリ開発時にサーバーの設定をGoogleに任せられる）
    =ドメインなどの設定が不要でめっちゃ便利

## ３. 継続していく

- ワクワクする気持ちを忘れない！
- 全力で楽しむ
- 成長しあえる仲間を作る！
- 一緒に頑張りましょう！！
【Rails】多対多の関連付け

# 1体多関連の復習
まずは1体多の関連を復習し、それからどのような場合に多対多の関連を付けるべきなのかを見ていきましょう。

関連ですので、二つモデルを用意します。一つはAuthorもう一つはBookにしましょう。

それぞれ著者と書籍を表すクラスです。書籍は一人の著者に書かれており、一人の著者は複数の書籍を出版しているとします。
![aso1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82541/dbd7894a-3873-cb46-b7a1-035afa193cce.png)

この時、1体多の関連を作成するには、Bookクラスにauthor_idというカラムを定義し、次のようにクラスを記述するのでした。

```ruby
class Author < ApplicationRecord
  has_many :books
end

class Book < ApplicationRecord
  belongs_to :author
end
```
このように定義することで、次のようなメソッドを使うことができます。

```ruby
author = Author.find(id)
# ある著者が書いた書籍の配列
# author_idがauthorのidと同じ値であるbookを取得
author.books

book = Book.find(id)
# ある書籍の著者
# bookが持つauthor_idと同じ値をidに持つauthorを取得
book.author
```

しかし、実際には一つの書籍に複数の著者がいるという状況の方が一般的です。

ですので、``book.authors``と``author.books``の双方向で複数の値を取得できるのが理想的です。現状、bookには一つのauthor_idを持つことしかできないので、何かしらの改修が必要になります。


# 多対多の実装

そこで多対多の関連が必要となってきます。
多対多の関連にはAuthor,Bookの他に中間クラスと言われるAuthorBookクラスを追加します。
このAuthorBookクラスはauthor_idとbook_idを持っており、著者と書籍の関連1つに付き1レコード生成されます。

ではモデルを作っていきましょう。

```
rails g model author_book author:references book:references
rake db:migrate
```

author:references,book:referencesと書くことでそれぞれのクラスと紐付けがされます。

次に各クラスを修正していきます。

```ruby
class Author < ApplicationRecord
  has_many :author_books
  has_many :books, through: :author_books
end


class Book < ApplicationRecord
  has_many :author_books
  has_many :authors, through: :author_books
end

class AuthorBook < ApplicationRecord
  belongs_to :book
  belongs_to :author
end
```

![aso2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82541/0ffcc4da-2e16-0e17-e1eb-d0ca7512b039.png)


これで準備は整いました。では実験してみましょう

```ruby
book = Book.create
author1 = Author.create
author2 = Author.create
book.authors
```

この時点ではまだ中間クラスによる関連付けが存在しないので、書籍に関連する著者は表示されないはずです。

```ruby
AuthorBook.create(author_id: author1.id, book_id: Book.id)
AuthorBook.create(author_id: author2.id, book_id: Book.id)
book.authors
```
では次はどうでしょうか？
設定がちゃんと出来れいれば2つのauthorインスタンスが表示されているはずです。

簡単ですが多対多の関連付けの説明は以上になります。

多対多の関連は例えば、投稿に対するイイね機能や俳優と出演作品の関連などに用いられます。
複数のモデルが出てきて複雑になってきましたが、使いこなして複雑なデータ構造も扱えるようにしましょう。
【GCS】画像を一般公開する

# はじめに
Google Cloud Storage（以下GCS）で、エンドユーザーにコンテンツを配信することはよくあると思います。
本稿では、GCSにアップロードした画像をエンドユーザーに配信する方法を記載します。

## 期限付きで公開する
**有効期限が最大７日間**の**署名付きの画像URL**を発行することができる
### node.jsで発行する
```js
import { Storage } from "@google-cloud/storage";

const storage = new Storage();
const file = storage.bucket(`バケット名`).file(`画像ファイル名`);
const url = await file.getSignedUrl({
  action: 'read',
  expires: Date.now() + 20 * 60 * 1000
});
```

## バケットを公開する
**無期限で画像を公開したい場合**は**バケット自体をパブリック**にする

![NO1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115823/786c85b5-3892-4c1b-cae1-6f38ffd32ef4.png)
デフォルトの設定では**Public access**が**Per object**となっている
![NO2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115823/0507ce6d-e73c-d9d5-7b8f-5a6ab44751fd.png)
バケットの**Permissions**より次を設定する
New members: **allUsers**
Role: **Storage Object Viewer**

![NO3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115823/6a9713d9-2a00-a604-bba0-36b7bb56e5c6.png)
**Public access**が**Public**になりバケットが一般公開された状態になる

![NO4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115823/a3532caa-9209-7876-16fd-27916cd0e9f0.png)
画像は次のURLでアクセスすることができる
https://storage.googleapis.com/{バケット名}/{画像ファイル名}
例えばmako.pngであれば
https://storage.googleapis.com/mako0715_images/mako.png
でアクセスすることができる

## 参考
https://cloud.google.com/storage/docs/access-control/signed-urls?hl=ja
ジェネリクスが解決する問題(駄文)

この投稿は「[ジェネリクス - TypeScript技術書 by YYTypeScript](https://book.yyts.org/generics)」をくだけた言葉でリメイクしたものです。

ここに2つの文字列のどちらかを五分五分の確率で返す関数があるよ。

```typescript
function chooseRandomlyString(v1: string, v2: string): string {
  return Math.random() <= 0.5 ? v1 : v2;
}
```

対戦結果とかおみくじとか、いろいろ使えて便利！

```typescript
const winOrLose = chooseRandomlyString("勝ち", "負け");
```

数字にも対応したぞ↓

```typescript
function chooseRandomlyNumber(v1: number, v2: number): number {
  return Math.random() <= 0.5 ? v1 : v2;
}
const num: number = chooseRandomlyNumber(1, 2);
```

URL版も作った! 広告のA/Bテストとかにも使えて便利だね。

```typescript
function chooseRandomlyURL(v1: URL, v2: URL): URL {
  return Math.random() <= 0.5 ? v1 : v2;
}
const url: URL = chooseRandomlyURL(urlA, urlB);
```

ん……、気がついたら同じような関数、3つになったぞ……

```typescript
function chooseRandomlyString(v1: string, v2: string): string {
  return Math.random() <= 0.5 ? v1 : v2;
}
function chooseRandomlyNumber(v1: number, v2: number): number {
  return Math.random() <= 0.5 ? v1 : v2;
}
function chooseRandomlyURL(v1: URL, v2: URL): URL {
  return Math.random() <= 0.5 ? v1 : v2;
}
```

リファクタリングだ！共通化だ！

```typescript
function chooseRandomly(v1: any, v2: any): any {
  return Math.random() <= 0.5 ? v1 : v2;
}
```

`any`にしたからどんな型も扱える。天才。

```typescript
let str = chooseRandomly(0, 1);
str = str.toLowerCase();
```

あれ、なんか実行時にエラー出るんだけど……😱

```
TypeError: str.toLowerCase is not a function
```

`string`入れるところに`number`入れてたー😱

さっきまでは、ちゃんと`string`型とか`number`型を書いて、コンパイラさんがチェックできるようにしてたからなあ。今までこんなバグらせ方、あり得なかったのになあ……。

もう`any`型だし、コンパイラさんもここはわからないよな……。しょうがないよな。。

・・・

コンパイラがチェックできるようにしようとすると、関数を量産しないといけない。。

かといって、関数を共通化しようとすると、コンパイラのチェックが効かなくなってしまう。。

悩ましい。

・・・

まてよ、

こんなふうに**型も引数みたいに扱えたら**いいのに！ 
そしたら、コンパイラさんも変なバグに気づいて教えてくれるのに！

```typescript
function chooseRandomly<type>(v1: <type>, v2: <type>): <type> {
  return Math.random() <= 0.5 ? v1 : v2;
}
chooseRandomly<string>("勝ち", "負け");
chooseRandomly<number>(1, 2);
chooseRandomly<URL>(urlA, urlB);
```

TypeScriptにこんな機能あったらな──！

・・・

それがジェネリクスです。

ジェネリクスを使うと、型の安全性とコードの共通化を両立できます！

```typescript
function chooseRandomly<T>(v1: T, v2: T): T {
  return Math.random() <= 0.5 ? v1 : v2;
}
```

さきほどのバグったコードも、コンパイルチェックで見つけられるようになります。

```typescript
let str = chooseRandomly<string>(0, 1); // コンパイルエラー
str = str.toLowerCase();
```

コンパイラさん「Argument of type '0' is not assignable to parameter of type 'string'.」

めでたし、めでたし。
foreach

日本語版[SPL Example](https://splunkbase.splunk.com/app/3456/)用
cf. [foreach](https://docs.splunk.com/Documentation/Splunk/latest/SearchReference/Foreach)
ここは譲れないでしょう。
#説明
>ワイルドカードフィールドリスト内の各フィールドに対して、テンプレート化されたストリーミングサブサーチを実行します。

わかりません。でも大事なことが書いてありますね
## ワイルドカードフィールドリスト
`*`のこと。　`*`は文字列順に処理されます。
`1,2,10,20`だと`1,10,2,20`の順です。:sweat:
`field_*`とか使えます。
`*_*`については後ほど。
##ストリーミングサーチ
`ストリーミング`なので_Fundamental 1_を思い出してください。
使えないSPLはわかりますね。わからない方は[Fundamental 1](https://www.splunk.com/ja_jp/training/free-courses/splunk-fundamentals-1.html)をまずやってみてください。Freeなコースです。
#記述
```
foreach <wc-field>... [fieldstr=<string>] [matchstr=<string>] [matchseg1=<string>] [matchseg2=<string>] [matchseg3=<string>] <subsearch>
```
#必須引数
_wc-field_と_subsearch_
`*`を使えると書いています。でも、どちらかというとフィールドを複数かけますの方が大事だと思う。
なお、この`*`、フィールドに[使えない文字](https://docs.splunk.com/Documentation/Splunk/latest/Knowledge/Aboutregularexpressionswithfieldextractions#Proper_field_name_syntax)が入っていると、\<\<FIELD>>の結果が化けます。
また、`_フィールド名`は読みません。`_time`や`_raw`は関係なし。
#オプション引数
|fieldstr|matchstr|matchseg1、2、3|
|:-:|:-:|:-:|
|フィールドそのもの|`*`で一致した文字列|*が複数の場合の<br>一致した文字列|
ただこちらについては\<\<FIELD>>、\<\<MATCHSTR>>、\<\<MATCHSEG1..3>>を別な文字に変えるだけです。`<<FIELD>>`とか使えない場合ってなんだろう:thinking:
#用例
`foreach`の考え方は**横に処理をしていく**
[２つのレコードで同一カラムの差分がとりたい](https://answers.splunk.com/answers/791787/%E3%81%A4%E3%81%AE%E3%83%AC%E3%82%B3%E3%83%BC%E3%83%88%E3%81%A6%E5%90%8C%E4%B8%80%E3%82%AB%E3%83%A9%E3%83%A0%E3%81%AE%E5%B7%AE%E5%88%86%E3%81%8B%E3%81%A8%E3%82%8A%E3%81%9F%E3%81%84.html)で`foreach`を使っているときの

```java:trim.spl
 | foreach * 
     [ eval <<FIELD>>=trim(<<FIELD>>)]
```
複数のフィールドの余計な空白を削除するために使用している。

[matchseg](https://answers.splunk.com/answers/690887/how-do-i-create-new-columns-with-the-foreach-comma.html)はこちらを参照。簡単な例は下に。

```java:matchseg.spl
| makeresults
| fillnull a_b_c
| foreach *_*_* [eval <<MATCHSEG3>><<MATCHSEG2>><<MATCHSEG1>> = '<<FIELD>>']
```

[multivalueを分割する](https://qiita.com/toshikawa/items/01ea913d7c2c36c50cec)ではmultivalueをsingleにするために`foreach`を使用している。
`foreach`の制御外にするために`rename`を使用して`_フィールド`にしているのはすごいコツ。

[Splunkでプログラムっぽいことをする](https://qiita.com/toshikawa/items/6345d888dd4ab9f4fe95)でループを実装している
#まとめ
使えるけど、難易度が高いのが`foreach`
複数のフィールドに対して同一の処理ができるで十分だと思います。
複数のフィールドを無理やり作るやり方は[質問してください](https://answers.splunk.com/index.html)
Markdownを書くにあたり

# Markdownを書くにあたっての余談
## 嚆矢として
本日ちょうどはじめての記事を投稿しました。投稿にするにあたって、
記事の内容に沿った[参考文献]は、記事自体に掲載したのですが、
**[Markdownの書き方]**や**[記事の書き方]** 自体に対して、
参考したものを別途用意したいと思い、この記事を作成しました。
随時、参考にしたものをここに追加して使っていく形になると思います。


## 参考文献リスト
### Markdownについて
***
- [Markdown記法 チートシート - Qiita](https://qiita.com/Qiita/items/c686397e4a0f4f11683d)

- [Qiitaでシンタックスハイライト可能な言語一覧 - Qiita](https://qiita.com/Qiita/items/e84f5aad7757afce82ba)

Qiitaの公式の記事。この記事かじりつきながら書いていました。
***

- [Markdown 記法 サンプル 一覧 - Qiita](https://qiita.com/Nukioman/items/01cd7ff819bc2e69b652)

- [Qiitaのマークダウンで色をつける方法[140色] - Qiita](https://qiita.com/twipg/items/d8043cd4681a2780c160)

基本的な記法や、その他について調べた時に見ました。

***
### 書き方、心得について
- [Qiitaで良い記事を書く技術 - Qiita](https://qiita.com/t12u/items/8c28484100dfd3a6351b)
CakePHPでの同時ログイン禁止

タイトルの通り、同時ログインを禁止したいときの処理について。
コードは会社にあるので概要だけだが、簡単な内容なので困らないと思う。

知らないうちに第三者に勝手にログインされているのはセキュリティ上も怖いので、2重ログインが必要なアプリでなければ実装しておきたい。

いつも頼りにしているスタッコオーバーフローであまり良いスレッドが見つけられず、結局普通に自分で作った。

##基本方針
* 後でログインしたセッションを有効とし、過去のセッションは全て強制ログアウトする
* sessionはDB保存している場合を想定
* ログイン時、DBから過去の同一ユーザーのsessionsを削除する(=強制ログアウト)

### sessionsテーブルにカラム追加
CakePHP標準のsessionテーブルにはid ,dataカラムがあるが、idはCookieのセッションID(ランダムな文字列)、dataはシリアライズされたセッションデータになっている。
すなわち、どのユーザーのデータか単純に調べられず、過去セッションの削除が簡単にできないため、追加カラム user_idを持たせる。
もし複数アプリでDB共用する場合、applicationカラムも必要。

```
user_id INT,
application vachar(255), #複数アプリでDB共用する場合のみ必要
```

###カスタムSession Handlerを作成＆設定
sessionsテーブルのuser_idに自動で書き込むため、カスタムハンドラを作成。
Cookbookの[カスタムセッションハンドラーの作成](https://book.cakephp.org/3/ja/development/sessions.html#id8)をベースにすれば簡単に作れる。(自分で書くのは数行くらい)
必要なのはwrite()のみで、ここで継承元のDatabaseSessionを見つつ、
user_idを書き込むように処理を追加する。
またapp.php等に設定も追加する。

なお、良いデータ取り回しが今一わからないので、Controllerからuser_idを伝えるのには
Configure::write(), read()で行ったが、終了時(?) Configureのデータがほぼ空になるタイミングでもwrite()が呼ばれるようなので、データがあるか否か確認してから書き込みを行う必要がある。
(何も考えずにConfigure::read()を放り込むと、nullで上書きされてしまう)

※Behaviorでもできると思うが、意味的にハンドラの方が良いと思う


###コントローラからuser_idをSession Handlerに伝える
ログイン処理(&認証不要処理)アクション、またAppController - isAuthorized()あたりでuser_idを伝えるようにする。
良い方法が思いつかず、Configure::write()/read()でやった。
Singletonかstaticでの情報受け渡し用クラスを作るのが正しいか？

**追記**
AuthComponentを呼べないという意味ではModelでも同じなので、その線でStackOverflowやgithub検索してみたものの、やはりConfigureかstaticでの受け渡し用クラス作る位しか見つけられなかった。


###ログイン時の過去セッション削除
ログイン処理時、そのuser idの過去セッションをsessionsテーブルから全削除する。
これにより、過去セッションは全てログアウトされる。
※ログアウト処理($this->Auth->logout())でもsessionテーブルのデータを消している
※このタイミングでは今回ログインのデータはまだ書き込まれていないようだが、バージョンによるかもしれない。今回ログインも消える場合は最新以外を消すよう調整。

```
$user = $this->Auth->identify();
if($user){
    ログイン成功時の処理...
    
    (追加)
    Sessionsテーブルから user_id =  $user['id'] のデータを全削除 (deleteAll)
    
}
```
Qiskit: 量子フーリエ変換

# 概要

量子フーリエ変換とは，離散フーリエ変換を量子回路上に実装したものです．
詳しい解説は参考書や他のサイトに任せて，ここではQiskitでの実装を行っていきたいと思います．
なお，完全に備忘録的な感じなので細かいところは気にしないでください．
今後はこのcodeを用いて他のアルゴリズム等を実装していきたいですね．

# code

```python:
# coding: utf-8

from qiskit import QuantumRegister, QuantumCircuit, ClassicalRegister
from math import log2, pi
import numpy as np


class QFT:

    def __init__(self, numQubit):
        self.numQubit = numQubit

    def construct_circuit(self, circuit=None, inverse=False):
        if circuit is None:
            circuit = QuantumCircuit(range(self.numQubit))
        if not inverse:
            self._input_initial_state(circuit)
            self._qft(circuit)
            self._swap_registers(circuit)
            return circuit
        elif inverse:
            self._swap_registers(circuit)
            self._qft(circuit, inverse=True)
            self._input_initial_state(circuit, inverse=True)
            return circuit

    def _input_initial_state(self, circuit, inverse=False):
        if not inverse:
            for j in range(self.numQubit):
                circuit.h(j)
                circuit.u1(-pi / float(2 ** j), j)
        elif inverse:
            for j in range(self.numQubit):
                circuit.u1(-pi / float(2 ** j), j)
                circuit.h(j)

    def _qft(self, circuit, inverse=False):
        if not inverse:
            for j in range(self.numQubit):
                circuit.h(j)
                for k in range(j + 1, self.numQubit):
                    circuit.cu1(pi / float(2 ** (k - j)), k, j)
        elif inverse:
            for j in range(self.numQubit).__reversed__():
                for k in range(j + 1, self.numQubit).__reversed__():
                    circuit.cu1(pi / float(2 ** (k - j)), k, j)
                circuit.h(j)
        circuit.barrier()

    def _swap_registers(self, circuit):
        for j in range(int(np.floor(self.numQubit / 2.))):
            circuit.swap(j, self.numQubit - j - 1)
```

# 参考文献

[1][Qiskit textbook](https://qiskit.org/textbook/preface.html)
iptablesコマンドよりも簡単に使えるufwコマンドでファイアウォールを設定する

## ファイアウォールを設定する意味

ファイアウォールとは外部ネットワークからの不要なアクセスを遮断したり、サーバに負荷をかけるアクセスを制限したりする機能です。

具体的には不必要なポートをあらかじめ閉じておくことでそのポートを通したアクセスを遮断することができます。

これを行うことにより、安心してサーバを外部公開できるようになります。

各Linuxディストリビューションでは標準でこの機能を用意しています。

ここではUbuntuを例にしていますが、基本的には他のディストリでも同じコマンドでいいはずです。

## iptablesコマンド

ファイアウォールの機能であるパケットフィルタリングできるコマンドです。

オプションを駆使すればかゆいところにも手が届きますが、初心者が使いこなすにはハードルが高いです。

ということで初心者エンジニアは次に紹介する`ufw`コマンドをまずは覚えましょう。

`iptables`の設定について詳しく知りたい方は以下を参考にしてみてください（何もわからないことがわかる）。

[【丁寧解説】Linuxファイアウォール iptablesの使い方](https://eng-entrance.com/linux-firewall)

## ufwコマンド

### 現在のネットワーク設定を確認する

では早速現在の設定を確認してみます。
 
`sudo ufw status`を実行
 
```
vagrant@ubuntu-xenial:~$ sudo ufw status
Status: inactive
```

`Uncomplicated FireWall`の略ということで、`complicate（複雑な） + un（打ち消す）`、つまり`簡単なファイアウォール`という意味です。

最初は`inactive`となっていて、`active（アクティブ） + in（打ち消す）` 、`非アクティブ`ということになる。

動いてないよーってことですね。

`un-`も`in-`も打ち消す意味を持っています。

## ファイアウォールをアクティブにする

`sudo ufw enable`を実行

```
vagrant@ubuntu-xenial:~$ sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup
```

これで有効化されました。

## default設定をOFFにする

ターミナルでサーバに`ssh`している場合はタブをもう一つ開いてサーバに接続しておきましょう。

`sudo ufw default deny`を実行する。

```
vagrant@ubuntu-xenial:~$ sudo ufw default deny
Default incoming policy changed to 'deny'
(be sure to update your rules accordingly)
```

これでサーバに外部からアクセスすることができなくなるため、誤って実行したターミナルのタブを閉じてしまった場合そのサーバにアクセスできなくなります。

## HTTP/HTTPS（Nginx：Webサーバ）用の80, 443番ポートへのアクセスを許可する

次に同じターミナルで`sudo ufw allow 'Nginx Full'`を実行してください。

```
vagrant@ubuntu-xenial:~$ sudo ufw allow 'Nginx Full'
Rule added
Rule added (v6)
```

事前にアプリケーション一覧を見たい場合は以下のように確認しましょう。

```
vagrant@ubuntu-xenial:~$ sudo ufw app list
Available applications:
  Nginx Full
  Nginx HTTP
  Nginx HTTPS
  OpenSSH
```

## SSH接続用のデフォルトポート（22番）を許可する

`sudo ufw allow 'OpenSSH'`を実行する。

```
vagrant@ubuntu-xenial:~$ sudo ufw allow 'OpenSSH'
Rule added
Rule added (v6)
```

## 設定を再確認する

最後にファイアウォールの設定を再確認する。

`sudo ufw status`

```
vagrant@ubuntu-xenial:~$ sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
Nginx Full                 ALLOW       Anywhere                  
OpenSSH                    ALLOW       Anywhere                  
Nginx Full (v6)            ALLOW       Anywhere (v6)             
OpenSSH (v6)               ALLOW       Anywhere (v6) 
```

上記設定になっていればOKです。

これでリモートアクセスとWebサーバへのアクセスのみを許可しているサーバが完成しました。

## まとめ

これで外部公開するサーバとして最低限のアクセス制限ができました。

次のステップは自分のWebアプリを公開することです。

プログラマーとして成長する秘訣は自分で作ったサービスを保守し続けることだって誰かが言ってた。

頑張りましょう。
Debian だって日本語入力したい

# 問題

### 環境

- ruby の docker image: `2.7-slim-buster` (DockerHub の公式のもの）
- `docker-compose` 使ってる


### 事象

ruby 環境を docker で立ち上げて
irb, pry から 日本語入力しようとしたらできない。（日本語を受け付けない）

# 最初に結果

```yml:docker-compose.yml
web:
  image: ruby:
  environment:
    ...
    LANG: C.UTF-8  # これを追加する
    ...
```

これで日本語入力ができるようになりました。

# 詳細

### 0. ググる

[こちら](https://qiita.com/yuki2006/items/6cea8c352e38f047b52a#comment-8e863c71962008035d0d) にたどり着く。
なるほど、OSによって対処が異なるのか。

### 1. 使用しているOSの確認

[こちら](https://uxmilk.jp/13610) を参考に使っている docker image のOSを確認した。
どうやら起動している ruby コンテナのOSは `Debian` らしい。

では、`Debian` の locale (ロケール) の設定の方法が簡単には見つからず…。

### 2. locale とは

[ロケールとは？](https://eng-entrance.com/linux-localization-locale)

> 言語_国.文字コード

### 3. locale コマンド

Linux には `locale` コマンドがあるとのこと。
fyi: https://www.atmarkit.co.jp/ait/articles/1812/06/news038.html

```
# コンテナのコンソール開く
$ docker-compose exec web bash

# 利用可能なロケール名を表示する
root@hogehoge# locale -a
C
C.UTF-8
POSIX
```

### 4. コンテナのENVに言語を設定

先程のサイトによると

> C,POSIX システム標準な英語
utf8(ja_JP.UTF-8) 日本語UTF-8

とのことなので、日本語入力が使えそうなのは `C.UTF-8`！

これを `docker-compose.yml` でENVに設定してみる。↓

```yml:docker-compose.yml
# 上部のコードの再掲

services:
  web:
    image: hoge
    environment:
      ...
      LANG: C.UTF-8  # これを追加する
      ...
```

### 5. いざ

日本語を入力してみる。↓

```bash

# コンテナのコンソール開く
$ docker-compose exec web bash

# ENVが設定されているか一応確認しておく
root@hogehoge# echo $LANG
C.UTF-8

# irb 開いて日本語入力してみる
root@hogehoge# irb
irb(main):001:0> あああ
Traceback (most recent call last):
        4: from /usr/local/bin/irb:23:in `<main>'
        3: from /usr/local/bin/irb:23:in `load'
        2: from /usr/local/lib/ruby/gems/2.7.0/gems/irb-1.2.1/exe/irb:11:in `<top (required)>'
        1: from (irb):1
NameError (undefined local variable or method `あああ' for main:Object)
```

入力できるようになりました。

# 最後に

いろいろと間違っているかもしれません。
その際はご指摘いただけますと幸いです。
Yet another article for "ImportError: cannot import name main" on Mac

Mac で pip(version は多分、19ぐらいだったと思います) が **ImportError: cannot import name main** といって動かなくなりました

[ググる](https://www.google.com/search?q=ImportError%3A+cannot+import+name+main&oq=ImportError%3A+cannot+import+name+main&aqs=chrome..69i57j69i59j69i61j69i58j69i60j69i61.1140j0j7&sourceid=chrome&ie=UTF-8)といろいろと皆様なんとかされているようですが、私の場合は[こちら](https://stackoverflow.com/questions/59842600/importerror-cannot-import-name-sourcedistribution-from-pip-internal-distrib) で紹介されてた [get-pip.py](https://bootstrap.pypa.io/get-pip.py) を使って

```bash:
wget https://bootstrap.pypa.io/get-pip.py
python get-pip.py
```

pip のバージョンを最新（本稿の時点で 20.0.2）にしたら、現症はでなくなりましたのでその旨をご報告させていただきます次第です

```bash
MacBook-Air:devtmp takeyuki$ pip --version
pip 20.0.2 from /Users/takeyuki/.pyenv/versions/anaconda-2.3.0/lib/python2.7/site-packages/pip (python 2.7)
```
『Unity C# 個人用メモ』 アイテムの一括生成と一括削除

```
public class Seisei : MonoBehaviour
{
    //生成したいオブジェクトを宣言
    [SerializeField] GameObject obj = default;

    void Update()
    {
        //一括生成
        if (Input.GetMouseButtonDown(0))
        {
            //x座標用
            for (int xi = 0; xi < 5; xi++)
            {
                //y座標用
                for (int zi = 0; zi < 3; zi++)
                {
                    //生成(対象,座標,角度)
                    Instantiate(obj, new Vector3(xi, 1f, zi), Quaternion.identity);
                }
            }
        }
```
        //一括削除
        if (Input.GetMouseButtonDown(1))
        {
            //あらかじめオブジェクトにタグをつけておいて、そのタグのついたオブジェクトをまとめて配列にぶち込む
            GameObject[] objs = GameObject.FindGameObjectsWithTag("obj");

            //配列onjsにぶち込んだものをを一纏めにする
            foreach(GameObject clone in objs)
            {
                Destroy(clone);
            }
        }
    }
}
DICOMから被験者の情報を一括自動収集

# はじめに
200件近いMRIのDICOMから被験者の
- 名前
- ID
- 生年月日
- 性別
- 年齢
- 検査日
を表にまとめる。
手作業では、いつまで経っても終わらないのとコピペのミス等のHuman Errorが出る可能性があるのでPCにまかせるプログラムを作成した。
<b>dcmdump</b>を使うととても便利。

コードと解説は[こちら](https://www.aiprogrammers.net/entry/2020/03/09/135424)に記載しました。
[【Linux】DICOMから被験者の情報を一括自動収集](https://www.aiprogrammers.net/entry/2020/03/09/135424)
rails s できない場合の原因事例

※初心者向け
アウトプットの練習の為記述しております。


rails sできなかったケースの１つ

かなりイージミスですので初心者の方のみ参考にしてください。

ターミナルでrails sを記述し実行したのですがエラーが発生しました。
下記のメッセージ内容です。

     => Booting Puma
     => Rails 5.2.4.1 application starting in development 
     => Run `rails server -h` for more startup options
     Puma starting in single mode...
     * Version 3.12.2 (ruby 2.5.1-p57), codename: Llamas in Pajamas
     * Min threads: 5, max threads: 5
     * Environment: development
     Exiting
     Traceback (most recent call last):
             44: from bin/rails:3:in `<main>'
             43: from bin/rails:3:in `load'
     .....

----

これは結果から言いますと、別のローカルサーバーが既に立ち上がっていた為、エラーとなりました。

解決策して、使用していないローカルサーバーをcontrolボタン＋Cボタンで切り再びrails s
これで解決しました。

もしかしたらと思ったら試してください。
レーザー加工用のG-codeを作成してみた

＜背景＞
最近CNCのミリングマシンの調整をしており、このミリングマシンがレーザー加工も行える。
そこでレーザー加工用のG-codeを作成してみた。

＜使用機材＞
汎用PC
OS windows10

<手順>
インクスペースのダウンロード
レーザーツールプラグインのダウンロード
エッジの検出
pngデータをベクターデータに変換する
ncファイル出力

＜方法＞
インクスペースをダウンロードして　インストールする
[INKSCAPE](https://inkscape.org/ja/)の公式サイトに行って
ダウンロードからWindows用のINKSCAPEをダウンロードする。
exeファイルを走らせるとウィザードで簡単にインストールできる。

レーザーカッターの加工用データを作成するためのプラグインInkscape laser Plug-Inをインストールする
[ここのサイト](https://jtechphotonics.com/?page_id=1980)で自分が使用してるINKSCAPEと同じバージョンのプラグインをダウンロードする。
ダウンロードしたファイルはzipなので全て展開する。（移動させるので、ここではどこで展開してもよい）
展開したファイルをINKSCAPEの下層、C\Program Files\inkscape\share\extensions　の中に入れてINKSCAPEを再起動する。メニューのエクステンションの中にGenerate laser Gcodeがあればインストールは完了。
![inkscape_laser.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/a9918979-81b0-7a90-16a5-671341669db0.jpeg)

作業をするためにページサイズを加工機のワークスペースのサイズをもとに指定して、画像データからエッジを検出してベクターファイルに変換する

画像データからエッジを検出する方法
すいれん氏の作成した輪郭検出器を利用してエッジを検出します。
[ここから](https://forest.watch.impress.co.jp/library/software/rinkakucyu/)ダウンロードできる。
ダウンロードして全て展開してexeを走らせるとアプリが立ち上がる。
![rinkaku.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/6cb25c7c-c91e-dcf2-da02-874233ace5ff.jpeg)

ファイルから加工したいデータを選択して開いて実行すると輪郭が抽出されるので、抽出された画像をファイルから保存する。
ここでできたデータをINKSCAPEを利用してベクターデータに変換する。
INKSCAPEのメニュー→ファイルからインポートで変換したい画像を読み込む
メニュー→パス→ビットマップをトレースをクリックする。
モードタブの平滑化と    オプションタブの角を平滑化のチェックを外す
画像の上にベクターオブジェクトができるのでドラッグしてずらす。
一旦名前をつけて保存する。
ベクターデータができたのでレーザー加工用のG-codeに変換する。
エクステンションからGenerate laser GcodeからJtech Photonic Laser Toolをクリックして開く。
必要な事項を調整する。path刃自分の場合はわかりやすいようにデスクトップを指定しています。
適用を押すと.ncというファイルの形で出力される。
![nc見本.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/56376a5f-913b-a65b-74f1-48537857ff84.jpeg)
ファイル例

このファイルをG-codesenderに入れるとレーザーカッターが制御できる。
![コメント 2020-02-21 211230.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/006d52aa-abf5-5a60-d474-fb194ebeb0ba.jpeg)



＜参考情報＞
Inkscappe 公式サイト　　
https://inkscape.org/ja/
InkscapeDesingn 　
http://inkscapedesign.web.fc2.com/index.html
Inkscape laser Plug-In Using the Inkscape Laser Tool Plug-in
https://jtechphotonics.com/?page_id=2012%E3%80%80%E3%80%8086953405
G-code加工データへの変換について
http://cubiio.muherz.com/jp/gcode_instruction.html
無料ソフト（オープンソース）のInkscapeを使って、簡単にベクター化
https://www.conifer.jp/qr_make/how_to/vector-henkan2.html
競馬データスクレイピングの流れ

まずは前回の記事ですが、意外にも多くの閲覧といいねを頂きまして、
大変感謝するとともに、震えております
今回から、具体的にどんなコードを書いたかを簡略に記事にしていきます。

競馬データといっても大きく分けてレース全体の情報とそのレースに出走した馬の情報があります。
いきなり目的の部分だけを切り抜かず、おおきなくくりで一度みてみる。.textなどもまだつけない

例えば以下のページの場合
![sankou.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534312/d66030a5-1670-accd-b713-e276856ef407.jpeg)
（netkeiba.com様より）

赤枠の部分にコースの種類、走行距離、馬場状態が書いてあるので、取得したいとします。
beautifulsuopを用いてもってくるとすると

```scr1.py
from bs4 import BeautifulSoup

id = '201806010101'#データ取得したいレースID
url = ('https://db.netkeiba.com/race/%s/' % (id))
response = request.urlopen(url)
bs = BeautifulSoup(response, 'html.parser')

raceinfo = bs.select("span")[6]
print(raceinfo)
#<span>ダ右1200m / 天候 : 晴 / ダート : 良 / 発走 : 09:55</span>
```
となるので、ここで初めて.textとか.splitとかをつける

```scr2.py
import re

racetype = raceinfo.text.split()[0][:1]
length = re.sub("\\D", "", raceinfo.text.split()[0])
conde = raceinfo.text.split()[8]
print(racetype,length,conde)
#ダ 1200 良
```
目的の情報である、コースの種類、走行距離、馬場状態を取得できました。

こうするメリットは、ループさせる際に最初の大きなくくりの部分に変数を使えば他は
そのままでもスムーズにデータ取得できること、リストの数字のアタリがつけやすいことでしょうか。
他のレースの情報や、馬毎の情報も同じ要領で取得すれば良いでしょう。

あと、過去10年ものデータを一度にスクレイピングするのはやめたほうが良いです。
何回かにわけて、データが揃ったら.concatとか.appendとかでくっつける。
1年毎にやると良い感じ(寝る時や出勤時にRUNさせると、大体タイムアウトしてますので…)

また取得した時点で何かしら計算を加えたものを保存したくなりますが、後にしましょう。ただでさえ時間がかかる作業なので…

以上のような流れでレースと馬のデータをわけて取得しました。

今回は短めですが、情報を取ってくるだけですし特別なことはしていませんので、これくらいで。
次はデータの整理、レースや馬の評価の仕方について書こうと思ってます。
次の記事からはどうしても競馬用語が多めになりますが、出来るだけ解説していきます。
MySQL/MariaDBのクラスタリングツール調査

# [Vitess(ヴィテス)](https://github.com/vitessio/vitess)

ライセンスは、Apache License 2.0
v5.20+20200204 (2020/02/05)

MySQLの水平方向スケールアウトを提供するための
データベースクラスタリングシステム

## Vitessの主な機能
・コネクションプール
・ACL
・パフォーマンス監視
・MySQLトポロジ管理インタフェースの提供
・水平分割/垂直分割

[MySQL + Kubernates = Vitess ? Vitess(ヴィテス)をインストールしてみよう！](https://www.s-style.co.jp/blog/2019/04/3855/)
[データベースクラスタリングシステムVitess](https://www.1915keke.com/entry/2018/10/08/062101)

[KubernetesでMySQLのクラスタツールVitessを動かす](https://qiita.com/teruq/items/36e90ba0ef8a43ab877c)
[Kubernetes を使ってスケールする MySQL クラスタ Vitess を試す](https://qiita.com/rrreeeyyy/items/90b3b1c73d22edc913ba)

[YouTubeがMySQLをスケールアウトする「Vitess」をオープンソースで公開。Kubernetesに対応](https://www.publickey1.jp/blog/15/youtubemysqlvitesskubernetes.html)
[元YouTubeのVitessデータベース開発者が手がける高性能Vitess、PlanetScale](https://techblitz.com/planetscale/)

# mysql-operator

oracleが開発しているものとpresslabsが開発しているものがある

[mysql-operatorを調べてみた](https://tech.griphone.co.jp/2019/05/14/survey-mysql-operator/)
[Kubernetes: MySQL Operatorの動作検証](https://qiita.com/ysakashita/items/a2f7060e1bc118e34811)
[Oracle MySQL Operator 検証してみた](https://speakerdeck.com/cotoc/oracle-mysql-operator-jian-zheng-sitemita)
Rails の helper でブロックを受け取って、そのブロックの中で render をつかいたい

# こんなことがしたい(けどうまくいかない)

ブロックを受け取って `h1` を出力するヘルパーと、それの使用例

```ruby:hoge_helper.rb
  def render_h1_with_block(&block)
    content_tag(:h1, yield, class: 'title')
  end
```

```erb:hoge/index.html.erb
<%= render_h1_with_block do %>
  <%= render 'fuga' %>
<% end %>
```

```erb:hoge/_fuga.html.erb
  <span>I am fuga.</span>
```

これは失敗する。`h1` の外側に `_fuga.html.erb`がレンダリングされてしまっている。 `render_h1_with_block` で `yield` したタイミングでレスポンスボディに `render 'fuga'` の結果が追加されてしまうようだ。

```html:意図しない結果になったindex.html
<span>I am fuga.</span>
<h1 class="title"></h1>
```

# 解決策: `capture` を使う

`CaptureHelper#capture` をつかって render の結果を保留すればうまくいく。

> The capture method extracts part of a template as a `String` object. You can then use this object anywhere in your templates, layout, or helpers.

(適当な翻訳) `capture` メソッドはテンプレートの一部を `String` オブジェクトとして切り出します。そのオブジェクトはテンプレート、レイアウト、ヘルパーで利用できます。

[ActionView::Helpers::CaptureHelper#capture - Ruby on Rails API Document より引用](https://api.rubyonrails.org/classes/ActionView/Helpers/CaptureHelper.html#method-i-capture)


```ruby:hoge_helper.rb
  def render_h1_with_block(&block)
    content_tag(:h1, capture(&block), class: 'title')
  end
```

公式ドキュメントに従って `yield` を `capture(&block)` に書き換えてみた。

```html:意図通りの結果になったindex.html
<h1 class="title"><span>I am fuga.</span></h1>
```

うまくいった！

# ドキュメント

- [ActionView::Helpers::CaptureHelper#capture - Ruby on Rails API Document](https://api.rubyonrails.org/classes/ActionView/Helpers/CaptureHelper.html#method-i-capture)
- [Action View の概要 - Rails ガイド](https://railsguides.jp/action_view_overview.html#capturehelper)
手順書を書くための基本

# 手順書を書くときに気をつけること

* スタートとゴールは一つ(条件分岐はしない)
* やることは一つに絞る
* 工程に見出しをつける

この三つを守ることで、読みやすい手順書が書けます。手順書は作業記録ではありません。自分のやった作業を箇条書きで書き出しても、手順書としては機能しません。

### スタートとゴールを絞る
どういう状態からスタートして、どういう状態になればゴールなのかをハッキリさせてから手順書を書きましょう。スタートをハッキリさせないと、どういう条件で使用できる手順書を書きたいのか分からなくなります。ゴールを決めておかないと、何をするための手順書か分からなくなります。

スタートとゴールをハッキリさせておくと、手順書に対しての補足を書くことができるようになります。また、「もし○○であれば」のような、条件分岐を避けることができます。結果として、手順がはっきりとして、分かりやすい手順書が書けます。

### やることを一つに絞る
書こうとしている手順が、ソフトウェアのセットアップなのか、設定なのか、それとも確認作業なのか、目的をはっきりさせましょう。例えば、調査をしながらソフトウェアのセットアップをしたとします。その時の手順をそのまま手順書に落とすと、どこが調査の手順なのか、どこがソフトウェアのセットアップの手順なのか、手順書を読んでも判断がつかなくなります。

同時に二つのことをやろうとすれば、その分、手順が複雑になり難易度が上がります。

### 工程に見出しをつける
手順を単に羅列しているだけでは、どのような作業をやっているのか分からなくなりやすいです。また、他のドキュメントと内容を関連付けたいときに見出しが役に立ちます。見出しをつけるだけでも、後から見直しがしやすくなりメンテナンス性が向上ます。
【UE4】ゲームパッドで動かす／第13回UE4ぷちコン進捗 - 2020/02/21

[1]:http://historia.co.jp/ue4petitcon13
[2]:https://qiita.com/Rinderon/items/68d5a5989aa3c9581cf0


[株式会社ヒストリアさん主催の第13回UE4ぷちコン][1]の作業進捗。

2/19(水)、20(木)とドタバタしていて更新できなかったので、そこまでの内容のまとめ。
これを書き終わったら今日の作業に着手するつもり。

# ゲームパッドで動かす

![20200221_1950.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358170/ca0b943d-0e03-26a6-c7d0-64294c626b33.gif)

> この二足歩行の恐竜、Paragon Minionsの中でのアセット名はBuff_Black。だが、Buffという言葉がプログラミング用語のバッファを連想して混乱しそうだったので、勝手に「サウルス(Saurus)」と命名。日本語的には「地竜」とでもしようか。

さて、[前回][2]やったテキトーにゲームパッドで動かす周りを、ちゃんと物理を使って実装しなおした。

## 移動について

- Saurusの「地面に沿った前方向」に、スティック入力の量に応じたForceを与えて、前向きに走らせた。
- Saurusの速度ベクトルのうち、水平方向（地面に沿った前後左右方向）には粘性抵抗を与えた。
    - 粘性抵抗：空気抵抗とか、筋肉はそんなに早く動けませんとか、そういう類のものをひっくるめて粘性抵抗と言ってしまう。
    - この粘性抵抗のおかげで、スティックを離すと勝手に速度がゼロにまで落ちていく。
    - いわゆる摩擦抵抗はやっていない。
- 方向転換をトルクでやってみたが、気持ちよくターンしてくれなかったのでやめた。
    - 純粋にスティックを入れた方向に向くようにした。
    - とはいえ、スティック入力に敏感に反応しすぎないように、補間を入れている。
- 急に向きを変えると慣性で滑った感じになる　…ように係数を調整。
    - 個人的に動きがちょっと重たい感じ（鈍感な感じ）が好きなので。

## アニメーションについて

- Blend Space 2DでIdle, Run Forward, Run Left, Run Right を混ぜてみたが、あまりいい動きをしてくれなかった。
    - もともと、Run Left/Right はターンする動きじゃなくて、平行移動する動きだったので、当然といえば当然。
    - 結局、IdleとRun ForwardをブレンドするBlend Space 1Dにした。
- ターンするときに先んじて首を振るのは、Aim Offset。試しに入れてみたらええ感じだったので採用。偶然の産物。

> Aim Offsetをいじっているうちにぶっ壊れて、Saurusが巨大かつポリゴンがぐちゃぐちゃに壊れる事件があったのだが…まあ気にしないことにしよう。

さて、今日の作業に入ろうかな。
VSCodeでリモートのソースを触る,いまさら？？！！

# VSCodeでリモートのソースを触る
いまさらなんですが（その２？） code-server でブラウザから vscode 使うっていうのを記事にしましたが、こちらはssh機能を使用してローカルのVSCodeからサーバのソースを触る方法です。

# 事前準備が必要、Windows で ssh 使えるようにする必要があるYO
いまどきのWindowsっていったら10ですが、何故か私が使用しているマシンは windows8 なの。そうするとちょっとだけ事前準備が必要となる（win10でも多少準備は必要ですよ）。
パスの設定とかしてsshコマンドが使えることを確認しておく。
・[Windows10標準のSSHクライアントを使ってみた](https://www.onebizlife.com/windows10-ssh-client-1980)
・[Windows8.1のコマンドプロンプトでSSH](https://i-doctor.sakura.ne.jp/font/?p=21912)

# sshコマンドからターゲットのサーバにsshできるのかを確認しておく
PuTTYやRloginからサーバにsshできている状態ならば、そんなに難しいことはないが黒い画面に拒否反応する方は一定数いるので、ここは我慢して設定してもらうｗ。

例：ホスト cent7 にssh(パスワード認証)でログインできる接続情報とした場合、`C:\Users\ユーザ名\.ssh\config`  に 下記の様に設定する。

```text
Host cent7
    HostName 192.168.11.xxx
    User vagrant
```
※その他の細かな設定はこちら ” [~/.ssh/config による快適 SSH 環境](https://qiita.com/oohira/items/7deae31469cfbbd740c1) ”

Windowsの黒いコマンドラインからsshを叩いてみる。

```command
C:\Users\xxxx>ssh cent7
vagrant@192.168.11.xxx's password:
Last login: Fri Feb 15 03:15:22 2020 from 192.168.11.x

[vagrant@vagrant ~]$ 
```

# リモート開発拡張機能（Remote Development）をインストールする
上記でsshの疎通が済んでいるのであればもう楽勝！！ Remote Development 拡張機能を入れましょう
・[VSCodeのリモート開発環境を使ってみた](https://qiita.com/yuzukaki/items/bb88e912cfafbfe25034)
・[Visual Studio CodeのRemote-SSH機能で、リモートのコードを触る方法](https://blog.masahiko.info/entry/2019/06/15/202003)
・[VSCodeのRemote Development機能が革命的な話。](https://crieit.net/posts/VSCode-Remote-Development)

# ローカルのWindowsからssh経由でサーバにアクセスする
![vscode_ssh.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44540/4e9bdea5-93f2-17c3-9978-ba4040fbf5cb.png)

はまったら、VScodeに表示されているログをみましょう
・[VSCodeのRemote SSHで「プロセスが、存在しないパイプに書き込もうとしました。」と出て繋がらない](https://qiita.com/CoffeeJunJun/items/29dda4b60a60bde3b771)

# 感想
いい時代になりましたねえ
JavaScriptのRandom関数の説明

JavaScriptのRandom関数について

Rancom関数とは何か？ということですが、まずはその意味について説明します。
Randomとは日本語で「でたらめな」という意味を持っています。
この意味からも想像できるように実行するたびに「乱数（＝でたらめな数字）を生成する」関数がRandom関数です。

次に疑問に思うことは「どんな乱数を生成するのか？」ということになりますよね？
答えは「0から1未満の小数値」で、つまり「0〜0.999…」です。

では、実際に使い方を見ていきましょう。
「0〜100」の乱数を発生させるには以下のようにプログラムを書きます。

  var random = Math.floor(Math.random() * (100 + 1));

Random関数は上記のようにMath.random()と書くことで呼び出すことができます。

この時、生成される値は「0〜0.999…」なので、
発生させたい値の範囲の最大値（今回は100）に+1したものを掛けることで、
0〜100の乱数を発生させることができます。
ただし、この時生成される乱数は小数点以下の値を持っているので、Math.floorで小数点以下を切り捨てます。

最後にn〜mの範囲の乱数を求めるための一般的なソースを紹介して終わります。

  var random = Math.floor(Math.random() * (m - n + 1)) + n

Random関数の理解に役立てていただけたら幸いです。

Ramdom関数はどういった場合に使えるかというと、以下のような結果をランダムに出したいときに使えます。
https://fortune.spicomi.net/yumeno-a/
https://fortune.spicomi.net/megrez-a/