OmniAICreator/Qiita-1.07M huggingface dataset:
openmpで並列して乱数生成する

# はじめに
確率微分方程式を解くときに並列計算ができるときがあります。毎ステップ、乱数の生成を行うわけですが、単純に並列化してしまうと乱数のseedが並列したスレッドで同じになってしまうので正確な計算ができなくなります。
そこで、再現性を持たせてシミュレーションするために乱数のseedの固定法について書きます。

# 並列化について
ここではOpenmpでの並列化を考えます。
おさらいとして簡単に並列化を確認します。

```c:openmp.c
void func(int i, int a[]){
    int j;
    for(j=0; j<M*i; j++){
        a[i]++;
    }
}

int main(void){
    int i = 0;
    int a[N] = {};
    int j = 0;
    #pragma omp parallel for
    for(i=0; i<N; i++){
        func(i, a);
        printf("thread: %d, a[%d]=%d\n", omp_get_thread_num(), i, a[i]);
    }

    return 0;
}
```
意味のない計算ですが、これでfunc()の計算は並列化できます。

# 乱数生成の並列化
乱数を生成する際にははじめにseedを固定しますが、単純にopenmpで並列化すると、今の変数がスレッドごとにコピーされるので全く同じ挙動をしてしまうはずです。
本家のsfmtを入れると簡単にseedの固定ができます。

以下のようなcodeで行うと、スレッドごとに乱数生成のためが固定されて、`schedule(static)`で`i`がどれかのスレッドに固定されて、毎回実行されることになります。

```c:random.c
#include<stdio.h>
#include<omp.h>
#include"sfmt.h"

#define N 8

int main(void){
    int i=0, t=0;
    sfmt_t sfmt[N];
    #pragma omp parallel for schedule(static)
    for(i=0; i<omp_get_max_threads(); i++){
        sfmt_init_gen_rand(sfmt+i, i%4);
    }
    for(t=0; t<3; t++){
        printf("step: %d\n", t);
        #pragma omp parallel for schedule(static)
        for(i=0; i<N; i++){
            printf("thread: %d, num: %d, rand: %f\n", omp_get_thread_num(), i, sfmt_genrand_real3(sfmt+omp_get_thread_num()));
        }
    }
    return 0;
}
```
オブジェクト指向ってなに？－私の解釈

# オブジェクト指向って何？

　そもそも**オブジェクト指向**って何か、スパっと言い切れますか？
　私は先生から「こんな感じで作っていくんだよ」とPython言語を用いて教わりましたが、今現在「**オブジェクト指向って何なの？**」と聞かれると説明出来ないな、と思い、自分の中の整理も兼ねて書き連ねることにします。（記事内に現れるコードはPythonをもとにしています）
　Qiitaにおける他の方のオブジェクト指向解説と盛大に被っているかもしれませんが、お目こぼしをお願いします。**言語に起こす事で思考を整理する**ことがこの記事の主目的です。もしよろしければ、モニターの前で「なるほどね」「私はこう思うな」なんて相槌をお願いします。（そして明らかなミスがあれば指摘をお願いします……）

## 「オブジェクト」=「object」=「物体」を考えるということ

　「オブジェクト指向って何？」という問いに対しての返答は、現在私の中では「プログラムの中身を物として考える考え方の事。物を作って、他の事に流用すると次のものを作るのが簡単で……」と煩雑なものです。
　私の中にある考え方、「**物として考える**」。具体的にはどういうことなのでしょう？ボールを例に挙げて、プログラムと紐づけてみましょう。

### 「ボール」にはいっぱい種類がある:soccer::baseball::volleyball::football::tennis::basketball:（クラスの作成）

　サッカーボール、野球ボール、バレーボール、ラグビーボール、テニスボール、バスケットボール。これらはそれぞれ特徴があります。だから、全く別のものです。でも、全部**ボール**です。
　この、**ボール**というひとくくり、これが`class`です。

　でも、種類によって名前、大きさ、素材や使い方、もちろん作り方だって全然違います。だから、「ボールを作るんです！」って宣言するときに必要な情報はたくさんあります。

```python
class ボール():
	def __init__(self,名前,大きさ,素材,使い方,作り方):
		self.名前 = 名前
        self.大きさ = 大きさ
        self.素材 = 素材
        self.使い方 = 使い方
        self.作り方 = 作り方
```

　これでボールを作る準備が整いました。一つ、`ボール`を作ってみましょう。

```python
ボールA = ボール('サッカーボール','大き目','合成革','蹴って遊ぶ','手縫い')
```

　これで、ボールA、蹴って遊ぶためのサッカーボールが作られました！なんと手縫いで！

### さらに、「野球ボール」にもいっぱい種類がある（クラスの継承）

　さて、これで一安心、いろんなボールをちまちま作っていると「ちょっと待ってよ」って声がかかります。

「野球ボールって、**軟式ボール**と**硬式ボール**っていう種類があるんじゃないの？」

　さて、困りました。**軟式ボール**、**硬式ボール**なんて分類は` class ボール`にはありません。これでは作られた野球ボールが軟式なのか、硬式なのかわかりません。野球ボールのためだけに`class ボール`に新しい分類を作らないといけないのでしょうか？　それともまた一から野球ボール用に新しい`class`を作り、`self.名前=名前`とちまちま書いていかないといけないのでしょうか……

　いいえ、そんな必要はありません。**野球ボール**という枠を**ボール**をもとに作ればいいのです。これが`class`の**継承**です。

　コードを書くときはこんなふうな感じになります。

```python
class 野球ボール(ボール):
    def __init__(self,大きさ,素材,使い方,作り方,種類):
        super().__init__('野球ボール',大きさ,素材,使い方,作り方)
        self.種類 = 種類
```

　`super().__init__('野球ボール',大きさ...作り方)`の部分では、`class 野球ボール(ボール)`の`()`の中、つまり**ボール**という`class`、枠にいろんな情報を当てはめています。そして、一行下側に新しく、種類を分類するための枠が追加されました！これからは、野球ボールは**野球ボール**の枠で作ります。

　もちろん、**ボール**の枠組みはそのままです。だから、バレーボールを作るときは、**ボール**の枠を使います。

```python
ボールB = 野球ボール('小さめ','ゴム','投げて遊ぶ','溶かして固める','軟式')
ボールC = ボール('バレーボール','中くらい','合成革','打って遊ぶ','手縫い')
```

これでボールB、軟式の野球ボールが作られました。ボールCはバレーボールです。

### つまり、オブジェクト指向って何だったの？

　私の思考は少しだけ整理されました。私の考える「**オブジェクト指向**」という考え方はどうやら枠組みを作って当てはめていくことだったようです。

　もしかすると、「いやいや、自分は違うと思うよ」っていう方がいるかもしれません。もしよろしければあなたのオブジェクト指向をお聞かせください。見識が広がることはとても嬉しいことです。
【Xcode】【Swift】No code signature found. と出た時の対処法

![75WRH.png](https://qiita-image-store.s3.amazonaws.com/0/345566/906191e5-0f57-a899-3879-980dbcddd185.png)

シュミレーターではビルドできるが実機だとインストール直前に上の通知が出てインストールできなかった。
原因はどうやらCarthageを使っている時に他のトラブルでBuild　phases　の　Run script only when installing にチェックを入れてしまっていたからのようだ。
普通はチェックが入っていないので、こういうエラーが起こることもなく、記事は少なかったのでここに記しておく。
[iOS][Swift] SkyWay-iOS-SDKのビデオ通話で通話用スピーカーから内蔵スピーカーへの変更

ビデオ通話の音声出力が通話用スピーカーがデフォルトなので、内蔵スピーカーへ変更。

```swift

        meshRoom?.on(SKWRoomEventEnum.ROOM_EVENT_STREAM, callback: { (arg:NSObject?) in
            self.remoteAudioSpeaker()
            
            if let msStream = arg as? SKWMediaStream{
                self.remoteStream = msStream
                DispatchQueue.main.async {
                    self.remoteStream?.addVideoRenderer(self.remoteStreamView, track: 0)
                }
                self.changeConnectionStatusUI(connected: true)
            }
        })
```

```swift

    func remoteAudioSpeaker() {
        self.remoteStream?.setEnableAudioTrack(0, enable: true)
        DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
            let audioSession = AVAudioSession.sharedInstance()
            do {
                try audioSession.overrideOutputAudioPort(AVAudioSession.PortOverride.speaker)
            } catch let error as NSError {
                print("audioSession error: \(error.localizedDescription)")
            }
        }
    }
```

[参考](https://qiita.com/shintaku_chiaki/items/d645bbf30e03ec5069b0)

[参考](https://stackoverflow.com/a/42357736)
TextSeek: デスクトップ上で文書検索

直接プログラミングに関係するものではないのですが。。。

パソコン操作時に文書をすぐ探し出せるTextSeekというソフトが現在(2019年3月8日～2019年3月9日 (土) 17:00まで) [Giveaway of the Day](https://www.giveawayoftheday.com/textseek/)で配布されています。

TextSeek (Windows/Mac対応) はPC内のGoogleライクな全文検索エンジンで、ファイル名とその中身どちらも検索可能です。

Microsoft Officeソフトや、PDF、RTFなどさまざまなフォーマットに対応しています。自分で検索範囲をカスタマイズできるので、より素早く的確に探しているテキストにアクセスできます。

検索結果はファイル名とそのスニペットが表示され、ファイル名をクリックすると、その内容が検索結果のハイライト付きで表示されます。

以前Google Desktopが気に入っていた方やPC標準の検索機能より高機能なソフトの欲しい方におすすめです。

[TextSeek公式サイト](https://www.textseek.net/ja/)
Cognos レポートで前回同じデータが発生した日時を取得する

#前回同じデータが発生した日時を取得する
もっとうまい方法が無いかな～と思いつつ、とりあえず投稿します。
こうやってみれば！という案あれば是非コメント下さい。

こういうテーブルがあったとします。
何かの監視をしていて、時々メッセージが挙がってくると思って頂ければ大丈夫です。
ID列はどうでも良いので無視して下さい。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/147246/cc7f9d7e-f2b3-95ab-9ad4-695e3206cb4a.png)

そんで、こんな風に、同じメッセージが前回いつ出力されたのか表示したい、というお題です。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/147246/cb3750c8-1402-3e04-225f-6dd4c9c68598.png)

#やり方
クエリー構造はこんな感じです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/147246/e796d627-82e0-ffb0-1b91-70b5438563f5.png)

クエリー1とクエリー2は、単にテーブルをそのまま取り込んだだけです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/147246/88380f8b-5b7f-ac3c-485d-4107e4b3e590.png)

クエリー1とクエリー2を結合する条件です。
TIMESTAMPの結合演算子は ">" 
![image.png](https://qiita-image-store.s3.amazonaws.com/0/147246/6949bccd-16f2-ffb0-f43f-1ef5a1658cde.png)

MESSAGEの結合演算子は "="
![image.png](https://qiita-image-store.s3.amazonaws.com/0/147246/f1ec0587-372f-2772-c60e-5eb8bd048603.png)

クエリー3はこの作り
　クエリー1より、TIMESTAMP、ID、MESSAGEを取得
　クエリー2より、MESSAGE1、TIMESTAMP1を取得
![image.png](https://qiita-image-store.s3.amazonaws.com/0/147246/0f043bca-bf19-ed94-5e2f-394c46821318.png)

**「前回発生時刻」**のデータアイテムの中身
maximum([TIMESTAMP1] for [MESSAGE1],[TIMESTAMP])

**出力結果**
![image.png](https://qiita-image-store.s3.amazonaws.com/0/147246/afd21f34-a993-c43d-23a7-0cdfebf80594.png)

とりあえずこれでできそうですけど、もっと簡単な方法あったら誰か教えて下さい！
Bigqueryの時刻のタイムゾーンに関する細かいこと

#タイムゾーンを色々変えて、クエリを走らせてみた
Bigqueryで時刻データを扱うとき、色々変換をしたら、結局どこのタイムゾーンで、何の時間なのかわからなくなってしまうことがあったので、まとめてみました。

```sql
select
--BQではディフォルトでUTC時間として認識される
timestamp('2019-03-06 08:01:17') as result_1,  

--特に書くことなし、もともとタイムゾーンがUTC時間なのでそのままである
timestamp('2019-03-06 08:01:17 UTC') as result_2,  

--タイムゾーンは日本時間なので、何も書かなければUTC時間に直される
timestamp('2019-03-06T08:01:17+09:00') as result_3,  

--下記のように書くと、これは日本時間ですよという命令になるので、-９時間してUTC時間表示に修正される
timestamp('2019-03-06 08:01:17', 'Asia/Tokyo') as result_4,  

--タイムゾーンはUTC時間で、日本時間に修正してくださいの命令は動きませんでした
--timestamp('2019-03-06 08:01:17 UTC','Asia/Tokyo') as result_5,  

--タイムゾーンは日本時間で、再度日本時間に修正してくださいの命令は動きませんでした
--timestamp('2019-03-06T08:01:17+09:00','Asia/Tokyo') as result_6,  

--日本時間タイムゾーンがついている時間を'%Y-%m-%d %H:%M:%S'形式の日本時間で表示
FORMAT_TIMESTAMP('%Y-%m-%d %H:%M:%S',timestamp('2019-03-06 08:01:17', 'Asia/Tokyo'),'Asia/Tokyo') as result_7,  

--UTC時間と認識されている時間を'%Y-%m-%d %H:%M:%S'形式の日本時間で表示　
FORMAT_TIMESTAMP('%Y-%m-%d %H:%M:%S',timestamp('2019-03-06 08:01:17'),'Asia/Tokyo') as result_8,  

--UTC時間の時間を'%Y-%m-%d %H:%M:%S'形式の日本時間で表示　
FORMAT_TIMESTAMP('%Y-%m-%d %H:%M:%S',timestamp('2019-03-06 08:01:17 UTC'),'Asia/Tokyo') as result_9,  

--UTC時間と認識されているデータを'%Y-%m-%d %H:%M:%S'形式の日本時間で表示する。しかし、タイムゾーン情報がなくなりタイムスタンプ型に直すとUTC時間と認識されてしまう。
timestamp_add(timestamp(FORMAT_TIMESTAMP('%Y-%m-%d %H:%M:%S',timestamp('2019-03-06 08:01:17'),'Asia/Tokyo')), interval 1 hour) as result_10
```
#実行結果
| result_1  | 2019-03-06 08:01:17 UTC |
|-----------|-------------------------|
| result_2  | 2019-03-06 08:01:17 UTC |
| result_3  | 2019-03-05 23:01:17 UTC |
| result_4  | 2019-03-05 23:01:17 UTC |
| result_7  | 2019-03-06 08:01:17     |
| result_8  | 2019-03-06 17:01:17     |
| result_9  | 2019-03-06 17:01:17     |
| result_10 | 2019-03-06 18:01:17 UTC |
#まとめ
#####1
Bigqueryではタイムゾーン情報が付いていなれば、ディフォルトでタイムゾーンはUTCと認識される。

#####2
Bigqueryでタイムゾーン情報が付いていない場合、クエリでタイムゾーンをつけた後編集した方が間違わずに済む
このように書く↓
timestamp('2019-03-06 08:01:17', 'Asia/Tokyo')

#####3
FORMAT_TIMESTAMP('%Y-%m-%d %H:%M:%S',…
のように書くとタイムゾーン情報がなくなるので、
変換しているうちに時間がずれることがある。
なるべくFORMAT_TIMESTAMPは使わない方が間違いが少ない
[iOS][Swift] UIBarButtonItem.appearanceで色やフォントがすぐに反映されない場合

変更前にnilを設定してから、再度、設定すると反映されます。

```swift

            UIBarButtonItem.appearance().setTitleTextAttributes(nil, for: .normal)
            UIBarButtonItem.appearance().setTitleTextAttributes(nil, for: .highlighted)

            let attributes = [NSAttributedString.Key.font:  UIFont(name: "Helvetica-Bold", size: 0.1)!, NSAttributedString.Key.foregroundColor: UIColor.clear]
            UIBarButtonItem.appearance().setTitleTextAttributes(attributes, for: .normal)
            UIBarButtonItem.appearance().setTitleTextAttributes(attributes, for: .highlighted)

```

[参考](https://stackoverflow.com/a/18849993)
iOSとAndroidプッシュ通知の仕組み  APNs と　FCM　の話

リモート通知を送りたい場合、Apple や Google が提供するプッシュ通知サーバーに対してプッシュ通知を送信することを依頼します。Apple は APNs (Apple Push Notification service)、Google は GCM/FCM というサービス名でプッシュ通知サービスを提供しています。APNs や GCM/FCM は端末との TCP コネクションを貼っており、プッシュ通知の配信を一括して代行しています。

Apple Push Notification Service（APNS）とは、アップルが作成したサービスで、2009年6月17日のiOS 3.0のリリースとともに開始された。Push技術を使って常にオープンなIP接続を通してサードパーティー製アプリケーションのサーバーからの通知をアップルの端末に転送する。バッジ、音、カスタムテキストアラートといった通知がある。APNSはまた開発者が活用するAPIをMac OS X Lionに追加する。

 ![apns-flow.PNG](https://qiita-image-store.s3.amazonaws.com/0/125746/1674a498-7a45-c2fe-e3eb-efd91e2edd45.png)


Firebase Cloud Messaging（FCM）は、メッセージを無料で確実に配信するためのクロスプラットフォーム メッセージング ソリューションです。前身のGoogle Cloud Messaging （GCM)　APIは2019年4月11日付けで廃止する予定です。

![messaging-overview.png](https://qiita-image-store.s3.amazonaws.com/0/125746/f621a7c0-1a4a-dc95-2205-21755e06d8cc.png)
javascriptのブラケット記法とドット記法のちょっとした違い

# 結論
ブラケット記法はキー指定に式を受け付けるけど、ドット記法はキー指定に式を受け付けない。

# 詳細
[【世界で2万人が受講】JavaScriptエンジニアのためのES6完全ガイド](https://www.udemy.com/javascriptes6/)の「応用問題：findWhere関数を作ってみよう」って演習を解いている途中、少し躓いたので、そこで学んだことの共有です。
リンク先の講座を今後受講する際にはネタバレですので、一応ご注意ください。

### 動かなかったコード
```
function findWhere(array, criteria) {
  var key = Object.keys(criteria)[0];
  return array.find(
      (element) =>
    {return element.key === criteria.key}
  )
}
```
### 動いたコード
```
function findWhere(array, criteria) {
  var key = Object.keys(criteria)[0];
  return array.find(
      (element) =>
    {return element[key] === criteria[key]}
  )
}
```

# 理由
結論と重複しますが**ブラケット記法はキー指定に式を受け付けるけど、ドット記法はキー指定に式を受け付けない**から。

# 参考
http://harakotan.hatenablog.jp/entry/2015/05/17/004707

# お礼
お読みいただきありがとうございました。本記事であなたの躓きがなくなったり、コードが良くなることを祈っております。
初心者がzshをカスタムしようととしたらハマった

チェリー本でRubyを学習している初心者です。
irbでコマンドを打っていくうちに、ターミナルをカスタムしたくなりました。
そこで、zshをカスタムしようとしたら少しハマったので、備忘録として残します。

・ MacBook Pro Early 2015(Mojave 10.14.2)を使用

##1.zshを入れる
zshの入れ方はもっと参考になる記事があるので、各自ググってください。
~~4,5ヶ月前に入れたので、失念しました。~~

##2.画面のデザインを変更する
まず、ターミナルの白い画面を、AtomのFlatland Darkのような黒基調のデザインに変更しようと思いました。
![スクリーンショット 2019-03-08 15.09.27.png](https://qiita-image-store.s3.amazonaws.com/0/297926/3b2e1558-7339-e85f-3b41-f37979ae4e5a.png)

[こちら](https://qiita.com/kinchiki/items/57e9391128d07819c321)や[あちら](http://no213015e.hatenablog.com/entry/2017/12/07/162535)のページで**Iceberg**という良さげなテーマが紹介されているので、それを導入します。


![スクリーンショット 2019-03-08 15.35.40.png](https://qiita-image-store.s3.amazonaws.com/0/297926/4df734ec-f84b-eb62-864e-6b8bad940f93.png)

[リンク](https://cocopon.github.io/iceberg.vim/)に飛んだら最下部までスクロールして、赤線のDownloadをクリック。
ダウンロードしたzipファイルを、解凍してください。

Iceberg.terminalというファイルが確認できたら、
ターミナルを起動し、```command + ,```で環境設定を開きます。
左のバーの下部にある歯車のマークをクリックして、先のIceberg.terminalを選択すると、Icebergを設定できます。
テーマをデフォルトにして完了です。


##3.ついでにフォントも変える
せっかくなので、**Ricty Diminished**というフォントに変更します。

```
brew tap caskroom/fonts
brew cask install font-ricty-diminished
```
ターミナルで↑の二つのコマンドを打てば、インストールできます。
そのまま ```command + ,```で環境設定を開き、画面右のフォントの変更ボタンを押して選択してください。

##4.Preztoを導入する
今回の**メイン**です。私はここで2,30分ハマりました。
Preztoによって、コマンドにハイライトがついたり、
パソコンの名称が表示されなくなったり、ターミナルが**使いやすく**なります。

```
git clone --recursive https://github.com/sorin-ionescu/prezto.git "${ZDOTDIR:-$HOME}/.zprezto"
```
Preztoを```git clone```します。

```
setopt EXTENDED_GLOB
for rcfile in "${ZDOTDIR:-$HOME}"/.zprezto/runcoms/^README.md(.N); do
  ln -s "$rcfile" "${ZDOTDIR:-$HOME}/.${rcfile:t}"
done
```
zshのコンフィグを作成します。

```
zstyle ':prezto:module:prompt' theme 'sorin'
```
また、```.zpreztorc```のプロンプトをsorinから

```
zstyle ':prezto:module:prompt' theme 'pure'
```
pureに変更します。

```
zstyle ':prezto:load' pmodule \
  'environment' \
  'terminal' \
  'editor' \
  'history' \
  'directory' \
  'spectrum' \
  'utility' \
  'completion' \
  'syntax-highlighting' \ # 追加
  'autosuggestions' \ # 追加
  'prompt' \
```
そして、サジェスト機能とハイライトを有効にします。

本来なら、ここでターミナルを再起動すれば反映して、
設定完了ですが、特に何も変化はありませんでした。

結論から言うと、
[公式](https://github.com/sorin-ionescu/prezto#installation)にも書いてある通り、**あらかじめzshのコンフィグファイル(```.zshrc```など)があると**

```
setopt EXTENDED_GLOB
for rcfile in "${ZDOTDIR:-$HOME}"/.zprezto/runcoms/^README.md(.N); do
  ln -s "$rcfile" "${ZDOTDIR:-$HOME}/.${rcfile:t}"
done
```

**zshのコンフィグを作成した際に、```ln```がエラーを引き起こすそうです。**

```
source "${ZDOTDIR:-$HOME}/.zprezto/init.zsh"
```
↑のコマンドを```.zshrc```の最下部に記載して、無事反映されました。
私のケースは単純だったので、これで済みましたが、設定変更前にバックアップを取っておくことをお勧めします。



デザインとフォントの変更、Preztoを導入しましたが、ターミナルが見やすくなってRuby学習が捗りそうです。
初心者でも、zshカスタムはオススメです。

##参考にしたページ
* [お前らのターミナルはダサい](https://qiita.com/kinchiki/items/57e9391128d07819c321)
* [HomebrewでRicty Diminishedフォントをインストールする](https://qiita.com/ryo0301/items/b6319b3a3d1feb0e932b)
* [Macの環境設定(3) zshを入れる](https://qiita.com/nenokido2000/items/763a4af5c161ff5ede68)
* [Terminalの配色を変更する — ガラクタの積み重ね](http://no213015e.hatenablog.com/entry/2017/12/07/162535)
* [Prezto — Github](https://github.com/sorin-ionescu/prezto#installation)
スマホで画面の縦と横を判定する


使わなくなったので供養

```js
const ua = navigator.userAgent.toLowerCase()
        // iPhone
        const isiPhone = (ua.indexOf('iphone') > -1)
        // iPad
        const isiPad = (ua.indexOf('ipad') > -1)
        // Android
        const isAndroid = (ua.indexOf('android') > -1) && (ua.indexOf('mobile') > -1)
        // Android Tablet
        const isAndroidTablet = (ua.indexOf('android') > -1) && (ua.indexOf('mobile') == -1)

        const directionCheck = () => {
          const direction = Math.abs(window.orientation)
          if(direction == 90) {
            alert('横向き')
          } else {
            alert('縦向き')
          }
        }

        // iOS
        if(isiPhone || isiPad) {
          window.onorientationchange = directionCheck
        }
        // Android
        if(isAndroid || isAndroidTablet) {
          window.onresize = directionCheck
        }
        directionCheck()
```
ブログからコードコピペしようとしたときにニュルッと出てくるアレを消し去る

## ブログのコードブロックでたまにみる邪魔なバー

<img style="border: 1px; box-shadow: 4px 4px 4px;" src="https://qiita-image-store.s3.amazonaws.com/0/283120/f752add5-0738-e359-b241-901596d8fdb6.gif">
</div>

↑こんな経験ありませんか？
1行目だけコピーしずらかったり、位置がずれたりして邪悪です。

WordPress プラグインの **Crayon Syntax Highlighter** の仕様みたいです。

## Bookmarklet を実行して邪魔なヘッダーだけ無効にする

```js
// Crayon のツールバーを消す
javascript: (function() {
  Array.from(document.querySelectorAll('.crayon-toolbar')).forEach(e =>
    e.remove()
  );
})();

```

このコードを実行することで無効にできます。

![Kapture 2019-03-08 at 17.05.04.gif](https://qiita-image-store.s3.amazonaws.com/0/283120/a2da019d-64ce-dc79-a075-29da32885309.gif)
)

※ `javascript: ` 込みでアドレスバーで実行する。または Bookmark に登録する。

参照: [ブックマークレット活用・すばやい登録と呼び出し \- Qiita](https://qiita.com/elzup/items/1698767d77af39d8dd19)
PostgreSQLと他のDBの比較

# PostgreSQLと他のDBの比較を行っているサイトを見つけた
* PostgreSQLに移行を検討する時に一番気になり箇所だと思うのでメモ。
* 機能的観点ではだいぶPostgreSQL有利に書かれている気がするが、サポートが少ないデメリットをどのようにケアするかが重要ですね。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/367069/81d3ab26-a908-1eec-6f57-80bcace63bd1.png)


# 参考資料
[Let's Postgres: PostgreSQLの機能と他のRDBMSの比較](https://lets.postgresql.jp/documents/tutorial/rdbms-hikaku/1/)
BitriseのDeploy to iTunes Connectステップをアップデート

![deploy-to-itunesconnect-shenzhen.png](https://qiita-image-store.s3.amazonaws.com/0/156085/27a4e18b-d99f-217c-636a-07e81d024c6f.png)
iTunesConnect(App Store Connect)にアップロードするために使用していた `deploy-to-itunesconnect-shenzhen` が **Deprecated** になり、うまく動作しなくなった。
[こちらのアナウンス](https://github.com/bitrise-io/steps-deploy-to-itunesconnect-shenzhen) には `deploy-to-itunesconnect-deliver` ステップに移行してねと書いてあるけど、**２段階認証を有効にしているとうまくいかないのでこれは罠！**


![deploy-to-itunesconnect-application-loader.png](https://qiita-image-store.s3.amazonaws.com/0/156085/d4e9e84b-c9e0-8aa9-417a-791b4957a8ff.png)
`deploy-to-itunesconnect-application-loader` ( **Deploy to iTunes Connect - Application Loader** ) を使いましょう！


# 作業
`deploy-to-itunesconnect-shenzhen` をworkflowから削除し、  `deploy-to-itunesconnect-application-loader` を追加する。
## ステップの設定
<img width="347" alt="input_variables.png" src="https://qiita-image-store.s3.amazonaws.com/0/156085/b70c96d7-1ba1-9379-6cf9-beafa4310c9d.png">

### Apple ID
Secretsに保存しているApple IDの変数名を指定する。
展開した時に表示される Select secret variable ボタンから変数の選択や追加が可能。
![select_secret_variable.png](https://qiita-image-store.s3.amazonaws.com/0/156085/4e38f32f-3086-70dc-0743-4d27456dc1fb.png)
### Password
Secretsに保存しているパスワードの変数名を指定する。
### Application Specific Password
Secretsに保存しているApp用パスワードを指定する。

App用パスワードは以下の手順で取得可能:
1. https://appleid.apple.com でログイン
2.  **セキュリティ** セクションの **App用パスワード** を生成
3. 画面の案内に従い、最後に表示されたテキストをコピーする
![app_specified_password.png](https://qiita-image-store.s3.amazonaws.com/0/156085/9d24df72-caf9-27fb-4799-5b62f29c27c5.png)
![app_specified_password_done.png](https://qiita-image-store.s3.amazonaws.com/0/156085/13ee1c33-d473-adf4-970b-628df5e90a05.png)
4. コピーしたテキストをBitriseのSecretsに変数保存して設定に適用する


## 設定した箇所のyml

```yaml

    - deploy-to-itunesconnect-application-loader@0.9.4:
        inputs:
        - password: "$ITUNES_CONNECT_PASSWORD"
        - app_password: "$ITUNES_CONNECT_APP_SPECIFIC_PASSWORD"
        - itunescon_user: "$ITUNES_CONNECT_USER_APPLE_ID"
```
[numpy] 時系列データから移動窓行列を作成

時系列データに対して、移動平均を計算するということはよくあり、このためにpandasのrolling関数などは非常に有用です。

その一方で、より複雑な処理のために、ある時点で移動窓の中に入っているデータを列とする行列を生成したいという状況もしばしば起こります。つまり、時系列データ{$x_1,x_2,\ldots,x_n$}が与えられた時に、次のような行列
$$\begin{pmatrix}
x_1 & x_2 & \ldots & x_m \\\ 
x_2 & x_3 & \ldots & x_{m+1} \\\
\vdots & \vdots & \vdots & \vdots \\\
x_{n-m+1} & x_{n-m+1} & \ldots & x_n  
\end{pmatrix}$$
を作りたいということです。ここで$m$は移動窓のサイズです。このような作業は、時系列データをRNNに入力する際にも必要になってきます。

これを簡単に行うための関数があることを最近見つけたので、ここでシェアしておきます。

```python
def moving_window_matrix(x,window_size):
    n = x.shape[0]
    stride = x.strides[0]
    return np.lib.stride_tricks.as_strided(x, shape=(n-window_size+1, window_size), strides=(stride,stride) ).copy()
```

以下は簡単な動作例です。

```
moving_window_matrix(np.arange(10),3)

>>> array([[0, 1, 2],
           [1, 2, 3],
           [2, 3, 4],
           [3, 4, 5],
           [4, 5, 6],
           [5, 6, 7],
           [6, 7, 8],
           [7, 8, 9]])
```

keyword: moving window, sliding window, rolling, matrix
【React+TypeScript】React Hooks useImperativeHandleのサンプル

![React+TypeScript.png](https://qiita-image-store.s3.amazonaws.com/0/189588/5a8e170b-6e26-9266-b772-037a3303c0b8.png)

TypeScriptでの`useImperativeHandle`の使い方のサンプル。

親のコンポーネントから、子で定義したメソッドを呼び出す場合に使用します。

```tsx:FancyInput.tsx
import React, { useRef, useImperativeHandle, forwardRef } from "react";

// 公開したいメソッドの定義
interface Handler {
  setFocus(): void;
}

// 公開したいメソッドを持つコンポーネントの定義
// プロパティを追加する場合は、forwardRef<Handler, Props>と定義する。
const FancyInput = forwardRef<Handler>((props, ref) => {
  const inputRef = useRef({} as HTMLInputElement);

  useImperativeHandle(ref, () => {
    return {
      setFocus() {
        inputRef.current.focus();
      }
    };
  });

  return <input ref={inputRef} type="text" />;
});

// コンポーネントの使い方
const App = () => {
  const ref = useRef({} as Handler);
  return (
    <>
      <FancyInput ref={ref} />
      <button
        onClick={() => {
          ref.current.setFocus();
        }}
      >
        click
      </button>
    </>
  );
};
```
Liferay開発時に、開いているポートレットのJSPを知りたい

# 開発時に、開いているポートレットのJSPを知りたい場合
Liferay開発ツールのチーフエンジニアであるGregory Amersonが、Chrome上で利用しているポートレットの該当のJSPを表示させる、[JSP Spy](https://github.com/gamerson/jsp-spy-demo)というエクステンションとバンドルを作成してくれました。

Liferayのセットアップが終わり、Liferay Bladeツールも導入済みということで話を進めます。

## 使い方
まず、`portal-ext.properties` に以下の設定をします。

```
include-and-override=portal-developer.properties
direct.servlet.context.enabled=false
```

1. [JSP Spy](https://github.com/gamerson/jsp-spy-demo)リポジトリをgit cloneします。
2. `blade server init`でLiferayサーバーを初期化します。
3. `blade server run`でLiferayサーバーが起動します
4. `blade deploy`でバンドルをLiferayサーバーにデプロイします。
5. Chromeブラウザを利用している場合、[エクステンションページを開きます。](chrome://extensions)
6. 開発者モードを有効にします。（右側にあります）
7. パッケージ化されていない拡張機能を読み込むを選択し、ディスク上の[jsp-spy-chrome-extension](https://github.com/gamerson/jsp-spy-demomodules/jsp-spy-chrome-extension)を指定します。
8. Liferayにアクセスし、Chromeブラウザの開発ツールにアクセスします。（ショートカットは`Cmd+Option+I`)
9. 要素を選択で、ページのDOM要素を選択します。
10.　要素サイドバーのJSP Spyペインをクリックすると、そこに該当JSPのパスが表示されます。

どうでしょうか？コードを追う際に、ポートレット名を見つけて、`view.jsp`を見つけて、コードを見てそのリンク先を予想して・・・という手順をもう踏まなくてすみますね！

Happy Liferay Coding!
CSSでblock要素を上下左右中央寄せにできなかった原因と解決

# 問題

CSSでblock要素を上下左右中央寄せしたくて

```
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 任意の値
height: 任意の値
```

こんな感じのCSSを入れたけど、上手くいかなかった。

# 原因＆解決

別CSSファイルで

```
* {
  margin:0;
  padding:0;
}
```
を入れていて、この `margin:0;` が原因だった。

```
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto; /* <-- 追加 */
width: 任意の値
height: 任意の値
```

これで解決。
JavaチュートリアルにあったInitializing Fieldsのためのメモ

https://docs.oracle.com/en/java/ に公開されているJavaチュートリアルの[「フィールドの初期化」](https://docs.oracle.com/javase/tutorial/java/javaOO/initial.html)https://docs.oracle.com/javase/tutorial/java/javaOO/initial.html のところで質問が多かった「Static Initialization Blocks（静的初期化ブロック ）」についての簡単なメモ。（細かい解説は、気が向いたら書くかも）


#ざっくりと説明

`static { .... }`を使ってブロックを書いて、そこにstaticフィールドの初期化を入れることができる。これがStatic Initialization Blocksというもの。

Static Initialization Blockは、コンストラクタより前に実行されるブロックである。

Static Initialization Blockは、そのクラスを宣言で利用しただけのときは、まだ実行されない。

Static Initialization Blockは、そのクラスのコンストラクタまたはstaticメソッドを呼び出したときに、先駆けて実行される。

staticの付いていない`  { .... }`は、インスタンスフィールドの初期化のためのブロック（Initialization Blocks）になる。これも、実行はコンストラクタより前。

Initialization Blocksにあるロジックは、どのコンストラクタからも呼び出されるので、コンストラクタのオーバーロードがある場合で、どのコンストラクタでも同じように行うロジックを入れておくことができる。



##動作確認したければ、以下のソースで。

```java:InitializationBlocksSample.java

public class InitializationBlocksSample {
	final static int x;
	int y;

	// Static Initialization Blocks, it is called before first load.
	static {
		x=10;
		System.out.println("Static Initialization Blocks");
	}

	// Initialization Blocks, it it called from all constructors.
	{
		y=10;
		System.out.println("Initialization Blocks");
	}

	// constructor
	public InitializationBlocksSample() {
		System.out.println("non-parameter constructor");
	}

	public InitializationBlocksSample(String param) {
		System.out.println("parameter constructor");
	}

	public static void staticMethod() {
		System.out.println("staticMethod");
	}

	public void instanceMethod() {
		System.out.println("instanceMethod");
	}
}
```

```java:Main.java

public class Main {
	public static void main(String[] args) {
		InitializationBlocksSample o;

		System.out.println("start");

		InitializationBlocksSample.staticMethod();

		o = new InitializationBlocksSample();
		o.instanceMethod();

		InitializationBlocksSample p = new InitializationBlocksSample("parameter");

	}
}
```

static関連の記事：[Javaのstaticな話](https://qiita.com/b1ueskydragon/items/2a6e0812a9cee3fc255f#static-%E3%82%A4%E3%83%8B%E3%82%B7%E3%83%A3%E3%83%A9%E3%82%A4%E3%82%B6)
Dockerで構築したJenkinsでDockerを使う(dind)

# Jenkins(dind)でいくつかハマりどころがあったので備忘録として

## 手順

### Dockerfile

```dockerfile
FROM zephyrhq/docker-jenkins-dind

RUN usermod -g docker jenkins
```

Docker(docker-compose入)のJenkinsイメージを使ってなるべく楽する。

参考:[jenkinsコンテナ上でdockerを利用する]
(https://qiita.com/paper2/items/751246ee7dcae50d5042)

### docker-compose.yml

```yml
version: '3'
services: 
  jenkins:
    build: ./
    ports:
      - 8080:8080
    privileged: true
    volumes:
      - ./jenkins_dind:/var/lib/jenkins
      - /var/run/docker.sock:/var/run/docker.sock
```

## Dockerで構築したJenkinsでdocker-compose.ymlを使いたい場合

相対パスでvolumeを設定するとvolumeが空になる問題がある。
volumeは絶対パスで指定する。ベタに直書きするとローカル環境と実際のサーバー上で異なるので、環境変数を使うのがベター。

```yml
version: '3'
services: 
  hoge_service:
    image: hoge
    volumes:
      - /home/hogeuser/jenkins_dind/workspace/hoge_service/project:/hoge_service/project #絶対パスにするのが肝
```

## 参考
[dockerでjenkinsを立てる+その中でDockerを走らせる(docker in docker)](https://qiita.com/gymnstcs/items/e74f98774db45bfbc212)
[jenkinsコンテナ上でdockerを利用する]
(https://qiita.com/paper2/items/751246ee7dcae50d5042)
Twilioの挙動を3分で確認できる！TwiML Binsの使い方

# TwiML Binsとは
TwiML Binsとはサーバーを立てることなくTwiMLのテストを行うことができるテスト環境です。
Twilioのチュートリアルとやってるとサーバーを用意してTwiMLを試してね！
みたいな記載があるのですが、その時にTwiML Binsを利用することが可能です。

使い方によっては本番アプリとして使用することが可能です。
TwiML Binsを使ったアプリ例：
[自前でサーバーを建てずに、順次発信をTwiML Binsだけで構築する！](https://qiita.com/mobilebiz/items/ca4a54e20dc1936378b0)

# TwiML Binsの使い方
## TwiML Binsの画面を開く
1. メニューボタンをクリックしてメニュー画面を開きます。
![スクリーンショット 2019-03-08 10.29.40.png](https://qiita-image-store.s3.amazonaws.com/0/92989/67a0550c-8ffd-8cee-e3f8-f5f775f70b64.png)

2. メニューの中からRunTimeを選択します
![スクリーンショット 2019-03-08 10.30.03.png](https://qiita-image-store.s3.amazonaws.com/0/92989/1e6210c0-bc67-a926-dc40-9826675eb5e8.png)

3. RunTime画面の左側のメニューの中から下の方にあるTwiML Binsを選択します。
![スクリーンショット 2019-03-08 10.30.57.png](https://qiita-image-store.s3.amazonaws.com/0/92989/42a8cdc6-0e0d-ca2d-87f5-e33eb8b42ae1.png)

## TwiML Binsを作成する
1. 新規TwiML Binsを作成する。
![スクリーンショット 2019-03-08 10.33.43.png](https://qiita-image-store.s3.amazonaws.com/0/92989/2ced535d-53c1-730b-4f09-0fe5abac0b26.png)

2. TwiMLを作成する
FRIENDRY NAME:任意 **別のTwiML Binと名前が被ると選択肢に片方しか表示されないので注意**
TWIML:TwiMLを入力する
![スクリーンショット 2019-03-08 10.33.55.png](https://qiita-image-store.s3.amazonaws.com/0/92989/272a4344-6c25-ced6-3666-e774f7b0495e.png)

3. 作成したTwiMLを保存する
![スクリーンショット 2019-03-08 10.34.11.png](https://qiita-image-store.s3.amazonaws.com/0/92989/9ae54213-8fde-ded7-5276-16a7d03f41c9.png)

## TwiML Binsを使う電話番号に設定する
1. 設定する電話番号を選択する
![スクリーンショット 2019-03-08 16.08.51.png](https://qiita-image-store.s3.amazonaws.com/0/92989/cce99a11-08d0-0b33-5dd5-528111e4bae1.png)
![スクリーンショット 2019-03-08 16.09.17.png](https://qiita-image-store.s3.amazonaws.com/0/92989/55e6bb06-1dd0-f69d-c390-a14396a0f81d.png)

2. TwiML Binを設定する
対象の電話番号が着信した時に挙動にTwiMLを選択する
![スクリーンショット 2019-03-08 16.10.09.png](https://qiita-image-store.s3.amazonaws.com/0/92989/e35459a6-64d4-ef2d-6077-fcdd12a4a919.png)

3. 作成したTwiML Binを選択する
![スクリーンショット 2019-03-08 16.10.19.png](https://qiita-image-store.s3.amazonaws.com/0/92989/28b0a943-4b62-3755-173b-c1601df32c2f.png)

4. 保存する
![スクリーンショット 2019-03-08 16.13.39.png](https://qiita-image-store.s3.amazonaws.com/0/92989/25ad2f39-5799-ea53-8188-cf60b2dbd71a.png)

## テスト
準備が完了したので試しに、設定した電話番号に電話をかけてみましょう！
StripeをVueにシンプルに導入してみた

# はじめに
カード決済システムのStripeをVueに組み込んだので備忘録として最低限動くコードを載せておきます
cssはサボって設定してないのでお好きなようにやっちゃってくださいw
あと`stripe_id`は自分のに置き換えましょう

## 完成形
cssがないので見た目があれですが、機能としては問題ないです

![image.png](https://qiita-image-store.s3.amazonaws.com/0/230651/8a28631d-3440-5e32-88b7-5fb578c9d2cc.png)

# 実装 

## スクリプトを読み込む

１行追加するだけ。簡単。

```index.html
  <head>
    <script src="https://js.stripe.com/v3/"></script>
  </head>

```

## Vueの開発

こんな感じが最低限動く形かなと。

```stripe.vue
<template>
  <div class="container">
    <div id="card-element">
    </div>
    <button @click="submit">Submit Payment</button>
    <div v-if="show_result">{{result_message}}</div>
  </div>

</template>

<script>
export default {
  data() {
    return {
      card: null,
      stripe: Stripe("stripe_id"),
      show_result: false,
      result_message: ""
    };
  },
  mounted() {
    const elements = this.stripe.elements();
    this.card = elements.create("card");
    this.card.mount("#card-element");
  },
  methods: {
    submit() {
      const self = this;
      self.show_result = false;
      this.stripe.createToken(this.card).then(result => {
        console.log("result: " + JSON.stringify(result));
        // エラーの場合
        if (result.error) {
          self.show_result = true;
          self.result_message = result.error.message;
          // 成功の場合
        } else {
          self.show_result = true;
          self.result_message = "token_id: " + result.token.id;
        }
      });
    }
  }
};
</script>

<style scoped>
</style>

```

成功の場合にトークンを表示してるだけなので、ここにサーバにトークンを投げる処理を入れるといいと思います

# おわりに

簡単にカード決済を導入できて便利ですね〜
お金系はバグが怖いからシンプルにできるのは嬉しい

それではよきStripeライフを〜
ブラウザ内で画面いっぱいに表示させる画像のサイズ

雑な感じですが。

|デバイス|作成サイズ|見切れないであろう範囲|
|---|---|---|
|PC|2560px × 1536px （1 : 0.6）|1536px × 1152px （1 : 0.45〜1）|
|タブレット|1536px × 1906px （1 : 1.241）|---|
|スマホ|750px × 1155px （1 : 1.54）|680px × 1050px （1 : 1.4〜1.7）|

以下は検証内容のメモです。
※OSやブラウザのバージョンは考慮してない（僕が確認した時の状態）
※タブレットはiPadしか確認できてない

# PC
ベストビューサイズ：2560x1536（1:0.6）
保証サイズ：1536x1152（1:0.45〜1）
※幅を1280で設定
※Ratina対応で倍サイズ

## MacBook Pro 13インチ ディスプレイ（1280×800）
### Google Chrome（ダウンロードバーあり）
高さ：717
幅が1280時の比率：0.560（最大幅）
幅が1024時の比率：0.700（最低保証幅）
### Safari
高さ：839
幅が1280時の比率：0.655（最大幅）
幅が1024時の比率：0.819（最低保証幅）

## フルHD ディスプレイ（1920x1080）
### Google Chrome（ダウンロードバーあり）
高さ：897
幅が1920時の比率：0.467（最大幅）
幅が1024時の比率：0.876（最低保証幅）
### Safari
高さ：1019
幅が1920時の比率：0.531（最大幅）
幅が1024時の比率：0.995（最低保証幅）
### Edge
高さ：963
幅が1920時の比率：0.502（最大幅）
幅が1024時の比率：0.940（最低保証幅）

## 求められる高さの比率
最小：0.467（より小さくなることは少ない）
最大：0.995（より大きくなることは多い）

フルHDで全画面に広げることは少ないので、ベストビューの比率は「0.6」くらいが良いかも（テキトー）
上記の結果を踏まえて「0.45〜1.0」も保証できるとよいと。



# タブレット
サイズ：1536x1906（1:1.241）
※Ratina対応で倍サイズ
※ポートレートだけ考える（ランドスケープはPCで設定）

## iPad（768×1024）
### Safari
高さ：953
幅768の比率：1.241

## 求められる高さの比率
iPadしかみてないけど、1.241で良いんじゃない（テキトー）


# スマホ
ベストビューサイズ：750x1155（1:1.54）
保証サイズ：680x1050（1:1.4〜1.7）
※幅を375で設定
※Ratina対応で倍サイズ

以下検証内容
※ランドスケープは考えてない

## iPhone 5s（320x568）
高さ：459
幅320の比率：1.434

## iPhone X（375x812）
高さ：635
幅375の比率：1.693

## iPhone 8（375x667）
高さ：553
幅375の比率：1.475

## iPhone 8 Plus（414x736）
高さ：620
幅414の比率：1.498

## Pixel 3（360x720）
高さ：602
幅360の比率：1.672

## 求められる高さの比率
最小：1.434（古い端末は小さめ）
最大：1.693（これ以上大きくなることはあまりない）

iPhone 6,7,8 と Pixel 3 の間をとり日本での割合を考えて、ベストビューの比率は「1.54」くらいが良いかも（テキトー）
上記の結果を踏まえて「1.4〜1.7」も保証できるとよいと。
仮想化ソフトの種類

# 仮想環境とは
仮想環境　＝　一つのOS内で複数のOSを動かすことのできる環境
仮想化ソフトウェア　＝　仮想環境を実現できるソフトウェア
仮想化マシン　＝　仮想化ソフトウェアで作られた仮想的な環境

#仮想化ソフトウェアの種類
- ホスト型仮想化ソフトウェア
 - VirtualBox [Oracle]　・・・Windows／Macに対応
 - WorkstationPlayer[VMWare]　・・・Windowｓに対応
- ハイパー型仮想化ソフトウェア
 - Hyper-V [Microsoft]
 - vSphereHypervisor [VMWare]
 - KVM [Linux]
- コンテナエンジン型仮想化ソフトウェア
 - Docker

## ホスト型仮想化ソフトウェアとは
以下ホスト型のイメージ
<img width="198" alt="スクリーンショット 2019-03-08 15.57.27.png" src="https://qiita-image-store.s3.amazonaws.com/0/285385/b03c2ace-644a-5b02-6f52-63325cc28e09.png">

[特徴]

- OS上に仮想ソフトをダウンロードし、仮想化ソフト上に仮想マシンを構築する。
- 仮想マシンには、任意のOSをインストールすることが可能である。　
- 個人環境の運用向き

[メリット]

- ホスト上で実行中のアプリと並行して利用できる。

[デメリット]

- ホストOSに負荷がかかると、仮想マシンのパフォーマンスに影響がある。

## ハイパー型仮想化ソフトウェアとは
以下ハイパー型のイメージ
<img width="205" alt="スクリーンショット 2019-03-08 16.10.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/285385/b40925d8-c543-88b6-5ffb-9def2450e5ef.png">

[特徴]

- 動作にOSがいらない ＝ ハードウェア上で動作
- 物理サーバーのCPUに組み込まれている仮想化技術を利用　
- 本番環境の運用向き

[メリット]

- パフォーマンスが優秀　＝　性能を最大限に発揮できる

[デメリット]

- ハードウェアを制御するため、専用のドライバーが必要

## コンテナエンジン型仮想化ソフトウェアとは
以下コンテナエンジン型のイメージ
<img width="216" alt="スクリーンショット 2019-03-08 16.16.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/285385/743dc158-3e82-8e3b-5ab2-19b7f2f44b6c.png">
[特徴]

- ゲストOSを起動せずに、アプリを起動　
- コンテナにはOSがない

[メリット]

- アプリの起動が早い
- 処理が軽量
- 使用メモリが小さい

[デメリット]

- ホストOSと同一のカーネルを利用する（共有する）必要がある
- コミットしない限り保存されない
深層学習用サーバセットアップ


#Ubuntu16.04
##ゲートウェイサーバ
ユーザ名と公開鍵をゲートウェイサーバ管理者に送り、アカウントを作ってもらう。

```terminal
#秘密鍵・公開鍵の作成
$ ssy-keygen -t rsa
```
##GPUサーバ
GPUサーバ管理者にアカウントを作ってもらう。

```terminal
#ログインしてパスワードの設定
$ passwd
```

##シェル
強力な補完を使いたいのでzshをインストール。
他には[fish](https://fishshell.com/docs/current/tutorial.html)もよいが、`command1 && command2`が使えなかったりfor文の書式がbash、zshと異なり慣れなかった。

```terminal
#インストール
$ sudo apt install zsh
$ chsh -s /usr/bin/zsh
```

##CUDA
バージョンを確認、CUDA:8、cuDNN:6

```terminal
$ nvcc -V
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2016 NVIDIA Corporation
Built on Tue_Jan_10_13:22:03_CST_2017
Cuda compilation tools, release 8.0, V8.0.61

$ cat /usr/local/cuda/include/cudnn.h | grep CUDNN_MAJOR -A 2
#define CUDNN_MAJOR    6
```
##systemのPython
```terminal
$ python3 -V
Python 3.5.2
$ python3 -m venv system35
The virtual environment was not created successfully because ensurepip is not
available.  On Debian/Ubuntu systems, you need to install the python3-venv
package using the following command.

    apt-get install python3-venv

You may need to use sudo with that command.  After installing the python3-venv
package, recreate your virtual environment.

Failing command: ['/home/natsuki/system35/bin/python3', '-Im', 'ensurepip', '--upgrade', '--default-pip']
```
venvが入っていない

systemのpython2.7からはchainerやtensorflowがセットアップされていることが確認できる
確認したサンプルプログラム`/usr/local/torch7/convnet-benchmarks/chainer/alex.py`

##pyenv
systemの環境を汚さずにユーザディレクトリにライブラリを入れたりPythonのバージョンをあげたりAnacondaを入れたりしたい。

```terminal
#インストール
$ git clone https://github.com/pyenv/pyenv.git ~/.pyenv
```

`~/.zshrc`に以下を追記

```zsh:~/.zshrc
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
```

`source ~/.zshrc`して現在のインタプリタでも有効にする。

##Anaconda
pyenvで入るAnacondaとPythonのバージョン対応表

|anaconda3-5.0.0|anaconda3-5.1.0|anaconda3-5.2.0|anaconda3-5.3.0|
|---|---|---|---|
|3.6.8|3.6.4|3.6.5|3.7.0|

以下のようにビルド名を確認してCUDAのバージョンに対応するtensorflow-gpuを探す。

```
$ conda search tensorflow-gpu
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/45682/b6dc6c52-3ad3-4aad-72ab-ee27e21761a7.png)

Python3.7系では動かないことが確認できたので、Python3.6.8のanaconda3-5.0.0をインストールする。

```terminal
$ pyenv install anaconda3-5.0.0
$ pyenv global anaconda3-5.0.0
```

以下のようにバージョンとビルドを指定してtensorflow-gpuをインストールする。

```terminal
$ conda install tensorflow-gpu=1.2.1=py36cuda8.0cudnn6.0_0
```

###GPUが見えているか確認

```python
from tensorflow.python.client import device_lib
device_lib.list_local_devices()
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/45682/9c599929-b392-22db-80ec-24603c852ca4.png)

###備考
```
$ pip install tensorflow-gpu
```
では共有ライブラリlibcublas.soの依存が解決できなかった。`conda`は便利。

##謝辞
研究室選びの相談に乗ってくれた友人と予算を引っ張ってきている先生方に感謝。
Vue.jsで自動的にプラグインを読み込む

# 概要
<font color="DarkGreen">Vue.js</font>においてモジュールを作る上でpluginの仕組みを利用すると以下のような恩恵を受けることができます

* モジュールをimportする必要がない
* チーム等での作業の際にimportしたモジュール変数の名前がブレない
* 関数内でvueインスタンスを取り扱える

このように便利なのでいつも僕は以下の画像のように大量にpluginを作ってます
（本当は数倍ありますが割愛しています）
![image.png](https://qiita-image-store.s3.amazonaws.com/0/137384/94d58fd2-065a-a5ff-7763-89c4715174ac.png)

しかし、このようにいっぱいpluginが増えてくると`app.js`へ大量に`Vue.use(hoge)`が増えますし、`import`文も盛り盛り増えます
そこでpluginフォルダ内に置かれた`index.js`を除く`js`ファイルを自動的に`Vue.use`してくれるように実装してみました


# 実装

**Webpack**のAPIを使います

`plugins/index.js`

```js
import Vue from 'vue'
export default {
  install: function () {
    let modules = require.context('./', true, /.*\.[tj]sx?/)
    modules.keys()
      .filter(v => !v.match(/index/))
      .forEach(v => {
        let m = modules(v)
        Vue.use(m.default)
      })
  }
}
```
終わりです

# 解説
### require.context
[Webpackでフォルダ内の全ファイルを一気にrequireする](https://qiita.com/jkr_2255/items/d23e66323857d3189a00)に全てが載っていますが
Webpackの`require`には`requrie.context`[^1]なるAPIが存在します

公式リファレンスから抜粋すると

```js
require.context(directory, useSubdirectories = false, regExp = /^\.\//);
```
とあります
それぞれの引数は以下のようになります

#### directory
この関数が記述されているファイルからの相対パス、もしくは絶対パス
#### useSubdirectories
サブディレクトリを探索対象にするか否か
#### regExp
マッチさせたいファイル名の正規表現

### context module API
`require.context`によって返却される関数オブジェクトは`resolve`,`keys`,`id`の3つのプロパティを持ちます
#### resolve
`module id`とexportされた`function`を返却します
#### keys
処理可能な全てのモジュールハンドルを返却します
#### id
Contextモジュールのidを返却します

ここでは`keys`を使い、`index.js`を除くモジュールを全ての取り出します
説明には
> 処理可能な全てのモジュールハンドルを返却します

とありますが、実際にはファイル名の配列が返却されるので

```js
modules.keys()
      .filter(v => !v.match(/index/))
```
のように簡単にfilterで除外できます
そして最後に

```js
      .forEach(v => {
        let m = modules(v)
        Vue.use(m.default)
      })
```
してあげることでVueにpluginとして認識させることができます
ここで`modules(v)`とありますが、`modules`自体が

> A context module exports a (require) function that takes one argument: the request.

とあるようにrequireする関数なので、パス名を渡してあげるだけで大丈夫です

# 終わりに
現状Nuxt.jsだとnuxt.config.jsにプラグインのファイル名を記述しないと使えないという冗長さがあるので自動で取り込んで欲しいですね
PR投げるか

[^1]: [Webpack - Dependency Management](https://webpack.js.org/guides/dependency-management/#requirecontext)
JSPとServletの連携で文字化け

【環境】
---
OS:Windows10
Eclipse:pleiades-4.8.0-java-win-32bit_20180923

【問題】
---
jspファイルをWebで見たときに文字化けしてしまう
![文字化け.png](https://qiita-image-store.s3.amazonaws.com/0/373772/8e951406-5e5d-e14b-a16d-264400613457.png)

<h2>対象ファイル</h2>


```java:WelcomeServlet.java
package study.servlet;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/*
 * クライアントから送信されるリクエストパラメーター"userName"と"password"を受信し、
 * 表示を行うServlet
 */
@WebServlet(name = "WelcomeServlet", urlPatterns = "/welcome")

public class WelcomeServlet extends HttpServlet {

	/**
	 * GETメソッドを受信する
	 */
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		//リクエストパラメータの文字エンコーディングを指定
		request.setCharacterEncoding("utf-8");

		//リクエストパラメータ"userName"の値を取得
		String userName = request.getParameter("userName");

		//userNameを"userName"という名前でrequestスコープに格納
		request.setAttribute("userName", userName);

		//welcome.jspへのforword処理
		RequestDispatcher rd = request.getRequestDispatcher("/welcome.jsp");
		rd.forward(request, response);
	}
}
```

```html:input.jsp
<%@ page contentType = "text/html; charset = utf-8" %>

<!DOCTYPE html>
<html>
<head>
	<title>送信フォーム</title>
</head>
<body>
	<form action="${ pageContext.request.contextPath }/welcome " method="post">
		お名前は？<input type="text" name="userName" size="30"><br>
		<input type="submit" value="送信">
	</form>
</body>
</html>
```

```html:welcome.jsp
<%@ page contentType = "text/html ; charser = utf-8" %>

<!DOCTYPE html>
<html>
<head>
	<title>ようこそ！</title>
</head>
<body>
	<h3>ようこそ！${ userName } さん!</h3>
</body>
</html>
```

【考えられる原因】
---
1.文字エンコーディングの設定をミスっている

【対処】
---
1.各jspファイルの定義部分の=前後にある半角スペースを削除

```html:input.jsp
<%@ page contentType="text/html　; charset=utf-8" %>
```

```html:welcome.jsp
<%@ page contentType="text/html ; charser=utf-8" %>
```

【原因と対策】
---
JSPファイルの定義文にはスペースをできる限り入れない。
Jupyter Notebookで簡単なグラフを書く

Jupyter Notebookで簡単なグラフを書いてみる。

## Paiza Cloud

Paiza Cloudを使うと、ブラウザがあればJupyter Notebookが使い始められてお試しにはちょうどいい。無料でも使える。

[クラウド開発環境 PaizaCloudクラウドIDE - クラウドIDEでWeb開発!](https://paiza.cloud/ja/)

Paizaのアカウントが無くても、GitHubアカウントでログインできる。

ログインしたら、Jupyter Notebookのコンテナを立ち上げる。

<img width="888" alt="suin___PaizaCloud_-_Instant_Linux_with_Web-UI.png" src="https://qiita-image-store.s3.amazonaws.com/0/889/ecefd51b-d11d-66f5-5445-0d4d76edea23.png">


コンテナが立ち上がるとNotebookのUIが表示されるので、Python3のノートを作る:

<img width="1336" alt="Banners_and_Alerts_and_suin___PaizaCloud_-_Instant_Linux_with_Web-UI.png" src="https://qiita-image-store.s3.amazonaws.com/0/889/c81653be-f726-fad8-9705-01ddfa269d89.png">


Paiza Cloud以外では、[Homebrewを使ってJupyter Notebookをインストールする](https://qiita.com/suin/items/8af8fc59f282eb2d35a4)のも結構簡単。

## Jupyter Notebookにコードを書く

```py
%matplotlib inline

import numpy as np
import matplotlib.pyplot as plt

時給 = 2000

def 給与計算(労働時間):
    return 時給 * 労働時間

労働時間 = np.linspace(0, 160, 16)
給与 = 給与計算(労働時間)

fig = plt.figure(dpi=144)
ax = fig.add_subplot(1, 1, 1)
ax.yaxis.set_major_formatter(plt.FuncFormatter(lambda 給与, loc: "{:,}".format(int(給与))))
plt.scatter(労働時間, 給与)
plt.plot(労働時間, 給与)
plt.grid(True)
plt.title("労働時間と給与(時給%d円)" % 時給)
plt.xlabel("労働時間")
plt.ylabel("給与")
plt.show()
```

書いたら「Run」を押すとグラフが描画される。

<img width="759" alt="Untitled.png" src="https://qiita-image-store.s3.amazonaws.com/0/889/8ecd5008-f9ee-818c-d328-de5d746a5d19.png">

便利。
VC++でUnix時間をローカル時間にするコード

現在のUnix時間(UTC 1970 年 1 月 1 日からの経過秒数を表す)を、`Fri Mar  8 15:17:26 2019`みたいな時間に変換して出力するコード。
[こちら](https://www.daniweb.com/programming/software-development/threads/177665/help-with-asctime-s-and-localtime-s)によると、`localtime_s`と`asctime_s`が標準関数ではないので、MSVC以外のコンパイラでは通らない。

##コード

```c++:Source.cpp
#include <iostream>
#include <ctime>
#include "time.h"
//これがないとstd::stringをstd::coutできない
#include <string>

time_t get_unix_time() {

	time_t now = std::time(nullptr);
	return now;
}

std::string unix_to_local(time_t utc) {

	struct tm now;
	char result[32];

	//utc -> local itme
	localtime_s(&now, &utc);
	//local time -> char*
	asctime_s(result, sizeof(result), &now);
	//char* -> std::string
	std::string str(result);

	return str;
}


int main() {

	time_t now = get_unix_time();
	std::cout << now << std::endl;
	std::cout << unix_to_local(now) << std::endl;

	_sleep(10000);
	return 0;
}

```

>1552025846
Fri Mar  8 15:17:26 2019


##参考にした記事

* [VC++で困惑した時刻関連処理まとめ](https://qiita.com/litencatt/items/711d719382edeea9c51e)
* [日付や時刻を扱う](https://toburau.hatenablog.jp/entry/20080425/1209148438)
* [localtiime_sをlocaltimeの代わりに使うときのやりかた](https://qiita.com/softnakikaiya/items/55e8b6b8cc2eca4f5b7c)
GASを使って更新日を自動記入


# やりたいこと
チームでスプレッドシートを使って情報を管理しています。
その時「いつ」最終更新されているかが重要な時がありました。

そこでGASを使って自動で最終更新日時が入力されるようにしてみました。

自動入力は今回紹介する更新日だけでなく、更新した人が「誰」といった情報も自動入力できたりすると思うので今後やってみようと思っています。

# 実装方法

全ての行の更新で反応すると不都合なのでif文で指定しています。
if文を使えばもっと細かく「どのシートの」とか色々な設定もできますね。

```javascript
function onEdit() {
    var ss = SpreadsheetApp.getActiveSpreadsheet();
    var sh = ss.getActiveSheet();
    var range = sh.getActiveRange();
    var row = range.getRow();
    var col = range.getColumn();
 
  if(row > 11){ //何行目以降の変更で反応するか
    var date = new Date();
    sh.getRange(row, 4).setValue(date);
  }
}
```

#
PostgreSQLの待機イベントをまとめてみた

# 待機イベントとは？
* Oracle DB使いの方であればご存知かと思いますが、Oracle DB全体の性能分析を行う際、確認する主要なポイントの一つとして、待機イベントが挙げられると思います。
* 待機イベントを簡単に説明すると、DBの処理において何らかの待ちが発生している状態のことです。代表的な待機イベントとして、物理読み込みやエンキューなどの待機が挙げられます。

# PostgreSQL(10.5)の待機イベントをまとめてみた
### 待機イベントの種類
![image.png](https://qiita-image-store.s3.amazonaws.com/0/367069/173a3310-e5c3-8598-68eb-244b23a6c769.png)

# 現在の待機イベントの状況を確認することができる動的統計情報ビュー
### pg_stat_activity
* 状態や現在の問い合わせ等のプロセスの現在の活動状況に関連した情報を表示します。

### サンプル
```postgres:psql
postgres=# SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event is NOT NULL;
  pid  | wait_event_type |     wait_event
-------+-----------------+---------------------
 13480 | Activity        | AutoVacuumMain
 14280 | Activity        | LogicalLauncherMain
  1268 | Activity        | BgWriterHibernate
 10816 | Activity        | CheckpointerMain
  3860 | Activity        | WalWriterMain
(5 行)
```

# 参考資料
[PostgreSQL 10.5文書 28.2. 統計情報コレクタ](https://www.postgresql.jp/document/10/html/monitoring-stats.html)
AWS CLIでCloudFrontのSSL証明書をIAM->ACMに切り替え

# あらすじ
・ 既存のCloudFrontに適用されているSSL証明書(iam)をACMに切り替えたかった
・ us-east-1での発行までは完了した
・ が、コンソール上で切り替えができず（プルダウン一覧に出てこない）、terraformの管理からも外れていた
・ CLIの出番やで

# 参考記事
検索力が足りずaws cliのドキュメントをうろうろしていたんですが、最終的に以下記事を読んで大枠が解決しました。ありがたい...
https://qiita.com/kooohei/items/c6dcf9dfee6abf693656

# というわけで作業メモです。
対象のdistribution idや、変更前後の設定確認はコンソールとにらめっこしてやってしまったので確認系のコマンドは割愛。

```aws-cli.sh
# 1.作業前confをファイルとして取得
aws cloudfront get-distribution-config --id "{ID}" | jq '.DistributionConfig' > {ID}.conf
# 2.confファイルの編集（後述）
vim {ID}.conf
# 3.変更用のETagを確認
aws cloudfront get-distribution-config --id "{ID}" | jq '.ETag'
# 4.編集後のconfファイル及び[3]で確認したETagを指定の上update
aws cloudfront update-distribution --id "{ID}" --distribution-config file://{ID}.conf --if-match {ETag}
# ~完~
```

`2.` の箇所、今回 `{ID}.conf` として取得したjsonファイルは以下の部分を書き換え

```({ID}.conf)変更前-抜粋.json
"ViewerCertificate": {
    "SSLSupportMethod": "sni-only",
    "MinimumProtocolVersion": "TLSv1.1_2016",
    "IAMCertificateId": "XXXXXXXXXXXXXXXXXXXXX",
    "Certificate": "XXXXXXXXXXXXXXXXXXXXX",
    "CertificateSource": "iam"
},
```

```({ID}.conf)変更後-抜粋.json
"ViewerCertificate": {
    "SSLSupportMethod": "sni-only",
    "MinimumProtocolVersion": "TLSv1.1_2016",
    "ACMCertificateArn": "arn:aws:acm:us-east-1:123456789012:certificate/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "Certificate": "arn:aws:acm:us-east-1:123456789012:certificate/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "CertificateSource": "acm"
},
```
Windows：コマンドプロンプト（Command Prompt）を起動する手順

### 技術サポートの現場では、システムエンジニアにとっては当たり前のことでも、意外とよくWindowsでのコマンドプロンプトの起動方法について質問を受けることがあります。
そこで、スクリーンショット付きで手順をまとめました。

1. windows10左下のタスクバーのフォームに「cmd」と入力
![1.png](https://qiita-image-store.s3.amazonaws.com/0/125746/5317c436-9ee8-58df-736d-6fef73e3b75f.png)
2. 「コマンドプロンプト」が表示されます
![2.png](https://qiita-image-store.s3.amazonaws.com/0/125746/f6512708-6f2d-e8fb-6698-698e29dd80da.png)
3. 表示された「コマンドプロンプト」を*右クリック*し、「管理者として実行」をクリック
![3.png](https://qiita-image-store.s3.amazonaws.com/0/125746/1fa02f87-8c95-74d6-82ae-93ce90ec8dd3.png)
4. 黒いウィンドウが起動されて、そこにcdコマンドで行きたいフォルダ名称を入力　※例： cd c:\mydata 
![4.PNG](https://qiita-image-store.s3.amazonaws.com/0/125746/872b7c6d-03e1-900e-c506-0376438f58d2.png)
5. 目標フォルダへ入りました。
![5.PNG](https://qiita-image-store.s3.amazonaws.com/0/125746/a27af74e-acb9-a5a7-22df-c5f85057afa9.png)
主観的に若手が今やっておきたいプログラミング言語を個人的未来予測をふまえてまとめた

若手プログラマのaimofです。最近体調を崩して職を離れ暇になったのでこれからのために学んでおくべき技術を真剣に考えています。そのメモから得られた情報を共有がてらまとめておきます。

[個人ブログ記事](https://blog.aimof.net/future-programming-summary)のちょっとしたリライトです。

## aimofのスタンス

* 直近数年で見ると日本は悪い方に向かいそうだが、技術力のあるプログラマにとってはそこまで悪いことにはならないだろう。
* 先日の移民政策が日本に与える影響を重く見ており、少子高齢化問題は移民で和らぐと思っている。
* 基本的に先を見据えて動きたい。。
* 日本はサービス部分に弱みがある反面ハードウェアは強いと考えている。

[メモ記事](https://blog.aimof.net/future-programming)に雑多な考えが書いてあります。これはまとめ記事。

## 結論（aimof個人）

仕事としてはもともとやっているGoを軸にRustを学び、低レイヤーに強みを持ちたい。
モバイルアプリやWebフロントは個人単位でやっておきたい。

## 一般論として考えたこと

専門性の乏しめな若手が自分の専門として言語を選ぶ際の興味度、おすすめ度。
こういうおすすめ度はネタ以上の価値はないので、議論の種に過ぎない。
いろいろ思うところはあると思うがあくまで個人の考え。

大した専門をもたない若いプログラマが一つの言語をメインに仕事を探すような状況を想定。

|言語|おすすめ度|強み|弱み|コメント|
|:--|:--|:--|:--|:--|
|Go|+2|現時点で求人が多く需要が高まっている|少し始めるには遅い気もする|私個人がすでにどっぷり浸かっているのでコメントし難い|
|Rust|+2|着々と成長中かつ代用が効きづらい。低レイヤー言語|現時点で求人がほとんどない|習得難易度高めなので狙いめ|
|C|+1|安定|ちゃんと書くのはめちゃくちゃ難しい|CとRustの両方を触ればいい感じになれると思う|
|C++|+1|やはり安定|Cに比べ仕様が難しい|勉学のためにやるならCかな？仕事ならC++|
|Kotlin|+2|Javaより書きやすいAndorid開発言語|プラットフォームの変化に振り回される|Android以外もできるので悪くなさそう|コメントし難い
|Swift|+1|Apple|Apple|Appleはrootバグ以降信用していない|
|Python|+1|汎用性が高く、特に機械学習に強い|AIブームはそのうち去って本物しか残れないと私は思う|あなたが機械学習を専門に行うのでなければおすすめし難い。WebのPythonは嫌いだ|
|Ruby|-2|RoR|国内に猛者が多いため今から始めるのは遅すぎると思う|海外のランキングでは人気が下がりつつあると評されがちだが国内では依然人気|
|PHP|-2|未だに根強い人気を誇り、Rubyに比べれば伸びている|Ruby同様若手がやるのならおすすめしづらい|徐々に進化しているが新しい言語に比べるといまいちな印象|
|Java|?|多分まだしばらくは業界に居座るため食いっぱぐれづらい|Ruby, PHP同様書ける人が多いので需給バランスの見定めが大切|KotlinやScalaなどやるとどうしても知識が必要になるためサブとして使う機会が多いだろう|
|JavaScript|?|真面目にやったらフロントでしっかり働ける|10年以上前の情報を平気でおすすめしてくるスクールが多いので見定めが大事|昔のJSと今のJSは並べても同じ言語とは思えないくら違うので、JSで何をするかが大切|
|TypeScirpt|+2|JSとのシェア争いに勝てそうなのでいけてそう|JSとのシェア争いに負けたときくらいしか心配することないんじゃないかな？|フロントなのでコメントが雑ですみません|
|関数系言語|+1|新しい考え方に触れるのはとても大切|シェアは増えていない（使う人が減っているわけでもない）|主流にはならなさそうだが学ぶ価値は高い|

### JavaScriptについての補足

JavaScirptを言語単位で語るのはちょっと無理でした。
jQueryから進歩してない人から、ReactとかVueとかよくわからない新しいフレームワークとかいろいろ学んでいる人まで様々なので一概には言えない。
ただ、Webサイト作りたければ真面目にJSかTypeScriptやるとよい。

## まとめ

若い人は21世紀の技術やるといいと思うよ