OmniAICreator/Qiita-1.07M huggingface dataset:
JavaScriptでclass構文を使ってみた

# はじめに
今作っている3D RPGを管理するためにクラス化して管理したくなって、ちょっと調べてみた。
で、privateメソッドとかできるのかな？と調べてみても、private 変数は宣言できてもメソッドはできないらしい。その辺も踏まえてちょっと試してみた。
ちなみに、ECMAScript 2015(ES6)で導入された機能らしい。
Windows10のIE11でエラーになったので、IEでは動かない。
Edgeはclass構文は問題なし。
private変数が使えなかった。
まぁ、Edgeに関してはChromiumベースになったら状況変わりそうだけど。
Appleはしらん。
ちなみにprivate fieldはいつ策定されたのかよくわからない・・・

## class
JavaScriptでclassはこんな感じで書ける。

```javascript
class Main{
    constructor(){
    }
}
```

とってもシンプル。
constructor()はなくても動作する模様。

## 変数の宣言

さて、変数の宣言はこんな感じ。

```javascript
class Main{
    testVal = 1;
    #privateVal = 2;

    constructor(){
    }
}
```

変数の先頭に#を付けるとprivateな変数になる。
つけないと、publicな変数になる。

参照方法は

```javascript
class Main{
    testVal = 1;
    #privateVal = 2;

    constructor(){
        alert(this.testVal + " / " + this.#privateVal );
    }
}
```

thisを付けて変数を参照することで利用可能となる。
インスタンスを作成した場合はこんな感じ

```javaascript
var main = new Main();
alert(main.testVal);
```

まぁ、普通の参照方法ですね。

## private メソッドを考える
privateメソッドはメソッドの先頭に#を付ければできるかと思ったら、できなかった。
実現するにはググるといくつか出てくると思うが、自分の考えた方法はこんな感じ

```javascript
class Main{
    //private fiels
    testVal = 1;
    #privateVal = 2;

    //private method
    #privateMethod = function(){
        return this.#privateVal;
    }

    constructor(){
    }

    callPrivateTestMethod(){
        alert(this.#privateMethod());
    }
}

var main;
window.addEventListener("load", function(e){
    main = new Main();
    main.callPrivateTestMethod();
});
```

private変数にメソッドを割り当ててprivateメソッドにする方法。
個人的にはこれで十分。

# 最後に
この方法がいいかどうかはわからないけど、とりあえずこれで3D RPGで使うクラスが作れそう。
お仕事でも使ってみたいけど、IEで動かす可能性も捨てきれないのがもやもやする。
IE早く消えてなくなってくれ！

あと、private 変数を#で始めるのはなんか、気持ち悪いｗ

# 参考

- [［JavaScript］クラスの書き方（クラスの継承・メソッドのオーバーライド）](https://qiita.com/tanakadaichi_1989/items/f49b0102bd36c99c52a6)
jinjaテンプレートでfor文ループ中の変数を更新したい

##変数の定義

```jinja
{% set cnt=1 %}
{{cnt}}
```

```
1
```

##for文でインクリメントさせる
現行のバージョンでは、**下記のようにfor文内で変数の上書きはできない**


```jinja
{% set cnt = 1 %}
{% set charaList = ['a','b','c'] %}
{% for chara in charaList %}
<h1>現在のcntは{{cnt}}です</h1>
{% set cnt = cnt + 1 %}
{% endfor %}
```


```
現在のcntは1です
現在のcntは1です
現在のcntは1です
```

###では、どうするか？
jinja 2.10で追加されたnamespaceオブジェクトを使う。
[参考](https://jinja.palletsprojects.com/en/2.10.x/templates/#assignments)

```jinja
{% set ns = namespace(cnt = 1) %}
{% set charaList = ['a','b','c'] %}
{% for chara in charaList %}
<h1>現在のcntは{{ns.cnt}}です</h1>
{% set ns.cnt = ns.cnt + 1 %}
{% endfor %}
```

```
現在のcntは1です
現在のcntは2です
現在のcntは3です
```

##ループカウンタ
ループ回数を数えたいだけであればloop.indexが使える。

```jinja
{% set charaList = ['a','b','c'] %}
{% for chara in charaList %}
<h1>現在は{{ loop.index }}回目です</h1>
{% endfor %}
```

```
現在は1回目です
現在は2回目です
現在は3回目です
```

##参考
[jinjaテンプレートのforループで変数をインクリメントする方法は？](https://www.it-swarm.net/ja/python/jinja%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88%E3%81%AEfor%E3%83%AB%E3%83%BC%E3%83%97%E3%81%A7%E5%A4%89%E6%95%B0%E3%82%92%E3%82%A4%E3%83%B3%E3%82%AF%E3%83%AA%E3%83%A1%E3%83%B3%E3%83%88%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95%E3%81%AF%EF%BC%9F/940140943/)

##追記(2019/12/28)
###namespaceオブジェクトについてもう少し詳しく
pythonの辞書型と同じようにふるまう。
要素の追加の仕方には注意。
[Jinja Api > namespace](https://jinja.palletsprojects.com/en/2.10.x/templates/?highlight=namespace#namespace)

```jinja
{%- set ns = namespace(key1 = "りんご" , key2 = "みかん") %}
{%- set ns.key3 = "バナナ" %}
<p>{{ns}}</p>
<p>{{ns.key3}}</p>
```

```
<Namespace {'key1': 'りんご', 'key2': 'みかん', 'key3': 'バナナ'}>
バナナ
```
VBS　全角英数字を半角に変換するStrCONVvbNarrowAlfa


#コード

```vb
Function StrCONVvbNarrowAlfa(buf) ' As String
Dim REG : Set REG = CreateObject("VBScript.REGExp")
'DIm FSO : Set FSO = CreateObject("Scripting.FileSystemObject")
'Dim WSH : Set WSH = CreateObject("WScript.Shell")
'Dim oShell : Set oShell = CreateObject("Shell.Application")
REG.Global = True : REG.Multiline = False : REG.IgnoreCase = False
Dim oFolder, oFile, oSubfolder, TS
Dim MC, M, im, Length, firstpoint
DIm i , Cnt , x
REG.pattern = "[０-９]"
set MC = REG.Execute(buf)
if MC.Count > 0 then
For im = 0 to MC.Count -1
i = Asc(Mc(im).value)
x = Clng(Asc(Mc(im).value) + 32225)
buf = Replace(buf , MC.item(im).Value, chr(x),1, -1, 1)
next
end if
REG.pattern = "[Ａ-Ｚ]"
set MC = REG.Execute(buf)
if MC.Count > 0 then
For im = 0 to MC.Count -1
i = Asc(Mc(im).value)
x = Clng(Asc(Mc(im).value) + 32225)
buf = Replace(buf , MC.item(im).Value, chr(x),1, -1, 1)
next
end if
REG.pattern = "[ａ-ｚ]"
set MC = REG.Execute(buf)
if MC.Count > 0 then
For im = 0 to MC.Count -1
i = Asc(Mc(im).value)
x = Clng(Asc(Mc(im).value) + 32224)
buf = Replace(buf , MC.item(im).Value, chr(x),1, -1, 1)
next
end if
Set REG = Nothing
StrCONVvbNarrowAlfa = buf
End Function
```

#原理と限界
要は正規表現で全角を抜き出してコードをずらすというもの。
ただし数字と英語の大文字、それらと英語の小文字ではずらす数が違う。
また記号はまた別の値になる。
というわけでまず英数字だけ変換しています。
SELECT文で本番環境を落としたお話

（この記事は [地平線に行く](https://yujisoftware.hatenablog.com/entry/postgresql_lock_table) とのマルチポストです）

[本番環境でやらかしちゃった人 Advent Calendar](https://qiita.com/advent-calendar/2019/yarakashi-production)で、このパターンのやらかしはなかったのでキーボードを叩くことにしました。
番外編のつもりでお楽しみください。

この記事が、新たな障害発生を防ぐことにつながれば幸いです。

# 何をやったのか

ある日、ちょっとした調査のために本番データベースのデータを確認することになりました。
（個人情報が格納されているようなシステムではなかったので、必要であれば本番データベースへのアクセスが許されていました）

もしメンテナンスがあればそのタイミングでやればよかったのですが、直近では特に予定はないとのことでした。そのため、システムが動いている状態のまま作業をすることにしました。
ごく単純な `SELECT` を実行するだけのつもりだったので、システムに影響がないと判断したためです。

その際、万が一コピペをミスって更新系の SQL を実行してしまったら怖いので、念のためトランザクションをかけてからSQLを実行することにしました。
具体的には、psql （PostgreSQL のターミナル）で本番データベースに繋いで、以下の SQL を実行しました。

```sql
BEGIN;
SELECT * FROM user_setting WHERE xxx = 1;
```

結果はすぐに帰ってきました。確か2行程度だったと思います。

続けてさらに SQL を実行しようとしました。しかし、ここで同僚から「ソースコードでわからないところがあるんですが…」と声をかけられました。
こちらは急ぎの作業ではなかったので、ターミナルをそのままにして同僚の質問に回答することにしました。

そして約10分後…。

**$\huge{「システムがダウンしてるー！」}$**

本番障害となりました。

# 何が悪かったのか

**「トランザクションをかけて `SELECT` 文を打ったお前が悪い」**ということになりました。

# 何が起きていたのか

ログからシステムの動きを確認したところ、あるスレッドで `user_setting` テーブルをロックしようとしていたことが分かりました。具体的には、以下の SQL が発行されていました。

```sql
LOCK TABLE user_setting;
```

この SQL には、ロックモードの指定がありません。この場合、PostgreSQL は `ACCESS EXCLUSIVE` ロックが指定されたものとみなされます。
→ [明示的ロック - PostgreSQL 15.4文書](https://www.postgresql.jp/document/15/html/explicit-locking.html)

**この `ACCESS EXCLUSIVE` ロックは<font color="red">最も強いテーブルロック</font>です。
SELECT 実行時に自動的に獲得される<font color="red">最も弱いテーブルロックである `ACCESS SHARE` ロックとも競合します。</font>**

![明示的ロック.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205989/7a85fa42-4182-e983-bf67-3202bbe4ae80.png)

つまり、システムが `LOCK TABLE` 文によって `user_setting` テーブルの `ACCESS EXCLUSIVE` ロックを獲得しようとしましたが、私が先に `SELECT` 文によって `ACCESS SHARE` ロックを獲得していたことで、ロック解除待ちに入って処理が止まってしまいました。

さらに、このあと別のスレッドが `user_setting` テーブルに対し `SELECT` を実行しようとしていました。しかし、`user_setting` テーブルは `ACCESS EXCLUSIVE` ロックの獲得待ちが発生しているので、この `SELECT` 文も止まってしまっていました。

結果、一つのスレッドが `LOCK TABLE` で、多数のスレッドが `SELECT` で止まってしまい、データベースとのコネクションプールが枯渇。システムダウンに至りました。

# どうすればよかったのか

二度と惨劇を起こさないために、以下の知見を得ました。

* `SELECT` しかしないとはいえ、油断しない
* トランザクションを開始したなら、放置しない
   * なるべく早く `COMMIT` か `ROLLBACK` をする

また、私がシステムを設計する際に以下の点に気を付けるようになりました。

* ロック粒度に注意する
* `LOCK TABLE` は極力使用しない
   * やむを得ず `LOCK TABLE` を使用するなら、可能な限り弱いロックモードを使用する
     * その際は、`LOCK TABLE` との競合について周知する[^LOCK]

[^LOCK]: 今回の場合、私が `LOCK TABLE` するコードを書いたわけではなかったので、このシステムでこのような競合が起きることを知りませんでした。

# MySQL では

MySQL だとテーブルロックのロックモードには READ と WRITE の2種類があります。
[MySQL :: MySQL 5.6 リファレンスマニュアル :: 13.3.5 LOCK TABLES および UNLOCK TABLES 構文](https://dev.mysql.com/doc/refman/5.6/ja/lock-tables.html)

このうち **WRITE ロックは SELECT と競合します。**
また、MySQL のテーブルロックはセッション単位です。ドキュメントにあるように、**ROLLBACK しただけではロックが解除されない**ので注意が必要です。

> * トランザクションを (たとえば、START TRANSACTION で) 開始すると、現在のトランザクションはすべて暗黙的にコミットされ、既存のテーブルロックが解放されます。 
> * （中略）
> * **ROLLBACK は、テーブルロックを解放しません。**
> 
> [MySQL :: MySQL 5.6 リファレンスマニュアル :: 13.3.5.1 テーブルロックとトランザクションの通信](https://dev.mysql.com/doc/refman/5.6/ja/lock-tables-and-transactions.html)

# 後日談

この件などでストレスが重なったことで胃痙攣をやらして、今度は私がダウンしました[^1]。人間の体も本番障害が起きるんですね…。

みなさんも、障害発生後の体調管理には十分ご注意ください！

[^1]: 布団の上で数時間のたうち回りました。
エンジニアリングマネージャのお仕事

2018年に転職したら、エンジニアリングマネージャ的な仕事をするようになったので、振り返りをかねて棚卸し。

# 何者？
- 東京本社の会社の、地方拠点で働くエンジニアリングマネージャ
- 前職は大雑把にいえばメーカー系SI系列子会社
- 転職前後ともいわゆる受託開発がメイン領域
- マネージメント対象は片手から出るくらい
- 全員が同じプロジェクトではなく、複数のプロジェクトを横断

# やっていること
- プロジェクトの提案活動
- プロジェクトへのメンバーのアサイン
- プロジェクトマネージメント（一部）
- 拠点メンバーの評価面談
- 中途採用面談
- （新卒採用を念頭に置いた）学生向けイベント実施
- 外部交流活動
- 余った時間で、ほんの少し手を動かす

# やってきたこと
- 前職がSIだったこともあり、思えば役割や領域は割と定まっていた
- ......に対して、現在はそこまででもない
- 自分が入った時点で拠点のエンジニアは全員入社1年以内の中途転職組
- お互いに様子見をしつつ、組織の文化とかカラーとかなにそれおいしいの？状態
- 本社と拠点の関係性の構築からして、手探りではじめる
- 最終的には、「とりあえずやればいいじゃん、大袈裟だなぁ」

# わかったこと
- プロジェクトマネージメントでよく引用されるQCDの三角形があるけど
- それと類似する形でエンジニアマネージメントにも三角形がありそう
<img width="567" alt="トライアングル.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23612/5d7dc7e0-a7c7-acdc-582e-765ec25a6443.png">
- QCDと同じように相互に関係していて、どれかひとつをいじると他に影響がある
- エンジニアリングマネージャの仕事は、この３つを円滑にまわしていくこと
- そのために、「組織」「エンジニア」「プロジェクト」それぞれの代弁者となる

### たとえば
- 組織から予算調達してエンジニアの作業関係を改善し、プロジェクトの効率をあげる
- エンジニアの進捗を管理してプロジェクトの進行を助け、組織の健全な収支を保つ
- 営業や提案活動を支援し、エンジニアの適性や志向と一致するプロジェクトを獲得する
- （風を吹かせて桶屋を儲けさせる）

こういう話って、どうしても鶏が先か卵が先かの議論になりがちだけど、互いに影響し合っているのだからまわしてみるしかなくて。必ずしも成果が約束されるわけではないので、正のフィードバックを得られそうな方に向けて、小さいところからパラメータを動かしていくしかないというのが体感。
大雑把には３つに分けてはみたけど、もちろんシステムとしてはこんな単純なものじゃないし、結局動かすのはそこにいる人間なので、そこに由来する困難がつきまとう。
とはいえある程度モデル化＝単純化しないと理解も進まないわけで。回してるのが正のループなのか、負のループなのかというところだけは意識したい。

# 次にやること
- 最終的には、自分がいなくても大丈夫な体制
開発環境では大丈夫だったのに本番環境でバグったPHPのお話LEVEL1～3 + 1

本番環境とかいってますが、だいたいテスト環境です。多めに見てください。

# LEVEL1 大文字小文字
windowsで開発してる人からしたらあるあるじゃないでしょうか？
開発環境(windows)では大文字小文字の区別が無く、Linuxでは区別されます。

私が一番ダメージを負ったのはクライアント様がサイト制作で使用する画像を送ってきた際に、
拡張子が大文字のファイルが数ファイルだけ混ぎれ込んでために、ふぁーーーしたことですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249312/054274d2-7f4a-e001-c302-c5cae61ce186.png)

おわかりいただけただろうか・・・

[コード].[拡張子]という取り決めで画像を送っていただいたため中々気づきませんでした。
本番環境にあげる直前に気が付いて事なきを得ましたが、非常に危なかったです。

なお、

```
if (file_exists($imagePath . $fileName '.jpg')) {

} elseif (file_exists($imagePath . $fileName '.JPG')) {

}
```
当時2年目の私がふぁああああしながら書いた負債は今もバリバリの現役です。

# LEVEL2 SSL
WEB系の開発をやってる方ならちょいちょい出会うのではないでしょうか。

```
<iframe name="iframe" src="http://example.com/aaaaa/bbbb/" width="100%" scrolling="no" align="top" frameborder="0"></iframe>
```
事件発生です。
httpsのサイトからhttpのiframeは読み込めません。

「ソースコードの管理は任せるけど、一部は自社からいじりたい！」とご要望いただく場合にしばしばiframeを使うのですが、クライアント様のソースがアップされてるドメインがSSL対応していないと、とんでもないことになります。

フレームの中身真っ白です。

ちゃんと開発環境も横着しないでSSLに対応させてればよかったのですが、今回はテスト環境にあげて初めて発覚しました。

先方がSSLの対応をするのには時間がかかるとのことで、双方話し合った結果「とりあえずフレーム内のコンテンツをハードコードする」という力技で制作を進めることになりました。(こわい)

今はまだjavascriptやiframeなどのコンテンツがブロックされるだけで、画像などはセキュアな通信が保証されないだけちゃんと映りますが、Chromeは2020年から順次画像もブロックしていくようですので、注意が必要です。


#LEVEL3 拡張モジュール
普段使わない関数は慎重にね。
結論から言うとphp標準搭載の関数ではない、拡張モジュールをインストールして初めて使える関数使ってバグりました。

これは私ではなく、後輩エンジニアちゃんが持ってきたソースコードをレビューしていた時のことです。

```
// 金額を1億で割った余り
$surplus = bcmod($price, '100000000');
```

(なんだこいつ初めて見た。。。%でよくね・・・？)
と思いつつ、間違ってもないし、新しい書き方を取り入れることは悪い事じゃないなーと思ってレビューにＯＫ出しました。

が、テスト環境にあげたところ・・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249312/637ce738-0b84-8cb4-f41a-26d867f993c8.png)
ふぁ！？

・・・冒頭でも書きましたが、初めて見る関数は慎重に吟味しましょう。

#LEVEL4(おまけ)
phpじゃないです。DB周りのお話。

詳細は省きますが、過去に突き当たった壁をいくつか紹介します。
・大量のデッドロック
⇒作成した処理以外のサービスからの書き込みを考慮していなかった。

・レプリケーションの遅延
⇒テスト環境でマスタとスレーブまでちゃんと用意していなかった。

・想定より処理が5倍以上遅い
⇒大規模データを扱う際は、WEBサーバとDBサーバ間の距離が離れているだけで、トータルの処理時間にかなりの差が出た。
また、外部のサーバからマウントしてデータを扱うという環境でテストしていなかった。

などなど・・・

#まとめ(というか教訓)
・本番環境と開発環境はなるべく近づけましょう。
・やったことないことをやる際はこれでもかってくらい慎重に進めましょう。
jQueryで実装するページトップへ戻るボタン

jQueryでトップへ戻るボタンを実装したので備忘録として書きます。　
この記事のコードをコピペすれば誰でも実装できるはず！

##html
```html
<button class="sticky_button">
 <a href="#contact">追従BUTTON</a>
</button>
```
HTMLはこれだけです。デザインに応じてaタグの中身を変更しましょう。

##css
```css
body{
 background: linear-gradient(-225deg, #2CD8D5 0%, #C5C1FF 56%, #FFBAC3 100%);
 height:3000px;
  
}
.sticky_button {
 bottom: 30px;
 display: none;
 position: fixed;
 right: 20px;
 z-index: 9999;
}
```
buttonタグのclass(.sticky_button)に表示する位置を指定しています。
今回はページ全体の右下部分に表示します。
※bodyのスタイルはわかりやすいように記述しているだけなので、適宜削除してください。


───────
##script
```js

$(document).ready(function () {
      var fixedElm = $('.sticky_button');//.sticky_btnを変数に代入
      var indicationPosition = 500;//要素が消える位置を指定する。
      var fixedHeight = fixedElm.height();//変数fixedElmの高さを取得
      $(window).on('scroll', function () {//scrollしたときにイベントが発火
        var sc = $(this).scrollTop();
          if($(window).scrollTop() > indicationPosition) {//もし、取得したスクロール位置がindicationPositionよりも大きい時
            fixedElm.fadeIn();
          } else {
            fixedElm.fadeOut();
          }
      });
      $(fixedElm).on('click',function(){//fixedElmを押した時にイベント発火
        $('body, html').animate({ scrollTop: 0 }, 500, 'swing');
        return false;
      });
    });
```
jQueryは直接コード部分に解説を記述しました。


※必ずjQuery本体をCDNなどで読み込んでください！

```html
 <script src="https://code.jquery.com/jquery-3.3.1.js"></script>
```


##まとめ
なるべく簡潔に記述することを意識しました！　　
色々な書き方があるので、迷うこともありますが実装する状況に合わせて最適な記述方法ができるようになりたいと思います！
もっとこうしたこうがいいよー！などご意見いただけたら嬉しいです！
NuxtjsのcomponentsでのAPI読み込み

#はじめに
NuxtjsのcomponentsでのAPI読み込みに苦労したので復習がてらに置いておきます。

#問題

```vue:/components/hoge.vue
<template>
 <div v-for="hoge in hoges" :key="hoge.id">
  <h1>{{ hoge.name }}</h1><!-- 挙動としてはここで名前が表示されてほしい -->
 </div>
</template>
<script>
export default {
 async asyncData({ $axios, store }) {
  const hoges = $axios.$get(`/api/hoge`).then((res) => res.data)
 }
}
</script>
```

といったコードを書きました。
しかし、どうやらNuxt（Vue？）の性質上、layoutやcomponentsでは`asyncData`が動かない模様・・・

#解決策
一つとしては`props`で値を渡してやるのもいいと思いますが、headerなど全ページ表示されるのに`props`を書くのはあまりにも汚いし、めんどくさい
なので別の方法にしました。

#mounted
mountの説明はまた別にしようかな（ネタがなくて困ってる。）

```vue:/components/hoge.vue
<template>
 <div v-for="hoge in hoges" :key="hoge.id">
  <h1>{{ hoge.name }}</h1>
 </div>
</template>
<script>
export default {
 data (){
  return {
   hoges: []
  }
 }
 async mounted() {
  this.hoges = await this.$axios.$get(`/api/hoge`)
                         .then((res) => res.data)
 }
}
</script>
```
とこのように、かけば`components`上でも`layout`上でもAPIの読み込みが可能なようです。
素晴らしい

#まとめ
書くこともネタもない！
createdとmountedの違いもイマイチわかってない！！！
わかったらまた復習がてらに書きます。
2019年を振り返って

#2019年を振り返って

皆さん、こんばんわ。
2019年も残りわずかとなりました。
今年一年を振り返ってどんな一年間だったでしょう。
今回は2019年どんなアプリが流行ったか紹介と思います。

##アプリダウンロードランキング
日本のランキングではなく、世界でのランキングになります。
日本では全く流行ってないものも多々ありました。

1位　　Facebook Messenger(アメリカ)
2位　　Facebook(アメリカ)
3位　　WhatsApp Messenger(アメリカ)
4位　　TikTok(中国)
5位　　Instagram(アメリカ)
6位　　SHERE it(中国)
7位　　Likee(シンガポール)
8位　　SnapChat(アメリカ)
9位　　Netflix(アメリカ)
10位　 Spotify(スウェーデン)

こんな感じでした。

1～3位とんで5位が『Facebook』ということになります。
**アンビリーバブルや…**
Facebookは実名ということもあり、日本では勢いがないように感じますが、世界的に使われているSNSというとやはりFacebookということになるでしょう。
また、私個人としては6位「SHERE it」、7位「Likee」は全く知りませんでした。
調べてみたところ
「SHERE it」はファイル共有アプリみたいなもののようです。通信設備やWi-Fiが整っていない新興国で流行っているとのこと。
「Likee」は簡単に動画を編集して投稿できるようなアプリみたいです。顔に耳を付けれたり、背景を変えたりできるやつですね。日本だとSNOWみたいなアプリと言えば伝わりますかね。
10位まで紹介しましたが、実はこのランキングの順位は2018年とほとんど顔ぶれが変わっていません。
7位の「Likee」だけ今年ランクインしました。
基本的に順位の変わらないランキングに食い込んでくるということは、何か選ばれる理由があるのだと思います。
そういった特徴を吸いあげて今後に活かしたいものですね。
**このアプリ、要チェックや！**

#終わりに
改めて調べてみて、日本で流行っているアプリが世界で流行っているわけではないのだなと分かりました。
普段AppStore(筆者はiPhoneユーザー)で確認するのは「なんか面白そうなゲームねぇかなー」でしたが、ランキングにも目を向けてみようかなと思いました。
ちなみに途中に某バスケ漫画のキャラクターを入れてみました。
間(相田)彦一なんちゃって…
色々と勢いで書いてるのでご容赦ください。
とても短いですが以上です。

(ちゃんと調べたつもりですが上のランキング間違ってるよ！という方は教えてください。）
laravel-adminを使って学んだこと

Laravelで簡単にログ機能つきの管理画面が作れるlaravel-adminですが、これを使って業務アプリを作っている時に色々とカスタマイズしなければならない場面があり、中身をちょこっと調べたのでまとめてみたいと思います。

https://github.com/z-song/laravel-admin

## こんな方向け
Laravelで管理画面を作っている
フォームインプット系の便利なライブラリを探している
とりあえずjQueryで使えるフロントのパーツを探している

jQueryとかうっ、、、ってなる方は微妙かもしれません(笑)

## 便利なライブラリ

### Select2(便利にカスタマイズできるselectbox)
https://github.com/select2/select2

一番便利だと思ったのがこれ。
selectboxですがテキストを入力できるようになっていて、選択肢の中から文字列が含まれるものでフィルタしてくれる機能がついています。
それ以外にもカスタマイズがいろいろできるようになっていて便利です。


### x-editable(Inline edit用)
https://github.com/vitalets/x-editable
edit画面に画面遷移せずに簡単なedit処理ができるパーツです。


### AdminLTE
https://adminlte.io/

管理画面のUIテンプレート。
上記サイトで探してみると、今どきのVueやReactなどを使って作られたテンプレートも販売されているようです。

オーソドックスだけど作るのが大変なパーツは、上記サイトから入手してカスタマイズするのもいいかもしれません。


### Pjax(jQuery-pjax)
https://qiita.com/kamem/items/b0c8f69044556865027f

恥ずかしながら、laravel-adminを使うまでPjaxの存在を存じ上げませんでした。
(PushState & Ajax)
画面遷移をせず、不要なパーツを読み込みする必要がないのは便利ですが、最近はSPAフレームワークで十分な気がしています。

jQuery-pjaxの他に、barba.jsというライブラリもあるみたいです。
https://barba.js.org/docs/v2/user/


メリークリスマス。

これからはReactやVueを頑張ります。
Glideを使ってローディングgifを表示する(kotlin)

#Glideとは？
android studioで使える画像読み込みライブラリ。
他にもpicasso, Universal Image Loaderとかがある。自分はpicassoとGlideしか使ったことがないが多分この2つが一番有名だからこれ使っとけば困ることはないだろう。

Glideの詳細： https://github.com/bumptech/glide

#今回やること
・Glideで画像のローディングgifを表示させる

表示させる画像はLorem Picsumからお借りした。
Lorem Picsum : https://picsum.photos/
URL入れるだけで画像のサイズを指定できるLorem Picsum便利でいい！！

####なんでGlide?
今まではpicassoを中心に使ってたが、picassoではgifを表示させることができなかった。そこでpicassoより高機能と言われてるGlideを使ってgifを表示させようと思った。

#実装
###ライブラリを導入
※2019年12月のときの最新バージョン
適宜githubから最新バージョンをコピペすればよい
まずGradleのdependencies に以下をに追加する

```:build.gradle
dependencies {
  implementation 'com.github.bumptech.glide:glide:4.10.0'
  annotationProcessor 'com.github.bumptech.glide:compiler:4.10.0'
}
```
###マニュフェスト設定
インターネットの画像を表示させるのでインターネットを許可する必要がある。これ忘れるとurl入れても表示されない
android manifestの適当な場所に以下を追加

```:AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
```

#基本的な使い方
```kotlin:MainActivity.kt

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        /// load に表示したいURLを入れてintoにimageViewのIDを入れる
        val url = "https://i.picsum.photos/id/777/400/500.jpg"
        Glide.with(this).load(url).into(imageView)
    }
```

with( )のなかにはアクティビティーを入れる。fragmentで使う場合はそのフラグメントを入れればよい。picassoと似た書き方だがアクティビティーやフラグメントが必要となる所が違う。

### プレースホルダ
```kotlin:MainActivity.kt

val url = "https://i.picsum.photos/id/777/400/500.jpg"
Glide.with(this).load(url).placeholder(R.drawable.ic_launcher_foreground).into(imageView)
```
placeholder( )を使うことで、load( )の画像が表示されるまでに表示しておくプレースホルダを入れることができる。

#gifを表示させる
###rawフォルダ作成
gif画像を入れるrawフォルダを作成する
android studio でresフォルダの下に新規リソースディレクトリを選択し、以下のようにしてrawフォルダを作成
この中に表示させたいgifを入れる
<img width="610" alt="キャプチャ.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520167/f4b97878-7f6a-8f0d-5abd-88a3f8295d80.png">

###gifを表示
```kotlin:MainActivity.kt

        Glide.with(this).load(R.raw.simple_circle).into(imageView)
```
とりあえずこれでGlideを使ってgifの表示ができる
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520167/82dcdbd8-661e-8ee6-5acb-a6c7c188294d.jpeg" width =300>

##プレースホルダにgifを表示
今回は画像のローディングに使いたいのでplaceholderにgifを表示したい

ここで注意すべき点がGlideのplaceholderにgifを入れてもただの画像と認識され、gifとして表示されないところだ。せっかくローディングにgif表示しようと思ってplaceholderにgifを入れてもgifが動かない...なんてことになる。そこで以下のように書けば良い。

```kotlin:MainActivity.kt
Glide.with(this).load(url)
            .thumbnail(Glide.with(this).load(R.raw.simple_circle)).into(imageView)

```
thumbnail( )というものを使ってもう一度Glideのload( )でgifを表示させる。
これでプレースホルダにgifをいれローディングにgifを表示できるようになる。

---

**画像のロード中...**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520167/82dcdbd8-661e-8ee6-5acb-a6c7c188294d.jpeg" width =300>

**画像のロード終了**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520167/ccd8e3c3-a2a7-ee1b-3c03-eccf1a9a6adb.jpeg" width =300>
VBScript Twitterの検索で使う Since Untilの日付をクリップボードに作り出すScript

#Twitterの日付検索の文字列が面倒
`Since:2019-01-01 Until:2019-12-31`はUntilをUntillにしたりSinceをSinceにしたり日付を間違ったりします
そこでVBSで作り出してクリップボードにコピーさせ、それを貼り付けるScriptを作りました

#コードと使用方法

##コード

```vb
Const SinceDate = "2019/05/01" '開始日 yyyy/mm/ddの形で入力
Const UntilDate = "2019/05/04" '終了日 yyyy/mm/ddの形で入力
Call Main
Sub Main()
Dim Dt, Dt2,str
Dt = Cdate(SinceDate)
Dt2 = Cdate(UntilDate)
Str = "Since:" & dateformat(dt) & "  Until:" &  dateformat(dt2)
PutInClipboardText(str)
End Sub
Function dateformat(vardate)
Dim d
Dim strY , strM , strD
d = Cdate(vardate)
if len(cstr(month(d))) = 1 then 
strM = cstr("0" & month(d))
else
strM = Cstr(Month(d))
end if
if len(cstr(day(d))) = 1 then 
strD = cstr("0" & day(d))
else
strD = Cstr(Day(d))
end if
dateformat = Year(d) & "-" & strM & "-" & strD
End Function
Function PutInClipboardText(str)
'http://osanai.org/47/
    Dim cmd
    cmd = "cmd /c ""echo " & str & " | clip"""
    CreateObject("WScript.Shell").Run cmd, 0
End Function
```

##使用方法
まず Win+R Run as を起動し `Notepad /a C:\hoge\hoge.vbs`　といれてコードをコピペします。
日付を変えます。
保存します。Ctrl+ Sで保存し就留させないようにします。
ダブルクリックして起動します。
検索欄でCtrl+vで日付が貼り付けられます。あとはスペースをあけて From:などを追加します。


#ただしマルウェア扱いされる恐れあり
途中でcmdを呼び出すのでマルウェア扱いされる場合があるので注意してください。
プログラミング経験0から2年間で学んだ運用のいろは

この記事は<a href="https://qiita.com/advent-calendar/2019/ielove">いえらぶ Advent Calendar 2019</a> 18日目の記事です。

# はじめに
Qiita初めて投稿します！

簡単に自己紹介すると、主にCLOUDサービス内の一機能の開発、運用を担当しています。
開発以外にも利用率計測したり、要望をヒアリングしたり、思い出すと色々してきました。
使用言語：PHP、JS(ほぼjQuery)、MySQLとか。Node.Js勉強中。
IDE：PhpStorm

# 概要
入社するまでプログラミングなんてやったことありませんでした。
(ましてや、ファーストキャリアは営業だろうとなんとなく思ってました。)
そんな僕が、プログラミングを始めて、運用を担当することになり、2年ほどで感じたことを書いていきます！
当たり前だよ！って思ったら読み飛ばして下さい。少しでもためになることがあれば嬉しいです。

# 運用のいろは
## 分岐を少なくする
調査でソースコードを読んでいた時のこと
「ここで分岐してるのか、その中にもう一つ分岐があるな、またその中で関数使ってる、関数の中身はっと、、、、、また分岐してる！！！」
分岐が多い分だけ、読むのに時間がかかります。あと読む気をなくします。。
せめて関数にまとめましょう。まとめたうえで命名は適切に。

## ドキュメントを残す
ER図、関数ごとの仕様書、テスト仕様書、機能のよくある質問、などなど目的に応じて整えていきましょう。
あとは「特殊仕様」。ないのが理想ですが、追加されたらドキュメントも更新を。
わりと最近、重要性に気付き始めました。ちゃんと書きます(自戒を込めて)

## ちゃんとコードフォーマット
アジャイルの開発だと、数年前のソースコードとか当たり前に残ってます。
そうするとフォーマットのルールが違うなんてこともしばしば、、
ほんのちょっとのボーイスカウト精神が、後々誰かを笑顔にします。

## コードレビューを「する」
コードレビュー「されて」受けた指摘を直すことで、もちろん身になります。
それ以上に、ソースコードをレビューしてみてください。
「そんな書き方があるのか！」とかとにかく気づきが多いです。めちゃくちゃ勉強になります。

## 要望の真の目的を理解する
何十件とあがってくる要望すべてに応えることはほぼ不可能です。
目的を把握したうえで、本当に必要な機能なのか検討する、実装しないなら別のやり方を提案していきましょう。

## 優先順位をつける
機能を担当してると、要望、質問、時にはバグの報告などが上がってきます。
内容によって、すぐやらないとダメ、明日までに調べる、今週中くらいでOKなど優先度は様々です。
どれをどの順番でこなすかを逐一判断して、途中で作業を移る時はどこまでやったかメモしておくと、戻る時役に立ちます。
人は忘れる生き物って誰かが言ってました。

# 終わりに
最初はとにかく分からないことだらけで大変でしたが、今ではすっかりエンジニア楽しんでます。
色々あげてたら、運用だけじゃなくて、仕事の進め方みたいなことも混ざってますね。
また、CLOUDサービスという特性上、読んでいただいた方によって当てはまらないこともあると思います。
少しでもためになることがあれば嬉しいです。

意見とか、異論反論、感想、などコメントいただけると嬉しいです。
最後までお読みいただきありがとうございました！

---
今はAPIの開発をしてるので、追々投稿しようと思います。
Cookieの仕組み

[CBcloud Advent Calendar 2019](https://qiita.com/advent-calendar/2019/cbcloud)の24日分の記事になります。

# Cookieとは
簡単に言えば、Cookieとはウェブサイトの情報をブラウザで保存する仕組みです。
HTTPのヘッダーをインフラとして実装されていて、最新の仕様書は[RFC6265](https://tools.ietf.org/html/rfc6265)です。

# 主な流れ
1. **ブラウザ側**
    - ウェブサイトに向けてHTTPリクエストを送信する
1. **サーバー側** 
    - HTTPヘッダにSet-Cookieヘッダをセットしてレスポンスを返す
       - `Set-Cookie: LAST_ACCESS_TIME=15:30`
1. **ブラウザ側**
    - レスポンスの`Set-Cookie`ヘッダの値を保存する。
    - 次回アクセス時には次のような形式でリクエストを送信する
        - `Cookie: LAST_ACCESS_TIME=15:30`

# なにが嬉しいのか
以上のような非常に単純なやりとりを経ることによって、サーバー側はこのクライアントが最後にアクセスしてきた時間を知ることができます。
HTTPはステートレスを基本とした仕組みですが、Cookieをうまく使うことによってステートフルであるかのようなアプリを作ることができます。
もちろんブラウザ上でもJavaScriptを通して取得することが可能です。適当なウェブサービスで開発者ツールを開き、下記のコードを打てばString型でCookieが格納されていることが分かります。

```javascript
console.log(document.cookie)
```

# アンチパターン
便利な機能ですが、いくつかの制約からアンチパターンももちろん存在します。
　まず永続性の問題です。ブラウザの設定によってはサーバーからの`Set-Cookie`ヘッダを無視することもありますし、履歴消去などで一緒に削除されることもよくあります(実際消した事ある人も多いはずです)。
　容量の問題もあります。最大容量は4kbです。通信のたびに毎回HTTPのヘッダに付与されるので単純に通信量が増大します。
　セキュリティにも問題があります。HTTPは常に平文で送受信されるため、クリティカルな情報を与えてしまうと漏洩の可能性があります。
また、SSL/TLSを利用していたとしてもユーザーから自由に見たり、編集したりできることも問題で、ログインに必要なIDなど書き換えられると誤作動につながるような情報を入れるのにも適しません。

# 制約を与える
Cookie周辺で使えるHTTPヘッダーは、`Set-Cookie`と`Cookie`以外にもRFCによって定められたいくつかのヘッダーが存在します。
- `Expires,Max-Age` クッキーの寿命を設定する
- `Domain` ブラウザからCookieを送信する対象のサーバーを設定する
- `Path` ブラウザからCookieを送信する対象のサーバーのパスを設定する
- `Secure` https以外での通信のときはサーバーへCookieを送信しない
- `HttpOnly` JavaScriptエンジンからCookieを隠すことができる(上記のように`document.cookie`で取れなくなる)。

# Cookieでのセッション管理
Web関係の入門書などでよくサンプルとして取り上げられる認証の仕組みとして、Basic認証とDigest認証がありますが、今現在もっともよく使われている認証の仕組みはCookieを用いたセッション管理だと思います。以下にCookieを用いたセッション管理の流れを書きます。

## セッション管理の流れ
1. ブラウザ側からIDとパスワードを送信します。
    - 注意点： 直接送信するため、SSL/TLSは**必須**です。
1. サーバー側ではIDとパスワードで認証しセッショントークンを発行します。サーバー側はそのトークンをRDBなりKVSなりに保存します。そして、`Set-Cookie`にトークンを付与させてブラウザにレスポンスを返します。
1. ブラウザは次回以降のアクセスでは`Cookie`ヘッダーにサーバーから発行されたトークンを付与してリクエストを送ることによって、サーバーからログイン済のユーザーであることが識別できるようにします。

以上が簡単なセッション管理の仕組みになります。時間経過による自動ログアウトなどのよく見る仕組みは、上記の`Expires`や`Max-Age`ヘッダを使うことによって簡単に実装できることが分かります。

# 例： Ruby on Railsでの署名付きCookieによるセッションデータの保存
上述のような、RDBなどにセッション管理用のテーブルを用意しユーザーの認証をする素朴な実装は悪くはないのですが、実はRailsなどのようなWebアプリケーションフレームワークは大抵の場合セッションストレージ機能を備えており、自前で実装する必要はないことがほとんどです。
Railsのセッションストレージ機能で用いられる[ActionDispatch::Sesstion::CookieStore](https://api.rubyonrails.org/classes/ActionDispatch/Session/CookieStore.html)は、`delete_session`と`load_session`と`new`の３つしかメソッド持ちませんが、ブラウザに対して改ざんされないように電子署名付きのCookieを送信します。
ブラウザ側がそのCookieをRails側に再送すると、Railsは署名を確認します。ブラウザは何も特別なことはしておらず、署名も確認もRails側で行います。
この仕組みを用いることによるサーバー側のメリットは、データを保存する仕組みが必要ない点です。マイクロサービスにおいても、暗号化の仕組みだけ共通化しておけば、別にデータストアを立てる必要なくセッションデータを読み書きできるようになります。

# おわりに
今回はサックリとまとめてしまいましたが、Cookieの歴史はWebセキュリティの歴史といってもいいほど試行錯誤がつまっており、Webアプリ作ってご飯を食べているWebエンジニア各位は一度しっかり時間を確保してCookieの仕組みなどを勉強してみるといいと思います。

# 参考図書
- [Real World HTTP](https://www.oreilly.co.jp/books/9784873118048/)
- [ActionDispatch](https://api.rubyonrails.org/classes/ActionDispatch.html)
- [RFC6265（日本語訳）](https://triple-underscore.github.io/http-cookie-ja.html)
C++の型推論や範囲ベースforを使って保守性と可読性を上げたプログラムを書こう

#どうしてこの記事を書くことのしたのか
範囲ベースforや型推論によってC++の組み込みやすさや演算速度とC#並みの可読性と保守性の高いプログラムを両立して書くため。
#どうして可読性が重要なのか
C++でプログラムを書くとどうしても可読性が低いプログラムになり、プログラムが大きくなればなるほどソースがスパゲッティになる場合が少なくない。それをコメントばかりで埋めようとするとそれは後からの保守作業が最悪になることが多い。だからプログラムを後から使う人のためにもスパゲッティプログラムを書かないようにすることを努めるべきだ。
#範囲ベースforとは
for(auto & refrange:initrange)の文である。これによりfor文より可読性の高いコードを生産できコメントも減らすことができる。
#型推論とは
所謂autoである。コンパイル時に型が決まるので実行時の速度を変えず可読性の高いコードが作られる。特に有用なのが以下のようなとき
hogehoge< hugahuga< std::string>,int> A = new hogehoge< hugahuga< std::string>,int>
auto A = new hogehoge< hugahuga< std::string>,int>
こちらは[C#](https://qiita.com/Nossa/items/e5e50d2fc1ae8b3e2389)でも言及されている方法。型推論をオススメする理由をお分かりいただけただろうか。あくまで可読性の高いコードを作るためにautoを使うので、型が分からない物に使えば逆効果になります。
#デイレクトリが汚染されていてはどんなにコードがきれいでも意味がない
よくデイレクトリの中が汚い場合もありますが、それは綺麗にすることが重要です。例えば外部テキストデータを50個ある時そのテキストデータ中からcppファイルを探せるのかっていう話です。多分無理だと思うので、デイレクトリを作ってそこにテキストデータを入れておいてください。
エンジニアに気持ち良くコーディングしてもらうために実施している11の施策

# この記事の対象者
・開発会社の経営者（CEO/CTO）
・エンジニア組織のリーダー（VPoE/TechLead/Lead Engineer）
・その他のエンジニアに気持ち良くコーディングしてもらいたい人たち

# 記事の投稿者
iOS/Androidアプリを中心としたシステム開発会社の経営者です。最近までバックオフィスメンバーが皆無のエンジニアだけの組織で、「エンジニアに気持ち良くコーディングしてもらうこと」を目的として、過去にやって来たことをまとめました。

# エンジニアに気持ち良くコーディングしてもらうために実施している11の施策
## 1. ディスプレイを用意しよう
コーディングする画面、ターミナルを触る画面、検索する画面が物理的に分かれていると生産性が上がる。1台で充分と言う人もいれば2台欲しいと言う人も。

## 2. 良い椅子を用意しよう
コーディングに詰まっている時に座り心地が悪いと気が散ってしまう一つの要因。長く座っても疲れない椅子を用意しよう。当社の椅子は全てHerman Miller社のセイルチェア。

## 3. 統合開発環境（IDE）へ投資しよう
こだわりのエディターがあるエンジニアもいるものの、特にこだわりがないようであればJetBrains社のIntelliJ IDEA Ultimateを契約しよう。主にコーディングしている言語以外の言語でコーディングする時はコード補完、Lint関連の機能は重宝するはず。

## 4. 重要な技術書は１冊以上購入しよう
エンジニアが増えれば増えるほど、その本を必要とするタイミングが重複することも多い。先人たちの知識には喜んでお金を払おう。

## 5. 関わりがありそうな技術書は現時点で読まなくても（決裁権者が進んで）購入しよう
今現在必要が無くとも、関わりがありそうな技術書は現時点で読まなくても、いつか必要となる可能性があれば購入しよう。そのいつかが訪れた時、「この本が今すぐ欲しい！無いと困る！」という未来を少しでも防ぐため。また、周辺知識が増えるのは個々の仕事、組織全体の仕事の領域が増える。ここで重要なのは技術領域のことがある程度分かるようであれば決裁権者が進んで購入すること。組織全体への重要度の説明責任の敷居を低くすることで、関わりがありそうな技術書の購入を促す。結果読まなかったとしても、エンジニア組織を経営する上での必要な経費と割り切る。

## 6. コードレビュー文化を根付かせよう
相互にコードレビューを実施しよう。コードレビュー時に指摘された際の謝罪を禁忌としよう。エンジニア組織のリーダーが実践できると、エンジニア同士でのマウンティングがなくなり、コードレビューの目的であるより良きコードにするということに組織全体で集中できる。他にも当社では実装経験が浅いメンバーが開発する研修プロジェクトでは三段階のコードレビューを実施している。多段階のコードレビューをすることで、前工程のコードレビュワーが後工程のコードレビュー内容を確認し、コードレビュー自体のトレーニングにもなっている。

## 7. カンファレンスのスポンサーになろう
開発言語、開発コミュニティへの感謝とこれからの発展を祈念して、活動をサポートしよう。スポンサーだけでなく、運営もサポートできればなおのこと。

## 8. 社内の勉強会を開催しよう
飽きないように勉強会のやり方・テーマを変えながら開催しよう。読書会、LT会、アウトプット共有会などを実施してみよう。

## 9. 社外の勉強会に参加しよう
やたら滅多に行くことを目的とすることはないが、年間に数回は参加しよう。その勉強会で喋ることができるのであれば尚更。そこでの出会いも意外に繋がることがある（仕事であったり、コーディングの相談できる相手としても）。

## 10. 視座を上げるために外部講師を招いた講演会を開催しよう
社内だけのエンジニアヒエラルキーに囚われないように、外部講師を招いた講演会を開催することでエンジニア組織全体の視座を上げて行こう。常に新しい発見がある組織であることを維持しよう。外部講師には講演料を払うことを前提とする。

## 11. 社内で必要そうなシステムを勝手に作るエンジニアをあたたかく見守ろう
当社では草の根活動と呼んでいるのだが、社内で必要そうなシステムを勝手に作るエンジニアがいた場合あたたかく見守ろう。何かする必要はない、何もしないことこそがサポートになる。必要は発明の母であり、自発的に何かが生まれる組織を作って行こう。
GoとGoogle Homeでガチでメリーさんの電話を実装してみました。

24日目で思ったより位置情報で遊べなかったので、位置情報を使ったネタを考えてみました

24日目
https://qiita.com/usk81/items/3b1357de73d99bb13781

# つくったもの

https://github.com/usk81/til/tree/master/go/marys-call

# ネタ

位置情報を使ったもの...
メリークリスマス...
メリー...
メリー...

( ﾟдﾟ)ﾊｯ! メリーさん!!

というわけで、メリーさんの電話をリアル実装してみました。

# 仕様

1. 最寄り駅からスタート
2. Google Home経由で連絡を取る
3. 途中で途中経過を伝える
3. 家についたらワンコール
4. 次の瞬間、「貴方の後ろにいるの」
5. 「ジョークですよｗ」で終わり

距離に関わらず同じ感覚でGoogle Homeが話すと面白くないので、人間の走る速度で最寄り駅から現在地を移動させて、距離に応じて話す内容を変えるようにしました。

人間が歩く速度（約2〜4.8km）だとゆっくりすぎるので、ウサインボルトが走る速さにしました。


## 最寄り駅の取得

駅データ.jpで日本の駅の位置情報を取得しました
http://www.ekidata.jp/

参考：
https://qiita.com/dorarep/items/af8c168a24a3ba2c468a

# コード

メイン処理は至って簡単です。
1秒間隔で時速に応じて距離を縮めていくだけです。

googlehome関数で5秒待っているのは、
待たないとGoogle Homeにリクエストが渡ってから話し終える前に次のリクエストが渡って中断してしまうのを防ぐためです。

```go:main.go
package main

import (
	"context"
	"errors"
	"fmt"
	"os"
	"strconv"
	"strings"
	"time"

	"github.com/ikasamah/homecast"
)

// km/h
const speed = 44.6

func main() {
	l, err := env2Location()
	if err != nil {
		panic(err)
	}
	ss, err := getStationsFromCSV("station.csv")
	if err != nil {
		panic(err)
	}

	_, dist, err := nearestStation(l, ss)
	if err != nil {
		panic(err)
	}

	ms := speed * 1000.0 / (60.0 * 60.0)

	googlehome("私、メリーさん。今、近くの駅にいるの", "ja")
	time.Sleep(5 * time.Second)
	var flg bool
	for {
		switch {
		case dist <= 0:
			googlehome("私、メリーさん。今、あなたのお家の前にいるの", "ja")
		case dist <= 50 && !flg:
			googlehome("私、メリーさん。今、あなたのお家の近くにいるの。", "ja")
			flg = true
		}
		if dist <= 0 {
			break
		}
		time.Sleep(1 * time.Second)
		dist -= ms
		fmt.Println(dist)
	}
	googlehome("私、メリーさん。今、あなたの後ろにいるの。", "ja")
	googlehome("Hahaha, It's joke!!", "en")
}

func env2Location() (loc Location, err error) {
	strLoc := os.Getenv("Location")
	if strLoc == "" {
		err = errors.New("Can't get location")
		return
	}
	ls := strings.Split(strLoc, ",")
	if len(ls) != 2 {
		err = errors.New(strLoc + " is invalid location")
	}
	lat, err := strconv.ParseFloat(ls[0], 64)
	if err != nil {
		return
	}
	lng, err := strconv.ParseFloat(ls[1], 64)
	if err != nil {
		return
	}
	return Location{
		Lat: lat,
		Lng: lng,
	}, nil
}

func googlehome(msg, lang string) {
	fmt.Println(msg)
	ctx := context.Background()
	devices := homecast.LookupAndConnect(ctx)
	for _, device := range devices {
		device.Speak(ctx, msg, lang)
	}
	time.Sleep(5 * time.Second)
}
```

距離の取得は球面三角法を使用しました。

参考：
https://qiita.com/chiyoyo/items/b10bd3864f3ce5c56291

```go:distance.go
package main

import (
	"math"
)

const radius = 6378137.0

type Location struct {
	Lat float64 `json:"lat"`
	Lng float64 `json:"lng"`
}

func distance(from, to Location) float64 {
	fx := deg2rad(from.Lat)
	fy := deg2rad(from.Lng)

	tx := deg2rad(to.Lat)
	ty := deg2rad(to.Lng)

	averageLat := (fx - tx) / 2
	averageLon := (fy - ty) / 2

	return radius * 2 * math.Asin(math.Sqrt(math.Pow(math.Sin(averageLat), 2)+(math.Cos(fx)*math.Cos(tx)*math.Pow(math.Sin(averageLon), 2))))
}

// deg2rad transforms radical value
func deg2rad(r float64) float64 {
	return (r * math.Pi) / 180.0
}
```
【Vue.js】Vue-Routerを使うとURLに出てくる`#`を消す方法と注意点

## はじめに
vue-routerを使用しているとURLにデフォルトで出てくる`#`を消す方法についてまとめました。

[公式ドキュメント](https://router.vuejs.org/ja/guide/essentials/history-mode.html#%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%81%AE%E8%A8%AD%E5%AE%9A%E4%BE%8B)

## 環境
```yaml
OS: macOS Catalina 10.15.1
Vue: 2.6.10
vue-cli: 4.1.1
vue-router: 2.6.10
```
## 結論：ヒストリーモードにする
`src/router.js`に以下を追記する。

```javascript:src/router.js
const router = new VueRouter
  mode: 'history',  //追記
  routes: [
  ...略
  ]
})
```

## 注意点と対処法
これで`#`自体は消えてくれるのですが、[公式ドキュメント](https://router.vuejs.org/ja/guide/essentials/history-mode.html#%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%81%AE%E8%A8%AD%E5%AE%9A%E4%BE%8B)に注意点が書かれています。

> history モードを使用する時は、URL は "普通" に見えます e.g. http://oursite.com/user/id。美しいですね!

> しかしながら一点問題があります。シングルページのクライアントサイドアプリケーションなので、適切なサーバーの設定をしないと、ユーザーがブラウザで直接 http://oursite.com/user/id にアクセスした場合に 404 エラーが発生します。

※各サーバー毎の処理方法は[公式](https://router.vuejs.org/ja/guide/essentials/history-mode.html#%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%81%AE%E8%A8%AD%E5%AE%9A%E4%BE%8B)に書かれているので、当記事ではnginxの設定のみ抜粋します。

### nginxでの対処法
以下を記述。
これにより、もし**404 Not Found**になったら`index.html`が読み込まれます。

```
location / {
  try_files $uri $uri/ /index.html;
}
```

## さらに注意点
このままでは、サーバー側が一切**404 Not Found**を表示してくれなくなるので、代わりにクライアント側で表示する必要があります。

```javascript:src/router.js
import NotFound from './components/NotFound.vue' //追記

const router = new VueRouter
  mode: 'history',
  routes: [
    { path: '*',　//ここから3行追記
      name: 'NotFound',
      component: NotFound },
  ]
})
```

```vue:NotFound.vue
<template>
  <div>
    <h1>Oops!!! Page Not Found</h1>
  </div>
</template>
```

## おわりに
最後まで読んで頂きありがとうございました:bow_tone1:

どなたかの参考になれば幸いです:relaxed:

## 参考にさせて頂いたサイト（いつもありがとうございます）
- [HTML5 History モード | Vue Router](https://router.vuejs.org/ja/guide/essentials/history-mode.html#%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%81%AE%E8%A8%AD%E5%AE%9A%E4%BE%8B)
- [かゆいところに手が届くvue-routerの機能 - Qiita](https://qiita.com/nishinoshake/items/9ce7d6a04ffb82755ae1)
【Cocos2d-x】プロジェクト全体でアンチエイリアスを無効にする

## 環境
cocos2d-x 3.17.2
C++

## アンチエイリアス無効化

cocos2d-xではデフォルトでアンチエイリアスが有効になっていて、無効にするためには

```cpp

auto sprite = Sprite::create("image.png");
sprite->getTexture()->setAliasTexParameters();
```

このように`Sprite`や`Label`のインスタンスを作る度に`setAliasTexParameters()`を呼んであげる必要があります。
（※ただ同じ画像だとアンチエイリアスの設定が共有されるっぽい。）

ドットゲーを作るときなどはいちいち呼ぶのは面倒なのでアンチエイリアス無効をデフォルトにしたいですが、どうやらそういった機能は用意されていないようです。

`Sprite`等を継承してコンストラクタで`setAliasTexParameters()`を呼ぶというのもアリですが、
今回はプロジェクト内のcocos2d-xのソースを直接弄ってこれを解決しようと思います。

## ソースを書き換える

プロジェクトフォルダ内の
`cocos2d/cocos/renderer/CCTexture2D.cpp`
`cocos2d/cocos/2d/CCFontAtlas.cpp`
を編集します。

それぞれクラス`Texture2D`, `FontAtlas`のコンストラクタの初期化子リストで
`_antialiasEnabled`というメンバが`true`で初期化されています。
これを`false`にしてやります。

まず、`CCTexture2D.cpp`の446行目

```cpp:CCTexture2D.cpp
, _antialiasEnabled(false)
```

に変更。

`CCFontAtlas.cpp`は54行目で同様に

```cpp:CCFontAtlas.cpp
, _antialiasEnabled(false)
```

に変更。

## 例

480×320のウインドウに
次の16×16ピクセルの画像を10倍の大きさで表示してみます。

![HelloWorld.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556054/aa7f6352-8d72-e551-c9fc-f1b4f8a3a640.png)

#### 変更前

![AliasExample 2019_12_25 22_51_19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556054/435a0f3e-4edf-29a9-166d-637116ae5e97.png)

#### 変更後

![AliasExample 2019_12_25 22_50_49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556054/a981f727-d11b-6644-7fee-056df7887aa5.png)

## その他

スプライトもフォントもドットなら、アンチエイリアス無効に加えて

```cpp:AppDelegate.cpp
glview->setDesignResolutionSize(240, 120, ResolutionPolicy::NO_BORDER);
```

のように仮想解像度を小さくしてしまうのもいいかと思います。
CPU Stolen Time について

vSphere でオンプレミス環境を構築する際、以前はサイジングはするけれど価格その他の関係でリソースを減らしたりしてどうにか予算を抑えることが結構行われていました。
その時の減らされるリソースは例えばストレージのグレードを下げる、メモリーを減らす、CPU コアを減らすなどがありました。そのようにした仮想化環境はサイジングよりもリソースが下回っているので負荷が低い時には正常に動いているのに、負荷が上がると急に性能が下がるなどの事象が発生したりするのですが、vRealize Operations などを入れていなかった場合、その原因を調べるためには事象が発生しているときに esxtop などを使って調査をしますが、CPU の場合はちょっと困ったことがあります。それが「CPU Stolen Time」と呼ばれるものです。

# CPU Stolen Time とは
CPU Stolen Time とは簡単に言うと「仮想マシンの vCPU に割当てられたリソースについて、仮想マシンが実際に CPU の処理として使用できなかった時間」のことで、仮想マシンの vCPU に対してハイパーバイザーがCPUリソースを割当てられたのに、他の処理に CPU リソースを盗まれて（stolen）仮想マシンが実際に CPU の処理として使用できたリソースが減ることがあります。つまり、物理 CPU (論理CPU) は仮想マシンからリクエストされた分仮想マシンにリソースを割り当てますが、仮想マシン側で実際の vCPU の処理として使うことができなかった分が「CPU Stolen Time」となります。つまりCPUスケジューリング競合が発生しているということになります。
CPU Stolen Time になる要因としては、仮想マシンの稼働している ESXi 上でなんらかの処理負荷（CPU 負荷の高い仮想マシンがあるなど）が高くなり、その結果そちらに CPU の処理が横取りされてしまった場合に発生します。
例として、ディスクへの I/O が高くなるアプリケーションが仮想マシン内で動作しており、仮想マシン自体でその処理への負担が非常に高くなっていたため CPU Stolen Time が発生してしまったなど、主にサイジングのミスで CPU リソースが足りなくなるなどで発生したりします。
CPU Stolen Time は、仮想マシン側で発生している状態に対し、今はどのようになっているかの結果が表示されているだけなので、この値を下げるためには仮想マシン内で発生している事象を特定し、それを適切に対応して解消しないかぎり、再度同じことが発生してしまいます。これらは、例えば仮想マシン内で発生している事象はアプリケーション処理などに起因するものならばそちらを対処する必要があり、ハイパーバイザを含めた仮想環境に起因するものの場合は、サイジングのミスで CPU リソースが必要な需要に追い付いていないなどが考えられます。
以下の絵は CPU Stolen Time のイメージです。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541683/abf8bc3a-1cce-ff20-be7f-3f7b546a0230.png)

# CPU Stolen Time を知る？
vSphere に関して CPU stoles time に関する情報は非常に少ないです。実はこの CPU stolen time については VMware vSphere ESXi 独自の話ではなく、Linux の Xen や KVM、Windows Hyper-V でも発生します。それぞれのハイパーバイザーでの stolen time 相当は以下の通りです。

+ Linux ：sar コマンドで表示される %steal 
+ Windows (Hyper-V)：パフォーマンスモニターのカウンターにある Hyper-V Hypervisor Virtual Processor\CPU Wait Time Per Dispatch が相当
+ ESXi：esxtop の %RDY が相当

[Timekeeping in VMware Virtual Machines](https://www.vmware.com/content/dam/digitalmarketing/vmware/en/pdf/techpaper/Timekeeping-In-VirtualMachines.pdf)に古いですが CPU stolen time のことが少し出ています。しかし他はなかなかまとまった情報がありません。但し、考え方はほかのハイパーバイザーと変わりませんので、理解するならそれらを参考にするのも良いかもしれません。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541683/891aa630-76d8-39cc-dcb1-d6f1f5c2065f.png)


ESXi の場合、esxtop を見て %RDY (CPU Ready) の値が高いと CPU Stolen time が発生しているので対処が必要です。具体的には CPU stolen time の値を下げる必要があり、他のホストに仮想マシンを移動させる（手動／DRSなどで）、仮想マシンのホストへの統合率を下げる、空きソケットがある場合は CPU を増強するなどが必要になります。ただ、%RDY の値があっても必ずしも直ぐに対処しなければならないということではなく、%RDY の値が極端に高く、かつ PCPU USED および PCPU UTIL の値もとても高くなっているなどいくつかの条件で判断します。このあたり、最後の esxtop をサポートするツール の [vSphere 6 ESXTOP quick Overview for Troubleshootin](http://www.running-system.com/vsphere-6-esxtop-quick-overview-for-troubleshooting/) の情報を見て判断するなどしてみてください。

# esxtop をサポートするツール
esxtop を使おうとした場合、そこに表示される数字や閾値などどのように見たらよいか悩むことがると思います。以下にいくつかご紹介しますので興味あれば見てください。

+ [vSphere 6 ESXTOP quick Overview for Troubleshootin](http://www.running-system.com/vsphere-6-esxtop-quick-overview-for-troubleshooting/)：esxtop について簡単な A4 一枚にまとめてある資料が公開されています。ここにある「vSphere 6 ESXTOP quick Overview for Troubleshooting」を見れば難解な esxtop もなんとなくわかってくると思います。
+ Virtual esxtop：[Virtual esxtop](https://labs.vmware.com/flings/visualesxtop
)Windoows から GUI で利用できる esxtopです。


文責：imaisato
Notionの更新をSlack通知する

[アルプ株式会社](https://thealp.co.jp/)でエンジニアをしています、集約のエンティティ@pictinyです。
これは[Notion Advent Calendar 2019](https://qiita.com/advent-calendar/2019/notion) 24日目のエントリです。
23日目は[Notionのブラウザ拡張](https://qiita.com/pictiny/items/6ff9e84943c8f36918bb)でした。

# Slack通知
Notionはページの更新をSlackに通知することができます。
ページ右上の`Updates`から`Connect Slack Channel`を有効にすると、Slack連携のウィンドウが開きます。

<img width="696" alt="通知1" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427952/fa93befb-1736-bc10-e053-b76ca01fcae3.png">

連携するSlack Workspaceを選択し、投稿先のSlackチャンネルを選択しましょう。
連携が完了するとインテグレーションが追加され`Updates`の内容が連携先のSlackチャンネルに流れるようになります。

# まとめ
重要なページはSlack連携しておくとよいでしょう。
Slack連携は1ページにつき1つだけなので乱用はご注意ください。

公式ドキュメントは[Integrate with Slack](https://www.notion.so/Integrate-with-Slack-46d081bdacdb4269aed1333bb195addb)にありますので、そちらもご覧ください。
OpenVINO IEPlugin.load()の実行時エラーの解決策

# はじめに
OpenVINOのハンズオンを受講したので、自宅のPCでも動作させようとしたときにハマったのでメモします。
ハンズオンはRaspberry Pi + Neural Compute Stickで行いました。(IntelCPUが必要なため)
このサイト[OpenVINOで始めるディープラーニング](http://jellyware.jp/openvino/)を参考にして手順通りに進めましたが、リアルタイム顔検出で実行時エラーに悩みました。
同じようにハマっている人の少しでも解決になればと思います。

# OpenVINOとは
OpenVINOは、エッジにおける視覚アプリケーションでコンピュータビジョンやディープラーニング推論を容易に実現するためのツールキットです。
[OpenVINO ツールキット](https://www.intel.co.jp/content/www/jp/ja/internet-of-things/solution-briefs/openvino-toolkit-product-brief.html)

# 動作環境
- MacBook Pro 2018
- macOS 10.14.6
- OpenVINO 2019 R3.1
- Python 3.7.3

# 実行時エラー
OpenVINOのライブラリでエラーが発生しています。
StackOverflowなどで検索しましたが、どれも解決しませんでした。

```python
{'data': <openvino.inference_engine.ie_api.InputInfo object at 0x1054d3578>}
<openvino.inference_engine.ie_api.IEPlugin object at 0x1054d34a8>
Traceback (most recent call last):
  File "sample.py", line 19, in <module>
    exec_net = plugin.load(network=net)
  File "ie_api.pyx", line 547, in openvino.inference_engine.ie_api.IEPlugin.load
  File "ie_api.pyx", line 557, in openvino.inference_engine.ie_api.IEPlugin.load
RuntimeError: Unsupported primitive of type: PriorBoxClustered name: fc7_mbox_priorbox
```

エラーが発生している箇所は、plugin.load()です。
モデルファイルのパスも正しく、ファイルも存在します。(何度も確認しました)
PCではFP32版を使用してくださいと記述がありましたが、FP16版にしてもエラーは変わりませんでした。

```python
# モデルの読み込み 
net = IENetwork(model='FP32/face-detection-retail-0004.xml', weights='FP32/face-detection-retail-0004.bin')
exec_net = plugin.load(network=net)
```

# 解決策
CPUを使用するときは、add_cpu_extension()で追加ライブラリが必要でした。

```python
# ターゲットデバイスの指定 
plugin = IEPlugin(device="CPU")
plugin.add_cpu_extension('/opt/intel/openvino/deployment_tools/inference_engine/lib/intel64/libcpu_extension.dylib')
```

パスは環境に合わせて設定してください。
手順通りに環境構築していれば、上記のパスになると思います。

# 参考
MacBookで内臓カメラを使用するには、下記を参考にしました。
[Mac内蔵カメラの動画をpythonでキャプチャ](https://qiita.com/seigot/items/9ae0dc3fed6d43bec828)

```python
cap = cv2.VideoCapture(0)
```

# おわりに
OpenVINOの実行時エラーが解決でき、カメラを使用したリアルタイム認識ができるようになりました。
まずは用意されているモデルを利用して、いろいろと試してみたいと思います。
PowerShellのプロンプトにカレントディレクトリ名だけ表示

PowerShell 6.2.3

デフォルトだとフルパスが表示されて階層が深くなるほど横に伸び邪魔になる。
とりあえずカレントディレクトリ名だけ表示したい。

``` powershell
PS C:\Users\******\Documents\Downloads>
```

PowerShellのプロンプトはprompt関数でカスタマイズ出来る。
PowerShell profileに書いておけば起動時に勝手に読み込まれる。

PowerShell profileのパスは＄PROFILE環境変数で参照出来る。

``` powershell
PS C:\Users\******\Documents\Downloads> $PROFILE
C:\Users\******\Documents\PowerShell\Microsoft.PowerShell_profile.ps1
```

`code $PROFILE`とかでファイルを開いて以下を書く

``` powershell:Microsoft.PowerShell_profile.ps1
function prompt {
    'PS ' + $(split-path . -Leaf) + '> '
}
```

split-pathは指定パスから特定の要素だけ取り出すコマンドレット、-Leafを指定でパスの末尾だけを取得出来る。
先頭の'PS 'は無くても良いけどPower Shellとわかるように一応つけている。

## 追記
改行パターン

``` powershell
function prompt {
    "${pwd}
[PS]> "
}
```

or

``` powershell
function prompt {
    $host.UI.WriteLine((Get-Location).Path);
    $host.UI.Write("[PS]");
    "> "
}
```

## 参考
- About Prompt
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_prompts?view=powershell-6

- About Profiles
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_profiles?view=powershell-6

- Split-Path
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/split-path?view=powershell-6

- $host.UI.WriteLine
https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.host.pshostuserinterface.writeline?view=powershellsdk-7.0.0#System_Management_Automation_Host_PSHostUserInterface_WriteLine_System_ConsoleColor_System_ConsoleColor_System_String_%20#%20https://docs.microsoft.com/en-us/dotnet/api/system.consolecolor?redirectedfrom=MSDN&view=netcore-3.1%20function%20prompt%20{%20$host.UI.Write(2,%200,%20%22[%22)%20$host.UI.Write(14,%200,%20%22${pwd}%22)%20$host.UI.Write(2,%200,%20%22]%22)%20$host.UI.Write(%22-%22)%20$host.UI.Write(2,%200,%20%22[%22)%20$host.UI.Write(10,%200,%20%22$(now)%22)%20$host.UI.WriteLine(2,%200,%20%22]%22)%20$host.UI.Write(%22[PS]%22)%20%22%3E%20%22%20}
家庭向けに小さなポータルを立ち上げる

## ことのはじまり

元々夫婦共々企業マンなので、
家庭内でやり取りするためにファイルサーバ的なのが欲しかった。

しかしながら、夫はSalesforce、妻はNotesの業務に従事した身。
実際に欲しかったのはファイルサーバというよりもポータルだった。

## 欲しいもの

- ファイル共有
- カレンダー

## 構築するもの

- Nextcloud
- Onlyoffice Document Server

docker-composeも考えたが、
本稼働と、楽という観点からsnapにします。
バックアップ等はすべてAzureまかせ。

## 準備

まずは２台のVMを立ち上げる。
弊家は自分が会社でも使っているという理由から、Azureにしてみた。
(このためにサブスクリプションを一つ切ったのは内緒)

どちらとも、Ubuntu Serverで、サイズはB1msとした。

それぞれ、

- NextCloud  -> storage-server
- Onlyoffice -> doc-server

とします。

## NextCloudの設定

```shell:storage-sever
$ sudo snap install nextcloud
```

ポートの設定。

```shell:storage-server
$ sudo snap set nextcloud ports.http=80 ports.https=443
```

Let's Encryptの設定。
これだけで終わってくれるのは嬉しいですね。

```shell:storage-server
$ sudo nextcloud.enable-https lets-encrypt
```

## OnlyOfficeの設定

### インストール

こちらもsnapでとっとと終わらせましょう。

```shell:doc-server
$ sudo snap install onlyoffice-ds
```

一旦これで非SSL環境は終了。

### SSL化

本当は最新版とか入れないといけないんでしょうが、
面倒なのでaptで入れちゃいます。

```shell:doc-server
$ sudo apt-get install -y letsencrypt
```

Let's encryptで証明書を発行する。

```shell:doc-server
$ sudo snap stop onlyoffice-ds
$ sudo letsencrypt certonly --standalone -d <<ドメイン名>> --agree-tos -m <<メールアドレス>>
```

コピー

```shell:doc-server
$ sudo cp /etc/letsencrypt/live/<<ドメイン>>/fullchain.pem /var/snap/onlyoffice-ds/current/var/www/onlyoffice/Data/certs/onlyoffice.crt
$ sudo cp /etc/letsencrypt/live/<<ドメイン名>>/privkey.pem /var/snap/onlyoffice-ds/current/var/www/onlyoffice/Data/certs/onlyoffice.key
$ sudo openssl dhparam -out /var/snap/onlyoffice-ds/current/var/www/onlyoffice/Data/certs/dhparam.pem
```

再起動

```shell:doc-server
$ sudo snap restart onlyoffice-ds
```

Let's encryptは期限が短いので、月に一度更新する必要がありますのでご注意ください。

### NextCloudにプラグインを入れていく

入れたプラグインは以下の通り。

#### Calendar

必須。共有カレンダーとして動作します。
それぞれの予定や家の予定も全部突っ込んで管理。

#### Group Folder

Nextcloudは、各個人のフォルダを共有する形になるため、
ホーム > 共有と辿りたくない。

Group Folderを使えば、共有フォルダとしてそれぞれのホームに出現するので、
1アクションでフォルダにアクセスすることができる。

- 家用
- 仕事用
- 子供の行事用

みたいな感じに分けて共通フォルダとして運用中。

#### Versions

バージョン管理を有効にしてくれるプラグイン。
企業マンには必須と言っても過言ではない。あんまり活用できてないけど。

#### Markdown Editor

地味に使ってる。
Markdownをブラウザで書けるので、
記事作成のプロットを作って共有するのに活用中。

もはやHachMDは不要となった。

## 顧客が本当に欲しかったもの

嫁氏「Officeあるんだからオンライン編集とか要らんて。」

結局、WebDAVからOffice開いた方が便利だということが判明し、doc-serverの役目は終わったとさ。

NextCloudは絶賛運用中です。
importパスにエイリアスをかけてパス指定を楽にする

# はじめに
フロントエンドの開発で嫌という程、経験したのですがプロジェクトが大きくなり階層構造が増えれば増えるほどimportによるパスの指定が複雑になってきます。
特に、ユーザによってデザインの出し分けをする場合、どこのコンポーネントを表示させるか相対パスで指定するのは悲惨でした（笑）
その解決策の１つとして、パスにエイリアスをかけてパス指定を楽にする方法を紹介します。

# 通常のパス指定
通常パスを指定する場合、今いるファイルからの相対パスで指定します。

```react
import Header from '../../../../../apartment/Header'
import Footer from '../../../../../house/Footer'
```

これでは、プロジェクトが大きくなって階層構造が増えるとパスの指定が非常にややこしくなります。

# エイリアスを使ったパス指定
webpack.config.jsにaliasを指定します。

```react:webpack.config.js
module.exports = {
  ...
  resolve: {
    alias: {
      '@apartment': path.resolve('src/components/designSet/apartment'),
      '@house': path.resolve('src/components/designSet/house'),
    }
  }
}
```

これで、エイリアスを指定しなかったパスを簡単に指定することができます。

```react
// src/components/designSet/apartment/Headerのエイリアス
import Header from '@apartment/Header'
// src/components/designSet/house/Headerのエイリアス
import Footer from '@house/Footer'
```

解決
テクニカルな書き方とは何かの説明。

まず初めに、「テクニカルな書き方とは何か」について説明しておきたいと思います。

記念すべき初投稿になります。

####そもそも

テクニカルな書き方（コード）とは何でしょうか。

私は、

- 簡潔さ
- イメージしやすさ
- 処理性能の高さ
- メンテナンスのしやすさ

だと思っています。

例えば、以下のようなコードを見たときの第一印象はどうでしょうか。
私は、やたら長く、書くのが面倒くさそうな、何をやってるのかイメージしにくいコードだと思いました。

```test.c
int fact(int a) {
...
if (a == 0)
   return 1;
else if (a == 1)
   return 1;
else if (a == 2)
   return 2;
else if (a == 3)
   return 6;
else if (a == 4)
...
}
```
if文の代わりに、switch文で書き直してみましょう。
どうでしょうか。
あいかわらず、長ったらしく、書くのも面倒くさそうではありますが、
簡潔さ、イメージのしやすさという点では少しばかり「改善」しているように感じます。

```test2.c
int fact(int a) {
...
   switch(a) {
      case 0:
         return 1; break;
      case 1:
         return 1; break;
      case 2:
         return 2; break;
      case 3:
         return 6; break;
      case 4:
      ...
   }
}
```
以上は、単にif文をswitch文に置き換えただけの例ですが、

テクニカルな書き方とは、これら「選択」の積み重ねのうえに生まれる至高の書き方とも言えます。

if文とswitch文どちらを選択するかは、書き手の「センス」と「経験」によると言えるでしょう。
####さらに
テクニカルなコードを記述するためには、「言語仕様の理解」も欠かせません。

先の例では、if文をswitch文に置き換えるといった構文的な変更の例でしたが、
例えば、ポリモーフィズム（多相性）的な書き方を許す言語であれば、条件分岐そのものを取り外すことができるのでよりスッキリさせることが出来ます。

その点で、テクニカルな書き方の可否は言語仕様に依存しているとも言えます。
####関連するものとして
コードの改善を試みるための技術[「リファクタリング」](https://ja.m.wikipedia.org/wiki/リファクタリング_(プログラミング))や、コードに対する感性[「コードの臭い」](https://ja.wikipedia.org/wiki/コードの臭い)などが挙げられます。
参考にしていただければ幸いです。
普段JISキーボードを使っている僕がHHKB HYBRID Type-SのUSキーボードを買って設定した話

![EMmsR0EU8AA9jDC.jfif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/292551/641e1ef3-be20-482c-97a1-30553232c267.jpeg)

いやー買っちゃいましたよ！

以前からHHKBいいなーって思いながらお金ないしーって我慢してきたんですけど、
4000円ぐらいするキーボードルーフが先着3000名についてくるっていうんで、
気が付いたら、自分へのクリスマスプレゼントだって自分に言い聞かせて買っていました。

ニンテンドースイッチはなかなか買わなかったのに、(まだ買ってないのに)
それよか高いキーボード買うっておかしな話です笑

さて、閑話休題

今回は
windowsもmacもubuntuも使う、
そして普段はJISキーボード使い、
Mac風配列使い
の僕がひとまずwindowsで今まで通り使えるように設定した話です。

# HHKBを買う前の話(今回のゴール)

* JISキーボード使い
* WindowsノートPC所有(JIS)
* 仕事場でmac、大学の研究室でubuntu使用
* macのキー配列に似せるため、無変換→英数、変換→かな、になるように変更

# 使ったもの、やったこと

* DIPスイッチの設定
* レジストリの書き換え
* Autohotkeyの使用

## DIPスイッチの設定

switch1と3がONで他はOFFにしました。

windowsでの設定なので、1をONに、
DeleteキーをBackSpaceにしたかったので3をONにしました。

## レジストリの書き換え

WindowsのノートPCで使用する予定なのですが、PC本体のキーボードはJISなんです...
通常の設定から行うキーボードの設定でUSキーボードに変更してしまうと、本体キーボードもUSになってしまうんです...

なので外部キーボードのみUSになるようにしました。

1. まずwindowsメニューでレジストリエディターを検索し、起動します。
2. `¥ HKEY_LOCAL_MACHINE ¥ SYSTEM ¥ CurrentControlSet ¥ Services ¥ i8042prt ¥ Paremeters` の中のLayerDriver JPNをkbd106.dllからkbd101.dllに変更します。
3. PCを再起動します。

これでhhkbのみus配列で本体キーボードはJIS配列になります。

=>と調べた限りではなっていたのですが、うまくいかなかったです。
また、デバイスインスタンスパスでデバイス指定してもできなかったので、現在調査中...

## Autohotkeyの使用

本来hhkbのus配列は全角半角の切り替えを ファンクションキー+` で行います。
しかし、普段JISキーボードではスペースの左右の無変換、変換キーが英数、かなになっています。
その変更のためにAutohotkeyを使って◇(左)を無変換に、◇(右)を変換に変えました。
また、普段右Altキーは使わないのでwindowsキーにしました。

1. Autohotkeyのダウンロード+インストール
2. 設定ファイルの作成
3. 設定ファイルがwindows起動時に読み込まれるよう設定

1. Autohotkeyのダウンロード+インストール

[公式ページ](https://www.autohotkey.com/)ここからダウンロードして。exeファイルを実行しました。

2. 設定ファイルの作成

```
RAlt::RWin
LWin::Send,{vk1Dsc07B}
RWin::Send,{vk1Csc079}
```

という内容のファイルを作成して適当なところに保存しました。
拡張子はahkです。

3. 設定ファイルがwindows起動時に読み込まれるよう設定

2で作成したahkファイルのショートカットを作成し、
エクスプローラーに `shell:startup` と入力しアクセスした先にショートカットを移動させます。


# おわりに

以上の設定でWindows起動時にus配列のhhkbをwindowsでmac風に使用することができるようになりました。

昔にレジストリいじってwindows吹っ飛ばして、OSを入れなおしたことがあるので、
ホントはレジストリをいじりたくはなかったのですがこのような形になりました。