OmniAICreator/Qiita-1.07M huggingface dataset:
【JavaEE】シングルトンでEntityManagerをDIする方法

<font color="red">※ EntityManagerのDIはできますが、データの更新が動きません。原因について調査中。取得と登録は問題ありません。</font>

# はじめに
JavaEEをやっていると、EntityManagerを扱うEJB（いわゆるビジネスロジッククラス）は通常ステートレス管理にします。理由としては、EntityManagerがスレッドセーフではないため、トランザクション単位でDIする必要があるためです。Springでいうところの```@Service```、```@Repository```は基本的にシングルトン管理になります。

じゃあ、JavaEEでもシングルトンにしましょう。

# なぜシングルトンか
単刀直入に言うと、メモリ節約のためです。ステートレス管理の場合、EJBプールというメモリ領域にEJBのインスタンスが保持されます。必要なときにプールからインスタンスを取得しDIされます。domain.xmlなどのサーバ設定ファイルにEJBのプールサイズなどを設定できますが、これより多いリクエストが発生した際に、新たにインスタンスが作られることになります。インスタンスが生成されるということはそれだけメモリを使うことになります。一方、シングルトンの場合は、アプリケーションで１つしかインスタンスを持ちませんので、メモリの使用を抑えることができます。

# NGパターン

```java:EntityManager利用クラス
@Singleton 
public class UserService {

    @PersistenceContext 
    private EntityManager em;

    // 〜以下省略〜
}
```
スレッドセーフではないEntityManagerをアプリケーションで１つしか持たないようになっています。

# OKパターン

EntityManagerを生成する ```EntityManagerFactory``` というクラスが存在します。
このクラスはスレッドセーフであるため、シングルトン管理で問題ないのでこれを利用します。

```java:EntityManager生成クラス
@ApplicationScoped
public class EntityManagerFactoryService {
    private static EntityManagerFactory factory;

    public EntityManagerFactory getEntityManagerFactory() {
        if (factory == null) {
            factory = Persistence.createEntityManagerFactory("testUnit");
        }
        return factory;
    }

    @Produces
    @RequestScoped
    public EntityManager getEntityManager() {
        return getEntityManagerFactory().createEntityManager();
    }

    @PreDestroy
    public void destroy() {
        if (factory.isOpen()) {
            factory.close(); // クローズしないと再デプロイ時にエンティティが見つからなくなる。
        }
    }
}
```

```java:EntityManager利用クラス
@Singleton 
public class UserService {
    @Inject
    private EntityManager em;
}
```
DBごとのSQLのクォーテーションを整理したった

データベースのクォーテーション、使い方まちまち。
まとめた。

|                  | 'シングル'  |"ダブル"    |`` `バック` ``| [大カッコ] | 備考 |
|:-----------------|:--------- |:--------- |:-----------|:----|:----|
| MySQL           | [文字列定数](https://dev.mysql.com/doc/refman/5.6/ja/string-literals.html)  | [文字列定数](https://dev.mysql.com/doc/refman/5.6/ja/string-literals.html) |[引用識別子](https://dev.mysql.com/doc/refman/5.6/ja/identifiers.html) | （なし） | 引用識別子はUNIX系では大文字小文字を区別[^refs] |
| MySQL<br>（[ANSI_QUOTES モード](https://dev.mysql.com/doc/refman/5.6/ja/sql-mode.html#sql-mode-full)） | 文字列定数 | 引用識別子 | 引用識別子 | （なし） |  |
| PostgreSQL      | [文字列定数](https://www.postgresql.jp/document/11/html/sql-syntax-lexical.html#SQL-SYNTAX-STRINGS)  |[引用識別子](https://www.postgresql.jp/document/11/html/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS) | （なし）          | （なし） | 引用識別子では大文字小文字を区別 |
| Oracle          |[文字列定数](https://dev.mysql.com/doc/refman/5.6/ja/sql-mode.html#sql-mode-full) | [引用識別子](https://docs.oracle.com/cd/E96517_01/sqlrf/Database-Object-Names-and-Qualifiers.html#GUID-75337742-67FD-4EC0-985F-741C93D918DA) | （なし） | （なし） | 引用識別子では大文字小文字を区別 |
| [SQLite](https://www.sqlite.org/lang_keywords.html) |文字列定数 |引用識別子|引用識別子 |引用識別子 | |
| Microsoft SQL Server<br>(Transact-SQL) | [文字列定数](https://docs.microsoft.com/ja-jp/sql/t-sql/data-types/constants-transact-sql?view=sql-server-ver15) |[引用識別子](https://docs.microsoft.com/ja-jp/sql/relational-databases/databases/database-identifiers?view=sql-server-ver15#classes-of-identifiers) |（なし） |[引用識別子](https://docs.microsoft.com/ja-jp/sql/relational-databases/databases/database-identifiers?view=sql-server-ver15#classes-of-identifiers) |QUOTED_IDENTIFIER が ON (既定値) の場合 |

こうみると、MySQLが異端児ってのがよくわかる。

引用識別子は識別子の１つ。識別子はテーブル名やカラム名など、データベース中のオブジェクトを表す文字列だが、決まった引用符（クォーテーションマーク）で囲むことで、空白や予約語などの特別な文字列を用いることができる（エスケープできる）のが引用識別子である。
ただ、そんな特別な文字列を使ったテーブル名やカラム名は、混乱の元なので、使わないほうがよいだろうね。

また表中にも書いたように引用識別子は大文字小文字を（大抵の場合は）区別する。フレームワークのORマッパでは、テーブルやカラムなどを自動的に引用識別子で定義する場合がある。都合悪くなることはまずないのでこれに従っておこう。

- 文字列は 'シングルクォーテーション' で囲む。
- 引用識別子はフレームワークに従い、命名規則のルールを統一。

が良さげ。

[^refs]: 参考： http://hito4-t.hatenablog.com/entry/2015/08/25/184107
【Ruby】ヒアドキュメントの初歩的なつかいかた

簡単に備忘録。

# 1. ヒアドキュメントとは
ヒアドキュメントは**「文字列をシェルスクリプトやプログラミングに埋め込むためのもの」**
`""`無しや改行&空白なども書いた通りに適用できる（長い文などに有効）。

#2. 使い方

通常

```ruby

puts "りんご"
puts "バナナ"
puts "メロン"
puts "いちご"

#=> 
りんご
バナナ
メロン
いちご
```

ヒアドキュメントの場合

```ruby

puts <<~EOS
りんご
バナナ
メロン
いちご
EOS

#=> 
りんご
バナナ
メロン
いちご
```

#参考
[【3分でわかる】Rubyでヒアドキュメント](https://www.sejuku.net/blog/14283)
[ヒアドキュメントとは・基本の使い方(ruby)](https://qiita.com/shukan0728/items/b830e97f563e63e46e91)
sketchのシンボル機能

# シンボル機能とは

sketchを利用する際に、より効率良くデザインを進めることが可能になる機能だ。


シンボル化により複数回利用するパーツを一括管理することができる。
これによりパーツの修正を行う場合、複数回同じ箇所の修正を行わなくて済む。
また、個別にデザインを変更することも可能だ。





# シンボルの作り方
シンボル化したいレイヤーorグループorアートボードを選択したあとに”右クリック → Create Symbol”で作れる
または左上にある<img width="101" alt="スクリーンショット 2020-01-23 16.50.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572110/be456313-f343-410c-8da7-56d968ef9719.png">をクリックする

確認ダイアログが表示されるので「Send Symbol to “Symbols ” Page」にチェックを入れる
<img width="479" alt="スクリーンショット 2020-01-23 17.16.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572110/a4e22415-56e4-1028-83b9-ef2068b4c451.png">
ページに新しくSymbolsが作成される

ここでシンボルの管理ができ、例えば四角のシンボルの角を丸くすると別のページにもその変更が適応される。ただ、サイズの変更は適応されない。
また、別のページで利用したシンボルをダブルクリックすることによりこのページに飛ぶことができる




# シンボルの機能

別のページで”[Insert]→[Symbolos]→[Document]”をクリックすることで、シンボルを選択・配置できる


Symbolsで変更を行えば全体に適応されるが、個別でも変更可能である。

個別でテキストを変更したい場合
<img width="451" alt="スクリーンショット 2020-01-23 17.05.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572110/a495eee4-995a-360c-ea1e-b734895b357e.png">
　　　　　　　　　　　　　　⬇️

<img width="461" alt="スクリーンショット 2020-01-23 17.09.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572110/ebfd64f8-9e3f-ef14-7f3b-fa122064b21e.png">

このようにテキストをいちいち配置し直さなくても修正が可能になる。


###シンボルからの切り離し
個別のカラーの変更など全体に影響を及ぼしたくない場合、
オブジェクトを選択して”右クリック → Detach from symbol”でシンボル化からの解除ができる

また、シンボル解除から”Set to Original Size”を選択した場合、個別でサイズ変更したものを大元のシンボルと同じサイズに戻すことができる。
Windowsでもchoosenimがしたい

## 追記

「Windows向けのインストールページにchoosenimを記載しようよ」
ってissueやPRが既にあったのですが、不注意で新規issueをあげてセルフクローズしました。
そしたら、リマインドになったのか速攻でPRがmasterにマージされました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223008/2c915088-e693-74a9-f1c7-cf80eb033ef5.png)
https://github.com/nim-lang/website/pull/148

めでたし、めでたし。
そして下記は昔話になってしまった。
読む必要はないですが、周知のためにしばらく残しておきます。

----
今の僕の気持ち

「Nim公式サイトよりchoosenim公式のインストール方法が楽じゃん」

## 発端
これまでWindowsではNimの環境作ったことがなかったのですが、とある事情でWindows上にNimの開発環境を作ることに。
よーし、Nimの公式サイトでWindowsへのインストールを調べてみるぞ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223008/b38ec7cd-b9aa-5a3e-37d0-a47af9dc93c2.png)

**ぼく「Zip展開して、finish.exeとかいうやつ叩いて、ディレクトリにパス通せばいいんだな」**

~その後~

**ぼく「インストールしたけどchoosenimがどこにもねぇ…」**[^1]

[^1]: choosenimはnimコンパイラのバージョンスイッチツールです。*nixは標準でついてくる。

## choosenim公式を見てみる

リポジトリはここ→https://github.com/dom96/choosenim
installationのWindowsの項目を読んで見る。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223008/416f6717-a0c0-2941-30f7-6403df085a1c.png)

**ぼく「WindowsはchoosenimのReleaseページからzip落として、runme.batを叩けばいいのか」**

というわけで無事にchoosenimでNimの関連ツール一式(nimbleとか)がインストールされて、*nixと同様に管理できるぞ。やったね。
Nim公式サイトのインストール方法だとバージョンアップが大変です。
choosenimが使えるようになったで今後は`choosenim stable`とかすればいい。とても楽。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223008/8f5594ff-5466-4b75-54af-d95ae57fda74.png)


ちなみにNim公式のダウンロードページにも書いてあるMingWもインストールされます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223008/59ee6393-0b28-40fc-0786-ef4123d77707.png)

dllも同梱されてるようなのでopensslも使えるっぽい。-d:sslつけてもビルド時に怒られなかった。

めでたし、めでたし。

## 余談：そういえばChocolateyなんてものもあったな。

https://chocolatey.org/packages/nim#individual
chocoはイマイチよくわからないのですが、インストール先はどうやらchoco管理の場所にNimが展開されるようです。
ただchoosenimは$HOME/.choosenimにツールをインストールします。なのでchoco管理のnimとchoosenim管理のnimが混在してややこしくなります。
choosenimでインストールしたあと、chocoのnimをアンインストールすれば混在しなくなりますが、それくらいならchoosenimで初めからインストールしたほうがいいと思う。
Robotics and Automation Letters（RA-L）への同時投稿に関する情報共有

# 要約

- ロボティクスの分野で最近，カンファレンス（ICRA，IROSなど）への論文投稿と同時に，レター（Robotics and Automation Letters: RA-L）に投稿できるようになったので，その情報共有
- RA-Lにリジェクトされても，カンファレンスにアクセプトされることもある
- RA-Lの採録の基準は，カンファレンスの採録基準より高そう

なお，筆者は3回RA-Lに同時投稿し，戦績は以下の通りです．
1. 1発リジェクト，カンファレンス（ICRA）もリジェクト
2. リバイス&リサブミット→リジェクト，カンファレンス（ICRA）はアクセプト
3. リバイス&リサブミット→アクセプト，カンファレンス（IROS）もアクセプト



# RA-Lとカンファレンスの査読

私が投稿した経験だと，**RA-Lの1回目の査読とカンファレンス側の査読は同じ**です．なので，RA-Lでの査読の評価がそのままカンファレンスの方の評価にも繋がるのだと思います．

なお，RA-Lとカンファレンスの採録基準は，RA-Lの方が厳し目だと思います．「RA-Lにアクセプトされたが，カンファレンスにはリジェクトされた例もある」と聞いたことはありますが，私は査読のときに「RA-Lのアクセプトには認められない」という言葉をもらいながらも，カンファレンスにはアクセプトされたことがあります．



# RA-Lの査読プロセス

基本的には2ヶ月で1度めの査読が返って来て，リジェクトか，リバイス&リサブミットになるのだと思います．リバイス&リサブミットの場合は，約30日で対応することになります．その後1ヶ月程度で最終通知が来ます．なので，**トータルで4ヶ月程度で最終的に採録されるかどうかの結果がわかります**．



# RA-Lが1発リジェクト，カンファレンスもリジェクトのとき（カンファレンスはICRA）

RA-Lで1発リジェクトになると，おおよそICRAとIROSもリジェクトになる気がします．少なくともここでリバイス&リサブミットぐらいはもらっておかないと，カンファレンスへの望みも薄くなるような印象があります．



# RA-Lがリバイス&リサブミット→リジェクト，カンファレンスはアクセプトのとき（カンファレンスはICRA）

RA-Lの方は最初にリバイス&リサブミットという結果でしたが，最終的にリジェクトになりました．そして，RA-Lの1回目の査読結果と同じものがカンファレンスの査読結果として返ってきて，こちらはアクセプトになりました．やはりRA-Lはジャーナルカウントされるので，査読結果が厳し目になるなという印象です．



# RA-Lがリバイス&リサブミット→アクセプト，カンファレンスもアクセプトのとき（カンファレンスはIROS）

RA-Lのプロセスでリバイス&リサブミットを行い，アクセプトの連絡をいただきました．その後，カンファレンス側からもRA-Lの1回目の査読結果が来て，アクセプトになりました．こちらも，やはりRA-Lはジャーナルカウントされるので，こちらが通るならカンファレンスも通るのかなという印象です．


# まとめ

ロボティクスの分野で最近できるようになった，ICRAやIROSなどと同時投稿できるRA-Lに関して，3回投稿してみてどんな結果になったかを書いてみました．やはり，**RA-Lはジャーナルカウントされるのでカンファレンスより査読が厳し目**という印象です．

この記事が，RA-Lへ投稿しようと思っている人に対して少しでも参考になれば幸いです．
MariaDB(MySQL)での767byte問題を解決する

# 概要
Laravelの[決済周りのテーブル](https://github.com/laravel/cashier/tree/10.0/database/migrations)を作成しようとしたときに、以下のようなエラーで失敗しました。

```sql
SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long;
  max key length is 767 bytes (SQL: alter table `users` add index `users_stripe_id_ind
  ex`(`stripe_id`))
```

MySQLでは767バイト以上のカラムに対してはインデックスを貼れないようです。

# 対処法

## 1. インデックスの制限をあげる
`my.conf`を書き換えることで、制限をあげることができます。

- `my.conf`の配置場所を探す

```bash
$ mysql --help | grep my.cnf
```

- 設定を追記

```my.conf
[mysqld]
innodb_large_prefix
innodb_file_per_table=1
innodb_file_format=Barracuda
```

- 設定されているか確認

```sql
> SHOW GLOBAL VARIABLES LIKE 'innodb_file%';
+--------------------------+-----------+
| Variable_name            | Value     |
+--------------------------+-----------+
| innodb_file_format       | Barracuda |
| innodb_file_format_check | ON        |
| innodb_file_format_max   | Antelope  |
| innodb_file_per_table    | ON        |
+--------------------------+-----------+
4 rows in set (0.01 sec)

> SHOW GLOBAL VARIABLES LIKE 'innodb_large%';
+---------------------+-------+
| Variable_name       | Value |
+---------------------+-------+
| innodb_large_prefix | ON    |
+---------------------+-------+
1 row in set (0.00 sec)
```
## 2. MariaDBのバージョンをあげる
MariaDBのバージョンが10.1以下の場合、`my.conf`の設定だけでは不十分で、10.2以上にあげる必要があります。

バージョンアップに関しては[こちらの記事](https://qiita.com/kozamurai/items/b6db028b7df6afa1f82a)でまとめたので、必要であれば参考にしていただけると幸いです。

# 参考
https://github.com/gogs/gogs/issues/4894

https://yassu.jp/pukiwiki/index.php?MySQL%20767byte%CC%E4%C2%EA
読んだ本の紹介04「仕事と人生を激変させるなら99.9％アウトプットを先にしなさい」

[仕事と人生を激変させるなら99.9％アウトプットを先にしなさい](https://www.amazon.co.jp/dp/B07MZK8CWV/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)
おすすめ度★★★☆☆

## なぜこの本を読んだのか
アウトプットが苦手な人なので知見を得たかった
いろいろな人のアウトプット本を読んでいき実践していきたいため

## まとめ

### 人を変えるのはアウトプットだけ

「読む」「聞く」がインプット
「書く」「行動する」がアウトプット

### iOIF
とは
「i」小さいインプット
「O」アウトプット
「I」インプット
「F」フィードバック

よくPDCAサイクルで計画をしっかりしてから実行に移そうっていうことが書かれているが「iOIF」は逆で　
`先にアウトプットを行う`
`事前知識で必要な程度のみを最初にインプットする`


### 得た知識を自分のものにする方法
- 1日のTODOリストを毎日書く
書かないとタスクが終わった後に何をするか考えてしまって集中が途切れる
└仕事でGoogleカレンダーを取り入れて実践中！！

- 2週間で3回復習すれば忘れない
一つの本で3つの気づきがあれば十分

- 書く
やることを頭に入れるだけだと忘れる
「気づき」を3つ書く
「TODO」を3つ書く
アナログでざっくりまとめて
デジタルで細かくまとめる

## 感想
タイトルにある通り「99.9％アウトプット」はやりすぎではないかと思っていたが読んでみると納得した
`相手に説明（アウトプット）するにはある程度の知識が事前に必要ということ`

PDCAサイクルとはまた別の手法の一つで「iOIF」を紹介しており、「iOIF」もとにアウトプットに関して説明
PDCAであることをしようとしてもそれに対しての知識がないとPの時点で正しい計画ができず破綻することが多い（実体験）
当たり前だがやることに対してある程度の知識を持っているうえで行う必要がある

アウトプットが必要なので人に話すか、こういった記事に残すがいい！！
Windows10にDocker for WindowsでKubernetesを使ってみる

## とりあえずKubernetes触ってみよう
- というわけでKubernetesの雰囲気を味わうためにWindows10にDocker for Windowsをインストールしていきます

## WindowsPCの確認
- コマンドプロンプトから`winver`で確認。Windows10のバージョンは以下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415280/281b71d8-dfe9-0f22-4a31-7217b78a040b.png)

- PCのスペック
    - CPU
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415280/a5cb8885-2116-73e7-b7bd-c148cb06a56d.png)

    - メモリ
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415280/4e53c2d5-704a-2f46-7a27-339807556cee.png)


## Docker for Windowsのインストール
- コマンドプロンプトから`control.exe /name Microsoft.ProgramsAndFeatures`で「プログラムと機能」を開き、そこから「Windowsの機能の有効化または無効化」をクリック
- 「Hyper-V」を有効化

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415280/c0caf8e7-f5d6-3eb2-2930-7d29c6d795e1.png)

- インストールできたらPCを再起動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415280/af03d671-075d-910e-97c8-4c2603d6afda.png)

- Docker for windowsをインストール
    - 以下のURLからDocker for windowsをダウンロード
        - 
 https://download.docker.com/win/stable/Docker%20for%20Windows%20Installer.exe

- exeの実行

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415280/d3fd0162-b21f-1d07-d97b-67e6b3e1f34a.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415280/807f4234-997e-4368-9560-c3f0c0652791.png)

- インストール完了したのでDocker Desktopを実行

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415280/8b596df4-85d6-1c33-e8fd-18f51fe13bb7.png)

- エラー出た、、、けど、2回再起動したら正常に起動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415280/c19f7fa5-33a4-d620-30d2-9aa0d2463fbb.png)

## Kubernetesを使う
- settingからKubernetesを使う設定をONにする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415280/aef95962-033d-090d-f26f-5c2c1aece84f.png)

- `Enable Kubernetes`にレ点を入れてApply
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415280/b4fcb977-ecef-9a75-03c5-28932a1e19c3.png)

- なにか動き出す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415280/7bd585b1-e492-64f9-9545-6360a3ed4ffb.png)

- 正常に完了した
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415280/eaf6d163-9c36-5a6d-6c28-db0c2a1f96f8.png)

- PowerShellで確認
    - `kubectl`コマンドが正常に打てたらOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415280/070c89bb-7f3e-600d-a9b9-6a38630a916f.png)

## 『Kubernetes完全ガイド』のサンプルを実行する
- 以下からサンプルをダウンロード
    - [GitHub - MasayaAoyama/kubernetes-perfect-guide: 『Kubernetes完全ガイド』の付録マニフェストのリポジトリ](https://github.com/MasayaAoyama/kubernetes-perfect-guide)
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415280/eedaea0e-cc14-fe57-0916-4fdd8889c131.png)

- ひとまず実行
    - chapter04の`sample-pod.yaml`を実行
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415280/d4fa96c2-71e8-1e73-ae2c-2c5bdaad2ffa.png)

## まとめ
- あとはこの調子でサンプルを実行してKubernetesの動きを見ていきましょう。
ホスト名を変更する hostname change

# はじめに
tmuxのstatuslineのホスト名を変更しようとしたときに少し嵌ったのでメモ。

# やり方

## 現在のhostnameを確認する

```terminal
hostnamectl
```

## hostnameを変更する

```
hostnamectl set-hostname 'new_hostname'
```
【Nuxt.js】TypeScript基礎編：Vue.extendでシンプルなコードを書こう

# 前置き
今回はNuxt.jsでTypeScript🎈🧸
大まかに3つに分けて書いています✍️
・TSのメリット
・TSの書き方3つ
・Vue.extendコード例

# TSのメリット
すごく簡単に言うと、
安全な開発がしやすくなります🦺👷‍♀️
ここが参考になります！
https://qiita.com/SoraKumo/items/43fba2ad2d10336a665

# TSの書き方
TSを入れた場合の書き方は3パターン
・Vue.extend
・vue-class-component
・vue-property-decorator

シンプルで書きやすいのがVue.extendです🍒

# Vue.extendのメリット
簡単⭕️
1番とっつきやすい書き方🌟

何故なら！
通常と書き方がほとんど変わらないから！
Vue、Nuxtらしさを保ったままTSが使えます。

**TSなしの場合と変わるのは3点のみ！！！**
・script langをtsに変更
・Vueモジュールをimport/extend
・コンポーネント、ページ自体にクラス名を付与

**他は通常と変わらない
これがVue.extendの良さ😄**

# 他の書き方は？
@Componentとかになるあれ。
書き方が結構変わりますよね〜！
・vue-class-component
・vue-property-decorator

nuxtの場合はこちら
・nuxt-class-component
https://github.com/nuxt-community/nuxt-class-component
・nuxt-property-decorator
https://github.com/nuxt-community/nuxt-property-decorator

詳しい書き方はこちらが参考になります！
https://qiita.com/potato4d/items/c9c0c8e674f20c85948a

# Vue.extend
【基礎構文】
通常と比較しても
シンプルで非常に分かりやすいですね！🍀

公式はこちら
https://typescript.nuxtjs.org/ja/
https://jp.vuejs.org/v2/guide/typescript.html#基本的な使い方

```index.vue
<script lang="ts">
import Vue from 'vue'

export default Vue.extend({
 // コンポーネント・ページ自体にクラスを付与
 name: 'Component',
 components: {
 },
 props: {
 },
 data() {
  return {
  }
 },
 computed: {
 },
 mounted () {
 },
 methods: {
 },
 created () {
   console.log('CLICK!!!')// eslint-disable-line
 },
})
</script>
```

【通常】

```index.vue
<script>
export default {
 components: {
 },
 props: {
 },
 data() {
  return {
  }
 },
 computed: {
 },
 mounted () {
 },
 methods: {
 },
 created () {
   console.log('CLICK!!!')// eslint-disable-line
 },
}
</script>
```

# data
Stringの場合は
" "(double quote)ではなく
' ' (single quote)のみ⭕️

```index.vue
<script lang="ts">
import Vue from 'vue'

export default Vue.extend({
 name: 'Component',
 data () {
   return {
     userName: '',
   }
 },
})
</script>
```

# props
TSなしの場合と変わりません。
・type
・required
・validator
全てそのまま書けます✍️

```index.vue
<script lang="ts">
import Vue from 'vue'

export default Vue.extend({
 name: 'Component',
 props: {
   status: {
     type: String,
     required: false,
     validator (value) {
       return [
         'default',
       ].includes(value)
     },
   },
 },
})
</script>
```

# methods
こちらも同様
$emitなども通常通り記載可能です。

```index.vue
<script lang="ts">
import Vue from 'vue'

export default Vue.extend({
 name: 'Component',
 methods: {
   alert () {
     this.$emit('componentAlert')
   },
 },
})
</script>
```

# console.log()
methodsやライフサイクルで
console.log()を使用する場合ESlintにひっかかります。
その場合は// eslint-disable-lineを追記すれば⭕️
https://eslint.org/docs/rules/no-console

```index.vue
<script lang="ts">
import Vue from 'vue'

export default Vue.extend({
 name: 'Component',
 created () {
   console.log('created!!!')// eslint-disable-line
 },
})
</script>
```
NunjucksでのエラーコードAssertionError [ERR_ASSERTION]: Task function must be specifiedの対処法

個人的な備忘録。

gulpのversionが4の状態で、

```
$npx gulp nunjucks
```

上記コマンドを実行すると、
#####`AssertionError [ERR_ASSERTION]: Task function must be specified`

エラーになる。
version4になった事で仕様が変わった為、
watchの引数の書き方を変える必要があるそうだ。

##gulp.watchの引数の変更


- ver3のコード

```
// task:watch
gulp.task('watch', function () {
  gulp.watch(paths.src.template + '**/*.njk', ['nunjucks']);
  gulp.watch(paths.dest.root + '**/*.html', ['reload']);
});

// task:default
gulp.task('default', ['brsync', 'watch']);
```

- ver4のコード

```
// task:watch
gulp.task('watch', function () {
  gulp.watch(paths.src.template + '**/*.njk', gulp.series('nunjucks'));
  gulp.watch(paths.dest.root + '**/*.html', gulp.series('reload'));
});

// task:default
gulp.task('default', gulp.series(gulp.parallel('brsync', 'watch')));
```

- 第二引数に`gulp.series()`を追加し、その中に要素を入れる。

- 引数が複数ある箇所には`gulp.series()`の中に`gulp.parallel()`を追加し、その中に要素を入れる。

```
npx gulp nunjucks
```

その後上記コマンドを実行する。
AmazonLinuxでPHP7.1から7.2にアップデート

# 概要

AmazonLinuxでPHP7.1から7.2にあげたときのメモです。
試行錯誤しながらやったので、これ通りに動かないことがあると思います。

- yumからインストール

```bash
$ sudo yum -y install php72 php72-mbstring php72-pdo php72-php-fpm.x86_64
```

__実行結果__

```
: (中略)
Error
Requires: scl-utils
```

- scl-utilsが必要らしいので、インストール
- yumでは用意されていないので、rpmから

```bash
$ sudo rpm -Uvh ftp://ftp.scientificlinux.org/linux/scientific/6.9/x86_64/updates/fastbugs/scl-utils-20120927-29.el6_9.x86_64.rpm
```

- 再度php72をインストール

```bash
$ sudo yum -y install php72 php72-mbstring php72-pdo php72-php-fpm.x86_64
```

- 新しいバージョンに切替

```bash
$ sudo unlink /usr/bin/php
$ sudo ln -s /usr/bin/php72 /usr/bin/php
$ sudo /etc/init.d/php-fpm stop && sudo /etc/init.d/php72-php-fpm start
```

- (Option) composerで必要なpackageを追加でインストール

```bash
$ sudo yum install php72-php-mbstring.x86_64 php72-php-pdo.x86_64 php72-php-xml.x86_64 php72-php-mysqlnd
```

## 困ったときに実行すると良いコマンド

- インストールできるpackageを確認

```bash
$ yum list | grep php
```

- インストール済みpackage確認

```bash
$ yum list installed | grep php
```

- php-fpmリスタート

```bash
$ sudo service php72-php-fpm restart
```

- nginxリスタート

```bash
$ sudo service nginx restart
```

- php.iniの場所確認

```bash
$ php -r "echo phpinfo();" | grep "php.ini"
```

# あとがき

Dockerにしたい、、

# 参考
https://qiita.com/kidatti/items/2d6a4a24f89dc71eb66e

https://skworkspace.net/archives/457

https://www.pgen.info/archives/506

https://qiita.com/ritukiii/items/624eb475b85e28613a70
[java] HttpURLConnection　POST

##使い方
以下の通りである。

~~~java
        try {
            //コネクション
            URL url = new URL("URL");
            httpURLConnection_ = (HttpURLConnection) url.openConnection();
            httpURLConnection_.setDoOutput(true);  //POST可能にする
            httpURLConnection_.connect();

            //送信したいデータ
            String param = "param1=1";

            //リクエストボディに送信したいデータを書き込む
            OutputStream os = httpURLConnection_.getOutputStream();
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
            writer.write(param);
            writer.flush();
            writer.close();

            //クローズ処理
            os.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
~~~

サーバ側で値を取得するときは以下のようにする。（サーバはHttpServletを継承したjavaファイル）

~~~java
public class Server extends HttpServlet{
    public void doPost(HttpServletRequest request, 
                       HttpServletResponse response)
                       throws IOException, ServletException{
        request.getParameter("param1");
    }
}
~~~

##感想
見かけは難しく見えたが、予想より簡単に実装できた。結構使うらしいので覚えておきたい。

##参考URL
http://konkea.hatenablog.com/entry/2016/10/20/181856
Laravel で カラムの型を変更したらエラーが出たので対処法

#やりたいこと

テーブルのカラムの型を
`string(varchar)`からintgerにしたい

公式に従い`doctrine/dbal`を入れる
変えるテーブルを指定し、対象カラムを変更し`change()`

```php
 public function up()
 {
     Schema::table('users', function (Blueprint $table) {
         $table->unsignedInteger('hoge')->length(7)->nullable(true)->default(null)->change();
     });
 }

```

しかしmigrateすると下記エラーが

`SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHARACTER SET utf8mb4 DEFAULT NULL
COLLATE ``utf8mb4_unicode_ci`

#対処法
`doctrine/dbal`の最新である`2.10`で追加されたバグが原因らしい

`v.2.9.3`にすると治りました


```
composer require doctrine/dbal:2.9.3

php artisan migrate

```

#追記
githubの[issue](https://github.com/doctrine/dbal/issues/3714)を見ていると回避策として`->charset(null)`を指定すると良いと有りました。

試してはいませんが下記のようにすると2.10.0でも動作すると有りました。
詳しくはissueを参考にしお試しください


```php
 public function up()
 {
     Schema::table('users', function (Blueprint $table) {
         $table->unsignedInteger('hoge')->length(7)->nullable(true)->default(null)->charset(null)->change();
     });
 }

```


#参考
https://stackoverflow.com/questions/58976719/how-to-convert-string-column-type-to-integer-using-laravel-migration
WebAuthnのテストツールでローカルのWebAuthn4Jを叩いてみた

昨年に「[5分で理解するWebAuthn@2019](https://qiita.com/otmb/items/7960519c3bbd820d1d76)」を書きました。
今回はテストツールの実施について書きます。

# テストツールの利用


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35973/1861d170-73cb-69c3-dbce-bf7d2c464917.png)

Fido Allianceの[Test Tool Access Request](https://fidoalliance.org/test-tool-access-request/)フォームに記載して登録依頼を出します。
社名まで記載し無事？3度目のリクエストでダウンロードURL/ID/PWの書かれた返事をいただきました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35973/0a994f7e-9c27-c0ac-c0a0-21e070f5f658.png)

ツールはWin(exe/msi)/Mac(dmg)でパッケージしてあり、解凍するとElectronのアプリケーションが起動します。
WebAuthnのテスト実行手順は、
FIDO2 Testを選択 -> Server Testにチェック -> URLを指定 -> RUNでテストを開始します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35973/332f7627-e2f3-0005-af79-07ffae117b8e.png)

テストツールの実施内容は、リクエストに対しレスポンスのJsonのDOM要素が含まれているか？から始まり、認証時の各証明書の署名のチェック、認証器の情報をまとめたMetadata(Fido Alliance提供)といったWebAuthnの仕様に準拠しているかをテストしていきます。


## WebAuthn4J

WebAuthn4Jはコアの実装と、リファレンスの実装があります。
リファレンス実装にはテストツール用の動作モード(fido-test)があるのでそちらをコールします。
今回はWebAuthnはSSLまたはlocalhostで動作しますので、WSL(Windows Subsystem for Linux)に構築したUbuntuで実行しました。
WSLだと画面が使えないこともありHeadless Chromeでエラーになりますが気にせずビルドします。

* コア実装
  * https://github.com/webauthn4j/webauthn4j
* リファレンス実装
  * https://github.com/sharplab/spring-security-webauthn

```
通常起動
./gradlew samples:javaconfig:webauthn:spa:bootRun
fido-test起動
./gradlew samples:javaconfig:webauthn:fido-server-conformance-test:bootRun
テスト用のURL
http://localhost:8080/webauthn/
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35973/660d2ce7-b737-5327-ff81-dd2f3321ba4b.png)

暫く待ち全てのテストが無事完了しました。
レポートは以上です。
[JavaScript][Node.js]メモ：アロー関数の文法

アロー関数（ES2015）の書き方。

```javascript
f = () => console.log('Hello!')
f()  // Hello!
```

```javascript:評価した値を返す
// 式（Expressions）の評価結果が戻り値になる
sum = (a, b) => a + b
r = sum(1, 2)
console.log(r) // 3
```

```javascript:returnで値を返す
// {}で文（Statements）を作り、returnで値を返す
sum = (a, b) => { 
  return a + b 
}
r = sum(1, 2)
console.log(r) // 3
```

```javascript:引数のカッコを省略
// 引数が一つの時のみカッコを省略可能（0個もしくは2つ以上のときは省略不可）
say = word => console.log(word + '!')
say('Yeah')  // Yeah!
```

```javascript:即時関数
(() => console.log('Hello!'))() 
```

```javascript:引数としてのアロー関数
arr = [1,2,3,4,5]

// かっこよくない
console.log(arr.map(function(e) { return e + 1 }))  // [ 2, 3, 4, 5, 6 ]

// かっこいい
console.log(arr.map(e => e + 1))  // [ 2, 3, 4, 5, 6 ]
```

## リンク（mozilla）
* [アロー関数](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Functions/Arrow_functions)
iTerm2 で alt+n を矢印キーに置き換えたい

# 問題
iterm でたまに間違って alt+n や alt+p を押してしまって、よくわからない制御コードが入ってしまうことがある。下記のように設定したい。

| キー入力 | 出力 |
|--------|-----|
| alt + p | ↑ |
| alt + n | ↓ | 

しかし通常のキーアサインでは矢印を入力することができない。

# 解決策

メニューのPreferences > Profiles > Keys で + ボタンを押して下記のように設定すれば期待した結果になる。

<img width="1022" alt="iterm-setting.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/10508/f2a362fd-5c1c-247f-492d-d77db79966f7.png">

# 解説

この記事 https://tanishiking24.hatenablog.com/entry/readascii が参考になった。

```sh
read key; echo "$key" | hexdump
```

を実行して矢印キーを入力する。たとえば上矢印を入力して enter を押すと下記のように表示される。

```
0000000 1b 5b 41 0a
```

これを見ると iterm で矢印キーが与えているキーコードがわかるらしい。この場合は `1b 5b 41` が上矢印が与える拡張キーコードとなる。なので iterm に `1b 5b 41` という hex code を与えれば上矢印を与えたのと同じ結果になる、という。同じようにして下矢印のコードを送ると `1b 5b 42` というコードが得られる。
なんやかんやパスワードをリセットしたり、修復したりしてみる(reset a password, recovery your PC and so on)

MacOSX パスワードリセット
-------
com+Rを押しながら起動し、
terminalに入り、
resetpassword

※T2チップが搭載されていると出来ないよ :p


Windows10 パスワードリセット
-------
Shiftを押しながら再起動し、リカバリーモードを起動
トラブルシューティング＞詳細オプション＞コマンドプロンプトを起動するか、
Windows10インストールUSBメモリから起動し、Shift+F10でコマンドプロンプトを出し、

cd \Windows\System32
ren utilman.exe utilman.org
copy cmd.exe utilman.exe
Windowsを再起動
                                                                                                                                                                                                                                                                                                        
ログイン画面で、真ん中のアイコンをクリックし、コマンドプロンプトを起動する　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/564748/e56ed3a7-3534-8fe6-ff8a-b56b918bda2e.png)



net user
net user Administrator 設定したいパスワード
Administratorがアクティブでない時は、以下のコマンドで（一度も設定されてなければパスなしでアクティブになる）
net user Administrator /active:yes

cd \Windows\System32
del utilman.exe
ren utilman.org utilman.exe


Windows10 システムファイル修復関係
-------
dism /image:c:\ /cleanup-image /restorehealth

または、

sfc /scannow


Windows10 HDD修復関係
-------
chkdsk c: /f

不良セクター修復（長時間必要）
chkdsk c: /b


Windows10関係
-------
フォルダ丸ごとコピー
xopy /e c:\data d:
（フォルダ構造保持）（コピーフォルダ）





...That's all. ☆ Knowledge of zealous young🌙🐰
Typescript Node.js メソッドの結果をキャッシュする

## 背景

APIの結果を指定した時間キャッシュさせたかったので、シンプルにキャッシュできるクラスを自前で実装する。

## 使用ライブラリ
* ioredis
* zlib

## 実装

``` typescript
import ioredis from 'ioredis'
import zlib from 'zlib'

class Client {
  private redis: ioredis.Redis = new ioredis('redis://exammple:6379')

  async fetch<T>(key: string, func: () => Promise<T>, expire): Promise<T> {
    const cached = await this.redis.get(key)
    // キャッシュがあれば、解凍して返却
    if (cached) {
      const cacheString = await new Promise<string>((resolve, reject) =>
        zlib.inflate(Buffer.from(cached, 'base64'), (err, buffer) => {
          if (err) return reject(err)
          resolve(buffer.toString())
        })
      )
      return JSON.parse(cacheString)
    }
    // キャッシュがなければ、メソッドの結果を圧縮してredisに保存
    const result = await func()
    const cache = await new Promise<string>((resolve, reject) =>
      zlib.deflate(JSON.stringify(result), (err, buffer) => {
        if (err) return reject(err)
        resolve(buffer.toString('base64'))
      })
    )
    await this.redis.setex(key, expire, cache)
    return result
  }
}

export const cacheClient = new Client()
```


## 使用例

```typescript
await cacheClient.fetch('cache-key', () => { heavyTask() }, 3000)
```
npm package.json でファイルコピーする時 cpx 使わなくてもいい

# 知ってた？

Mac も Windows も共通でファイルコピーするために
cpx 
なんてインストールしなくてよかったんだよ。

## node にスクリプトを直接流し込める

次のようにして、copyFileSync 呼べばいい。

```json:package.json
{
  "scripts": {
    "filecopy": "node -e \"require('fs').copyFileSync('./a.txt', './b.txt')\""
  }
}
```

## 参考

cpx がリネームしてくれないので、なんとかならないかと調べていたらみつけた。

javascript - Rename file with NPM - Stack Overflow
https://stackoverflow.com/questions/35258871/rename-file-with-npm
#Ruby / nested Array elements / map and delete / Broken modified original array / So use dup ( deep copy )

```rb
# GOOD
# dup element in map
arr = [[:A, :B], [:C, :D]]; changed_arr = arr.map { |a| x = a.dup; x.delete_at(-1); x }; p changed_arr; p arr
# [[:A], [:C]]
# [[:A, :B], [:C, :D]]

# BAD
# map and delete
arr = [[:A, :B], [:C, :D]]; changed_arr = arr.map { |a| a.delete_at(-1); a }; p changed_arr; p arr
#  [[:A], [:C]]
# [[:A], [:C]]

# BAD
# dup array and map and delete
arr = [[:A, :B], [:C, :D]]; dupped_arr = arr.dup; changed_arr = dupped_arr.map { |a| a.delete_at(-1); a }; p changed_arr; p arr
# [[:A], [:C]]
# [[:A], [:C]]


```

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2957








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Visual Studio2017でLivetがインストールできなくなっている件

仕事で使っているVisualStudio2017にLivetをインストールしようと
サイトhttps://www.nuget.org/packages/LivetCask/
からダウンロードしたファイルを実行したところ
「この拡張機能は、現在インストール済みの製品にはインストールできません。」と表示された。

ダウンロードサイトに飛ぶと「Work with」には「Visual Studio 2019」と書かれていて2017の記述がない。

あちこち調べたところサポート切れていた。

下記URLからダウンロードできる古いインストーラでインストールできた。
https://github.com/runceel/Livet/releases/tag/v2.2.0
Microsoft Ignite Osaka 1/23 APPS40

# APPS40 AzureKubernetesServiceを使用したインフラストラクチャの統合

MicrosoftIgniteOsaka

1/23 session4 APPS40 AzureKubernetesServiceを使用したインフラストラクチャの統合のメモです。

- アプリの紹介
  - Tailwind Traders
- AKSアーキテクチャ
  - Kubernetes及びコンポーネントの概要
- スケール
  - アプリケーションのスケールイン及びスケールアウト
- Network & Security
  - PodアイデンティティとCalicoネットワークポリシー
- 障害の処理
  - クラスタ及びアプリケーションのエラー管理

## Tailwind Tradersのアプリ

- PostgreSQL
- SQL
- 仮想マシン
- コンテナインスタンス
- Blobストレージ

### 経営・ビジネス課題に対する対応

- 復元力
- セキュリティ
- 柔軟性
- スケール

### Kubernetesを選択する理由

- インフラストラクチャ抽象化のための標準化されたAPI
- 自己修復（ヘルスチェックのエンドポイントだけちゃんと作っておけば自動検知・修復する）
- スケーラビリティ
- 拡張性

### AzureKubernetesService(AKS)のアーキテクチャ

- マスターノード
  - コントローラマネージャ
     - APIサーバー
     - レプリケーション
     - ネームスペース
     - サービスアカウント etc
  - スケジューラ
  - etcd
- ワーカーノード
  - Pod
  - kubelet
  - kube-proxy

#### AKSのポイント

- AKSではマスターノードはAzureで管理される。またマスターノードは課金されない。
- AzureVNETを使用するとセキュアに通信が可能。
- 仮想ノード（コンテナインスタンスを接続して、ワーカーノードの一部として扱える）
- AZ

リソースグループ
```
az group create ¥
-l ¥
-n
```

vnet
```
az network vnet create ¥
--resource-group ¥
--name ¥
--address-prefixs ¥
--subnet-name ¥
--subnet-prefix
```

subnet
```
az network vnet subnet create
--resource-group
--vnet-name
--name
--address-prefixs
```

サービスプリンシパル
k8sから他のリソースを作成

```
az ad sp create-for-rbac
--name
--role
```

k8sの作成。最低限のオプションで作るのは簡単。
本番オプションはもっと必要。

```
az aks create
--resource-group
--name
--node-count
--generate-ssh-keys
```

オプションは作成時に重要。後から追加できず、再作成しないといけないケースもあるので、最初に慎重に選択する。

### スケーリング

#### 水平Podオートスケーラー(HPA)

kubernetes標準の技術。メトリクスに応じてPod数を増減させる。

#### クラスタオートスケーラー

ワーカーノードのオートスケーラー。kubernetesではなくクラウドサービス側の機能。
AKSではプレビュー提供中。

#### 仮想ノード

nodeSelectorをyamlファイルに追加することで利用することができる。

```
nodeSelector: beta.kubernetes.io/os:linux
...
```

## AKSセキュリティの導入

### PodIdentity

- Podが他のAzureサービスに安全に接続可能
- AzureADおよびAzureManagedIDを使用
- PodからAzureサービスへの接続

AzureIdentityBinding
ActiveDirectoryPodIdentity

### AKSネットワークポリシーのオプション

- Pod間トラフィックの保護
- Azureは二種類のネットワークポリシーが存在
- AKSクラスター作成時に作成可能
- 作成後に変更可能

Azureが提供しているものとCalicoがサポートされている。
Calicoの方がパフォーマンスが良い。

## マルチAZ

データセンター障害に対する回復力
レプリカの数は必ず３以上にしないといけない。
プレビュー提供
2段階認証（Google Authenticator）が通らなくなって焦ったときの備忘録

ぶっちゃけ初歩的なミスです
技術以前の問題なのでQiitaの記事としてOKなのかどうか・・・

### Qiitaの2段階認証が通らない

先日、Qiitaから一旦ログアウトしてから再度ログインしようとしたところ、

`不正な認証コードです。`

なぬ？

何度試してみても

`不正な認証コードです。`

しまいには間違えすぎてロックがかかる始末。
しかもバックアップコードは控えていない。 ← 最大のミス

試しに**BitBucketの方にログインしてみたところ、こちらは入れる**。
**LastPassでも問題なし**。
この日、Qiitaのアカウントはもうお亡くなりになったとほぼ諦めました。

### 翌日

このままでは不便なので仕方なく別のアカウントを作成してこちらで改めて管理しようと
2段階認証の設定を行おうとしたところ、

`不正な認証コードです。`

ブルータスお前もか・・・


### 原因は**時刻の同期**でした。
Android端末の自動時刻設定を切っていたために、Android端末の時刻と本来の時刻との差がQiitaの許容範囲を超えてしまっていたようです。

### 修正手順

1. Google Authenticator（認証システム）アプリの「設定」
2. コードの時刻調整
3. 今すぐ同期

これだけで治りました。
恐らくAndroidの時刻設定で時刻の同期をしても直ります。

本当に焦りました。
この記事でQiitaアカウントが救われる人が100万人に1人くらいいたらいいなぁ

というか、Qiitaって時刻の許容範囲がかなり狭いんですね。
GatsbyでNotionなソースにする

# プラグイン
- [gatsby\-source\-notionso \| GatsbyJS](https://www.gatsbyjs.org/packages/gatsby-source-notionso/)
- いくつか候補はありましたが、公開対象の親ページを指定出来るという点でこちらにしました
- まだ活用出来ていませんが、GraphQLのプロパティに`slug`や`isDraft`というのもあり、urlに指定したり下書きに使えそうです

# 実際の様子
- https://blog.bear.tokyo/
- https://github.com/km-tr/blog
- GatsbyJS + Notion + Netlifyです

# 感想
[[What's New?](https://www.notion.so/What-s-New-157765353f2c4705bd45474e5ba8b46c)](https://www.notion.so/What-s-New-157765353f2c4705bd45474e5ba8b46c)を待ちたい
![スクリーンショット 2020-01-23 15.58.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24135/f1e4fcda-3a79-e45d-5fb1-1ec803552956.png)
RedshiftでGRANTする時に地味なハマり方したときのメモ

## 前提

Redshiftで、あるスキーマテーブルを特定のユーザにSELECT権限を付与したかったが、なかなか上手く進まずハマったのでメモ。

## TL;DR

RedshiftでGRANTするときには、SELECT権限だけじゃなく、スキーマに対して`GRANT USAGE`も必要です。


## 実行すべきコマンド

adminでRedshiftに入り、下記のクエリを実行する。

```.sql
GRANT USAGE ON SCHEMA <権限付与したいスキーマ名> TO <権限付与したいユーザ名>;
GRANT SELECT ON ALL TABLES IN SCHEMA <権限付与したいスキーマ名> TO <権限付与したいユーザ名>;
TypeScriptで FileReaderのonloadした後、resultに対してエラーが出る時の暫定対処

# FileReader
https://developer.mozilla.org/ja/docs/Web/API/FileReader/result

## なんかおかしいらしい。

![スクリーンショット 2020-01-23 15.48.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73087/81ee06ee-38f5-300c-278f-5830153bfdac.png)

`TS2339: Property 'result' does not exist on type 'EventTarget'`

なぜか怒られる

https://github.com/Microsoft/TypeScript/issues/4163
なんかおかしいらしい。
※翻訳してまで読んでないので興味がある方は調べてください。


```javascript
const reader = new FileReader();
      reader.onload = (e) => {
        //(e.target as any)でany型に変換する
        console.log((e.target as any).result);
      };
      reader.readAsDataURL(file);
```
Wifi経由でadbコマンドを実行しよう（2．Linux編）

# はじめに
ずっとWindowsからAndroidアプリのテストをしていたので意識していませんでしたが、
Linuxからでもadbコマンドを実行することができるようです。
# 使用ツール
- Linux環境
- teraterm
- Linux用のAndroid SDK
- WinSCP

# 手順
1. Android端末の開発者モードをONにしてUSBデバッグを可能にする。
2. PC、Android端末ともにWifiに接続。
3. Linux環境にAndroid SDKをインストール。
4. sdkmanagerコマンドでパッケージをインストール。
5. adb接続。
6. adbコマンドを実行。
7. adbを切断。

ほとんど、[Wifi経由でadbコマンドを実行しよう（1．Windows編）](https://qiita.com/erik_t/items/47fcb7e2ec092bfb6761)と
やることは変わりませんが、
[3. Linux環境にAndroid SDKをインストール。](https://qiita.com/erik_t/items/8cb59d624b667c061d12#3-linux%E7%92%B0%E5%A2%83%E3%81%ABandroid-sdk%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)、
[4. sdkmanagerコマンドでパッケージをインストール。](https://qiita.com/erik_t/items/8cb59d624b667c061d12#4-sdkmanager%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%A7%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)、
[5. adb接続。](https://qiita.com/erik_t/items/8cb59d624b667c061d12#5-adb%E6%8E%A5%E7%B6%9A)にWindowsと違いがありますので、そこだけ説明します。

# 3. Linux環境にAndroid SDKをインストール。
## Android SDKのインストール手順
1. Android SDKを入手
2. Linuxの適当なパスに1で入手したAndroid SDKを移動
3. パスを通す。
 
### 1. Android SDKを入手
[ここ](https://developer.android.com/studio)にアクセスしてAndroid SDKをダウンロードします。
アクセスしたらDOWNLOAD OPTIONSをクリック。
![android_dev.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409907/ebbc955b-16a3-0bc3-5297-8d80d370d595.png)
Command line tools onlyよりLinux用のファイルを選択してダウンロードしてください。
![adb_dev.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409907/6ce5cde9-bd9d-6767-8dc1-f44316487496.png)

### 2. Linuxの適当なパスに1で入手したAndroid SDKを移動
1で入手したSDKをAndroid SDKのzipファイルを解凍するとtoolsというフォルダが出てきますので、
WinSCPを使用して、Linuxの好きな場所に移動しましょう。
私は`/opt/android-sdk`に移動しました。

### 3. パスを通す。
.bashrcの末尾に1行追加します。

.bashrcをviで開いて

```
vi ~/.bashrc
```

一行追加して

```
export PATH=${PATH}:/fssdb/android-sdk/tools:/fssdb/android-sdk/platform-tools
```

内容を反映。

```
source ~/.bashrc
```

# 4. sdkmanagerコマンドでパッケージをインストール。
下記を実行します。

```
/opt/android-sdk/tools/bin/sdkmanager "platforms;android-26"
/opt/android-sdk/tools/bin/sdkmanager "build-tools;26.0.1"
```

ちょっと前まで上記までやってればadbも使えたのですが、
いまはadbを実行するために下記も実行してください。

```
/opt/android-sdk/tools/android update sdk
/opt/android-sdk/tools/bin/sdkmanager platform-tools
```

# 5. adb接続。
ほとんどWindowsと同じなのですが、1点だけ違いがあります。
Linuxでは、`:5555`部分が省略不可です。

```
adb connect 123.456.789.012:5555
```

# ちなみに
違う方法で接続してadbコマンドを実行していた場合、
例えばWindowsから有線でadbを事項していた場合、
一旦許可を取り消さないと新たな端末（今回設定したLinuxとか）からadbコマンドが実行できませんので注意。

# 関連ページ
[Wifi経由でadbコマンドを実行しよう（1．Windows編）](https://qiita.com/erik_t/items/47fcb7e2ec092bfb6761)
[Wifi経由でadbコマンドを実行しよう（2．Linux編）]()

# 参考サイト
[adb の使い方(Linux 編)](https://w.atwiki.jp/p10an01/pages/30.html)
[Ubuntu 16.04にAndroid SDKをインストール](https://symfoware.blog.fc2.com/blog-entry-2002.html)
[How To Fix ADB Device Unauthorized Message On Android](https://www.addictivetips.com/android/fix-adb-device-unauthorized-message-android/)
npmとは　yarnとは

#### この記事の目的
yarnとは何か、npmとは何かという概念を理解することを目的としています。

---

#### yarnとは　npmとは・・・
**Node.js**で動作する**パッケージマネージャー**

#### Node.jsとは
Node.jsというのは、JavaScriptでサーバーサイドの処理を可能にさせるプログラム

#### パッケージマネーシャーとは
「パッケージマネージャとは、コンピュータに何のソフトウェアがインストールされたかを記録し、新しいソフトウェアのインストール・新しいバージョンへのソフトウェアの更新・以前インストールしたソフトウェアの削除を容易に行えるようにするプログラム」
[【Debian公式ページ】パッケージマネージャとは](https://www.debian.org/doc/manuals/aptitude/pr01s02.ja.html)

---

#### つまり
yarnとnpmはJavaScriptでサーバーサイドの処理を行うために使うプログラム（Node.js）上で使うパッケージマネージャーということです。
下記で一つずつ確認していきましょう。

---

## JavaScriptはもともとフロントエンド言語
- ブラウザでの画面表示部分、つまりフロントエンドで使用されることを前提に作られたプログラム言語。
- データベースへのアクセスなどサーバーサイドの処理はできなかった。

## Node.jsの誕生でJavaScriptでサーバーサイドの処理が可能に
- Node.jsが開発されたことで、JavaScriptでサーバーサイドの処理ができるようになった。
- それに伴い、JavaScriptのフレームワークが開発された。（React、Express、）

## フレームワークを使うためにはインストールを簡単にする必要がある
- 1000個のプログラムで出来ているフレームワークをインストールするとして、そのフレームワークが動くために必要なプログラムを全て手作業でサーバーの適切な場所にコピーし、特定の設定ファイルを書き換え、正常にインストールできたかを確認し、バージョン管理をするのはかなり困難。

## パッケージマネージャーがインストールや管理を簡単にする
- 簡単なコマンドの入力でインストールを完了することができる。

## Node.jsで動作するパッケージマネージャー、それがyarnとnpm
:)

## npmは
- Node.jsをインストールすれば一緒にインストールされる。
- 2009年にNode.jsがリリースされた翌年にnpmがリリースされた。

## yarnは
- 2016年にリリース。npmと互換性があり、npmで使用していたプロジェクト設定ファイル（package.json）がそのまま使える。
- npmと比べてインストールが速い、セキュリティが高いという特徴がある。
 - セキュリティが高いというのは、インストール時にパッケージが不正に変更されていないかなどをチェックサムを用いて検証することができ、安全なパッケージのインストールが可能であるということ。
- バージョン管理についても優れていて、yarnではプログラムのインストール後に、yarn.lockというファイルが作成され、それにはインストールしたプログラムが使用している別のプログラム（依存プログラム/パッケージ）のバージョンが明確に書き込まれている。
 - 依存プログラム/パッケージをその後再度インストールしてもバージョンの整合性が保たれるので、バージョン不一致でプロジェクトが動かなくなる危険性が無くなる。
- npm、homebrew、MacPortsからインストールできる。

[【公式ページ】Yarnのインストール](https://yarnpkg.com/ja/docs/install#mac-stable)

## npmとyarnの違い
#### 依存プログラム/パッケージのケア
npm：バージョン違いの依存プログラム/パッケージをインストールしてしまう可能性あり
yarn：yarn.lockファイルにより、バージョン違いの依存プログラム/パッケージのインストールは起こらない
#### インストール速度
npm：遅い
yarn：早い

## 参考
[【Samurai Blog】JavaScriptのパッケージマネージャーnpmとYarnについて解説します！](https://www.sejuku.net/blog/96866)
[【Samurai Blog】【Node.js】初心者も理解できる言語の特徴を体系的に解説！](https://www.sejuku.net/blog/45745)
ローカル開発環境では画像が表示されるのに,VPSのリモートサーバーでは画像が表示されない

chromeDevoolのコンソール
エラーメッセージ

```
GET ~image_name~.jpeg 403 (Forbidden)
```

- [このリンク](https://stackoverflow.com/questions/44247272/laravel-5-4-forbidden-403-on-files-in-storage-with-public-visibility)から情報収集

> 私はあなたが経験しているこの403の問題が共有ホスティングに置かれていると推測しています。
>
> シンボリックリンクを作成する`php artisan storage:link、`にはstorage/app/public`フォルダーへの完全な絶対パスが含まれます。これがおそらくサーバーによる403応答の原因です。
>
> ***解決策は、プロジェクトルートからの相対パスでシンボリックリンクを作成することです***

[シンボリックリンクに関する操作（linux）の参考](https://qiita.com/colorrabbit/items/2e99304bd92201261c60)

解決　

- `php artisan storage:link でつくったシンボリックリンクを削除

- ```bash
  ln -s ../storage/app/public public/storage
  ```

  上記で貼り直し
実行する階層に注意

理由

- 上に書いてある通りの原因だった
- 一番上のリンクに一通り原因が書かれてるっぽい
- autloaderがよみに行かないくらい上から書かれてたから403エラーだったってことでいいのかな
MuJoCoで地形をカスタマイズする方法！

# MuJoCoで地形をカスタマイズしたい！
強化学習でシミュレーション環境といえばMuJoCoですが，やってるうちに地形をいじりたいな〜と思ってリファレンスを軽く読んだので残しておきます．

# gray scale画像から読み込む
MuJoCoのリファレンスによると，gray scale画像から地形情報を読み込めるらしいです．
やってみました．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/571510/34c652db-1f1b-5968-7c55-496767421307.png)
これが
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/571510/e3cb83da-5918-b371-2599-fcad5ad73716.png)
こうなります！

# やり方
1. gray scale 画像を作る（terrain4.png）
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/571510/2c6eb0fb-39dc-2d6b-57e9-78c30ee6d26e.png width=300>

2. xmlファイルをいじる
assetの部分．主にhfieldの部分．

```xml:ant.xml
<asset>
    <texture builtin="gradient" height="100" rgb1="1 1 1" rgb2="0 0 0" type="skybox" width="100"/>
    <texture builtin="flat" height="1278" mark="cross" markrgb="1 1 1" name="texgeom" random="0.01" rgb1="0.8 0.6 0.4" rgb2="0.8 0.6 0.4" type="cube" width="127"/>
    <texture builtin="checker" height="100" name="texplane" rgb1="0.2 0.4 0.6" rgb2="0.8 0.8 0.8" type="2d" width="100"/>
    <material name="MatPlane" reflectance="0.5" shininess="1" specular="1" texrepeat="60 60" texture="texplane"/>
    <material name="geom" texture="texgeom" texuniform="true"/>
    <hfield name="mytilted" file="terrain4.png" nrow="0" ncol="0" size="50 50 3 0.1" />
</asset>
```

worldbodyの部分

```xml:ant.xml
<geom conaffinity="1" condim="3" hfield="mytilted" material="MatPlane" name="floor" pos="0 0 0" rgba="0.8 0.9 0.8 1" type="hfield"/>
```

3.完成
![IMG_3573.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/571510/493ee000-cb8b-ba1b-d1bf-76c66da956c3.jpeg)
Juliaでproxy経由でパッケージをインストールしたいけどエラーがでる時の解決策

少しハマったので解決策をシェアしたいと思います。

Juliaのバージョンを上げた途端にこれまでできていたproxy経由でのパッケージインストールができなくなったようなケースが対象です。
Julia 1.3で確認済みです。

参考URL:
https://github.com/libgit2/libgit2/issues/5255

# 解決策
proxyが```http://myproxy.com```でポートが1111のときですが、
.gitconfigに

```
[http]
        proxy = http://myproxy.com:1111
```
と書かれていると通常のgitはちゃんとproxyを通ってくれるのですが、Juliaだとこれがうまくいかない場合があります。
この場合、

```
[http]
        proxy = http://myproxy.com:1111/
```
とスラッシュを最後に入れると解決する場合があります。
Jerjey(Jax-rs)でmultipart/form-dataの受け取り

##はじめに
[[Android]端末からサーバへ画像のアップロード](https://qiita.com/hire1105/items/b5a8681405d9f437f759)にて受け取る側がServletになっていました。本当はJerjeyで受け取りたかったのですが、勝手がわからず妥協していました。今回その方法がなんとなくわかったので紹介させていただきます。

###環境
* Eclipse 4.13.0
* java 11
* Jerjey 2.29
 * 入れ方は[こちら](https://qiita.com/hire1105/items/3cc5c70727ea68bff83a)

##multipart/form-dataを対応させる

以下をダウンロードしてください。

* [jersey-media-multipart.jar](https://mvnrepository.com/artifact/org.glassfish.jersey.media/jersey-media-multipart)
* [mimepull.jar](https://mvnrepository.com/artifact/org.jvnet.mimepull/mimepull)

この2つにパスを通します。

###Applicationクラスを作成
このままでは、multipart/form-dataがまだ使えないので対応させたいプロジェクトのパッケージ内に
[ApplicationConfig.java]を作成し、以下をコピペしてください。

```java:ApplicationConfig.java
package com.Sample.api;

import org.glassfish.jersey.media.multipart.MultiPartFeature;
import org.glassfish.jersey.server.ResourceConfig;

public class ApplicationConfig extends ResourceConfig {
   public ApplicationConfig() {
     packages("pakage").register(MultiPartFeature.class);
   }
}
```
"pakage"には使用するパッケージ名を各自入れてください。
次に[Web.xml]を変更します。

```xml:Web.xml
<servlet>
  <servlet-name>jersey-app</servlet-name>
  <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
  <init-param>
    <param-name>javax.ws.rs.Application</param-name>
    <!--ここの"pakage.ApplicationConfig"は上で作成したクラスのパスです。-->
    <param-value>pakage.ApplicationConfig</param-value>
  </init-param>

  <init-param>
    <param-name>jersey.config.server.provider.classnames</param-name>
    <param-value>org.glassfish.jersey.media.multipart.MultiPartFeature</param-value>
</init-param>
 </servlet>
```
これでmultipart/form-data対応が完了しました。

##実装

以下クラスを作成してください。

```java:Upload.java
import static java.nio.file.StandardCopyOption.*;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;

import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataParam;

@Path("/Upload")
public class Upload {
	@POST
	@Path("/File")
	@Consumes(MediaType.MULTIPART_FORM_DATA)
	public String upload(@FormDataParam(value = "file") InputStream fileStream,
	                    @FormDataParam(value = "file") FormDataContentDisposition fileDisposition) {
		 try {
		      Files.copy(fileStream, Paths.get("保存先フォルダ",fileDisposition.getFileName()), REPLACE_EXISTING);
		      return "END";
		    } catch (IOException e) {
		      throw new WebApplicationException(e, 500);
		    }

	}
}
```

これでhttp://localhost/XX/api/Upload/File
(XXはパッケージ名)にファイルを送れば保存されるはずです。

##参考
JAX-RSでファイルアップロード！
http://blog.yumix.net/entry/2012/12/17/002515

Jerseyの設定1(web.xmlとかApplicationクラスとか)
https://edgegram.hatenablog.jp/entry/2015/11/25/160433

java - JAX-RS HTTPマルチパートリクエスト
https://tutorialmore.com/questions-1757453.htm
assert_not と vlaid? を使い validation が有効かどうか確認するテスト   6.2.2 存在性を検証する

##assert&emsp;と&emsp;assert_not　メソッド

-  `assert hoge` の場合&emsp;➡︎&emsp;`hoge` が trueなら成功、falseなら失敗となる

-  `assert_not hoge`の場合&emsp;➡︎&emsp;`hoge` が trueなら失敗、falseなら成功となる<br/><br/>



##valid? メソッド
`valid?` は、モデル（ActiveRecord）のメソッドで、バリデーションを実行して、モデルが正しい値かどうかを調べるものです。
バリデーションが通ればtrue、通らなければfalseを返します。<br/><br/>



##バリデーションの有効性
```rb:user_test.rb


  test "name should be present" do
    @user.name = "   "
    assert_not @user.valid? #←バリデーションをまだ設定していないので、どんな値でも true で返ってくる。
  end                       #なので、assert_notメソッドでエラーが起きる  

```

`test "name should be present" do  ... end`
の中では@userの値が空欄になっています。
もし presenceのバリデーションが有効ならば `@user.valid?`は false を返すため、
`assert_not`が成功となりエラーは起きません。<br/>
しかし presenceのバリデーションが無効(もしくは未設定）の場合は、たとえ`@user.name`が空欄であろうとなかろうと、
`valid?`メソッドはtrueを返すため、`assert_not`が失敗となります。<br/><br/>

Railsではこのようにバリデーションの有効性をテストしているようです。
Nuxt.jsのbeforeDestroyed()でイベントリスナーを削除できなかった時の対処法。

#発端
偉い人「このページは横画面でしか表示したくない」
蝦「はい」

#環境
OS: windows10 64bit
node.js v10.16.3
Nuxt.js v2.10.2

#イベントリスナーを追加
蝦「画面の向きが変わるたびにVueファイル内のdata()の値を変えてやればおｋ」
とりあえずMDNのサンプルをそのままつかう。
[Window: orientationchange イベント - Web API | MDN](https://developer.mozilla.org/ja/docs/Web/API/Window/orientationchange_event)

```javascript:ebi.js
<script>
//中略
beforeMount() {
    console.log("beforeMount");
    window.addEventListener("orientationchange", this.checkRotate, false);
  }

</script>

```

しかし
#イベントリスナーが消えない。
「後はbeforeDestroy()でイベントリスナーを削除するように書けばおｋ」

```javascript:kani.js
<script>
//中略
  beforeDestroy() {
    console.log("beforeDestroy");
    window.removeEventListener("orientationchange", this.checkRotate, false);
  },

</script>

```

消えない。
![コメント 2020-01-23 145126.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425022/7bb46dd5-7932-24d4-608a-fad7dec5eea5.png)
追加はされるが削除はされないので、該当ページに遷移するたびにイベントリスナーが増える。やばい

##原因: beforeDestroy()もDestroy()も実行されてない
プリントデバッグしてみると、ページ離脱時にbeforeDestroy()もDestroy()も実行されてない。
再起動してもキャッシュを消しても実行されないという不思議。

#解決策: ナビゲーションガードを使う。
どうにもならなくなったらbeforeRouteLeave(to, from, next)で削除すればおｋ。
[ナビゲーションガード | Vue Router](https://router.vuejs.org/ja/guide/advanced/navigation-guards.html)
[Vue-Routerのナビゲーションガードを使ってみる - Qiita](https://qiita.com/SatohJohn/items/cd7067ac64d8e45da4dd)

```javascript:uni.js
<script>
//中略
 beforeRouteLeave(to, from, next) {
    if (to.name) {
      next();
      window.removeEventListener("orientationchange", this.checkRotate, false);
      return;
    }
    return;
  },

</script>

```

消えました。
![コメント 2020-01-23 151735.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425022/1a626ee9-e5c3-624a-4c76-6ff285e59be2.png)

別のプロジェクトでは再現しなかったので、多分もう使うことはほぼないだろうけど備忘録代わりに書いておく。
原因がわかる人がいたらだれか教えてください。